Библиотека · Хуки и помощники-агенты

Hooks — автоматические правила Claude Code

Строитель50 минОбновлено: октябрь 2026
35 из 105 в библиотеке

Модуль: 7. Хуки — автономность системного уровня | Время: ~30 мин теории + 20 мин практики


Суть урока

Скиллы ты вызываешь сам — когда нужно. Hooks работают без твоего участия — всегда. Это как правила в трудовом договоре: сотрудник следует им автоматически, не ждёт напоминания каждый раз. Хук срабатывает при определённом событии — перед действием, после, при ошибке, при завершении — и выполняет то что ты предписал.

В этом уроке — полная картина: около 30 типов событий, 5 типов обработчиков, точный формат данных. Начнём с главного.


Ключевые концепции

  • Hook — автоматическое правило которое срабатывает при конкретном событии в Claude Code
  • Событие (event) — момент в жизненном цикле Claude Code: старт сессии, вызов инструмента, завершение и т.д.
  • Обработчик (handler) — что именно выполняется при событии: bash-скрипт, HTTP-запрос, MCP-инструмент, prompt или agent
  • Matcher — фильтр: на какие именно инструменты или события реагировать
  • settings.json — файл конфигурации хуков (.claude/settings.json для проекта, ~/.claude/settings.json глобально)
  • Exit code — как хук сообщает решение: 0 = ок, 2 = заблокировать

Теория

Skills vs Hooks: в чём разница

Это не конкуренты — это разные инструменты.

Skills Hooks
Активация Ты вызываешь явно Автоматически при событии
Уровень Проект или глобально Проект или глобально
Хранение .claude/skills/<name>/SKILL.md .claude/settings.json или ~/.claude/settings.json
Назначение Инструкции как делать задачу Правила безопасности и автоматизации
Аналогия Рецепт Правила трудового договора

🎨 Образ: хук — это охранник на входе и на выходе. Скилл — это специалист которого ты нанимаешь под конкретную задачу. Охранник работает всегда. Специалист — когда нужен.


Типы событий (events) — когда хуки срабатывают

Claude Code поддерживает около 30 типов событий (точный список растёт от версии к версии — см. официальную документацию). Для начала тебе нужны 6 основных. Остальные — для продвинутых сценариев.

Основные 6 событий (80% использования)

Событие Когда Зачем
PreToolUse ДО выполнения инструмента Блокировка опасных действий, проверка условий
PostToolUse ПОСЛЕ успешного выполнения Логирование, аудит, уведомления
Stop Claude завершил ответ Уведомление "готово", cleanup, запуск тестов
Notification Claude отправляет уведомление Реакция на промежуточные события
SessionStart Начало или возобновление сессии Загрузка контекста, проверка окружения
UserPromptSubmit Пользователь отправил запрос Валидация, добавление контекста перед обработкой

Продвинутые события (когда вырастешь из основных)

Событие Когда Пример
SubagentStart Запуск субагента Логирование какие агенты запускаются
SubagentStop Субагент завершил работу Проверка результата субагента
PostToolUseFailure Инструмент завершился ошибкой Отправка алерта при ошибке
PostToolBatch Пакет параллельных вызовов завершён Проверка после batch-операций
FileChanged Файл изменился на диске Перезагрузка .env при изменении
ConfigChange Изменилась конфигурация Реакция на обновление settings
PreCompact Перед сжатием контекста Сохранение важного перед compaction
SessionEnd Сессия завершается Финальный cleanup, сохранение состояния
StopFailure Ответ прерван ошибкой API Алерт при rate limit или billing error
PermissionRequest Появилось окно permission Авто-одобрение определённых операций
CwdChanged Смена рабочей директории Переключение окружения
Setup Запуск с --init или --maintenance Установка зависимостей при инициализации

🎨 Образ: события — это камеры на заводе. Камера у входа (PreToolUse), камера у выхода (PostToolUse), камера в кабинете директора (Stop). Ты не ставишь три десятка камер в первый день — начинаешь с 3-4 на критичных точках.


Подробнее: 4 главных события

⚠️ Важно про актуальность: Ранние материалы про Claude Code упоминают "4 типа хуков" (Pre-tool / Post-tool / Stop / Need you) — это базовая модель из старой документации. К октябрю 2026 экосистема выросла до около 30 lifecycle events (PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart, SubagentStop, Notification, PreCompact, PostCompact и др.) и 5 типов обработчиков (command, http, mcp_tool, prompt, agent). Эти 4 базовых сценария всё ещё покрывают большую часть задач. Остальные события — для тонкой настройки поверх. Подробнее в уроке Hook-Deny-By-Design — там как раз продвинутые события используются.

