Docs/Tools & Features/Hooks

Hooks

Hooks are shell commands that fire automatically on events — before tool calls, after edits, when the model finishes. Configure in dynamo.yaml or .dynamo/hooks/*.yaml.

Configuration

yaml
hooks:
  - event: PreToolUse
    matcher: "run_command"
    if: "rm"
    command: "echo 'blocked' >&2; exit 2"

  - event: PostToolUse
    matcher: "edit_file"
    command: ".dynamo/hooks/lint.sh"

  - event: Stop
    command: ".dynamo/hooks/build-gate.sh"
    timeout: 30000

Hooks can also be defined in separate files under .dynamo/hooks/*.yaml (project) or ~/.config/dynamo/hooks/*.yaml (global).

Events

EventWhenUse case
PreToolUseBefore tool executesBlock dangerous commands, modify input
PostToolUseAfter tool executesAuto-lint, inject build errors as context
StopModel finishes respondingBuild gates — model auto-fixes errors
SessionStartSession beginsEnvironment checks, context loading
SessionEndSession endsCleanup, metrics, logging

Matching

  • `matcher` — tool name to match (e.g. "run_command", "edit_file")
  • `if` — content filter within the tool call (e.g. "rm" to match only rm commands)

Sequential execution, first block wins.

Exit Codes

CodeMeaning
0Approve — continue execution. Parse stdout as JSON for structured output.
2Block — prevent the tool from executing
OtherWarn — show a warning but continue

Hooks receive JSON on stdin with the tool call details and can return structured output on stdout.

Managing Hooks

Use /hooks to browse configured hooks — a 3-level picker showing event types, numbered hook list, and detail view with execution history.

Trusting project hooks

Hooks that live in the project (dynamo.yaml or .dynamo/hooks/*.yaml) run only after you trust the folder once:

bash
dynamo hooks trust

Trust takes effect the next time you launch `dynamo` — the gate is read once at startup, and there's no in-session way to re-trust, so running the command in a second terminal while Dynamo is open won't make hooks start firing.

The trust check is fingerprinted over the hook set, so it asks again after you add or change a project hook — that's deliberate, since a hook is arbitrary shell. Personal hooks in your Dynamo config dir (~/.config/dynamo/hooks/ on macOS and Linux, %APPDATA%\dynamo\hooks\ on Windows) always run. Dynamo tells you at startup when project hooks are waiting on trust.

Examples

Auto-lint after edits

yaml
hooks:
  - event: PostToolUse
    matcher: "edit_file"
    command: "jq -r '.toolInput.path' | xargs -r npx eslint --fix"

Build gate on Stop

yaml
hooks:
  - event: Stop
    command: "npm run build 2>&1 || exit 1"
    timeout: 30000

When a Stop hook fails, Dynamo feeds the error back to the model which auto-fixes and retries.

Block dangerous commands

yaml
hooks:
  - event: PreToolUse
    matcher: "run_command"
    if: "docker"
    command: "echo 'Docker commands blocked' >&2; exit 2"