Настройка вашего первого hook
Чтобы создать hook, добавьте блокhooks в файл параметров. Это пошаговое руководство создаёт hook для уведомлений на рабочем столе, чтобы вы получали оповещение всякий раз, когда Claude ждёт вашего ввода вместо того, чтобы смотреть на терминал.
Добавьте hook в ваши параметры
Откройте Если ваш файл параметров уже имеет ключ
~/.claude/settings.json и добавьте hook Notification. Пример ниже использует osascript для macOS; см. Получайте уведомления, когда Claude требует ввода для команд Linux и Windows.hooks, объедините запись Notification в него, а не заменяйте весь объект. Вы также можете попросить Claude написать hook для вас, описав то, что вы хотите, в CLI.Проверьте конфигурацию
Введите
/hooks для открытия браузера hooks. Вы увидите список всех доступных событий hook с количеством рядом с каждым событием, которое имеет настроенные hooks. Выберите Notification для подтверждения того, что ваш новый hook появляется в списке. Выбор hook показывает его детали: событие, matcher, тип, исходный файл и команду.Что вы можете автоматизировать
Hooks позволяют запускать код в ключевых точках жизненного цикла Claude Code: форматировать файлы после редактирования, блокировать команды перед их выполнением, отправлять уведомления, когда Claude требует ввода, внедрять контекст при запуске сеанса и многое другое. Для полного списка событий hook см. справочник Hooks. Каждый пример включает готовый к использованию блок конфигурации, который вы добавляете в файл параметров. Наиболее распространённые шаблоны:- Получайте уведомления, когда Claude требует ввода
- Автоматическое форматирование кода после редактирования
- Блокировка редактирования защищённых файлов
- Повторное внедрение контекста после компактирования
- Аудит изменений конфигурации
- Перезагрузка окружения при изменении каталога или файлов
- Автоматическое одобрение определённых запросов разрешений
Получайте уведомления, когда Claude требует ввода
Получайте уведомление на рабочем столе всякий раз, когда Claude завершает работу и требует вашего ввода, чтобы вы могли переключиться на другие задачи без проверки терминала. Этот hook использует событиеNotification, которое срабатывает, когда Claude ждёт ввода или разрешения. Каждая вкладка ниже использует собственную команду уведомления платформы. Добавьте это в ~/.claude/settings.json:
- macOS
- Linux
- Windows (PowerShell)
Автоматическое форматирование кода после редактирования
Автоматически запускайте Prettier на каждом файле, который редактирует Claude, чтобы форматирование оставалось согласованным без ручного вмешательства. Этот hook использует событиеPostToolUse с matcher Edit|Write, поэтому он запускается только после инструментов редактирования файлов. Команда извлекает путь отредактированного файла с помощью jq и передаёт его в Prettier. Добавьте это в .claude/settings.json в корне вашего проекта:
Примеры Bash на этой странице используют
jq для анализа JSON. Установите его с помощью brew install jq (macOS), apt-get install jq (Debian/Ubuntu) или см. загрузки jq.Блокировка редактирования защищённых файлов
Предотвратите изменение Claude чувствительных файлов, таких как.env, package-lock.json или что-либо в .git/. Claude получает обратную связь, объясняющую, почему редактирование было заблокировано, чтобы он мог скорректировать свой подход.
Этот пример использует отдельный файл скрипта, который вызывает hook. Скрипт проверяет путь целевого файла против списка защищённых шаблонов и выходит с кодом 2 для блокировки редактирования.
Сделайте скрипт исполняемым (macOS/Linux)
Скрипты hook должны быть исполняемыми для запуска Claude Code:
Повторное внедрение контекста после компактирования
Когда контекстное окно Claude заполняется, компактирование суммирует разговор для освобождения места. Это может привести к потере важных деталей. Используйте hookSessionStart с matcher compact для повторного внедрения критического контекста после каждого компактирования.
Любой текст, который ваша команда выводит в stdout, добавляется в контекст Claude. Этот пример напоминает Claude о соглашениях проекта и недавней работе. Добавьте это в .claude/settings.json в корне вашего проекта:
echo любой командой, которая производит динамический вывод, например git log --oneline -5 для отображения недавних коммитов. Для внедрения контекста при каждом запуске сеанса рассмотрите использование CLAUDE.md вместо этого. Для переменных окружения см. CLAUDE_ENV_FILE в справочнике.
Аудит изменений конфигурации
Отслеживайте, когда файлы параметров или skills изменяются во время сеанса. СобытиеConfigChange срабатывает, когда внешний процесс или редактор изменяет файл конфигурации, поэтому вы можете регистрировать изменения для соответствия или блокировать несанкционированные изменения.
Этот пример добавляет каждое изменение в журнал аудита. Добавьте это в ~/.claude/settings.json:
user_settings, project_settings, local_settings, policy_settings или skills. Для блокировки вступления изменения в силу выйдите с кодом 2 или верните {"decision": "block"}. См. справочник ConfigChange для полной схемы ввода.
Перезагрузка окружения при изменении каталога или файлов
Некоторые проекты устанавливают разные переменные окружения в зависимости от того, в каком каталоге вы находитесь. Инструменты, такие как direnv, делают это автоматически в вашей оболочке, но инструмент Bash Claude не подхватывает эти изменения самостоятельно. HookCwdChanged исправляет это: он запускается каждый раз, когда Claude меняет каталог, поэтому вы можете перезагрузить правильные переменные для нового местоположения. Hook записывает обновлённые значения в CLAUDE_ENV_FILE, который Claude Code применяет перед каждой командой Bash. Добавьте это в ~/.claude/settings.json:
FileChanged с matcher, указывающим имена файлов для наблюдения (разделённые трубой). Matcher как настраивает, какие файлы наблюдать, так и фильтрует, какие hooks запускаются. Этот пример наблюдает .envrc и .env на предмет изменений в текущем каталоге:
watchPaths и деталей CLAUDE_ENV_FILE.
Автоматическое одобрение определённых запросов разрешений
Пропустите диалог одобрения для вызовов инструментов, которые вы всегда разрешаете. Этот пример автоматически одобряетExitPlanMode, инструмент, который Claude вызывает, когда он завершает представление плана и просит продолжить, чтобы вас не спрашивали каждый раз, когда план готов.
В отличие от примеров с кодом выхода выше, автоматическое одобрение требует, чтобы ваш hook написал решение JSON в stdout. Hook PermissionRequest срабатывает, когда Claude Code собирается показать диалог разрешения, и возврат "behavior": "allow" отвечает на него от вашего имени.
Matcher ограничивает hook только ExitPlanMode, поэтому никакие другие запросы не затрагиваются. Добавьте это в ~/.claude/settings.json:
updatedPermissions с записью setMode. Значение mode — это любой режим разрешения, такой как default, acceptEdits или bypassPermissions, и destination: "session" применяет его только для текущего сеанса.
Чтобы переключить сеанс на acceptEdits, ваш hook пишет этот JSON в stdout:
.* или оставление matcher пустым автоматически одобрит каждый запрос разрешения, включая записи файлов и команды оболочки. См. справочник PermissionRequest для полного набора полей решения.
Как работают hooks
События hook срабатывают в определённых точках жизненного цикла Claude Code. Когда событие срабатывает, все соответствующие hooks запускаются параллельно, и идентичные команды hook автоматически дедублируются. Таблица ниже показывает каждое событие и когда оно срабатывает:| Event | When it fires |
|---|---|
SessionStart | When a session begins or resumes |
UserPromptSubmit | When you submit a prompt, before Claude processes it |
PreToolUse | Before a tool call executes. Can block it |
PermissionRequest | When a permission dialog appears |
PermissionDenied | When a tool call is denied by the auto mode classifier. Return {retry: true} to tell the model it may retry the denied tool call |
PostToolUse | After a tool call succeeds |
PostToolUseFailure | After a tool call fails |
Notification | When Claude Code sends a notification |
SubagentStart | When a subagent is spawned |
SubagentStop | When a subagent finishes |
TaskCreated | When a task is being created via TaskCreate |
TaskCompleted | When a task is being marked as completed |
Stop | When Claude finishes responding |
StopFailure | When the turn ends due to an API error. Output and exit code are ignored |
TeammateIdle | When an agent team teammate is about to go idle |
InstructionsLoaded | When a CLAUDE.md or .claude/rules/*.md file is loaded into context. Fires at session start and when files are lazily loaded during a session |
ConfigChange | When a configuration file changes during a session |
CwdChanged | When the working directory changes, for example when Claude executes a cd command. Useful for reactive environment management with tools like direnv |
FileChanged | When a watched file changes on disk. The matcher field specifies which filenames to watch |
WorktreeCreate | When a worktree is being created via --worktree or isolation: "worktree". Replaces default git behavior |
WorktreeRemove | When a worktree is being removed, either at session exit or when a subagent finishes |
PreCompact | Before context compaction |
PostCompact | After context compaction completes |
Elicitation | When an MCP server requests user input during a tool call |
ElicitationResult | After a user responds to an MCP elicitation, before the response is sent back to the server |
SessionEnd | When a session terminates |
type, который определяет, как он запускается. Большинство hooks используют "type": "command", который запускает команду оболочки. Доступны три других типа:
"type": "http": POST данные события на URL. См. HTTP hooks."type": "prompt": однооборотная оценка LLM. См. Hooks на основе подсказок."type": "agent": многооборотная проверка с доступом к инструментам. См. Hooks на основе агентов.
Чтение ввода и возврат вывода
Hooks взаимодействуют с Claude Code через stdin, stdout, stderr и коды выхода. Когда событие срабатывает, Claude Code передаёт данные, специфичные для события, в виде JSON в stdin вашего скрипта. Ваш скрипт читает эти данные, выполняет свою работу и сообщает Claude Code, что делать дальше, через код выхода.Ввод hook
Каждое событие включает общие поля, такие какsession_id и cwd, но каждый тип события добавляет разные данные. Например, когда Claude запускает команду Bash, hook PreToolUse получает что-то вроде этого на stdin:
UserPromptSubmit получают текст prompt вместо этого, hooks SessionStart получают source (startup, resume, clear, compact) и так далее. См. Общие поля ввода в справочнике для общих полей и раздел каждого события для схем, специфичных для события.
Вывод hook
Ваш скрипт сообщает Claude Code, что делать дальше, записывая в stdout или stderr и выходя с определённым кодом. Например, hookPreToolUse, который хочет заблокировать команду:
- Exit 0: действие продолжается. Для hooks
UserPromptSubmitиSessionStartвсё, что вы пишете в stdout, добавляется в контекст Claude. - Exit 2: действие блокируется. Напишите причину в stderr, и Claude получит её как обратную связь, чтобы он мог скорректировать.
- Любой другой код выхода: действие продолжается. Stderr регистрируется, но не показывается Claude. Переключите режим подробности с помощью
Ctrl+Oдля просмотра этих сообщений в стенограмме.
Структурированный вывод JSON
Коды выхода дают вам два варианта: разрешить или заблокировать. Для большего контроля выйдите с 0 и выведите объект JSON в stdout вместо этого.Используйте exit 2 для блокировки с сообщением stderr или exit 0 с JSON для структурированного управления. Не смешивайте их: Claude Code игнорирует JSON при выходе 2.
PreToolUse может отклонить вызов инструмента и сказать Claude почему, или передать его пользователю на одобрение:
permissionDecision и отменяет вызов инструмента, затем передаёт permissionDecisionReason обратно Claude как обратную связь. Эти три варианта специфичны для PreToolUse:
"allow": пропустить интерактивный запрос разрешения. Правила отказа и запроса, включая управляемые списки отказов предприятия, по-прежнему применяются"deny": отменить вызов инструмента и отправить причину Claude"ask": показать запрос разрешения пользователю как обычно
"allow" пропускает интерактивный запрос, но не переопределяет правила разрешений. Если правило отказа соответствует вызову инструмента, вызов блокируется даже когда ваш hook возвращает "allow". Если правило запроса соответствует, пользователь по-прежнему получает запрос. Это означает, что правила отказа из любой области параметров, включая управляемые параметры, всегда имеют приоритет над одобрениями hook.
Другие события используют разные шаблоны решений. Например, hooks PostToolUse и Stop используют поле decision: "block" верхнего уровня, а PermissionRequest использует hookSpecificOutput.decision.behavior. См. таблицу сводки в справочнике для полного разбора по событиям.
Для hooks UserPromptSubmit используйте additionalContext вместо этого для внедрения текста в контекст Claude. Hooks на основе подсказок (type: "prompt") обрабатывают вывод иначе: см. Hooks на основе подсказок.
Фильтрация hooks с помощью matchers
Без matcher hook срабатывает при каждом возникновении его события. Matchers позволяют вам сузить это. Например, если вы хотите запустить форматер только после редактирования файлов (не после каждого вызова инструмента), добавьте matcher к вашему hookPostToolUse:
"Edit|Write" — это шаблон regex, который соответствует имени инструмента. Hook срабатывает только, когда Claude использует инструмент Edit или Write, а не когда он использует Bash, Read или любой другой инструмент.
Каждый тип события соответствует определённому полю. Matchers поддерживают точные строки и шаблоны regex:
| Событие | Что фильтрует matcher | Примеры значений matcher |
|---|---|---|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest | имя инструмента | Bash, Edit|Write, mcp__.* |
SessionStart | как начался сеанс | startup, resume, clear, compact |
SessionEnd | почему закончился сеанс | clear, resume, logout, prompt_input_exit, bypass_permissions_disabled, other |
Notification | тип уведомления | permission_prompt, idle_prompt, auth_success, elicitation_dialog |
SubagentStart | тип агента | Bash, Explore, Plan или пользовательские имена агентов |
PreCompact, PostCompact | что запустило компактирование | manual, auto |
SubagentStop | тип агента | те же значения, что и SubagentStart |
ConfigChange | источник конфигурации | user_settings, project_settings, local_settings, policy_settings, skills |
StopFailure | тип ошибки | rate_limit, authentication_failed, billing_error, invalid_request, server_error, max_output_tokens, unknown |
InstructionsLoaded | причина загрузки | session_start, nested_traversal, path_glob_match, include, compact |
Elicitation | имя MCP сервера | ваши настроенные имена MCP серверов |
ElicitationResult | имя MCP сервера | те же значения, что и Elicitation |
FileChanged | имя файла (basename изменённого файла) | .envrc, .env, любое имя файла, которое вы хотите наблюдать |
UserPromptSubmit, Stop, TeammateIdle, TaskCompleted, WorktreeCreate, WorktreeRemove, CwdChanged | поддержка matcher отсутствует | всегда срабатывает при каждом возникновении |
- Регистрируйте каждую команду Bash
- Соответствие MCP инструментам
- Очистка при завершении сеанса
Соответствуйте только вызовам инструмента
Bash и регистрируйте каждую команду в файл. Событие PostToolUse срабатывает после завершения команды, поэтому tool_input.command содержит то, что запустилось. Hook получает данные события в виде JSON на stdin, и jq -r '.tool_input.command' извлекает только строку команды, которую >> добавляет в файл журнала:Настройка местоположения hook
Где вы добавляете hook, определяет его область:| Местоположение | Область | Общий доступ |
|---|---|---|
~/.claude/settings.json | Все ваши проекты | Нет, локально на вашей машине |
.claude/settings.json | Один проект | Да, можно зафиксировать в репо |
.claude/settings.local.json | Один проект | Нет, gitignored |
| Управляемые параметры политики | Организация | Да, контролируется администратором |
Plugin hooks/hooks.json | Когда плагин включен | Да, упакован с плагином |
| Skill или agent frontmatter | Пока skill или agent активны | Да, определено в файле компонента |
/hooks в Claude Code для просмотра всех настроенных hooks, сгруппированных по событиям. Чтобы отключить все hooks сразу, установите "disableAllHooks": true в вашем файле параметров.
Если вы редактируете файлы параметров напрямую во время работы Claude Code, наблюдатель файлов обычно автоматически подхватывает изменения hook.
Hooks на основе подсказок
Для решений, требующих суждения, а не детерминированных правил, используйте hookstype: "prompt". Вместо запуска команды оболочки Claude Code отправляет вашу подсказку и данные ввода hook модели Claude (Haiku по умолчанию) для принятия решения. Вы можете указать другую модель с полем model, если вам нужна большая возможность.
Единственная работа модели — вернуть решение да/нет в виде JSON:
"ok": true: действие продолжается"ok": false: действие блокируется."reason"модели передаётся обратно Claude, чтобы он мог скорректировать.
Stop для запроса модели, завершены ли все запрошенные задачи. Если модель возвращает "ok": false, Claude продолжает работать и использует reason как свою следующую инструкцию:
Hooks на основе агентов
Когда проверка требует проверки файлов или запуска команд, используйте hookstype: "agent". В отличие от hooks подсказок, которые делают один вызов LLM, hooks агентов порождают subagent, который может читать файлы, искать код и использовать другие инструменты для проверки условий перед возвратом решения.
Hooks агентов используют тот же формат ответа "ok" / "reason", что и hooks подсказок, но с более длинным временем ожидания по умолчанию 60 секунд и до 50 оборотов использования инструмента.
Этот пример проверяет, что тесты проходят перед тем, как позволить Claude остановиться:
HTTP hooks
Используйте hookstype: "http" для POST данных события на HTTP конечную точку вместо запуска команды оболочки. Конечная точка получает тот же JSON, который hook команды получил бы на stdin, и возвращает результаты через тело ответа HTTP, используя тот же формат JSON.
HTTP hooks полезны, когда вы хотите, чтобы веб-сервер, облачная функция или внешний сервис обрабатывали логику hook: например, общий сервис аудита, который регистрирует события использования инструмента в команде.
Этот пример отправляет каждое использование инструмента на локальный сервис логирования:
hookSpecificOutput. Коды состояния HTTP сами по себе не могут блокировать действия.
Значения заголовков поддерживают интерполяцию переменных окружения, используя синтаксис $VAR_NAME или ${VAR_NAME}. Разрешены только переменные, указанные в массиве allowedEnvVars; все остальные ссылки $VAR остаются пустыми.
Для полных параметров конфигурации и обработки ответов см. HTTP hooks в справочнике.
Ограничения и устранение неполадок
Ограничения
- Hooks команд взаимодействуют только через stdout, stderr и коды выхода. Они не могут напрямую запускать команды или вызовы инструментов. HTTP hooks взаимодействуют через тело ответа вместо этого.
- Время ожидания hook составляет 10 минут по умолчанию, настраивается для каждого hook с помощью поля
timeout(в секундах). - Hooks
PostToolUseне могут отменить действия, так как инструмент уже выполнен. - Hooks
PermissionRequestне срабатывают в неинтерактивном режиме (-p). Используйте hooksPreToolUseдля автоматизированных решений разрешений. - Hooks
Stopсрабатывают всякий раз, когда Claude завершает ответ, а не только при завершении задачи. Они не срабатывают при прерывании пользователем. Ошибки API срабатывают StopFailure вместо этого.
Hook не срабатывает
Hook настроен, но никогда не выполняется.- Запустите
/hooksи подтвердите, что hook появляется под правильным событием - Проверьте, что шаблон matcher точно соответствует имени инструмента (matchers чувствительны к регистру)
- Убедитесь, что вы запускаете правильный тип события (например,
PreToolUseсрабатывает перед выполнением инструмента,PostToolUseсрабатывает после) - Если используете hooks
PermissionRequestв неинтерактивном режиме (-p), переключитесь наPreToolUseвместо этого
Ошибка hook в выводе
Вы видите сообщение вроде “PreToolUse hook error: …” в стенограмме.- Ваш скрипт неожиданно вышел с ненулевым кодом. Протестируйте его вручную, передав образец JSON:
- Если вы видите “command not found”, используйте абсолютные пути или
$CLAUDE_PROJECT_DIRдля ссылки на скрипты - Если вы видите “jq: command not found”, установите
jqили используйте Python/Node.js для анализа JSON - Если скрипт вообще не запускается, сделайте его исполняемым:
chmod +x ./my-hook.sh
/hooks показывает, что hooks не настроены
Вы отредактировали файл параметров, но hooks не появляются в меню.
- Редактирования файлов обычно подхватываются автоматически. Если они не появились через несколько секунд, наблюдатель файлов мог пропустить изменение: перезагрузите сеанс для принудительной перезагрузки.
- Убедитесь, что ваш JSON действителен (конечные запятые и комментарии не допускаются)
- Подтвердите, что файл параметров находится в правильном месте:
.claude/settings.jsonдля hooks проекта,~/.claude/settings.jsonдля глобальных hooks
Stop hook работает вечно
Claude продолжает работать в бесконечном цикле вместо остановки. Ваш скрипт Stop hook должен проверить, не срабатывал ли он уже. Проанализируйте полеstop_hook_active из JSON ввода и выйдите рано, если оно true:
Ошибка валидации JSON
Claude Code показывает ошибку анализа JSON, даже если ваш скрипт hook выводит действительный JSON. Когда Claude Code запускает hook, он порождает оболочку, которая источает ваш профиль (~/.zshrc или ~/.bashrc). Если ваш профиль содержит безусловные операторы echo, этот вывод добавляется к JSON вашего hook:
$- содержит флаги оболочки, и i означает интерактивный. Hooks запускаются в неинтерактивных оболочках, поэтому echo пропускается.
Методы отладки
Переключите режим подробности с помощьюCtrl+O для просмотра вывода hook в стенограмме или запустите claude --debug для полных деталей выполнения, включая какие hooks совпали и их коды выхода.
Узнайте больше
- Справочник Hooks: полные схемы событий, формат вывода JSON, асинхронные hooks и MCP tool hooks
- Соображения безопасности: просмотрите перед развёртыванием hooks в общих или производственных средах
- Пример валидатора команд Bash: полная справочная реализация