> ## Documentation Index
> Fetch the complete documentation index at: https://docs.augmentcode.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks Examples

> Ready-to-use examples of hooks for common security, automation, and integration workflows.

You're viewing docs for **Auggie 0.x.x**
. To see Auggie 1.x.x, go to
[the 1.x.x docs](https://docs.augmentcode.com/cli/hooks-examples.md)
.

## Example Hooks

Here are practical examples of hooks you can use in your projects. Each example includes the hook script and the corresponding configuration.

> **Block Dangerous Commands**
>
> Block shell commands that could be destructive:
>
> **Hook Script** (`/etc/augment/hooks/security-block-dangerous.sh`):
>
> ```bash Bash theme={null}
> #!/usr/bin/env bash
>
> EVENT_DATA=$(cat)
> COMMAND=$(echo "$EVENT_DATA" | jq -r '.tool_input.command // ""')
>
> # Check for dangerous patterns
> if echo "$COMMAND" | grep -qE "rm -rf|sudo|chmod 777"; then
>   echo "Blocked dangerous command: $COMMAND" >&2
>   exit 2
> fi
>
> exit 0
> ```
>
> ```python Python theme={null}
> #!/usr/bin/env python3
> import sys
> import json
> import re
>
> event_data = json.load(sys.stdin)
> command = event_data.get('tool_input', {}).get('command', '')
>
> # Check for dangerous patterns
> if re.search(r'rm -rf|sudo|chmod 777', command):
>     print(f"Blocked dangerous command: {command}", file=sys.stderr)
>     sys.exit(2)
>
> sys.exit(0)
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "launch-process",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/security-block-dangerous.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Auto-Format Code Before Editing**
>
> Automatically format code files using language-specific formatters (Biome, Ruff, gofmt, rustfmt) before the agent edits them.
>
> **Hook Script** (`/etc/augment/hooks/auto-format.sh`):
>
> ```bash Bash theme={null}
> #!/usr/bin/env bash
>
> EVENT_DATA=$(cat)
> TOOL_NAME=$(echo "$EVENT_DATA" | jq -r '.tool_name')
>
> # Only run for file editing tools
> [[ "$TOOL_NAME" != "str-replace-editor" ]] && exit 0
>
> FILE_PATH=$(echo "$EVENT_DATA" | jq -r '.tool_input.path // ""')
> [[ -z "$FILE_PATH" || ! -f "$FILE_PATH" ]] && exit 0
>
> EXT="${FILE_PATH##*.}"
>
> case "$EXT" in
>   ts|tsx|js|jsx) command -v biome &>/dev/null && biome format --write "$FILE_PATH" ;;
>   py) command -v ruff &>/dev/null && ruff format "$FILE_PATH" ;;
>   go) command -v gofmt &>/dev/null && gofmt -w "$FILE_PATH" ;;
>   rs) command -v rustfmt &>/dev/null && rustfmt "$FILE_PATH" ;;
> esac
>
> exit 0
> ```
>
> ```python Python theme={null}
> #!/usr/bin/env python3
> import sys, json, subprocess, shutil
> from pathlib import Path
>
> event_data = json.load(sys.stdin)
> if event_data.get('tool_name') != 'str-replace-editor':
>     sys.exit(0)
>
> file_path = event_data.get('tool_input', {}).get('path', '')
> if not file_path or not Path(file_path).exists():
>     sys.exit(0)
>
> ext = Path(file_path).suffix.lstrip('.')
> formatters = {
>     'ts': ['biome', 'format', '--write'],
>     'tsx': ['biome', 'format', '--write'],
>     'js': ['biome', 'format', '--write'],
>     'py': ['ruff', 'format'],
>     'go': ['gofmt', '-w'],
>     'rs': ['rustfmt'],
> }
>
> if ext in formatters and shutil.which(formatters[ext][0]):
>     subprocess.run(formatters[ext] + [file_path], timeout=30)
>
> sys.exit(0)
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "str-replace-editor",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/auto-format.sh",
>             "timeout": 30000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```
>
> **Supported Formatters:**
>
> | Language | Formatter | Command |
> | :-: | :-: | :-: |
> | TypeScript/JavaScript | [Biome](https://biomejs.dev/) | `biome format --write` |
> | Python | [Ruff](https://docs.astral.sh/ruff/) | `ruff format` |
> | Go | [gofmt](https://pkg.go.dev/cmd/gofmt) | `gofmt -w` |
> | Rust | [rustfmt](https://rust-lang.github.io/rustfmt/) | `rustfmt` |

> **Audit Sensitive File Access**
>
> Monitor when the agent accesses sensitive files:
>
> **Hook Script** (`/etc/augment/hooks/audit.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
> FILE_PATH=$(echo "$EVENT_DATA" | jq -r '.tool_input.path // ""')
>
> if echo "$FILE_PATH" | grep -qE "\.env|secrets|credentials"; then
>   echo "[AUDIT] Sensitive file access: $FILE_PATH" >&2
> fi
>
> exit 0  # Audit only, don't block
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "view|str-replace-editor",
>         "hooks": [
>           { "type": "command", "command": "/etc/augment/hooks/audit.sh" }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Block Sudo Commands**
>
> A simple hook to block sudo commands:
>
> **Hook Script** (`/etc/augment/hooks/validate-tool.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
> COMMAND=$(echo "$EVENT_DATA" | jq -r '.tool_input.command // ""')
>
> if echo "$COMMAND" | grep -q "sudo"; then
>   echo "Blocked: sudo not allowed" >&2
>   exit 2  # Block execution
> fi
>
> exit 0
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "launch-process",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/validate-tool.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Load Context at Session Start**
>
> Inject development context when a session starts:
>
> **Hook Script** (`/etc/augment/hooks/load-context.sh`):
>
> ```bash Bash theme={null}
> #!/usr/bin/env bash
>
> # Load recent git commits
> echo "Recent commits:"
> git log --oneline -5
>
> # Load current branch info
> echo ""
> echo "Current branch: $(git branch --show-current)"
>
> # Load open issues (example)
> echo ""
> echo "Open issues:"
> # curl -s https://api.example.com/issues | jq -r '.[] | "- \(.title)"'
>
> exit 0
> ```
>
> ```python Python theme={null}
> #!/usr/bin/env python3
> import sys
> import subprocess
>
> # Load recent git commits
> print("Recent commits:")
> result = subprocess.run(['git', 'log', '--oneline', '-5'],
>                        capture_output=True, text=True)
> print(result.stdout)
>
> # Load current branch info
> print("")
> print("Current branch:", end=" ")
> result = subprocess.run(['git', 'branch', '--show-current'],
>                        capture_output=True, text=True)
> print(result.stdout.strip())
>
> sys.exit(0)
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "SessionStart": [
>       {
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/load-context.sh",
>             "timeout": 10000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Session Cleanup**
>
> Run cleanup when a session ends:
>
> **Hook Script** (`/etc/augment/hooks/cleanup.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> echo "[$(date)] Session ended" >&2
> exit 0
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "SessionEnd": [
>       {
>         "hooks": [
>           { "type": "command", "command": "/etc/augment/hooks/cleanup.sh" }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Block Production Database Access**
>
> Prevent agents from accessing production systems or sensitive data:
>
> **Hook Script** (`/etc/augment/hooks/block-prod.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
> TOOL_INPUT=$(echo "$EVENT_DATA" | jq -r '.tool_input | tostring')
>
> if echo "$TOOL_INPUT" | grep -qE "prod-db|production\.database"; then
>   echo "Access to production databases is not allowed" >&2
>   exit 2
> fi
>
> exit 0
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": ".*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/block-prod.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Compliance Auditing**
>
> Log all tool executions for compliance:
>
> **Hook Script** (`/etc/augment/hooks/audit-log.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
> TOOL=$(echo "$EVENT_DATA" | jq -r '.tool_name')
> echo "[$(date -u +%FT%TZ)] Tool: $TOOL" >&2
> exit 0
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PostToolUse": [
>       {
>         "matcher": ".*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/audit-log.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

> **Rate Limiting MCP Tools**
>
> Block excessive API calls to MCP servers:
>
> **Hook Script** (`/etc/augment/hooks/rate-limit.sh`):
>
> ```bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
> SERVER=$(echo "$EVENT_DATA" | jq -r '.mcp_metadata.mcpExecutedToolServerName // ""')
> RATE_FILE="/tmp/rate-$SERVER"
> COUNT=$(cat "$RATE_FILE" 2>/dev/null || echo "0")
>
> if [ "$COUNT" -gt 10 ]; then
>   echo "Rate limit exceeded" >&2
>   exit 2
> fi
>
> echo $((COUNT + 1)) > "$RATE_FILE"
> exit 0
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "mcp:*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/rate-limit.sh",
>             "timeout": 5000
>           }
>         ],
>         "metadata": {
>           "includeMCPMetadata": true
>         }
>       }
>     ]
>   }
> }
> ```

> **Require Tests Before Finishing**
>
> Block the agent from stopping until tests are modified:
>
> **Hook Script** (`/etc/augment/hooks/require-tests.sh`):
>
> ```bash Bash theme={null}
> #!/usr/bin/env bash
> EVENT_DATA=$(cat)
>
> # Extract code changes
> CODE_RESPONSE=$(echo "$EVENT_DATA" | jq -r '.conversation.agentCodeResponse // []')
>
> # Check if any test files were modified
> TEST_FILES=$(echo "$CODE_RESPONSE" | jq -r '.[] | select(.path | test("test|spec")) | .path')
>
> if [[ -z "$TEST_FILES" ]]; then
>   # No test files modified - block stop
>   cat << EOF
> {
>   "hookSpecificOutput": {
>     "hookEventName": "Stop",
>     "decision": "block",
>     "reason": "Please add or update tests before finishing"
>   }
> }
> EOF
>   exit 0
> fi
>
> exit 0
> ```
>
> ```python Python theme={null}
> #!/usr/bin/env python3
> import sys
> import json
> import re
>
> event_data = json.load(sys.stdin)
> conversation = event_data.get('conversation', {})
> code_response = conversation.get('agentCodeResponse', [])
>
> # Check if any test files were modified
> test_files = [
>     change['path'] for change in code_response
>     if re.search(r'test|spec', change.get('path', ''))
> ]
>
> if not test_files:
>     output = {
>         "hookSpecificOutput": {
>             "hookEventName": "Stop",
>             "decision": "block",
>             "reason": "Please add or update tests before finishing"
>         }
>     }
>     print(json.dumps(output))
>     sys.exit(0)
>
> sys.exit(0)
> ```
>
> **Configuration:**
>
> ```json theme={null}
> {
>   "hooks": {
>     "Stop": [
>       {
>         "matcher": ".*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/require-tests.sh",
>             "timeout": 5000
>           }
>         ],
>         "metadata": {
>           "includeConversationData": true
>         }
>       }
>     ]
>   }
> }
> ```

## Advanced Configuration Patterns

These patterns show how to combine multiple hooks effectively:

> **Multiple Hooks on Same Event**
>
> Execute multiple hooks in order for the same event:
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "launch-process",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/log-command.sh",
>             "timeout": 5000
>           },
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/security-check.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```
>
> If any hook returns exit code 2, execution is blocked and subsequent hooks are not run.

> **Combining Matchers**
>
> Use multiple matcher configurations for different tools:
>
> ```json theme={null}
> {
>   "hooks": {
>     "PreToolUse": [
>       {
>         "matcher": "mcp:*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/log-mcp.sh",
>             "timeout": 5000
>           }
>         ]
>       },
>       {
>         "matcher": "launch-process",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/security-bash.sh",
>             "timeout": 5000
>           }
>         ]
>       },
>       {
>         "matcher": ".*",
>         "hooks": [
>           {
>             "type": "command",
>             "command": "/etc/augment/hooks/audit-all.sh",
>             "timeout": 5000
>           }
>         ]
>       }
>     ]
>   }
> }
> ```

## See Also

* [Hooks](https://docs.augmentcode.com/cli/v0/hooks.md) - Learn how hooks work and configure them
* [Permissions](https://docs.augmentcode.com/cli/v0/permissions.md) - Tool permission system
* [Rules & Guidelines](https://docs.augmentcode.com/cli/v0/rules.md) - Custom rules and guidelines


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.