Маппинг старой "четвёрки" на современные события:

Старая категория Современные события 2026
Pre-tool PreToolUse + PreCompact + UserPromptSubmit
Post-tool PostToolUse + PostCompact + SessionStart
Stop Stop + SubagentStop
Need you Notification + UserPromptSubmit

🎨 Образ: старая "четвёрка" — это четыре поста охраны на маленьком складе. Сегодня склад вырос до завода: три десятка постов, но 4 основных входа всё ещё несут основной поток. Остальные — для специальных коридоров.


🎨 Образ: PreToolUse — это контроль качества на сборочном конвейере. Деталь ещё не прикручена — но уже проверяется. Поймал брак до установки. Установил бракованную — разбирать весь агрегат.

1. PreToolUse — проверка перед действием

Когда срабатывает: до того как Claude выполнит любой инструмент (запись файла, чтение, bash-команда, etc.)

Зачем: блокировать опасные действия, проверять условия, защищать чувствительные файлы.

Практические сценарии:

  • Не давать Claude редактировать .env файл с API-ключами
  • Проверять что код не содержит захардкоженных секретов
  • Блокировать запись в production базу данных
  • Проверять бюджет перед дорогими операциями
json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/check-secrets.sh"
          }
        ]
      }
    ]
  }
}

Если скрипт возвращает exit code 2 → Claude Code останавливается и не выполняет действие. Сообщение из stderr передаётся Claude.


🎨 Образ: PostToolUse — это регистратор в архиве. Документ подписан и сдан — регистратор делает запись в журнале: кто, что, когда. Без него через месяц не вспомнишь какие файлы Claude трогал в понедельник.

2. PostToolUse — действие после выполнения

Когда срабатывает: после того как Claude успешно выполнил инструмент.

Зачем: логировать что изменилось, создавать аудит-трейл, уведомлять о конкретных изменениях.

Практические сценарии:

  • Записывать в лог-файл какие файлы Claude изменил и когда
  • Отправлять уведомление в Telegram когда изменился критичный файл
  • Обновлять счётчик операций для бюджет-контроля
  • Создавать git commit после изменений
json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/audit-log.sh"
          }
        ]
      }
    ]
  }
}

3. Stop — при завершении ответа

Когда срабатывает: когда Claude Code заканчивает отвечать и завершает задачу.

Зачем: уведомлять что работа выполнена, делать cleanup, запускать следующий шаг.

Практические сценарии:

  • Mac OS уведомление "Claude завершил задачу" — ты можешь работать параллельно
  • Отправка итогового отчёта в Telegram
  • Запуск тестов после того как Claude написал код
  • Автоматический git commit по завершении
json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude завершил задачу\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

🎨 Образ: Stop-хук = курьер который звонит "доставил заказ". Ты не стоишь у двери весь день — ждёшь звонка.


4. Notification — информирование

Когда срабатывает: когда Claude Code отправляет уведомление пользователю (но не Stop).

Зачем: реагировать на промежуточные сообщения Claude, не только на завершение.

Отличие от Stop: Stop — полное завершение задачи. Notification — Claude что-то сообщает в процессе.

Matcher-варианты: permission_prompt, idle_prompt, auth_success

Практические сценарии:

  • Логировать все промежуточные сообщения Claude
  • Уведомлять когда Claude встречает ошибку и продолжает работу
  • Трекать прогресс длинных задач

5 типов обработчиков (handlers) — КАК хук выполняет действие

Событие — это КОГДА. Обработчик — это КАК. Claude Code поддерживает 5 типов обработчиков:

Тип Что делает Когда использовать
command Запускает bash-скрипт 90% случаев — проверки, логи, уведомления
http Отправляет HTTP POST запрос Webhook в Telegram, Slack, внешний сервис
mcp_tool Вызывает инструмент MCP-сервера Когда MCP-сервер уже подключён
prompt Отправляет текст в быструю модель AI-проверка запроса перед выполнением
agent Запускает субагента (экспериментально) Сложные проверки требующие рассуждения

🎨 Образ: 5 обработчиков = 5 видов реакции охранника. Может сам проверить (command), позвонить начальнику (http), воспользоваться рацией (mcp_tool), спросить напарника (prompt), вызвать группу реагирования (agent).

Обработчик command (bash-скрипт) — основной

Самый простой и распространённый. Запускает shell-скрипт.

json
{
  "type": "command",
  "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-secrets.sh",
  "timeout": 30
}

Обработчик http (webhook) — для внешних сервисов

