You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+72Lines changed: 72 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -521,6 +521,78 @@ Stop:
521
521
decision: "block"
522
522
reason: "Stopping Claude in this directory may lose work context"
523
523
```
524
+
### PostToolUse JSON Output
525
+
526
+
PostToolUse hooks support JSON output format for Claude Code integration. Actions can return structured output with decision control and additional context:
527
+
528
+
**Output Action** (type: `output`):
529
+
```yaml
530
+
PostToolUse:
531
+
- actions:
532
+
- type: output
533
+
message: "Additional context message"
534
+
decision: "block" # optional: "block" only; omit to allow tool result
535
+
reason: "Reason for blocking" # required when decision is "block"
536
+
```
537
+
538
+
**Command Action** (type: `command`):
539
+
Commands must output JSON with the following structure:
540
+
```json
541
+
{
542
+
"continue": true,
543
+
"decision": "block",
544
+
"reason": "Detailed reason for blocking",
545
+
"hookSpecificOutput": {
546
+
"hookEventName": "PostToolUse",
547
+
"additionalContext": "Message to display"
548
+
},
549
+
"systemMessage": "Optional system message"
550
+
}
551
+
```
552
+
553
+
Note: To allow the tool result, omit the `decision` field entirely.
554
+
555
+
**Important**: PostToolUse executes **after** tool execution completes. The tool cannot be blocked (it already ran). Setting `decision: "block"` prompts Claude with the reason but does not prevent tool execution.
556
+
557
+
**Field Merging**:
558
+
When multiple actions execute:
559
+
- `continue`: Always `true` (cannot be changed for PostToolUse)
560
+
- `decision`: Last value wins (no early return - all actions execute)
561
+
- `reason`: Reset when decision changes; concatenated with newline within same decision
562
+
- `hookEventName`: Set once by first action
563
+
- `additionalContext`: Concatenated with newline separator
564
+
- `systemMessage`: Concatenated with newline separator
565
+
- `stopReason` and `suppressOutput`: Last value wins
566
+
567
+
**Exit Code Behavior**:
568
+
PostToolUse hooks **always exit with code 0**. The `decision` field controls whether Claude is prompted with the reason:
569
+
- `decision` field omitted: Tool result accepted normally
570
+
- `"block"`: Claude is prompted with the reason (tool execution already complete)
571
+
572
+
Errors are logged to stderr as warnings, but cchook continues to output JSON and exits successfully. On errors, `decision` defaults to `"block"` for safety (fail-safe).
573
+
574
+
**Backward Compatibility**:
575
+
Prior to JSON output support, PostToolUse hooks used exit codes:
576
+
- `exit_status`field controlled blocking behavior
577
+
578
+
After JSON migration:
579
+
- `exit_status`field is **ignored** in output actions
580
+
- Use `decision` field instead: omit for allow, `"block"` to prompt Claude
581
+
- A stderr warning is emitted if `exit_status` is set (migration reminder)
0 commit comments