---
title: "Lifecycle Hooks"
description: "Understanding hook events and the data available at each stage"
icon: "rotate"
hidden: true
---

<Warning>
**Coming Soon** — Hooks are not yet available in Devin for Terminal. This documentation describes planned functionality.
</Warning>

Each hook event fires at a specific point in the agent's lifecycle and provides different data you can match against or use in your hook logic.

---

## pre_tool

Fires **before** a tool executes. Use this to block, modify, or add context to tool calls.

**Available data:**

| Field | Description | Example |
|-------|-------------|---------|
| `tool_name` | Name of the tool being called | `exec`, `edit`, `mcp__github__create_issue` |
| `tool_args` | Arguments passed to the tool | `{ "command": "rm -rf /", "shell_id": "main" }` |
| `tool_use_id` | Unique identifier for this tool call | `toolu_abc123` |

**Example — Block destructive commands:**

```yaml
hooks:
  - name: block-rm-rf
    on:
      - type: pre_tool
        tool_name: exec
        tool_args.command:
          regex: "rm\\s+(-rf|-fr|--recursive)"
    then:
      decision: block
      add_context: "Recursive deletion commands are blocked by project policy."
```

**Example — Require confirmation for writes outside src/:**

```yaml
hooks:
  - name: confirm-non-src-writes
    on:
      - type: pre_tool
        tool_name: edit
        tool_args.file_path:
          glob: "!src/**"
    then:
      decision: ask
```

---

## post_tool

Fires **after** a tool finishes executing. Use this for logging, validation, or triggering follow-up actions.

**Available data:**

| Field | Description |
|-------|-------------|
| `tool_name` | Name of the tool that ran |
| `tool_args` | Arguments that were passed |
| `tool_use_id` | Unique identifier for this tool call |
| `tool_result.success` | Whether the tool succeeded (boolean) |
| `tool_result.output` | The tool's output text |
| `tool_result.error` | Error message if the tool failed |

**Example — Log all shell commands:**

```yaml
hooks:
  - name: log-commands
    on:
      - type: post_tool
        tool_name: exec
    then:
      command:
        cmd: ["sh", "-c", "echo \"$(date): $TOOL_ARGS\" >> ~/.devin-command-log"]
```

---

## permission_request

Fires when the agent needs a permission decision. Use this to implement custom approval logic.

**Available data:**

| Field | Description |
|-------|-------------|
| `tool_name` | Tool requesting permission |
| `tool_args` | Arguments for the tool call |
| `tool_use_id` | Unique identifier for this tool call |

**Example — Auto-approve git commands:**

```yaml
hooks:
  - name: approve-git
    on:
      - type: permission_request
        tool_name: exec
        tool_args.command:
          glob: "git *"
    then:
      decision: approve
```

---

## user_prompt

Fires when the user submits a message. Use this to transform input, add context, or trigger workflows.

**Available data:**

| Field | Description |
|-------|-------------|
| `prompt` | The user's message text |

**Example — Add project context for certain keywords:**

```yaml
hooks:
  - name: add-deploy-context
    on:
      - type: user_prompt
        prompt:
          glob: "*deploy*"
    then:
      add_context: |
        Deployment checklist:
        1. Run tests first
        2. Check the staging environment
        3. Use the deploy script at scripts/deploy.sh
```

---

## stop

Fires when the agent decides to stop (finish its turn). Use this to add follow-up instructions or prevent premature stopping.

**Available data:**

| Field | Description |
|-------|-------------|
| `stop_hook_active` | Whether a stop hook is already active |

**Example — Remind agent to run tests:**

```yaml
hooks:
  - name: remind-tests
    on:
      - type: stop
    then:
      add_context: "Before stopping, make sure you've run the test suite."
```

<Warning>
Be careful with stop hooks that add context — they can cause the agent to loop if the condition isn't eventually satisfied.
</Warning>

---

## session_start

Fires when a new session begins. Use this for initialization, logging, or environment setup.

**Available data:**

| Field | Description |
|-------|-------------|
| `source` | How the session was started |

**Example — Run setup script:**

```yaml
hooks:
  - name: setup-env
    on:
      - type: session_start
    then:
      command:
        cmd: ["sh", "-c", "./scripts/dev-setup.sh"]
        timeout_ms: 10000
```

---

## session_end

Fires when a session ends. Use this for cleanup or final logging.

**Available data:**

| Field | Description |
|-------|-------------|
| `reason` | Why the session ended |

---

## Matching Multiple Events

A single hook can match multiple event types using a list:

```yaml
hooks:
  - name: audit-all-tool-calls
    on:
      - type: pre_tool
      - type: post_tool
    then:
      command:
        cmd: ["sh", "-c", "echo \"$EVENT_TYPE: $TOOL_NAME\" >> audit.log"]
```

You can also use `type: any` to match all events:

```yaml
hooks:
  - name: log-everything
    on:
      - type: any
    then:
      command:
        cmd: ["./scripts/log-event.sh"]
```
