Перейти к основному содержанию
Claude Code hooks — это определяемые пользователем команды оболочки, которые выполняются в различных точках жизненного цикла Claude Code. Hooks обеспечивают детерминированный контроль над поведением Claude Code, гарантируя, что определённые действия всегда происходят, а не полагаются на то, что LLM выберет их запуск.
Справочную документацию по hooks см. в разделе Hooks reference.
Примеры использования hooks включают:
  • Уведомления: Настройте способ получения уведомлений, когда Claude Code ожидает вашего ввода или разрешения на запуск чего-либо.
  • Автоматическое форматирование: Запустите prettier на файлах .ts, gofmt на файлах .go и т. д. после каждого редактирования файла.
  • Логирование: Отслеживайте и подсчитывайте все выполненные команды для соответствия требованиям или отладки.
  • Обратная связь: Предоставляйте автоматическую обратную связь, когда Claude Code создаёт код, который не соответствует соглашениям вашей кодовой базы.
  • Пользовательские разрешения: Блокируйте изменения файлов производства или конфиденциальных каталогов.
Кодируя эти правила как hooks вместо инструкций подсказок, вы превращаете предложения в код уровня приложения, который выполняется каждый раз, когда ожидается его запуск.
Вы должны учитывать последствия для безопасности hooks при их добавлении, поскольку hooks выполняются автоматически во время цикла агента с учётными данными вашей текущей среды. Например, вредоносный код hooks может утечь ваши данные. Всегда проверяйте реализацию hooks перед их регистрацией.Полные рекомендации по безопасности см. в разделе Security Considerations в справочной документации hooks.

Обзор событий Hook

Claude Code предоставляет несколько событий hook, которые выполняются в разных точках рабочего процесса:
  • PreToolUse: Выполняется перед вызовами инструментов (может их блокировать)
  • PostToolUse: Выполняется после завершения вызовов инструментов
  • UserPromptSubmit: Выполняется, когда пользователь отправляет подсказку, перед обработкой Claude
  • Notification: Выполняется, когда Claude Code отправляет уведомления
  • Stop: Выполняется, когда Claude Code завершает ответ
  • SubagentStop: Выполняется, когда задачи подагента завершаются
  • PreCompact: Выполняется перед тем, как Claude Code собирается выполнить операцию компактирования
  • SessionStart: Выполняется, когда Claude Code запускает новый сеанс или возобновляет существующий сеанс
  • SessionEnd: Выполняется, когда сеанс Claude Code завершается
Каждое событие получает различные данные и может контролировать поведение Claude различными способами.

Быстрый старт

В этом быстром старте вы добавите hook, который логирует команды оболочки, которые запускает Claude Code.

Предварительные требования

Установите jq для обработки JSON в командной строке.

Шаг 1: Откройте конфигурацию hooks

Запустите slash command /hooks и выберите событие hook PreToolUse. Hooks PreToolUse выполняются перед вызовами инструментов и могут их блокировать, предоставляя Claude обратную связь о том, что делать по-другому.

Шаг 2: Добавьте matcher

Выберите + Add new matcher…, чтобы запустить ваш hook только на вызовах инструмента Bash. Введите Bash для matcher.
Вы можете использовать * для соответствия всем инструментам.

Шаг 3: Добавьте hook

Выберите + Add new hook… и введите эту команду:
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt

Шаг 4: Сохраните вашу конфигурацию

Для места хранения выберите User settings, так как вы логируете в ваш домашний каталог. Этот hook затем будет применяться ко всем проектам, а не только к вашему текущему проекту. Затем нажимайте Esc, пока не вернётесь в REPL. Ваш hook теперь зарегистрирован!

Шаг 5: Проверьте ваш hook

Запустите /hooks снова или проверьте ~/.claude/settings.json, чтобы увидеть вашу конфигурацию:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
          }
        ]
      }
    ]
  }
}

Шаг 6: Протестируйте ваш hook

Попросите Claude запустить простую команду, такую как ls, и проверьте ваш файл журнала:
cat ~/.claude/bash-command-log.txt
Вы должны увидеть записи вроде:
ls - Lists files and directories

Дополнительные примеры

Для полного примера реализации см. bash command validator example в нашей открытой кодовой базе.

Hook форматирования кода

Автоматически форматируйте файлы TypeScript после редактирования:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }"
          }
        ]
      }
    ]
  }
}

Hook форматирования Markdown

Автоматически исправляйте отсутствующие теги языка и проблемы форматирования в файлах markdown:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/markdown_formatter.py"
          }
        ]
      }
    ]
  }
}
Создайте .claude/hooks/markdown_formatter.py со следующим содержимым:
#!/usr/bin/env python3
"""
Markdown formatter for Claude Code output.
Fixes missing language tags and spacing issues while preserving code content.
"""
import json
import sys
import re
import os

def detect_language(code):
    """Best-effort language detection from code content."""
    s = code.strip()
    
    # JSON detection
    if re.search(r'^\s*[{\[]', s):
        try:
            json.loads(s)
            return 'json'
        except:
            pass
    
    # Python detection
    if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
       re.search(r'^\s*(import|from)\s+\w+', s, re.M):
        return 'python'
    
    # JavaScript detection  
    if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
       re.search(r'=>|console\.(log|error)', s):
        return 'javascript'
    
    # Bash detection
    if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
       re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
        return 'bash'
    
    # SQL detection
    if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
        return 'sql'
        
    return 'text'

def format_markdown(content):
    """Format markdown content with language detection."""
    # Fix unlabeled code fences
    def add_lang_to_fence(match):
        indent, info, body, closing = match.groups()
        if not info.strip():
            lang = detect_language(body)
            return f"{indent}```{lang}\n{body}{closing}\n"
        return match.group(0)
    
    fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
    content = re.sub(fence_pattern, add_lang_to_fence, content)
    
    # Fix excessive blank lines (only outside code fences)
    content = re.sub(r'\n{3,}', '\n\n', content)
    
    return content.rstrip() + '\n'

# Main execution
try:
    input_data = json.load(sys.stdin)
    file_path = input_data.get('tool_input', {}).get('file_path', '')
    
    if not file_path.endswith(('.md', '.mdx')):
        sys.exit(0)  # Not a markdown file
    
    if os.path.exists(file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        formatted = format_markdown(content)
        
        if formatted != content:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(formatted)
            print(f"✓ Fixed markdown formatting in {file_path}")
    
except Exception as e:
    print(f"Error formatting markdown: {e}", file=sys.stderr)
    sys.exit(1)
Сделайте скрипт исполняемым:
chmod +x .claude/hooks/markdown_formatter.py
Этот hook автоматически:
  • Определяет языки программирования в немаркированных блоках кода
  • Добавляет соответствующие теги языка для подсветки синтаксиса
  • Исправляет чрезмерные пустые строки, сохраняя содержимое кода
  • Обрабатывает только файлы markdown (.md, .mdx)

Hook пользовательского уведомления

Получайте уведомления рабочего стола, когда Claude нуждается в вводе:
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' 'Awaiting your input'"
          }
        ]
      }
    ]
  }
}

Hook защиты файлов

Блокируйте редактирование конфиденциальных файлов:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 -c \"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\""
          }
        ]
      }
    ]
  }
}

Узнайте больше

  • Справочную документацию по hooks см. в разделе Hooks reference.
  • Полные рекомендации по безопасности и руководства по безопасности см. в разделе Security Considerations в справочной документации hooks.
  • Шаги по устранению неполадок и методы отладки см. в разделе Debugging в справочной документации hooks.