Verboo

Hooks

Hooks are handlers executed automatically in response to agent lifecycle events. With hooks you can:

  • Format code after edits
  • Block dangerous operations before execution
  • Send notifications when the agent finishes
  • Perform automatic recovery on failures
  • Audit all tool calls

Configure hooks

Hooks are defined in settings.json or settings.local.json:

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|FileWrite",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write {{file}}"
          }
        ]
      }
    ]
  }
}

Use /update-config to configure hooks with automatic 7-step verification.

Available events

Event When it fires
PermissionRequest Before asking the user for permission to use a tool
PreToolUse Immediately before executing any tool
PostToolUse Immediately after the tool returns (success or failure)
PreCompact Before compacting the conversation context
PostCompact After compaction is complete
Stop When the agent finishes the response
Notification When the agent needs to notify the user
SessionStart At the start of a new session
UserPromptSubmit When the user submits a prompt

Hook types

`command` — shell script

Executes a shell command. The hook receives a JSON via stdin and can return a JSON via stdout to influence agent behavior.

json
{
  "type": "command",
  "command": "bash /home/user/.verboo/hooks/lint-on-edit.sh"
}

Input format (stdin):

json
{
  "event": "PostToolUse",
  "tool_name": "Edit",
  "tool_input": { "file_path": "/src/main.ts", "..." },
  "tool_result": { "..." }
}

Output format (stdout) — optional:

json
{
  "continue": true,
  "decision": "approve",
  "reason": "File formatted successfully"
}

`prompt` — LLM evaluation

Uses a language model to evaluate whether the operation should continue:

json
{
  "type": "prompt",
  "prompt": "Is the following command safe to run? Answer only 'allow' or 'deny'.\n\nCommand: {{command}}"
}

`http` — POST to URL

Makes an HTTP POST to an external URL:

json
{
  "type": "http",
  "url": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
  "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer ${SLACK_TOKEN}"
  },
  "body": {
    "text": "Agent finished: {{TASK_SUBJECT}}"
  }
}

Environment variables are expanded with ${VAR}. Context template variables are expanded with {{VAR}}.

`agent` — agentic verification

Invokes a sub-agent to verify the operation:

json
{
  "type": "agent",
  "prompt": "Check if the edit in {{file_path}} doesn't introduce security vulnerabilities."
}

Hook fields

Field Type Description
type string command, prompt, http, agent
command string Shell command (command only)
url string Endpoint URL (http only)
prompt string Model prompt (prompt, agent only)
headers object HTTP headers (http only)
body object Request body (http only)
timeout number Timeout in ms (default: 10000)
statusMessage string Message shown while the hook runs
once bool Runs only once per session
async bool Runs in background without blocking the agent
asyncRewake bool Rewakes the agent when the async hook finishes
if string Execution condition (permission rule syntax)

Hook matchers

The matcher field is a pattern that filters which tool the hook fires for:

json
{
  "matcher": "Bash|Edit|Write",
  "hooks": [...]
}

Supported patterns:

  • Exact name: "Edit"
  • Alternation: "Edit|Write|FileWrite"
  • Wildcard: "*" (all tools)
  • Negation with if: "if": "not tool_name:Bash"

Hook output (decision)

command type hooks can return a JSON to control the agent:

json
{
  "continue": false,
  "decision": "block",
  "reason": "Operation blocked: destination outside authorized directory",
  "stopReason": "Security policy violated"
}
Field Values Description
continue true/false If false, aborts the operation
decision approve, deny, block Explicit decision
reason string Explanation shown to the user
stopReason string Stop message (when continue: false)

Practical examples

Format code after edit

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write \"{{tool_input.file_path}}\" 2>/dev/null || true",
            "async": true
          }
        ]
      }
    ]
  }
}

Block dangerous rm commands

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'echo $HOOK_INPUT | jq -r .tool_input.command | grep -qE \"rm -rf /\" && echo \\'{ \"continue\": false, \"reason\": \"rm -rf / blocked\" }\\' || echo \\'{ \"continue\": true }\\''",
          }
        ]
      }
    ]
  }
}

Slack notification on finish

json
{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "http",
            "url": "https://hooks.slack.com/services/T.../B.../XXX",
            "body": {
              "text": "Verboo Code finished: {{TASK_SUBJECT}}"
            }
          }
        ]
      }
    ]
  }
}

Bash command audit log

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date): $HOOK_INPUT\" >> ~/.verboo-audit.log",
            "async": true
          }
        ]
      }
    ]
  }
}

Hook Chains

Hook Chains are automatic recovery rules triggered by tool or task outcomes.

Configuration

json
{
  "hookChains": {
    "version": 1,
    "enabled": true,
    "maxChainDepth": 2,
    "defaultCooldownMs": 30000,
    "rules": [
      {
        "id": "retry-on-bash-fail",
        "enabled": true,
        "trigger": {
          "event": "PostToolUse",
          "outcome": "failed"
        },
        "condition": {
          "toolNames": ["Bash"],
          "errorIncludes": "ECONNREFUSED"
        },
        "actions": [
          {
            "type": "spawn_fallback_agent",
            "prompt": "The command failed with ECONNREFUSED. Check if the service is running and try again."
          }
        ]
      }
    ]
  }
}

Rule fields

Field Description
id Unique rule identifier
enabled Enables/disables the rule
trigger.event Event that fires (e.g., PostToolUse, TaskCompleted)
trigger.outcome success, failed, timeout, unknown
condition.toolNames List of tools that activate the rule
condition.errorIncludes Substring in the error
cooldownMs Minimum ms between triggers (default: 30000)
dedupWindowMs Deduplication window (default: 30000)
maxDepth Maximum chain depth (default: 2, max: 10)
actions Array of actions to execute

Action types

Type Description
spawn_fallback_agent Triggers a recovery agent
notify_team Notifies the configured team
warm_remote_capacity Pre-warms remote capacity

Template variables in actions

Variable Value
{{EVENT_NAME}} Event name
{{OUTCOME}} Event outcome
{{RULE_ID}} Rule ID
{{TASK_SUBJECT}} Task subject
{{ERROR}} Error message
{{PAYLOAD_JSON}} Full event JSON

Hook Chains are disabled by default. Enable gradually per environment after validating behavior.