Skip to main content
Hooks let you run custom logic at key points during Agent execution in QoderWork — no source code changes required. Edit a JSON config file to:
  • Block dangerous operations before a tool runs
  • Auto-lint after every file write to enforce code style
  • Send a desktop notification when the Agent finishes, so you don’t have to watch the screen
Unlike prompt instructions, hooks are deterministic — when the event fires, your script runs. No model interpretation, no drift.

Quick Start

Here is an example that blocks rm -rf commands:
1

Create the script

2

Add the config

Add the following to ~/.qoderwork/settings.json:
3

Verify it works

Open QoderWork and ask the Agent to run a command containing rm -rf. The hook blocks execution and feeds the error message back to the Agent.

Configuring Hooks

Config File Location

QoderWork loads hook configurations from the user-level settings file:
Hot reload is not yet supported — restart QoderWork after editing hook configurations for changes to take effect.

Config Format

You can define multiple matcher groups under a single event, and each group can contain multiple hook commands.

Matcher Rules

matcher determines when a hook fires. What it matches against depends on the event (see each event’s description).

Writing Hook Scripts

Hook scripts receive JSON input via stdin and communicate results through their exit code and stdout. This section covers the input/output format common to all events. For event-specific fields, see Hook Events.
QoderWork currently does not inject environment variables into hook scripts. All data is passed via stdin JSON. If you need session ID, working directory, or tool information, parse them from the stdin JSON input.

Input

Your hook script receives JSON data via stdin. Every event includes these common fields: Each event adds its own fields on top of these (see the individual event descriptions). Parse the input with jq:

Output

Hooks communicate results through exit code and stdout. The exit code determines the basic behavior: 0 for success, 2 for blocking (stderr content is injected into the conversation, only effective for blockable events), other values are non-blocking errors. stdout JSON (only parsed on exit 0) provides fine-grained control for some events — see each event’s description for supported fields. stdout is ignored when exit code is non-zero.

Hook Events

SessionStart

Fires when a session starts. Matcher: Session source Extra input fields:

SessionEnd

Fires when a session ends. Matcher: End reason Extra input fields:

UserPromptSubmit

Fires after the user submits a prompt, before the Agent processes it. Extra input fields:

PreToolUse

Fires before a tool executes. Can block tool execution. Matcher: Tool name (e.g. Bash, Write, Edit, Read, Glob, Grep, MCP tool names like mcp__server__tool) Extra input fields:
Blocking tool execution: exit code 2, stderr content is returned to the Agent as an error. See Quick Start for a complete example.

PostToolUse

Fires after a tool executes successfully. Matcher: Tool name Extra input fields:

PostToolUseFailure

Fires after a tool execution fails. Matcher: Tool name Extra input fields:

Stop

Fires after the Agent completes its response (main Agent, no pending tool calls). Can block the Agent from stopping to keep it working. Blocking the Agent from stopping: exit code 2, stderr content is injected into the conversation as a message, and the Agent continues working.

SubagentStart / SubagentStop

Fires when a subagent starts or completes. SubagentStop, like Stop, can block the subagent from stopping. Matcher: Agent type name Extra input fields:

PreCompact

Fires before context compaction. Matcher: Trigger method Extra input fields:

Notification

Fires on notification events (permission requests, task completion, etc.). Matcher: Notification type Extra input fields:

PermissionRequest

Fires when a tool execution requires user authorization. Matcher: Tool name Extra input fields:

Scenario Examples

Desktop Notification

Show a desktop notification when the Agent finishes a task or needs authorization. Script ~/.qoderwork/hooks/notify.sh (macOS):
Config:

Auto Lint After File Write

Automatically run lint after every file write or edit by the Agent. Script ${project}/.qoderwork/hooks/auto-lint.sh:
Config: event PostToolUse, matcher Write|Edit, command .qoderwork/hooks/auto-lint.sh.

Keep Agent Working

Check for unfinished tasks when the Agent stops. If there are uncommitted git changes, inject a message to keep the Agent going. Script ~/.qoderwork/hooks/check-continue.sh:
Config: event Stop, command ~/.qoderwork/hooks/check-continue.sh.

Next Steps

Skills

Extend QoderWork capabilities with Skills

Scheduled Tasks

Run tasks automatically on a schedule