Система хуков
События жизненного цикла
Хуки — это shell-команды, которые автоматически выполняются при определённых событиях в Claude Code.
Применения
- • Авто-форматирование после Edit
- • Валидация команд Bash
- • Уведомления в Slack
- • Логирование действий
Ограничения
- • Выполняются синхронно
- • Таймаут по умолчанию 600 секунд
- • Могут блокировать операции
Как устроены хуки (hooks) и зачем они нужны
Хуки (hooks) в Claude Code — это обычные shell-команды, которые агент запускает автоматически в ответ на определённые события жизненного цикла сессии. Вместо того чтобы просить ассистента «не забудь отформатировать файл» или «проверь команду перед запуском», вы один раз описываете правило, и оно срабатывает детерминированно при каждом подходящем событии. Ключевая идея в том, что хуки выполняются вне модели: это код, который вы контролируете, поэтому его поведение предсказуемо и не зависит от того, «вспомнит» ли языковая модель про нужный шаг. Это делает хуки удобным инструментом для встраивания гарантированных проверок (validation), форматирования (formatting) и оповещений в рабочий процесс.
Событий много — более тридцати. Среди распространённых — сессионные SessionStart и SessionEnd: срабатывают при старте и завершении работы и подходят для инициализации окружения или отправки метрик. Связанные с инструментами — PreToolUse и PostToolUse — окружают любой вызов инструмента (tool), например Edit или Bash. Кроме них есть UserPromptSubmit (когда вы отправляете сообщение), Notification (когда Claude хочет о чём-то сообщить), Stop и SubagentStop, PermissionRequest, PreCompact и другие. Поле matcher в конфигурации сужает срабатывание для tool-событий: значение "*" (или пустая строка, или его отсутствие) означает «все инструменты», "Bash" или "Edit|Write" — точное имя или список через |, а более сложные шаблоны трактуются как регулярные выражения (например "mcp__.*").
Разберём примеры конфигурации с этой страницы. Блок в settings.json описывает событие PostToolUse: после каждого редактирования файла с расширением .ts, .tsx, .js или .jsx выполняется prettier --write. Хук получает данные о событии (включая путь к файлу) как JSON на stdin — никаких шаблонов вроде {{path}} нет; для путей проекта и плагина доступны переменные ${CLAUDE_PROJECT_DIR} и ${CLAUDE_PLUGIN_ROOT}. Второй пример — хук PreToolUse для инструмента Bash: он перехватывает команду до выполнения, ищет в ней опасные паттерны вроде rm -rf и при совпадении завершается с кодом 2 — именно это блокирует операцию, а текст из stderr передаётся обратно Claude. Код 0 означает успех (операция продолжается), а любой другой ненулевой код (например 1) — это неблокирующая ошибка: операция всё равно выполнится. Главные подводные камни: хуки выполняются синхронно, а таймаут команды по умолчанию — 600 секунд, поэтому тяжёлые команды могут надолго затормозить сессию; слишком широкий matcher может срабатывать чаще, чем нужно; а ошибки внутри хука стоит логировать, иначе блокировку будет трудно отлаживать. Перед коммитом конфигурации хук всегда полезно прогнать локально.
SessionStartПри запуске сессии Claude Code
SessionEndПри завершении сессии
PreToolUseПеред вызовом инструмента
PostToolUseПосле вызова инструмента
UserPromptSubmitКогда пользователь отправляет сообщение
NotificationПри уведомлениях от Claude
StopКогда Claude останавливается
Автоматическое форматирование файлов после редактирования:
// ~/.claude/settings.json (or .claude/settings.json)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | { read f; case \"$f\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$f\";; esac; }"
}
]
}
]
}
}PreToolUse блокирует операцию, завершаясь с exit code 2:
// settings.json — block dangerous commands
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "cmd=$(jq -r '.tool_input.command'); if echo \"$cmd\" | grep -qE 'rm -rf|drop database'; then echo 'BLOCKED: dangerous command' >&2; exit 2; fi"
}
]
}
]
}
}Exit code 0
Успех — операция продолжается
Exit code 2
Операция блокируется, stderr передаётся Claude
Хуки настраиваются в settings.json под ключом hooks:
~/.claude/settings.json # user (global) settings .claude/settings.json # project settings (committed) .claude/settings.local.json # project settings (not committed) # all of them hold hooks under a single "hooks" key
matcherКакие инструменты ловить ("*", "Bash", "Edit|Write", regex)typeТип хука — обычно "command"commandShell-команда для выполненияЛучшие практики хуков
- 1.Делайте хуки быстрыми — они блокируют основной поток
- 2.Используйте matcher для точного срабатывания
- 3.Логируйте ошибки хуков для отладки
- 4.Тестируйте хуки локально перед коммитом
Частые вопросы
Что такое хуки (hooks) в Claude Code?
Хуки — это обычные shell-команды, которые Claude Code запускает автоматически при определённых событиях сессии: старте и завершении работы, до и после вызова инструмента, при отправке сообщения или остановке агента. Они выполняются вне модели, поэтому срабатывают детерминированно и не зависят от того, «вспомнит» ли ассистент нужный шаг.
Как настроить хук для авто-форматирования после редактирования файла?
Создайте файл .claude/hooks/format-on-edit.json с событием PostToolUse, укажите в match инструмент Edit и glob-шаблон пути (например **/*.{ts,tsx,js,jsx}), а в command — команду форматирования, например npx prettier --write {{path}}. Плейсхолдер {{path}} автоматически подставит путь к изменённому файлу.
Как заблокировать опасные команды через хук PreToolUse?
Добавьте хук PreToolUse для инструмента Bash, который перехватывает команду до выполнения. Если в команде находится опасный паттерн (например rm -rf), хук возвращает exit code 1 — операция блокируется. При exit code 0 операция продолжается. Так можно поставить защиту от случайного удаления данных.
Какие есть ограничения у хуков в Claude Code?
Хуки выполняются синхронно и имеют таймаут около 60 секунд, поэтому тяжёлые команды затормозят всю сессию. Слишком широкий match приводит к лишним срабатываниям, а ошибки внутри хука стоит логировать — иначе молчаливую блокировку трудно отлаживать. Конфигурацию полезно прогнать локально перед коммитом.
Этот урок — часть структурированного курса по LLM.
Мой путь обучения