Отправляет данные хука как POST запрос. Тело запроса — тот же JSON что получает command-хук через stdin.

json
{
  "type": "http",
  "url": "http://localhost:8080/hooks/validate",
  "headers": {
    "Authorization": "Bearer $MY_TOKEN"
  },
  "allowedEnvVars": ["MY_TOKEN"],
  "timeout": 30
}

Ответ сервера в формате JSON обрабатывается так же как stdout command-хука.

Обработчик prompt — быстрая AI-проверка

Отправляет текст в быструю модель. Полезно для оценки безопасности запроса.

json
{
  "type": "prompt",
  "prompt": "Эта bash-команда безопасна? Команда: $ARGUMENTS\nОтветь JSON: {\"decision\": \"allow\"} или {\"decision\": \"deny\"}",
  "timeout": 30
}

Обработчики mcp_tool и agent — продвинутые

mcp_tool вызывает инструмент подключённого MCP-сервера. agent запускает субагента для проверки (в документации помечен как экспериментальный). Оба — для сложных сценариев, не для старта.


Matcher — фильтр "на что реагировать"

🎨 Образ: matcher — это фильтр на вахте. Охранник не останавливает всех подряд — только тех кто несёт коробки (Write|Edit). Курьеров пропускает без проверки. Иначе очередь на вход растянется на сто метров.

Matcher определяет на какие КОНКРЕТНЫЕ инструменты реагировать. Без matcher хук срабатывает на ВСЁ.

Значение matcher Что делает Пример
"Bash" Только bash-команды Хук сработает при npm test, git push
"Write|Edit" Запись или редактирование файлов Хук на проверку секретов
"mcp__memory__.*" Все инструменты MCP-сервера memory Аудит MCP-операций
"*" или отсутствует Все инструменты Универсальный лог

Matcher — это регулярное выражение если в нём есть спецсимволы, или точное совпадение если только буквы.

Дополнительный фильтр "if" позволяет фильтровать по аргументам (например, Bash(git *) или Edit(*.ts)):

json
{
  "matcher": "Bash",
  "hooks": [{
    "type": "command",
    "if": "Bash(rm *)",
    "command": "echo 'rm заблокирован' >&2 && exit 2"
  }]
}

Здесь хук сработает только для Bash, и только если команда начинается с rm. Полный синтаксис if — в официальном справочнике по хукам.


Структура settings.json (официальный формат)

Все хуки хранятся в settings.json. Есть три уровня файлов:

Файл Область Делиться?
~/.claude/settings.json Все проекты (глобально) Нет
.claude/settings.json Этот проект Да (коммитить в git)
.claude/settings.local.json Этот проект (локально) Нет (в .gitignore)

Структура: 3 уровня вложенности

Код
hooks → Событие → [{ matcher, hooks: [{ type, command, ... }] }]

Полный пример с 3 хуками:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-secrets.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit-log.sh"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude завершил\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Ключевые правила:

  • Имена событий — CamelCase: PreToolUse, не pre_tool_use
  • Каждое событие содержит массив групп с matcher и hooks
  • Каждая группа содержит массив обработчиков hooks
  • matcher фильтрует по инструменту (для Stop/SessionStart — не нужен)
  • Можно полностью отключить все хуки: "disableAllHooks": true

Как хук получает данные (JSON-протокол)

Claude Code передаёт хуку данные через stdin (для command-хуков) или POST body (для http-хуков) в формате JSON.

Что получает PreToolUse хук

json
{
  "session_id": "abc123",
  "cwd": "/Users/me/project",
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/project/config.py",
    "content": "API_KEY = 'sk-proj-abc123...'"
  }
}

Что получает PostToolUse хук

json
{
  "session_id": "abc123",
  "cwd": "/Users/me/project",
  "hook_event_name": "PostToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "npm test" },
  "tool_response": "All tests passed"
}

Что получает SessionStart хук

json
{
  "session_id": "abc123",
  "cwd": "/Users/me/project",
  "hook_event_name": "SessionStart",
  "source": "startup",
  "model": "<идентификатор модели>"
}

Как хук отвечает Claude Code (JSON-ответ)

Хук может вернуть JSON через stdout для управления поведением:

json
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "Безопасная команда",
    "additionalContext": "Подсказка для Claude"
  }
}

Решения для PreToolUse: "allow" (разрешить без вопросов), "deny" (заблокировать), "ask" (спросить пользователя); в новых версиях есть ещё "defer".

Если несколько хуков дают разные решения, приоритет: deny > ask > allow.

Exit codes — как хук сообщает решение

