476| `async` | нет | Если `true`, запускается в фоне без блокировки. См. [Run hooks in the background](#run-hooks-in-the-background) |476| `async` | нет | Если `true`, запускается в фоне без блокировки. См. [Run hooks in the background](#run-hooks-in-the-background) |
477| `asyncRewake` | нет | Если `true`, запускается в фоне и пробуждает Claude при коде выхода 2. Hook stderr или stdout, если stderr пусто, показывается Claude как [системное напоминание](/docs/ru/glossary#system-reminder) чтобы он мог реагировать на долгоживущий фоновый сбой |477| `asyncRewake` | нет | Если `true`, запускается в фоне и пробуждает Claude при коде выхода 2. Hook stderr или stdout, если stderr пусто, показывается Claude как [системное напоминание](/docs/ru/glossary#system-reminder) чтобы он мог реагировать на долгоживущий фоновый сбой |
478| `shell` | нет | Оболочка для использования для этого hook. Принимает `"bash"` или `"powershell"`. По умолчанию `"bash"`, или `"powershell"` на Windows когда Git Bash не установлен. Установка `"powershell"` запускает команду через PowerShell на Windows. Не требует `CLAUDE_CODE_USE_POWERSHELL_TOOL`, так как hooks порождают PowerShell напрямую. Игнорируется когда установлен `args` |478| `shell` | нет | Оболочка для использования для этого hook. Принимает `"bash"` или `"powershell"`. По умолчанию `"bash"`, или `"powershell"` на Windows когда Git Bash не установлен. Установка `"powershell"` запускает команду через PowerShell на Windows. Не требует `CLAUDE_CODE_USE_POWERSHELL_TOOL`, так как hooks порождают PowerShell напрямую. Игнорируется когда установлен `args` |
479| `onFailure` | нет | Что происходит с действием при сбое хука: `"continue"` (по умолчанию) или `"block"`. См. [Блокировка действия при сбое хука](#block-the-action-when-a-hook-fails). Требует Claude Code v2.1.295 или новее |
479 480
480<a id="exec-form-and-shell-form" />481<a id="exec-form-and-shell-form" />
481 482
533| `url` | да | URL для отправки POST запроса |534| `url` | да | URL для отправки POST запроса |
534| `headers` | нет | Дополнительные HTTP заголовки как пары ключ-значение. Значения поддерживают интерполяцию переменных окружения с использованием синтаксиса `$VAR_NAME` или `${VAR_NAME}`. Разрешены только переменные, указанные в `allowedEnvVars` |535| `headers` | нет | Дополнительные HTTP заголовки как пары ключ-значение. Значения поддерживают интерполяцию переменных окружения с использованием синтаксиса `$VAR_NAME` или `${VAR_NAME}`. Разрешены только переменные, указанные в `allowedEnvVars` |
535| `allowedEnvVars` | нет | Список имён переменных окружения, которые могут быть интерполированы в значения заголовков. Ссылки на неуказанные переменные заменяются пустыми строками. Требуется для любой интерполяции переменных окружения |536| `allowedEnvVars` | нет | Список имён переменных окружения, которые могут быть интерполированы в значения заголовков. Ссылки на неуказанные переменные заменяются пустыми строками. Требуется для любой интерполяции переменных окружения |
537| `onFailure` | нет | Что происходит с действием при сбое хука: `"continue"` (по умолчанию) или `"block"`. См. [Блокировка действия при сбое хука](#block-the-action-when-a-hook-fails). Требует Claude Code v2.1.295 или новее |
536 538
537Claude Code отправляет [JSON входные данные](#hook-input-and-output) hook как тело POST запроса с `Content-Type: application/json`. Тело ответа использует тот же [JSON формат выхода](#json-output), что и command hooks.539Claude Code отправляет [JSON входные данные](#hook-input-and-output) hook как тело POST запроса с `Content-Type: application/json`. Тело ответа использует тот же [JSON формат выхода](#json-output), что и command hooks.
538 540
821 Вывод через код выхода823 Вывод через код выхода
822</h3>824</h3>
823 825
824Код выхода вашей команды хука сообщает Claude Code, следует ли продолжить действие, заблокировать его или проигнорировать. Код выхода не действует сам по себе. Claude Code читает [поля вывода JSON](#json-output) из stdout при любом коде выхода, а не только при 0, и для событий, использующих стандартную модель решений, разобранный объект, прошедший проверку схемы, вступает в силу наряду с кодом. Блокировка при выходе с кодом 2 — единственный результат, который JSON не может переопределить.826Код выхода вашего хука сообщает Claude Code, следует ли продолжить действие, вызвавшее хук, например вызов инструмента или промпт. Завершившийся запуск имеет один из трёх результатов:
825 827
826Исключения для отдельных событий описаны в двух таблицах: [Поведение кода выхода 2 для каждого события](#exit-code-2-behavior-per-event) показывает, что делают коды выхода для каждого события, а [Управление решениями](#decision-control) — какие поля решений учитывает каждое событие. Универсальные поля, такие как `systemMessage`, работают для большинства событий и перечислены в таблице [Вывод JSON](#json-output).828* **Успех**: ваш хук завершается с кодом 0. Claude Code применяет все поля [вывода JSON](#json-output), которые вывел ваш хук, и действие выполняется, если эти поля не блокируют и не отклоняют его.
829* **Блокирующая ошибка**: ваш хук завершается с кодом 2. Для [событий, которые могут блокировать](#exit-code-2-behavior-per-event), Claude Code останавливает действие.
830* **Неблокирующая ошибка**: ваш хук завершается с любым другим кодом или завершается сбоем иным образом, например не запускается или выводит некорректный JSON. Действие выполняется, а для таких событий, как `PreToolUse`, в транскрипте отображается уведомление `<hook name> hook error`. Если вы хотите, чтобы хук, завершившийся сбоем, блокировал действие, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
831
832То, что ваш хук выводит в stdout, может изменить результат. Например, если хук `PreToolUse` завершается с кодом 1, но выводит JSON, прошедший проверку, запуск считается успешным, и происходящее определяют поля JSON. Чтобы узнать результат вашего хука для такого события, как `PreToolUse`, найдите в первом столбце то, что он вывел в stdout, а в верхней строке — его код выхода:
833
834| Stdout | Выход с кодом 0 | Выход с кодом 2 | Любой другой код выхода |
835| :- | :- | :- | :- |
836| Объект JSON, прошедший [проверку схемы](#json-output) | Успех. Поля применяются | Блокирующая ошибка. Claude Code всё равно читает поля, но они не могут переопределить блокировку | Успех. Claude Code игнорирует код выхода, и результат определяют только поля. При [`onFailure: "block"`](#block-the-action-when-a-hook-fails) это считается сбоем |
837| JSON, который [не удаётся разобрать](#exit-code-0) или который не прошёл проверку схемы | Неблокирующая ошибка. Уведомление содержит сообщение о разборе или проверке | Блокирующая ошибка. Причиной служит ваш stderr | Неблокирующая ошибка. Уведомление содержит сообщение о разборе или проверке |
838| [Обычный текст](#exit-code-0) или ничего | Успех | Блокирующая ошибка. Причиной служит ваш stderr | Неблокирующая ошибка. Уведомление содержит первую строку вашего stderr |
839
840У некоторых событий собственные правила:
841
842* **`WorktreeCreate`**: любой ненулевой код выхода приводит к ошибке создания worktree, что бы ни содержал ваш JSON.
843* **`WorktreeRemove`**: любой ненулевой код выхода приводит к ошибке удаления worktree, если каталог после этого всё ещё существует.
844* **`Stop`, `SubagentStop`, `TaskCompleted` и хук `UserPromptSubmit` плагина**: если ваш хук завершается с кодом 2, ничего не выводит в stdout, а его stderr сообщает об отсутствии файла, например `No such file or directory`, Claude Code обрабатывает запуск как неблокирующую ошибку.
845* **`Elicitation` и `ElicitationResult`**: Claude Code применяет ваш `hookSpecificOutput`, когда хук завершается с кодом 0, и игнорирует его при любом другом коде выхода.
846* **События, отбрасывающие вывод хука, такие как `StopFailure`**: Claude Code игнорирует ваш JSON при любом коде выхода, за исключением полей с побочными эффектами, таких как `terminalSequence`, которые всё равно срабатывают.
847
848Чтобы узнать, что делает код выхода 2 для вашего события, смотрите [Поведение кода выхода 2 для каждого события](#exit-code-2-behavior-per-event). Чтобы узнать, какие поля решений оно учитывает, смотрите [Управление решениями](#decision-control).
827 849
828<h4 id="exit-code-0">850<h4 id="exit-code-0">
829 Код выхода 0851 Код выхода 0
835 857
836Читает ли Claude Code ваш stdout как [вывод JSON](#json-output) или как обычный текст, зависит от того, с чего он начинается и чем заканчивается, без учёта окружающих пробельных символов:858Читает ли Claude Code ваш stdout как [вывод JSON](#json-output) или как обычный текст, зависит от того, с чего он начинается и чем заканчивается, без учёта окружающих пробельных символов:
837 859
838* **Начинается с `{` и заканчивается `}`**: Claude Code разбирает его как JSON. Если вывод состоит из двух или более строк, каждая из которых по отдельности разбирается как JSON, и ни одна строка не является объектом [вывода JSON](#json-output), задающим какое-либо поле, Claude Code обрабатывает весь вывод как обычный текст. Если одна из этих строк задаёт поле, весь вывод считается ошибкой разбора, описанной ниже.860* **Начинается с `{` и заканчивается `}`**: Claude Code разбирает его как JSON. Если вывод состоит из двух или более строк, каждая из которых по отдельности разбирается как JSON, и ни одна строка не является объектом [вывода JSON](#json-output), задающим какое-либо поле, Claude Code обрабатывает весь вывод как обычный текст. Если одна из этих строк задаёт поле, весь вывод считается ошибкой разбора.
839* **Начинается с `{`, но не заканчивается `}`**: Claude Code обрабатывает его как обычный текст.861* **Начинается с `{`, но не заканчивается `}`**: Claude Code обрабатывает его как обычный текст.
840* **Начинается с чего-либо другого**: Claude Code обрабатывает его как обычный текст, включая массив JSON или строку JSON в кавычках.862* **Начинается с чего-либо другого**: Claude Code обрабатывает его как обычный текст, включая массив JSON или строку JSON в кавычках.
841 863
842Для событий, использующих стандартную модель решений, выход с кодом 0 с разобранным объектом, не прошедшим проверку схемы, является неблокирующей ошибкой: действие продолжается, а в транскрипте отображается уведомление `<hook name> hook error` с сообщением о проверке. То же самое происходит при любом коде выхода, кроме 2, тогда как [выход с кодом 2 по-прежнему блокирует](#exit-code-2).864Если Claude Code пытается разобрать ваш stdout как JSON и не может или разобранный объект не проходит [проверку схемы](#json-output), запуск считается [неблокирующей ошибкой](#exit-code-output). Уведомление `<hook name> hook error` содержит сообщение о разборе или проверке. Для событий, которые добавляют обычный текст из stdout как контекст, Claude Code не добавляет stdout, который ему не удалось разобрать.
843
844Для событий, использующих стандартную модель решений, если Claude Code пытается разобрать ваш stdout как JSON и не может, он сообщает о неблокирующей ошибке при любом коде выхода, кроме 2. В транскрипте отображается уведомление `<hook name> hook error` с сообщением о разборе. Для событий, которые добавляют обычный текст из stdout как контекст, Claude Code не добавляет этот текст. До версии v2.1.248 Claude Code обрабатывал такой stdout как обычный текст.
845 865
846Stderr хука, завершившегося с кодом 0, попадает только в отладочный лог, никогда не в транскрипт, и Claude его никогда не видит. Чтобы прочитать его самостоятельно, включите [отладочное логирование](#debug-hooks). Чтобы передать предупреждение Claude из хука `PostToolUse` или `PostToolUseFailure`, вместо этого выйдите с кодом 2, чтобы [Claude увидел stderr](#exit-code-2-behavior-per-event), хотя инструмент уже выполнился.866Claude никогда не видит stderr хука, завершившегося с кодом 0. Чтобы прочитать его самостоятельно для таких событий, как `PreToolUse`, включите [отладочное логирование](#debug-hooks). Чтобы передать предупреждение Claude из хука `PostToolUse` или `PostToolUseFailure`, вместо этого выйдите с кодом 2, чтобы [Claude увидел stderr](#exit-code-2-behavior-per-event), хотя инструмент уже выполнился.
847 867
848<h4 id="exit-code-2">868<h4 id="exit-code-2">
849 Код выхода 2869 Код выхода 2
850</h4>870</h4>
851 871
852Выход с кодом 2 означает блокирующую ошибку. Для [событий, которые могут блокировать](#exit-code-2-behavior-per-event), выход с кодом 2 блокирует независимо от того, выводите ли вы JSON: даже `permissionDecision` со значением `"allow"` в JSON не может его переопределить. Claude Code по-прежнему читает любой корректный [вывод JSON](#json-output) из stdout. Для `Elicitation` и `ElicitationResult` поле `hookSpecificOutput` хука, завершившегося с кодом 2, игнорируется.872Завершитесь с кодом 2, чтобы заблокировать действие. Для [событий, которые могут блокировать](#exit-code-2-behavior-per-event), Claude Code останавливает действие: например, хук `PreToolUse` блокирует вызов инструмента, а хук `UserPromptSubmit` отклоняет промпт.
853 873
854Сообщением о блокировке служит причина из блокирующего решения в вашем JSON, если оно есть, а в противном случае — текст вашего stderr. Действие блокировки зависит от события: `PreToolUse` блокирует вызов инструмента, `UserPromptSubmit` отклоняет промпт и так далее. В разделе [Поведение кода выхода 2 для каждого события](#exit-code-2-behavior-per-event) перечислен эффект для каждого события, а раздел каждого события указывает, куда попадает сообщение.874Сообщением, сопровождающим блокировку, служит stderr вашего хука. Если ваш хук также вывел JSON с блокирующим решением, Claude Code вместо этого использует причину из этого решения.
855 875
856Хук, который завершается с кодом 2 и при этом выводит JSON, не прошедший проверку схемы [вывода JSON](#json-output), всё равно блокирует: Claude Code использует stderr как причину блокировки и записывает ошибку проверки в отладочный лог. До версии v2.1.214 Claude Code обрабатывал такое сочетание как неблокирующую ошибку, и действие продолжалось.876Выход с кодом 2 блокирует, даже если ваш хук выводит JSON:
877
878* **JSON, прошедший проверку схемы**: Claude Code по-прежнему читает поля [вывода JSON](#json-output), но они не могут переопределить блокировку. Даже `permissionDecision` со значением `"allow"` не пропускает действие. Для `Elicitation` и `ElicitationResult` поле `hookSpecificOutput` хука, завершившегося с кодом 2, игнорируется.
879* **JSON, не прошедший проверку схемы**: хук всё равно блокирует. Claude Code использует ваш stderr как причину блокировки и записывает ошибку проверки в отладочный лог.
857 880
858Этот скрипт блокирует команды `rm`, завершаясь с кодом 2, и оставляет все остальные команды обычному процессу разрешений:881Этот скрипт блокирует команды `rm`, завершаясь с кодом 2, и оставляет все остальные команды обычному процессу разрешений:
859 882
871exit 0 # No decision: the normal permission flow applies894exit 0 # No decision: the normal permission flow applies
872```895```
873 896
897Если этот скрипт зарегистрирован как хук `PreToolUse` для `Bash`, команда, начинающаяся с `rm`, блокируется, а Claude получает stderr хука как ошибку инструмента с префиксом из имени события, имени инструмента и команды хука:
898
899```text theme={null}
900PreToolUse:Bash hook error: [${CLAUDE_PROJECT_DIR}/.claude/hooks/no-rm.sh]: Blocked: rm commands are not allowed
901```
902
874<h4 id="other-exit-codes">903<h4 id="other-exit-codes">
875 Другие коды выхода904 Другие коды выхода
876</h4>905</h4>
877 906
878Любой другой код выхода сам по себе не блокирует для большинства событий хуков. Что произойдёт, зависит от вашего stdout:907Если ваш хук завершается с кодом, отличным от 0 или 2, и выводит в stdout обычный текст или ничего, запуск считается [неблокирующей ошибкой](#exit-code-output). В транскрипте отображается уведомление `<hook name> hook error` с `Failed with non-blocking status code:` и первой строкой stderr вашего хука. Например, если хук `PreToolUse` для `Bash` выводит `something broke` в stderr и завершается с кодом 1, уведомление `PreToolUse:Bash hook error` содержит такую строку:
879 908
880* При разобранном объекте, прошедшем проверку схемы, для событий, использующих стандартную модель решений, Claude Code игнорирует код выхода, и результат определяет только JSON:909```text theme={null}
881 * Учитывается каждое поле, которое поддерживает событие, включая `permissionDecision`, `additionalContext`, `updatedInput` и `systemMessage`, и хук не считается ошибкой.910Failed with non-blocking status code: something broke
882 * В разделе [Управление решениями](#decision-control) перечислены поля решений для каждого события; универсальные поля, такие как `systemMessage`, описаны в таблице [Вывод JSON](#json-output).911```
883* При разобранном объекте, не прошедшем проверку схемы, для событий, использующих стандартную модель решений, это та же неблокирующая ошибка, что и [при выходе с кодом 0](#exit-code-0): действие продолжается, а уведомление `<hook name> hook error` содержит сообщение о проверке.
884* При stdout, который Claude Code [пытается разобрать как JSON](#exit-code-0) и не может, Claude Code сообщает о той же неблокирующей ошибке, что и при выходе с кодом 0, для событий, использующих стандартную модель решений. Действие продолжается, а уведомление содержит сообщение о разборе.
885* При stdout, который Claude Code [обрабатывает как обычный текст](#exit-code-0), или при пустом stdout это неблокирующая ошибка для большинства событий хуков: действие продолжается, а в транскрипте отображается уведомление `<hook name> hook error`, за которым следует первая строка stderr с префиксом `Failed with non-blocking status code:`. Чтобы получить полный stderr, включите [отладочное логирование](#debug-hooks).
886 912
887События вне стандартной модели решений сохраняют собственные строки в [таблице по событиям](#exit-code-2-behavior-per-event): `WorktreeCreate` прерывает создание при любом ненулевом коде выхода независимо от того, что содержит ваш JSON, а события, полностью отбрасывающие вывод хука, такие как `StopFailure`, игнорируют ваш JSON при любом коде выхода, за исключением полей с побочными эффектами, таких как `terminalSequence`, которые всё равно срабатывают.913Чтобы получить полный stderr, а не только его первую строку, включите [отладочное логирование](#debug-hooks).
888 914
889Хук, который не удаётся запустить, попадает в ту же категорию неблокирующих ошибок. Если путь к скрипту не существует или файл не является исполняемым, оболочка завершается с кодом вроде 127, и вы видите то же уведомление с сообщением интерпретатора, например `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Для большинства событий хуков действие продолжается. Настраивая хук для политики, следите за этим уведомлением при его первом запуске: опечатка в пути в `settings.json` незаметно отключает проверку.915Хук, который не удаётся запустить, тоже считается неблокирующей ошибкой. В форме оболочки, если путь к скрипту не существует или файл не является исполняемым, оболочка завершается с кодом вроде 127, и уведомление содержит сообщение интерпретатора, например `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Настраивая хук для политики, следите за этим уведомлением при его первом запуске, потому что опечатка в пути в `settings.json` означает, что хук никогда не выполнится. Чтобы вместо этого блокировать действие, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
890 916
891<Warning>917<Warning>
892 Для большинства событий хуков код выхода 2 — единственный код выхода, который блокирует сам по себе. Без корректного JSON в stdout Claude Code обрабатывает код выхода 1 как неблокирующую ошибку и продолжает действие, хотя 1 — общепринятый код ошибки в Unix. Если ваш хук предназначен для соблюдения политики, используйте `exit 2`. События worktree отличаются: любой ненулевой код выхода из `WorktreeCreate` прерывает создание worktree, а любой ненулевой код выхода из `WorktreeRemove` приводит к ошибке удаления worktree, если каталог после этого всё ещё существует.918 Без корректного JSON в stdout Claude Code обрабатывает код выхода 1 как неблокирующую ошибку, хотя 1 — общепринятый код ошибки в Unix. Если ваш хук предназначен для соблюдения политики, используйте `exit 2`.
893</Warning>919</Warning>
894 920
895<h4 id="timeouts">921<h4 id="timeouts">
900 926
901Для [`PreModelSwitch`](#premodelswitch) хук, отменённый по таймауту, блокирует переключение модели. Для `PreToolUse` два семейства хуков ведут себя по-разному:927Для [`PreModelSwitch`](#premodelswitch) хук, отменённый по таймауту, блокирует переключение модели. Для `PreToolUse` два семейства хуков ведут себя по-разному:
902 928
903* Хук `command`, `http` или `mcp_tool`, превысивший таймаут, не блокирует вызов инструмента. Вызов продолжается через обычный [процесс разрешений](/docs/ru/permissions), поэтому не рассчитывайте, что зависший хук сработает как защитный барьер.929* Хук `command`, `http` или `mcp_tool`, превысивший таймаут, не блокирует вызов инструмента. Вызов продолжается через обычный [процесс разрешений](/docs/ru/permissions), поэтому не рассчитывайте, что зависший хук сработает как защитный барьер. Чтобы блокировать вызов при превышении таймаута хуком `command` или `http`, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
904* [Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks), превысивший свой таймаут, [блокирует вызов инструмента](#pretooluse).930* [Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks), превысивший свой таймаут, [блокирует вызов инструмента](#pretooluse).
905 931
932<h4 id="block-the-action-when-a-hook-fails">
933 Блокировка действия при сбое хука
934</h4>
935
936Для большинства событий, когда хук завершается сбоем или превышает таймаут, Claude Code всё равно выполняет действие, поэтому хук политики с неверным путём или падающим скриптом пропускает всё. Чтобы вместо этого блокировать действие, установите `"onFailure": "block"` для хука `command` или `http`. Значение по умолчанию — `"continue"`. Требуется Claude Code v2.1.295 или новее.
937
938Этот хук `PreToolUse` в `.claude/settings.json` запускает скрипт проекта перед каждой командой Bash и блокирует команду, если скрипт завершается сбоем:
939
940```json theme={null}
941{
942 "hooks": {
943 "PreToolUse": [
944 {
945 "matcher": "Bash",
946 "hooks": [
947 {
948 "type": "command",
949 "command": "node",
950 "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js"],
951 "onFailure": "block"
952 }
953 ]
954 }
955 ]
956 }
957}
958```
959
960Чтобы проверить его, не создавайте `check-command.js` и попросите Claude выполнить команду Bash, например `ls`. Claude Code блокирует вызов, и ошибка содержит `failed; blocking because onFailure is "block"`, за которым следует собственный вывод ошибки node, сокращённый здесь до одной строки:
961
962```text theme={null}
963PreToolUse:Bash hook error: [node ${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js]: failed; blocking because onFailure is "block"
964Error: Cannot find module '/path/to/project/.claude/hooks/check-command.js'
965```
966
967После таймаута сообщение содержит `timed out` вместо `failed`. Без заданного `onFailure` тот же отсутствующий скрипт является неблокирующей ошибкой, и `ls` выполняется.
968
969Каждый из следующих случаев считается сбоем:
970
971* **Не удаётся запустить**: командный хук не запускается, например потому что скрипт или исполняемый файл не существует
972* **Код выхода, отличный от 0 или 2**: учитывается для командного хука, даже если он вывел JSON, разрешающий действие, например `permissionDecision: "allow"`. Чтобы вернуть решение в JSON, завершитесь с кодом 0
973* **Ошибка HTTP**: соединение HTTP-хука не удаётся установить, или статус ответа не 2xx
974* **Таймаут**: хук достигает своего [`timeout`](#common-fields)
975* **Некорректный вывод**: вывод JSON [не удаётся разобрать](#exit-code-0) или он не проходит [проверку схемы](#json-output). Для HTTP-хука сбоем также считается тело ответа 2xx, которое не является ни пустым, ни объектом JSON. Обычный текст в stdout командного хука сбоем не считается
976
977При установленном `"block"` сбой действует так же, как [код выхода 2 для этого события](#exit-code-2-behavior-per-event), за исключением `PermissionRequest`, где он отклоняет запрос. Например, сбой `PreToolUse` блокирует вызов инструмента, а сбой `UserPromptSubmit` блокирует промпт.
978
979Поле не действует для следующих хуков:
980
981* **Хуки `Stop`, `SubagentStop`, `TaskCompleted` и `TeammateIdle`**: код выхода 2 для этих событий отправляет Claude продолжать работу, а Claude не может исправить хук, который не запускается
982* **Фоновые командные хуки**: командные хуки, в которых задано [`async` или `asyncRewake`](#run-hooks-in-the-background)
983
906<h4 id="exit-code-2-behavior-per-event">984<h4 id="exit-code-2-behavior-per-event">
907 Поведение кода выхода 2 для каждого события985 Поведение кода выхода 2 для каждого события
908</h4>986</h4>
960* **Сбой соединения**: неблокирующая ошибка, выполнение продолжается1038* **Сбой соединения**: неблокирующая ошибка, выполнение продолжается
961* **Таймаут**: хук отменяется, как описано в разделе [Таймауты](#timeouts)1039* **Таймаут**: хук отменяется, как описано в разделе [Таймауты](#timeouts)
962 1040
963В отличие от командных хуков, HTTP-хуки не могут сигнализировать о блокирующей ошибке только через коды состояния. Чтобы заблокировать вызов инструмента или отклонить разрешение, верните ответ 2xx с телом JSON, содержащим соответствующие поля решения.1041HTTP-хуки не могут сигнализировать о блокирующей ошибке только через код состояния: статус не 2xx или сбой соединения является [неблокирующей ошибкой](#exit-code-output). Чтобы заблокировать вызов инструмента или отклонить разрешение, верните ответ 2xx с телом JSON, содержащим соответствующие поля решения. Чтобы блокировать действие, когда запрос завершается сбоем или возвращает статус не 2xx, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
964 1042
965<h3 id="json-output">1043<h3 id="json-output">
966 Вывод JSON1044 Вывод JSON
1237 Управление решениями SessionStart1315 Управление решениями SessionStart
1238</h4>1316</h4>
1239 1317
1240Claude Code добавляет в контекст Claude stdout, который он [обрабатывает как обычный текст](#exit-code-0). Помимо [полей вывода JSON](#json-output), доступных всем хукам, вы можете возвращать следующие поля, специфичные для события:1318Хук SessionStart может добавлять контекст для Claude, задавать первое сообщение пользователя, устанавливать название сессии, отслеживать файлы и перезагружать скиллы. Для каждого из этих действий верните соответствующее поле в дополнение к [полям вывода JSON](#json-output), доступным всем хукам:
1241 1319
1242| Поле | Описание |1320| Поле | Описание |
1243| :- | :- |1321| :- | :- |
1244| `additionalContext` | Строка, добавляемая в контекст Claude в начале диалога, до первого промпта. О том, как доставляется текст и что в него помещать, см. [Добавление контекста для Claude](#add-context-for-claude) |1322| `additionalContext` | Строка, добавляемая в контекст Claude в начале диалога, до первого промпта. О том, как доставляется текст и что в него помещать, см. [Добавление контекста для Claude](#add-context-for-claude) |
1245| `initialUserMessage` | Строка, используемая как первое пользовательское сообщение сессии. Применяется в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`, где она становится первым ходом, даже если промпт не передан. Если промпт передан, он следует за ней как следующий ход. В отличие от `additionalContext`, который прикрепляется к существующему ходу, это поле создаёт ход |1323| `initialUserMessage` | Строка, используемая как первое сообщение пользователя в сессии в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. Она становится первым ходом, даже если вы не передаёте промпт. Переданный вами промпт следует за ней как следующий ход |
1246| `sessionTitle` | Задаёт название сессии, с тем же эффектом, что и `/rename`. Используйте, чтобы автоматически именовать сессии по папке запуска, ветке git или имени worktree. Применяется, когда `source` равен `"startup"`, `"resume"` или `"fork"`; игнорируется для `"clear"` и `"compact"` |1324| `sessionTitle` | Устанавливает название сессии с тем же эффектом, что и `/rename`. Применяется, когда `source` равно `"startup"`, `"resume"` или `"fork"` |
1247| `watchPaths` | Массив абсолютных путей для отслеживания событий [FileChanged](#filechanged) во время этой сессии |1325| `watchPaths` | Массив абсолютных путей для отслеживания событий [FileChanged](#filechanged) во время этой сессии |
1248| `reloadSkills` | Логическое значение. При `true` Claude Code повторно сканирует каталоги [скиллов](/docs/ru/skills) и команд после завершения хуков SessionStart, чтобы скиллы, установленные хуком, были доступны в той же сессии, начиная с первого промпта |1326| `reloadSkills` | Логическое значение. Если `true`, Claude Code повторно сканирует каталоги [скиллов](/docs/ru/skills) и команд после завершения хуков SessionStart. См. [Перезагрузка скиллов, устанавливаемых хуком](#reload-skills-that-a-hook-installs) |
1327
1328Этот вывод добавляет контекст и даёт сессии название:
1249 1329
1250```json theme={null}1330```json theme={null}
1251{1331{
1257}1337}
1258```1338```
1259 1339
1260Поскольку для этого события обычный stdout и так доходит до Claude, хук, который только загружает контекст, может выводить его прямо в stdout, не формируя JSON. Используйте форму JSON, когда нужно совместить контекст с другими полями, например `sessionTitle`.1340Хук, который только добавляет контекст, может просто вывести его без формирования JSON, поскольку Claude Code добавляет [обычный текстовый stdout](#exit-code-0) хука SessionStart в контекст Claude.
1341
1342Если хук SessionStart вашего плагина предоставляет `initialUserMessage` или `sessionTitle`, установите плагин до начала сессии. Claude Code игнорирует оба поля от плагина, установка которого завершается после того, как хуки SessionStart уже отработали.
1343
1344<h4 id="reload-skills-that-a-hook-installs">
1345 Перезагрузка скиллов, устанавливаемых хуком
1346</h4>
1347
1348Чтобы скиллы, устанавливаемые хуком SessionStart, стали доступны в той же сессии, верните `reloadSkills`. Обнаружение скиллов обычно выполняется до завершения хуков SessionStart, поэтому без этого поля файлы, которые хук записывает в `~/.claude/skills/` или `.claude/skills/`, могут отсутствовать при выполнении первого промпта.
1261 1349
1262Используйте `reloadSkills`, когда хук SessionStart устанавливает или обновляет скиллы. Обнаружение скиллов обычно выполняется до завершения хуков SessionStart, поэтому файлы, которые хук записывает в `~/.claude/skills/` или `.claude/skills/`, иначе появились бы только в следующей сессии. Этот пример синхронизирует общий репозиторий скиллов и запрашивает повторное сканирование:1350В этом примере синхронизируется общий репозиторий скиллов и запрашивается повторное сканирование:
1263 1351
1264```bash theme={null}1352```bash theme={null}
1265#!/bin/bash1353#!/bin/bash
1270echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1358echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1271```1359```
1272 1360
1273URL репозитория здесь — заглушка; замените его на собственный репозиторий скиллов. С заглушкой клонирование завершается ошибкой и выводит сообщение `fatal:` в stderr. Stderr хука SessionStart, завершившегося с кодом 0, носит лишь информационный характер, поэтому запрос `reloadSkills` всё равно применяется.1361URL репозитория — это заглушка. Замените его адресом вашего собственного репозитория скиллов.
1274 1362
1275<h4 id="persist-environment-variables">1363<h4 id="persist-environment-variables">
1276 Сохранение переменных окружения1364 Сохранение переменных окружения
1419 1507
1420Хуки `UserPromptSubmit` имеют таймаут по умолчанию 30 секунд для типов `command`, `http` и `mcp_tool` — меньше, чем стандартные 600 секунд для этих типов в большинстве других событий. Поскольку этот хук выполняется перед каждым промптом и блокирует обработку моделью до своего завершения, зависший хук останавливает сессию. Если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.1508Хуки `UserPromptSubmit` имеют таймаут по умолчанию 30 секунд для типов `command`, `http` и `mcp_tool` — меньше, чем стандартные 600 секунд для этих типов в большинстве других событий. Поскольку этот хук выполняется перед каждым промптом и блокирует обработку моделью до своего завершения, зависший хук останавливает сессию. Если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.
1421 1509
1422За исключением командного хука, который вы запускаете с [`async: true`](#run-hooks-in-the-background), хук `UserPromptSubmit` типа command, HTTP или MCP tool, достигший таймаута, отменяется, а его вывод, включая `additionalContext`, отбрасывается. Промпт всё равно доходит до Claude, но без этого контекста. В транскрипте отображается уведомление с именем хука, сработавшим таймаутом и сообщением о том, что вывод был отброшен.1510За исключением command-хука, запущенного с [`async: true`](#run-hooks-in-the-background), command-, HTTP- или MCP tool-хук `UserPromptSubmit`, достигший таймаута, отменяется, а его вывод, включая любой `additionalContext`, отбрасывается. Промпт всё равно доходит до Claude, но без этого контекста. Чтобы вместо этого заблокировать промпт, задайте [`onFailure: "block"`](#block-the-action-when-a-hook-fails) для command- или HTTP-хука. В транскрипте отображается уведомление с именем хука, сработавшим таймаутом и сообщением о том, что вывод был отброшен.
1423 1511
1424[Хук обратного вызова Agent SDK](/docs/ru/agent-sdk/hooks) для `UserPromptSubmit`, достигший таймаута, блокирует промпт с сообщением, в котором названы хук и таймаут, поскольку обратный вызов в этом месте может выступать в роли шлюза политики, который не должен при сбое пропускать всё подряд. Сессия продолжается. До версии v2.1.208 таймаут обратного вызова для этого события завершал ход с ошибкой выполнения.1512[Хук обратного вызова Agent SDK](/docs/ru/agent-sdk/hooks) для `UserPromptSubmit`, достигший таймаута, блокирует промпт с сообщением, в котором названы хук и таймаут, поскольку обратный вызов в этом месте может выступать в роли шлюза политики, который не должен при сбое пропускать всё подряд. Сессия продолжается. До версии v2.1.208 таймаут обратного вызова для этого события завершал ход с ошибкой выполнения.
1425 1513
1860| :- | :- | :- | :- |1948| :- | :- | :- | :- |
1861| `url` | string | `"https://example.com/api"` | URL, с которого загружается содержимое |1949| `url` | string | `"https://example.com/api"` | URL, с которого загружается содержимое |
1862| `prompt` | string | `"Extract the API endpoints"` | Промпт, применяемый к загруженному содержимому |1950| `prompt` | string | `"Extract the API endpoints"` | Промпт, применяемый к загруженному содержимому |
1951| `offset` | number | `100000` | Необязательное количество символов, пропускаемых от начала страницы. Claude задаёт его, чтобы продолжить чтение длинной страницы. Требуется Claude Code v2.1.290 или новее |
1863 1952
1864<h5 id="websearch">1953<h5 id="websearch">
1865 WebSearch1954 WebSearch
2112| `message` | Только для `"deny"`: сообщает Claude, почему в разрешении отказано |2201| `message` | Только для `"deny"`: сообщает Claude, почему в разрешении отказано |
2113| `interrupt` | Только для `"deny"`: если `true`, останавливает Claude |2202| `interrupt` | Только для `"deny"`: если `true`, останавливает Claude |
2114 2203
2115Хук, который завершается с кодом 2 без объекта `decision`, оставляет процесс проверки разрешений без изменений, а его stderr отбрасывается. Предоставить или отклонить запрос может только объект `decision`.2204Хук, завершающийся с кодом 2 без объекта `decision`, оставляет процесс разрешений без изменений, а его stderr отбрасывается. Чтобы предоставить или отклонить запрос, верните объект `decision`.
2116 2205
2117```json theme={null}2206```json theme={null}
2118{2207{
2678 Управление решениями TaskCreated2767 Управление решениями TaskCreated
2679</h4>2768</h4>
2680 2769
2681Хук TaskCreated может заблокировать создание двумя способами. В любом случае Claude Code удаляет задачу и возвращает ваше сообщение Claude в качестве ошибки инструмента. Claude Code игнорирует `continue: false` от этого события, и Claude продолжает работу.2770Хук TaskCreated может заблокировать создание с помощью кода выхода 2 или решения в JSON. В обоих случаях Claude Code удаляет задачу и возвращает ваше сообщение Claude как ошибку инструмента. Claude Code игнорирует `continue: false` от этого события, и Claude продолжает работу.
2682 2771
2683* **Код выхода 2**: Claude Code возвращает текст из stderr в качестве сообщения.2772* **Код выхода 2**: Claude Code возвращает текст из stderr в качестве сообщения.
2684* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code возвращает `reason` в качестве сообщения.2773* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code возвращает `reason` в качестве сообщения.
3561 3650
3562Claude Code показывает пользователю любое `systemMessage`, возвращённое вашим хуком, независимо от решения, поэтому хук, сообщающий о стоимости, может вернуть `{"systemMessage": "..."}` и завершиться с кодом 0.3651Claude Code показывает пользователю любое `systemMessage`, возвращённое вашим хуком, независимо от решения, поэтому хук, сообщающий о стоимости, может вернуть `{"systemMessage": "..."}` и завершиться с кодом 0.
3563 3652
3564Хук PreModelSwitch, который не ответил до истечения таймаута, блокирует смену. Для [PreToolUse](#timeouts), напротив, командный хук с истёкшим таймаутом позволяет вызову инструмента продолжиться. Таймаут по умолчанию для этого события — 30 секунд. `PreModelSwitch` запускает только хуки `command`, `http` и `mcp_tool`, поэтому значения по умолчанию для `prompt` и `agent` не применяются.3653Хук PreModelSwitch, который не ответил до истечения таймаута, блокирует переключение. О том, что делает таймаут для других событий, см. [Таймауты](#timeouts). Таймаут по умолчанию для этого события — 30 секунд. `PreModelSwitch` запускает только хуки `command`, `http` и `mcp_tool`, поэтому значения по умолчанию для `prompt` и `agent` не применяются.
3565 3654
3566Хук, который завершается с кодом, отличным от 0 или 2, и не выводит JSON-решение, не блокирует смену: Claude Code показывает его stderr и применяет смену, как описано в разделе [Другие коды выхода](#other-exit-codes).3655Хук, который завершается с кодом, отличным от 0 или 2, и не выводит JSON-решение, считается неблокирующей ошибкой, как описано в разделе [Другие коды выхода](#other-exit-codes).
3567 3656
3568<h3 id="postmodelswitch">3657<h3 id="postmodelswitch">
3569 PostModelSwitch3658 PostModelSwitch
4279Асинхронные hooks имеют дополнительные ограничения по сравнению с синхронными hooks:4368Асинхронные hooks имеют дополнительные ограничения по сравнению с синхронными hooks:
4280 4369
4281* Выход hook доставляется на следующий ход разговора. Если сеанс неактивен, ответ ждёт до следующего взаимодействия пользователя. Исключение: hook `asyncRewake`, который выходит с кодом 2, пробуждает Claude немедленно даже когда сеанс неактивен.4370* Выход hook доставляется на следующий ход разговора. Если сеанс неактивен, ответ ждёт до следующего взаимодействия пользователя. Исключение: hook `asyncRewake`, который выходит с кодом 2, пробуждает Claude немедленно даже когда сеанс неактивен.
4282* Каждое выполнение создаёт отдельный фоновый процесс. Нет дедупликации между несколькими срабатываниями одного и того же асинхронного hook.4371* Каждое выполнение создаёт отдельный фоновый процесс.
4283 4372
4284<h2 id="security-considerations">4373<h2 id="security-considerations">
4285 Соображения безопасности4374 Соображения безопасности