Configuring hooks
Hooks live in~/.geoff/config.toml as an array of [[hooks]] tables:
After editing
config.toml, run geoff doctor config to validate it, then start a new session. View active hooks in the TUI with the /hooks command.
Events
Hooks can fire on any of these lifecycle events:Input and output protocol
Each hook command receives a single JSON object on stdin with the session ID, working directory, event name, and event-specific fields (such astool_name, tool_input, or tool_output). It signals its decision through its exit code:
For finer control, a hook can exit
0 and print structured JSON declaring a permissionDecision (allow / deny) with a reason.
Examples
Auto-format after edits
Protect sensitive files
Notify when a turn ends
Behavior notes
- Fail-open — a hook that times out or crashes does not block the operation; the agent continues.
- Parallel — multiple hooks bound to the same event run concurrently.
- Loop-safe —
Stophooks carry astop_hook_activeflag so a hook that re-triggers a turn can’t loop forever.
Related
Config Files
Where hooks are declared, alongside the rest of your config.
Command Reference
Use
geoff doctor to validate your hook config.