Exit code Результат
0 Успех. Claude Code парсит stdout как JSON
2 Блокировка. Stderr передаётся Claude как причина
1 или другой Некритичная ошибка — запись в лог, работа продолжается

Важно: exit code 2 (не 1!) блокирует действие. Exit code 1 — это просто ошибка, хук "сломался", но Claude продолжает работу.


Как добавить хук: два способа

Способ 1: Попросить Claude Code (рекомендуется для начала)

Напиши в чат
Я хочу сделать хук: когда Claude завершает ответ,
отправлять мне Mac OS уведомление

Claude Code задаст уточняющие вопросы, создаст bash-скрипт и добавит запись в settings.json.

Способ 2: Через /hooks в терминале

bash
claude
# В интерфейсе Claude Code:
/hooks
# Открывает список настроенных хуков (просмотр)
# Для редактирования — правь settings.json напрямую

Показывает текущие хуки: тип обработчика ([command], [http], [prompt]), источник ([User], [Project], [Local]) и matcher.


Глобальные vs проектные хуки

🎨 Образ: глобальные хуки — как правила пожарной безопасности. Они действуют в любом здании которое ты заходишь. Проектные хуки — как инструкция конкретного объекта. "На этом складе дополнительно проверяй температурный режим."

Хуки безопасности (секреты, бюджет) — ставь глобально (~/.claude/settings.json). Они защищают тебя во всех проектах.

Хуки специфичные для проекта (линтер, тесты, деплой) — ставь проектно (.claude/settings.json). Их можно коммитить в git и шарить с командой.

Код
~/.claude/settings.json          ← Безопасность (все проекты)
  └── PreToolUse: no-secrets
  └── PreToolUse: budget-check

.claude/settings.json            ← Проектные (этот проект)
  └── PostToolUse: run-linter
  └── Stop: run-tests

Все уровни объединяются. Глобальные + проектные + локальные хуки работают вместе.


Переменные окружения в хуках

Внутри command-хука доступны:

Переменная Что содержит
$CLAUDE_PROJECT_DIR Корень проекта (оборачивай в кавычки!)
$CLAUDE_ENV_FILE Путь для сохранения env-переменных на всю сессию

Пример использования:

bash
#!/bin/bash
# Запуск скрипта из папки проекта
"$CLAUDE_PROJECT_DIR"/.claude/hooks/my-check.sh

Практика

Задание: Изучить структуру settings.json

  1. Открой или создай файл .claude/settings.json
  2. Попроси Claude Code: Покажи мне текущие настройки хуков
  3. Попроси создать самый простой хук: Создай хук: когда Claude завершает ответ, выводи уведомление "Готово" — нажми yes
  4. Проверь что settings.json обновился: посмотри новую запись в разделе Stop (CamelCase!)
  5. Протестируй: задай Claude любой простой вопрос — должно появиться уведомление
  6. Набери /hooks в Claude Code — убедись что хук виден в списке

Цель: понять что settings.json — единая точка конфигурации всех хуков, хуки работают автоматически без твоего участия


Инструменты и ресурсы

  • .claude/settings.json — проектный файл хуков (коммитить в git)
  • ~/.claude/settings.json — глобальный файл хуков (все проекты)
  • /hooks — команда для просмотра настроенных хуков в Claude Code
  • jq — инструмент для парсинга JSON в bash-скриптах (нужен для command-хуков)
  • osascript — Mac OS команда для отправки нативных уведомлений
  • Официальная документация (актуальный reference): https://code.claude.com/docs/en/hooks — все lifecycle events, форматы JSON, exit codes
  • Продвинутые события: урок Hook-Deny-By-Design — практика SubagentStop, PreCompact, PermissionRequest

Источники


Ключевые выводы

Hooks ≠ Skills. Скиллы вызываешь сам. Хуки работают автоматически при событии — ты их настраиваешь один раз.

Около 30 типов событий, но начинай с 4-6 основных: PreToolUse, PostToolUse, Stop, Notification, SessionStart, UserPromptSubmit.

5 типов обработчиков: command (bash), http (webhook), mcp_tool, prompt (AI-проверка), agent (субагент). Для старта хватит command.

Matcher фильтрует по инструменту: "Write|Edit" — только файловые операции, "Bash" — только команды.

Exit code 2 = блокировка, exit code 0 = разрешить. Не 1, а именно 2 блокирует!

Хуки хранятся в settings.json на трёх уровнях: глобальный, проектный, локальный. Все объединяются.


Что дальше

→ Hooks LIVE: строим хуки с нуля

Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс