Skip to content

Hooks

Hooks run your commands at fixed points in the agent lifecycle — audit logging, lint-on-edit, policy gates, notifications. A hook is a shell command that receives event JSON on stdin and can (for some events) block the action or inject context via its output.

Events

EventFiresCan block?
SessionStartA session begins (REPL, exec, serve, ACP)
UserPromptSubmitYou submit a prompt, before the model sees it✅ block, or add context
PreToolUseBefore a tool call executes✅ block the call
PostToolUseAfter a tool call returns— (can add context)
StopA turn completes
SessionEndThe session ends

Hooks fire on every path — interactive REPL, headless exec, serve sessions and tasks, ACP connections, and the stream-json SDK host.

Configuration

In <native-config-root>/config.json (or standard settings layers, where the native root is HIPMMCODE_CONFIG_DIR → else CLAUDE_CONFIG_DIR (v0.16.0+) → else HIPMMCODE_HOME → else ~/.hipmmcode):

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "/usr/local/bin/audit-bash.sh" }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "FileEdit|FileWrite",
        "hooks": [{ "type": "command", "command": "npx prettier --write \"$FILE\" 2>/dev/null || true" }]
      }
    ],
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "echo session-started >> ~/audit.log" }] }
    ]
  }
}
  • matcher — a regex over the tool name (for tool events); omit to match everything.
  • Each hook receives the event payload as JSON on stdin: session id, cwd, event name, tool name + input (tool events), the prompt (UserPromptSubmit), the tool result (PostToolUse).
  • Environment: native HIPMMCODE_SESSION_ID, HIPMMCODE_TURN, HIPMMCODE_PROJECT_DIR, and, where applicable, HIPMMCODE_PLUGIN_ROOT / HIPMMCODE_PLUGIN_DATA are injected. Corresponding CLAUDE_* fields are also exported where the external hook/plugin protocol requires them, so existing integrations remain compatible.

Controlling the agent from a hook

Exit status and stdout decide what happens:

Hook resultEffect
exit 0, empty stdoutContinue normally
exit 0, stdout JSON { "decision": "block", "reason": "…" }Block the prompt / tool call; the reason is shown to the model
exit 0, stdout JSON { "additionalContext": "…" }Inject context into the turn
exit 2Block (shorthand) — stderr becomes the reason

Inspecting

/hooks            # list configured hooks in the REPL

Headless stream runs can surface hook activity as events with --include-hook-events.

Killswitches

For managed environments: disableAllHooks disables everything; allowManagedHooksOnly restricts execution to policy-defined hooks. --safe-mode also disables hooks for one run (troubleshooting).

WARNING

Hooks execute arbitrary shell commands with your credentials, on events the model influences. Treat hook scripts like any other privileged automation: review them, pin them to absolute paths, and keep them out of world-writable locations.