Skip to main content
Hooks run a shell command or send an HTTP request when something happens in Enconvo, such as an agent starting, completing, failing, or using a tool. You set them up in a JSON file, so you can add notifications, logs, local automation, or integrations without building an extension.
Most hooks are fire-and-forget: they run in the background and don’t block Enconvo. PreToolUse, Stop, and SubagentStop are the exception during agent runs. The agent waits for them, so they can block a tool call or send the agent back to work. See Blocking hooks.

Quick start

1

Create the hooks folder

2

Create ~/.enconvo/hooks.json

3

Trigger an agent

Start any agent or chat command. When its status changes, Enconvo runs the configured command and appends a line to /tmp/enconvo-hooks.log.

Config file

Hooks live in:
Enconvo also reads the legacy file at ~/.config/enconvo/hooks.json when the new file doesn’t exist. If both files exist, ~/.enconvo/hooks.json wins. The file is read again whenever an event fires, so you can edit hooks while Enconvo is running. You don’t need to restart.

Manage hooks in Settings

Open Settings → Hooks to see the hooks in ~/.enconvo/hooks.json, grouped by event. Turn an entry on or off with its switch, or click Open hooks.json to edit the file. Turning an entry off or on writes enabled: false or enabled: true on that entry, without changing its command or webhook.

How hooks work

When an event fires, Enconvo:
  1. Loads ~/.enconvo/hooks.json.
  2. Falls back to ~/.config/enconvo/hooks.json only if the new file is absent.
  3. Finds entries inside the top-level hooks object whose key matches the event name.
  4. Applies the optional matcher regex.
  5. Skips entries where enabled is false.
  6. Runs every configured hook concurrently.
Hook event names follow the Claude Code and Codex lifecycle set: SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, Stop, and SubagentStop. The old Enconvo event names and the old flat JSON shape still work for existing installs, but new writes use the wrapped Codex-style format.

Configuration reference

Command hook

A command hook runs a shell command. Enconvo writes the event payload to the command’s stdin as JSON.

HTTP hook

An HTTP hook sends the event payload as the JSON request body.

Blocking hooks

During an agent or bot run, three events run as blocking hooks. The agent waits for every matching hook (they run in parallel) before it continues, and reads their result the same way Claude Code and Codex do. A hook decides in one of two ways:
  • Exit code 2 blocks. The text the command writes to stderr is the reason.
  • Exit code 0 with JSON on stdout. Any other output, exit code, error, or timeout decides nothing, and the run continues as if the hook weren’t there.
HTTP hooks decide with a 2xx response whose body is the same JSON. When several hooks match, a deny wins over ask, which wins over allow. The reasons are joined, and the last updatedInput is used. A Stop hook can send the agent back at most 5 times in one turn. On the second and later checks, stop_hook_active is true, so a hook can let the agent stop once its instruction has been followed. Stop blocking applies only when the agent finishes normally; a failed or stopped run still fires Stop in the background.
The agent waits for blocking hooks, so a slow PreToolUse hook slows every tool call, and a slow Stop hook delays the end of the turn. Keep them fast, set a short timeout, or run slow work in the background (command &).
Blocking hooks receive the regular event payload plus the Claude Code fields at the top level:
Stop and SubagentStop receive stop_hook_active and last_assistant_message instead of the tool fields. Command hooks run in the agent’s working directory.

Block a dangerous command

Make the agent run tests before finishing

Event payload

Command hooks receive this JSON on stdin. HTTP hooks receive the same JSON as the request body.
Background hooks get the Claude Code fields too: hook_event_name, session_id when the event has one, and, for tool events, tool_name, tool_input, and tool_use_id.

Available events

Legacy Enconvo names such as run_status_changed and agent_tool_step_changed still work, so existing hook files don’t need to be migrated right away.

Recipes

macOS notification when an agent fails

Log agent status changes

Log agent tool calls

Send to Slack

Custom script

Create a script that reads the event payload from stdin:
Reference it from ~/.enconvo/hooks.json:
Make the script executable:

Troubleshooting

Test a script by hand

Pipe a sample payload into the script:

Agents

Learn about Enconvo agents and custom bots

Extension API Reference

Build extensions that emit or listen to events