← Модуль 3: Power User
3.2

Хуки: детерминированная автоматизация

Цель: понять разницу между "Claude обычно делает X" и "X всегда происходит". Написать свои хуки которые работают каждый раз.

CLAUDE.md vs хуки — критическая разница

CLAUDE.md — это рекомендации. Claude следует им в большинстве случаев. Но не всегда. Нельзя полагаться на языковую модель в том, что она всегда запустит линтер или всегда проверит опасные команды.

Хуки делают это поведение детерминированным. Это обработчики событий, которые срабатывают автоматически в определённых точках. Твой shell-скрипт выполняется каждый раз, без исключений.

События

СобытиеКогда срабатываетПример использования
SessionStartВ начале сессииПодгрузить контекст из API/файлов
UserPromptSubmitКогда ты нажал EnterВалидация промпта
PreToolUseПеред запуском инструментаЗащитный барьер — блок опасных команд
PostToolUseПосле успешного инструментаАвтоформатирование, автолинт
StopClaude завершает задачуКонтроль качества — тесты должны пройти
PermissionRequestЗапрос разрешенияУведомление на телефон для одобрения
NotificationНужно вниманиеDesktop-уведомления

Конфигурация в .claude/settings.json

Пример — автоформат каждого файла который Claude трогает + блок опасных bash-команд:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write 2>/dev/null"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/bash-firewall.sh"
          }
        ]
      }
    ]
  }
}

Коды возврата — протокол хуков

  • 0 — пропустить, всё ок
  • 1 — предупредить но продолжить
  • 2заблокировать полностью

Пример 1. Bash-firewall

.claude/hooks/bash-firewall.sh:

#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
 
if echo "$COMMAND" | grep -qE "rm -rf|git push --force|DROP TABLE|:(){"; then
  echo "Blocked: dangerous pattern detected" >&2
  exit 2
fi
 
exit 0

Читает команду которую Claude собирается запустить, проверяет на опасные паттерны, блокирует exit code 2. Claude получает ошибку и не выполняет команду.

Не забудь:

chmod +x .claude/hooks/bash-firewall.sh

Пример 2. Test-gate (Stop-хук)

Не даёт Claude объявить "готово" пока тесты красные:

.claude/hooks/test-gate.sh:

#!/bin/bash
if ! npm test --silent; then
  echo "Tests failing — please fix before finishing" >&2
  exit 2
fi
exit 0

В settings.json:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/test-gate.sh"
          }
        ]
      }
    ]
  }
}

Теперь Claude не завершит работу пока тесты не пройдут. Без исключений.

Пример 3. Autoformat

PostToolUse matcher на Write|Edit: прогонять файл через prettier. Уже в примере конфига выше.

Пример 4. Permission notify

PermissionRequest — отправить уведомление в WhatsApp/Telegram чтобы одобрить с телефона:

#!/bin/bash
INPUT=$(cat)
ACTION=$(echo "$INPUT" | jq -r '.permission.action')
 
curl -X POST "https://api.telegram.org/bot$TG_TOKEN/sendMessage" \
  -d "chat_id=$MY_CHAT_ID" \
  -d "text=Claude Code requests: $ACTION. Approve at your terminal."

Важные замечания

⚠️ Хуки не перезагружаются на лету — перезапусти сессию после изменений в settings.json или скриптах.

⚠️ Запускаются с полными правами пользователя — валидируй JSON-ввод, экранируй shell-переменные. Не доверяй содержимому stdin слепо.

⚠️ Хуки > промпт-инструкции когда нужна гарантия. Но они менее гибкие — не могут "понять контекст" как Claude. Используй для чёрно-белых правил.

Что делать хуками и что — промптами

ПравилоГде
"Всегда запускай prettier после edit"Hook (автоматизация)
"Блокируй rm -rf всегда"Hook (безопасность)
"Тесты должны пройти перед завершением"Hook (гарантия качества)
"Предпочитай функциональные компоненты классовым"CLAUDE.md (стиль)
"Комментарии пиши на английском"CLAUDE.md (стиль)
"Для платёжных операций нужна верификация клиента"Hook (критическая бизнес-логика)

Практика (20 минут)

Задача 1. Bash-firewall

Создай .claude/hooks/bash-firewall.sh (взять из этого урока). Сделай executable. Добавь в settings.json. Перезапусти сессию. Попробуй попросить Claude выполнить rm -rf /tmp/test_folder — увидишь блок.

Задача 2. Autoformat

Если у тебя проект с Prettier — добавь PostToolUse хук из примера. Проверь: Claude правит файл → prettier форматирует автоматически.

Задача 3. Test-gate (опционально)

Если у тебя есть тесты — добавь Stop-хук. Попробуй попросить Claude сделать изменение которое ломает тесты → он не сможет завершить пока не починит.

Что дальше

Следующий урок: MCP — как превратить Claude Code из "хорошего помощника для кодинга" в "оркестратор всего рабочего процесса".