Loading...
Loading...
Use when Claude Code should do something by itself - at session start (`SessionStart`), on every prompt (`UserPromptSubmit`), or after each response (`Stop`) - or when that automation misbehaves. Symptoms: a hook script that runs but whose output never reaches the model, a session that keeps restarting its own turn with no user input, a hook that works locally but does nothing in a web session. Also for writing or reviewing a `hooks` entry in `.claude/settings.json` or a script under `.claude/hooks/`.
npx skill4agent add normanderwan/claude-casebook write-hook| Event | How its output reaches the model |
|---|---|
| stdout on exit 0 is added to context as-is |
| stdout is NOT. Emit JSON with |
Stop{
"hookSpecificOutput": {
"hookEventName": "Stop",
"additionalContext": "..."
}
}Stopstop_hook_activeStopStopstop_hook_activeINPUT=$(cat)
if printf '%s' "$INPUT" | grep -Eq '"stop_hook_active"[[:space:]]*:[[:space:]]*true'; then
exit 0
fiStopSessionStartUserPromptSubmitStopstop_hook_active| Substitute seen in review | Why it is not one |
|---|---|
| Marker file, once-per-session flag | Not turn-scoped. Silences the hook for the rest of the session, and a stale or wiped file changes behaviour |
Matching the reminder text in | Depends on the model repeating a string. A guard that the model can decline to honour is not a guard |
| "It exits 0 / never blocks / is idempotent" | Describes the exit path, not the re-fire. See the table below |
| Excuse | Reality |
|---|---|
" | This is the reasoning that produced the four-turn cascade. Injecting context restarts the turn on its own; blocking is a separate mechanism |
"My dedupe is strictly stronger than | Stronger at something else. It is session-scoped, not turn-scoped, and it lives outside the harness |
| "Add the guard after the demo / after the release" | Four lines. The cascade fires on the first live turn, in front of whoever is watching |
| "The reviewer said it is cargo cult" | Ask them for a |
Stop| Fact | Consequence |
|---|---|
Hooks in a repo's | Commit the hook, or it does not exist in a web session |
| Never make persistence depend on it. Commit and push as work is produced |
| The only dependable per-turn hook point |
Stop