Chapter 8: jevhooks-events/src, thirty-three events and three roles
Claude Code 2.1.287 raises thirty-three kinds of settings-hook event, and
HookEvent in lib.rs names every one, spelled exactly as the
hooks are (PreToolUse, Stop, UserPromptSubmit, ...). The plugin's
claim is "every Claude Code hook event backed by Jev", and this is where
that is made concrete: every event has a role, and the function that
gives it one, HookEvent::role, has no default case.
| Role | Events | What happens |
|---|---|---|
Decide | PreToolUse, Stop | Sent to the daemon and waited on: the answer changes what happens. |
Observe | UserPromptSubmit, PostToolUse, PostToolUseFailure, PermissionDenied, SessionEnd | Sent to the daemon without waiting: the daemon needs them to decide (the prompt a turn's end is judged against, what became of a command it judged, a session to forget). |
Ignore | the other twenty-six | Not sent. Nothing is judged on them, or needed for a judgment, yet. |
Aside: why "no default case" matters. In Rust a
matchmust cover every variant, or the program does not compile.rolelists all thirty-three by name, with no_ =>catch-all. So the day Claude Code adds a thirty-fourth event and someone adds it toHookEvent, the build stops until they say what is done with it. An event cannot slip in as "ignored" because nobody thought about it.
Then two more types for the answer:
Verdict:Allow(run it without asking),Ask(ask the user first, or, for aStop, do not stop yet),Pass(no opinion: whatever would have happened without the plugin happens). Lowercase on the wire.Decision: the daemon's whole answer to a deciding event: theverdict, alinefor the user (what Jev said and how sure it was, or why nothing was asked),ms(the daemon's time, Jev included) andsession_usd(what this session's questions have cost so far).
Try it.
cargo test -p jevhooks-events.every_event_is_listed_oncewalksHookEvent::ALLand checks for thirty-three distinct events;names_are_the_hook_nameschecks thatPreToolUsetravels as"PreToolUse"and that"Stop"reads back asStop.
For the people who maintain it
Roles are not the whole routing. The mod narrows them per call (chapter 10): a tool event for anything but Bash, or for a plainly read-only Bash command, is ignored whatever its role says.
In this folder
| Path | What |
|---|---|
| lib.rs | HookEvent and HookEvent::ALL, HookEvent::role, Role, Verdict, Decision, and the two tests. |
← Previous: Chapter 7, jevhooks-events/ · Up: jevhooks-events · Next: Chapter 9, jevhooks-mod/ →