Lifecycle hooks
Since v0.7.2, Zagens can run user-defined shell commands at agent lifecycle points — for audit, policy injection, env vars, or enterprise integration.
Where to configure
| Surface | Role |
|---|---|
| Settings → Hooks | Edit global [hooks] in ~/.zagens/config.toml; save restarts the sidecar |
| Project tree | {workspace}/.zagens/hooks.toml, .zagens/hooks.json, .cursor/hooks.json |
Merge order: global config → project TOML → project JSON → Cursor hooks; project entries append after global.
Common events
| Event | Blocking? | When |
|---|---|---|
session_start / session_end |
No | Session start / shutdown |
message_submit |
Yes | Before user message hits the LLM |
tool_call_before / tool_call_after |
Before yes / after no | Before / after tool execution |
shell_env |
No | Before each exec_shell; stdout merged as env vars |
pre_compact / post_compact |
No | Before / after context compaction |
subagent_start / subagent_end |
Before yes / after no | Before sub-agent spawn / on terminal state |
Cursor-style aliases supported (e.g. beforeShell → tool_call_before + exec_shell filter).
Blocking vs background
- Blocking hooks may return
denyor modify stdin JSON to cancel or reshape tools/messages. background=trueis ignored on blocking events so deny still works.- Per-hook timeout overrides global
default_timeout_secs.
I/O protocol
Sync hooks read JSON context on stdin (session id, tool name, workspace, …) and return JSON actions on stdout (allow / deny / modify, …). See product repo docs/desktop/HOOKS.md for the full schema.
Example uses
tool_call_before: blockexec_shelltouching production pathsshell_env: injectCI=trueor proxy varsmessage_submit: redact or block prompts with secretssubagent_start: log CRAFT spawns to your SIEM
Tips
- Keep scripts idempotent and fast; long work belongs in
tool_call_after+ background. - Validate in a test workspace before attaching to production repos.
- Layer with Tool approval and Windows sandbox — hooks do not replace them.
Related: Scheduled tasks · Shell tools · CRAFT