Skip to content

Commit e0226f7

Browse files
authored
Merge pull request #176 from Lint111/agent/split-hook-lifecycle
fix(hooks): reawaken jobs without replacing user hooks
2 parents e8681f5 + 3c903b3 commit e0226f7

5 files changed

Lines changed: 467 additions & 56 deletions

File tree

docs/claude-code-hooks-reference.md

Lines changed: 88 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
> Official documentation for Claude Code hooks system, extracted from [code.claude.com](https://code.claude.com/docs/en/hooks).
44
5-
**Last Updated**: 2026-01-24
5+
**Last Updated**: 2026-07-25
66
**Source**: [Claude Code Hooks Documentation](https://code.claude.com/docs/en/hooks)
77

8+
> This is a maintained summary, not an exhaustive copy of the upstream reference.
9+
> Check the source link for event-specific schemas before adding a new hook.
10+
811
---
912

1013
## Overview
1114

1215
Hooks are automated scripts that execute at specific events during your Claude Code session. They allow you to:
16+
1317
- Validate, modify, or block tool usage
1418
- Add context to prompts
1519
- Implement custom workflows
@@ -21,12 +25,12 @@ Hooks are automated scripts that execute at specific events during your Claude C
2125

2226
Hooks are configured in settings files:
2327

24-
| File | Scope |
25-
|------|-------|
26-
| `~/.claude/settings.json` | User (global) |
27-
| `.claude/settings.json` | Project |
28+
| File | Scope |
29+
| ----------------------------- | -------------------------- |
30+
| `~/.claude/settings.json` | User (global) |
31+
| `.claude/settings.json` | Project |
2832
| `.claude/settings.local.json` | Local project (gitignored) |
29-
| Plugin hook files | Plugin-specific |
33+
| Plugin hook files | Plugin-specific |
3034

3135
### Basic Structure
3236

@@ -49,8 +53,9 @@ Hooks are configured in settings files:
4953
```
5054

5155
**Key Fields**:
56+
5257
- `matcher`: Pattern to match tool names (case-sensitive, supports regex like `Edit|Write` or `*` for all)
53-
- `type`: `"command"` for bash or `"prompt"` for LLM-based evaluation
58+
- `type`: `"command"`, `"http"`, `"mcp_tool"`, `"prompt"`, or `"agent"` where the event supports it
5459
- `command`: Bash command to execute
5560
- `prompt`: LLM prompt for evaluation (prompt-based hooks only)
5661
- `timeout`: Optional timeout in seconds (default: 60)
@@ -59,22 +64,28 @@ Hooks are configured in settings files:
5964

6065
## Hook Events
6166

67+
Claude Code's current event surface is broader than the detailed subset below. In
68+
particular, `TeammateIdle` and `TaskCompleted` are supported lifecycle events used
69+
by Codeman; they are not stale or plugin-defined event names.
70+
6271
### PreToolUse
6372

6473
**When**: After Claude creates tool parameters, before processing the tool call.
6574

6675
**Use Cases**: Approval, denial, or modification of tool calls.
6776

6877
**Common Matchers**:
78+
6979
- `Bash` - Shell commands
7080
- `Write` - File writing
7181
- `Edit` - File editing
7282
- `Read` - File reading
73-
- `Task` - Subagent tasks
83+
- `Agent` - Subagent tasks
7484
- `WebFetch`, `WebSearch` - Web operations
7585
- `mcp__<server>__<tool>` - MCP tools
7686

7787
**Output Control**:
88+
7889
```json
7990
{
8091
"hookSpecificOutput": {
@@ -96,13 +107,14 @@ Hooks are configured in settings files:
96107
**Use Cases**: Auto-approve or deny permissions.
97108

98109
**Output Control**:
110+
99111
```json
100112
{
101113
"hookSpecificOutput": {
102114
"hookEventName": "PermissionRequest",
103115
"decision": {
104116
"behavior": "allow|deny",
105-
"updatedInput": { },
117+
"updatedInput": {},
106118
"message": "deny reason",
107119
"interrupt": false
108120
}
@@ -117,6 +129,7 @@ Hooks are configured in settings files:
117129
**Use Cases**: Provide feedback, run formatters/linters, log operations.
118130

119131
**Output Control**:
132+
120133
```json
121134
{
122135
"decision": "block",
@@ -128,15 +141,30 @@ Hooks are configured in settings files:
128141
}
129142
```
130143

144+
#### Asynchronous Rewake
145+
146+
Command hooks can set `"asyncRewake": true` to run asynchronously and wake an
147+
idle Claude turn when the hook exits with code 2. The hook's stderr is delivered
148+
to Claude as a system reminder. This implies `"async": true`; ordinary async
149+
hooks do not wake an idle turn, and their output waits for the next interaction.
150+
151+
Codeman uses this on `PostToolUse(Bash)`: a self-contained Node helper extracts
152+
the background task ID from the Bash result, watches the session transcript for
153+
the matching completion notification, and exits 2. It does not send terminal
154+
input, so it cannot submit a user's partially written prompt.
155+
131156
### Notification
132157

133158
**When**: When Claude Code sends notifications.
134159

135160
**Matchers**:
161+
136162
- `permission_prompt`
137163
- `idle_prompt`
138164
- `auth_success`
139165
- `elicitation_dialog`
166+
- `elicitation_complete`
167+
- `elicitation_response`
140168

141169
### UserPromptSubmit
142170

@@ -145,6 +173,7 @@ Hooks are configured in settings files:
145173
**Use Cases**: Add context, validate, or block prompts.
146174

147175
**Output Control**:
176+
148177
```json
149178
{
150179
"decision": "block",
@@ -165,6 +194,7 @@ Hooks are configured in settings files:
165194
**Use Cases**: **Ralph Wiggum loops** - block exit and refeed prompt.
166195

167196
**Output Control**:
197+
168198
```json
169199
{
170200
"decision": "block",
@@ -173,6 +203,7 @@ Hooks are configured in settings files:
173203
```
174204

175205
Or to allow exit:
206+
176207
```json
177208
{
178209
"continue": true,
@@ -184,15 +215,32 @@ Or to allow exit:
184215

185216
### SubagentStop
186217

187-
**When**: When a subagent (Task tool call) finishes responding.
218+
**When**: When a subagent (Agent tool call) finishes responding.
188219

189220
**Use Cases**: Control nested loops, verify subagent output.
190221

222+
### TeammateIdle
223+
224+
**When**: When an agent-team teammate is about to go idle.
225+
226+
**Use Cases**: Reassign work, continue a teammate loop, or notify an orchestrator.
227+
228+
**Matcher Support**: None. The hook fires for every occurrence.
229+
230+
### TaskCompleted
231+
232+
**When**: When a task is about to be marked completed.
233+
234+
**Use Cases**: Validate completion or forward team progress to an external UI.
235+
236+
**Matcher Support**: None. The hook fires for every occurrence.
237+
191238
### PreCompact
192239

193240
**When**: Before a compact operation.
194241

195242
**Matchers**:
243+
196244
- `manual` - Invoked from `/compact`
197245
- `auto` - Invoked from auto-compact
198246

@@ -201,6 +249,7 @@ Or to allow exit:
201249
**When**: When Claude Code starts or resumes a session.
202250

203251
**Matchers**:
252+
204253
- `startup` - Fresh start
205254
- `resume` - From `--resume`, `--continue`, or `/resume`
206255
- `clear` - From `/clear`
@@ -209,6 +258,7 @@ Or to allow exit:
209258
**Use Cases**: Load development context, set environment variables.
210259

211260
**Persisting Environment Variables**:
261+
212262
```bash
213263
#!/bin/bash
214264
if [ -n "$CLAUDE_ENV_FILE" ]; then
@@ -219,6 +269,7 @@ exit 0
219269
```
220270

221271
**Output Control**:
272+
222273
```json
223274
{
224275
"hookSpecificOutput": {
@@ -233,6 +284,7 @@ exit 0
233284
**When**: When a session ends.
234285

235286
**Reason Values**:
287+
236288
- `clear`
237289
- `logout`
238290
- `prompt_input_exit`
@@ -254,14 +306,15 @@ Hooks receive JSON via stdin with common fields:
254306
"permission_mode": "default",
255307
"hook_event_name": "PreToolUse",
256308
"tool_name": "Bash",
257-
"tool_input": { },
309+
"tool_input": {},
258310
"tool_use_id": "toolu_01ABC123..."
259311
}
260312
```
261313

262314
### Tool-Specific Input
263315

264316
**Bash**:
317+
265318
```json
266319
{
267320
"tool_name": "Bash",
@@ -274,6 +327,7 @@ Hooks receive JSON via stdin with common fields:
274327
```
275328

276329
**Write**:
330+
277331
```json
278332
{
279333
"tool_name": "Write",
@@ -285,6 +339,7 @@ Hooks receive JSON via stdin with common fields:
285339
```
286340

287341
**Edit**:
342+
288343
```json
289344
{
290345
"tool_name": "Edit",
@@ -302,11 +357,11 @@ Hooks receive JSON via stdin with common fields:
302357

303358
### Exit Codes
304359

305-
| Code | Behavior |
306-
|------|----------|
307-
| 0 | Success. `stdout` processed (shown in verbose or added as context) |
308-
| 2 | Blocking error. Only `stderr` used. Blocks tool/prompt based on event |
309-
| Other | Non-blocking error. `stderr` shown in verbose, execution continues |
360+
| Code | Behavior |
361+
| ----- | --------------------------------------------------------------------- |
362+
| 0 | Success. `stdout` processed (shown in verbose or added as context) |
363+
| 2 | Blocking error. Only `stderr` used. Blocks tool/prompt based on event |
364+
| Other | Non-blocking error. `stderr` shown in verbose, execution continues |
310365

311366
### JSON Output (Exit Code 0)
312367

@@ -323,7 +378,12 @@ Hooks receive JSON via stdin with common fields:
323378

324379
## Prompt-Based Hooks
325380

326-
For Stop and SubagentStop events, you can use LLM-based evaluation:
381+
Prompt and agent handlers are supported by decision-oriented events including
382+
`PreToolUse`, `PermissionRequest`, `PostToolUse`, `PostToolUseFailure`,
383+
`PostToolBatch`, `UserPromptSubmit`, `Stop`, `SubagentStop`, `TaskCreated`, and
384+
`TaskCompleted`. Check the upstream reference before choosing a handler type.
385+
386+
For example, a Stop event can use LLM-based evaluation:
327387

328388
```json
329389
{
@@ -344,6 +404,7 @@ For Stop and SubagentStop events, you can use LLM-based evaluation:
344404
```
345405

346406
**LLM Response Format**:
407+
347408
```json
348409
{
349410
"ok": true,
@@ -362,17 +423,18 @@ Hooks can be defined in Skills, Agents, and Slash Commands using frontmatter:
362423
name: secure-operations
363424
hooks:
364425
PreToolUse:
365-
- matcher: "Bash"
426+
- matcher: 'Bash'
366427
hooks:
367428
- type: command
368-
command: "./scripts/security-check.sh"
429+
command: './scripts/security-check.sh'
369430
---
370431
```
371432

372433
These hooks:
434+
373435
- Are scoped to the component's lifecycle
374436
- Only run when that component is active
375-
- Support: PreToolUse, PostToolUse, Stop
437+
- Support all hook events; a subagent-scoped `Stop` is converted to `SubagentStop`
376438

377439
---
378440

@@ -550,11 +612,11 @@ exit 0
550612

551613
## Environment Variables
552614

553-
| Variable | Description |
554-
|----------|-------------|
555-
| `CLAUDE_PROJECT_DIR` | Project root directory |
556-
| `CLAUDE_CODE_REMOTE` | `"true"` for web, empty for CLI |
557-
| `CLAUDE_ENV_FILE` | Path to write persistent env vars (SessionStart) |
615+
| Variable | Description |
616+
| -------------------- | ------------------------------------------------ |
617+
| `CLAUDE_PROJECT_DIR` | Project root directory |
618+
| `CLAUDE_CODE_REMOTE` | `"true"` for web, empty for CLI |
619+
| `CLAUDE_ENV_FILE` | Path to write persistent env vars (SessionStart) |
558620

559621
---
560622

@@ -593,4 +655,4 @@ Use `/hooks` command to view registered hooks and make changes.
593655

594656
---
595657

596-
*Source: [Claude Code Hooks Documentation](https://code.claude.com/docs/en/hooks)*
658+
_Source: [Claude Code Hooks Documentation](https://code.claude.com/docs/en/hooks)_

0 commit comments

Comments
 (0)