Skip to main content
The ChatCLI Hooks System lets you execute automatic actions in response to application lifecycle events. With hooks, you can auto-format code after edits, send notifications, block dangerous commands, log audit trails, and much more.
Hooks are additive: global and workspace configurations are merged. Workspace hooks complement global ones — they never replace them.

Configuration

Hooks are defined in JSON files at two levels:
Workspace hooks are additive — they combine with global hooks. If the same event has hooks at both levels, all are executed (global first, then workspace).

File Structure


Available Events

ChatCLI emits 8 lifecycle events that hooks can bind to: Compaction events carry a trigger field (auto, manual, recovery) and, on PostCompact, an outcome (applied when the history changed, skipped when nothing changed: no-op, rejected summary, failure) in the JSON payload and in CHATCLI_HOOK_TRIGGER / CHATCLI_HOOK_OUTCOME; every PreCompact is paired with exactly one PostCompact, so a hook can snapshot the transcript before an automatic rewrite, log manual /compact runs separately, or alert on overflow recoveries. PreCompact runs synchronously before the history changes; PostCompact runs detached from the turn.
The PreToolUse event is blocking: if the hook returns exit code 2, the tool execution is blocked. This allows you to create guardrails that prevent dangerous operations.

Hook Types

Executes a shell command on the operating system. The command has access to environment variables with event context.
Exit codes:
  • 0 — Success (execution continues normally)
  • 1 — Error (logged, but does not block)
  • 2 — Blocks the operation (only for PreToolUse)
The command is executed via sh -c on Linux/macOS and cmd /c on Windows.

ToolPattern — Tool Filtering

The toolPattern field lets you filter which tools trigger the hook. It accepts glob patterns:

Environment Variables

Command hooks receive environment variables with event context: Everything else about the event — tool arguments and output, the user prompt, the working directory, the error message — arrives as the JSON payload on stdin (toolArgs, toolOutput, userPrompt, workingDir, error, trigger); read it with jq when a hook needs more than the four variables above.

Turning Hooks Off

Hooks also never fire inside a chatcli eval run, whatever that variable says. Each eval candidate is a real chatcli process, so without this rule a hook that runs an eval would fire again inside every candidate the eval spawns, without end, and a UserPromptSubmit hook that injects context would change the result being measured. The eval harness also sets CHATCLI_HOOKS_ENABLED=false on each candidate.

Complete Examples

Auto-format Go files after any edit:

Use Cases

Auto-Format

Run formatters (gofmt, prettier, black) automatically after file edits.

Notifications

Send alerts to Slack, Discord, or email at the end of sessions or on errors.

Guardrails

Block dangerous commands (rm -rf, DROP TABLE, force push) with PreToolUse.

Audit

Log all agent actions to files for compliance.

Auto-Test

Run tests automatically after every code edit.

Linting

Run linters (golangci-lint, eslint) after every write/patch.

Running an Eval from a Hook

A hook can run an eval suite, for example a cheap check when you leave the REPL that warns you only on a regression. An eval takes seconds to minutes and SessionEnd runs while ChatCLI shuts down, under the hook timeout (10 s by default). The hook therefore starts the eval in the background and returns at once, with its output going to a file so nothing waits on it.
~/.chatcli/hooks.json
~/.chatcli/hooks/eval-smoke.sh
Exit code 3 means a regression against the baseline. Replace osascript (macOS) with notify-send on Linux, or with a curl to a chat webhook. To run the eval only when you change something that shapes behavior, such as a skill or a slash command, use PostToolUse with "toolPattern": "@coder" and have the script check toolArgs on stdin for .chatcli/skills or .chatcli/commands. You do not need a recursion guard: hooks do not fire inside the eval’s own runs.

Next Steps

Coder Security

Security policies and approval for coder operations.

Security

Understand the ChatCLI security model.

Compact UI

Minimalist display mode for coder mode.

Coder Mode

The full engineering cycle with integrated hooks.