Хуки: детерминированная автоматизация
Цель: понять разницу между "Claude обычно делает X" и "X всегда происходит". Написать свои хуки которые работают каждый раз.
CLAUDE.md vs хуки — критическая разница
CLAUDE.md — это рекомендации. Claude следует им в большинстве случаев. Но не всегда. Нельзя полагаться на языковую модель в том, что она всегда запустит линтер или всегда проверит опасные команды.
Хуки делают это поведение детерминированным. Это обработчики событий, которые срабатывают автоматически в определённых точках. Твой shell-скрипт выполняется каждый раз, без исключений.
События
| Событие | Когда срабатывает | Пример использования |
|---|---|---|
SessionStart | В начале сессии | Подгрузить контекст из API/файлов |
UserPromptSubmit | Когда ты нажал Enter | Валидация промпта |
PreToolUse | Перед запуском инструмента | Защитный барьер — блок опасных команд |
PostToolUse | После успешного инструмента | Автоформатирование, автолинт |
Stop | Claude завершает задачу | Контроль качества — тесты должны пройти |
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 из "хорошего помощника для кодинга" в "оркестратор всего рабочего процесса".