827 827
828Код выхода вашего хука сообщает Claude Code, следует ли продолжить действие, вызвавшее хук, например вызов инструмента или промпт. Завершившийся запуск имеет один из трёх результатов:828Код выхода вашего хука сообщает Claude Code, следует ли продолжить действие, вызвавшее хук, например вызов инструмента или промпт. Завершившийся запуск имеет один из трёх результатов:
829 829
830* **Успех**: ваш хук завершается с кодом 0. Claude Code применяет все поля [вывода JSON](#json-output), которые вывел ваш хук, и действие выполняется, если эти поля не блокируют и не отклоняют его.830* **Успех**: ваш хук завершается с кодом 0. Claude Code применяет все поля [вывода JSON](#json-output), которые вывел ваш хук, и действие выполняется, если эти поля не блокируют и не отклоняют его. Исключение описано в разделе [Хуки, запускающие фоновый процесс](#hooks-that-start-a-background-process).
831* **Блокирующая ошибка**: ваш хук завершается с кодом 2. Для [событий, которые могут блокировать](#exit-code-2-behavior-per-event), Claude Code останавливает действие.831* **Блокирующая ошибка**: ваш хук завершается с кодом 2. Для [событий, которые могут блокировать](#exit-code-2-behavior-per-event), Claude Code останавливает действие.
832* **Неблокирующая ошибка**: ваш хук завершается с любым другим кодом или завершается сбоем иным образом, например не запускается или выводит некорректный JSON. Действие выполняется, а для таких событий, как `PreToolUse`, в транскрипте отображается уведомление `<hook name> hook error`. Если вы хотите, чтобы хук, завершившийся сбоем, блокировал действие, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).832* **Неблокирующая ошибка**: ваш хук завершается с любым другим кодом или завершается сбоем иным образом, например не запускается или выводит некорректный JSON. Действие выполняется, а для таких событий, как `PreToolUse`, в транскрипте отображается уведомление `<hook name> hook error`. Если вы хотите, чтобы хук, завершившийся сбоем, блокировал действие, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
833 833
932* Хук `command`, `http` или `mcp_tool`, превысивший таймаут, не блокирует вызов инструмента. Вызов продолжается через обычный [процесс разрешений](/docs/ru/permissions), поэтому не рассчитывайте, что зависший хук сработает как защитный барьер. Чтобы блокировать вызов при превышении таймаута хуком `command` или `http`, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).932* Хук `command`, `http` или `mcp_tool`, превысивший таймаут, не блокирует вызов инструмента. Вызов продолжается через обычный [процесс разрешений](/docs/ru/permissions), поэтому не рассчитывайте, что зависший хук сработает как защитный барьер. Чтобы блокировать вызов при превышении таймаута хуком `command` или `http`, установите [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
933* [Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks), превысивший свой таймаут, [блокирует вызов инструмента](#pretooluse).933* [Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks), превысивший свой таймаут, [блокирует вызов инструмента](#pretooluse).
934 934
935<h4 id="hooks-that-start-a-background-process">
936 Хуки, запускающие фоновый процесс
937</h4>
938
939Если ваш командный хук принимает решение в фоновом процессе и завершается, то отказ, который этот процесс выводит после того, как Claude Code перестал читать вывод, не блокирует вызов инструмента. Для хука, который не является [асинхронным](#run-hooks-in-the-background), Claude Code заканчивает чтение вывода хука вскоре после завершения собственного процесса хука.
940
941Выводите решение до запуска фонового процесса и перенаправляйте stdout и stderr этого процесса. Если ваш скрипт выводит разрешение, а затем запускает фоновый процесс, не перенаправив его stdout и stderr, Claude Code блокирует вызов инструмента. Ошибка хука содержит `refusing to honor the suspect capture`.
942
943Этот скрипт хука `PreToolUse` выводит решение с помощью `policy-check.sh`, а затем загружает метрики в фоновом режиме:
944
945```bash theme={null}
946#!/bin/bash
947"$CLAUDE_PROJECT_DIR"/.claude/hooks/policy-check.sh || exit $?
948"$CLAUDE_PROJECT_DIR"/.claude/hooks/upload-metrics.sh >/dev/null 2>&1 &
949```
950
951Остальная часть скрипта делает следующее:
952
953* **`|| exit $?`**: делает код выхода проверки собственным кодом выхода хука, поэтому проверка, завершающаяся с кодом 2 для отказа, по-прежнему блокирует. Иначе хук завершается с кодом последней строки, то есть 0.
954* **`>/dev/null 2>&1 &`**: запускает `upload-metrics.sh` в фоновом режиме с перенаправленным выводом, чтобы он не удерживал вывод хука открытым.
955
956Чтобы проверить скрипт, сделайте так, чтобы `policy-check.sh` завершался с кодом 2, а затем вызовите инструмент, которому соответствует хук. Вызов инструмента будет заблокирован.
957
935<h4 id="block-the-action-when-a-hook-fails">958<h4 id="block-the-action-when-a-hook-fails">
936 Блокировка действия при сбое хука959 Блокировка действия при сбое хука
937</h4>960</h4>
1245 События хуков1268 События хуков
1246</h2>1269</h2>
1247 1270
1248Каждое событие соответствует точке жизненного цикла Claude Code, в которой могут выполняться хуки. Разделы ниже упорядочены в соответствии с жизненным циклом: от настройки сессии через агентный цикл до завершения сессии. В каждом разделе описано, когда срабатывает событие, какие значения matcher оно поддерживает, какие входные данные JSON получает и как управлять поведением через вывод.1271Каждое событие соответствует точке в жизненном цикле Claude Code, в которой могут выполняться хуки. Разделы ниже упорядочены в соответствии с жизненным циклом: от настройки сессии через агентный цикл до завершения сессии. В каждом разделе описано, когда срабатывает событие, какие значения matcher оно поддерживает, какие входные данные JSON получает и как управлять поведением через вывод.
1249 1272
1250<h3 id="sessionstart">1273<h3 id="sessionstart">
1251 SessionStart1274 SessionStart
1252</h3>1275</h3>
1253 1276
1254Выполняется, когда Claude Code начинает новую сессию или возобновляет существующую. Полезно для загрузки контекста разработки, например существующих задач или недавних изменений в вашей кодовой базе, или для настройки переменных окружения. Для статического контекста, которому не требуется скрипт, используйте вместо этого [CLAUDE.md](/docs/ru/memory).1277Выполняется, когда Claude Code начинает новую сессию или возобновляет существующую. Полезно для загрузки контекста разработки, например существующих issues или недавних изменений в вашей кодовой базе, или для настройки переменных окружения. Для статического контекста, который не требует скрипта, используйте вместо этого [CLAUDE.md](/docs/ru/memory).
1255 1278
1256SessionStart выполняется в каждой сессии, поэтому такие хуки должны работать быстро. Поддерживаются только хуки `type: "command"` и `type: "mcp_tool"`. О том, когда выполняются хуки `mcp_tool`, см. [Поля хуков инструментов MCP](#mcp-tool-hook-fields).1279SessionStart выполняется в каждой сессии, поэтому такие хуки должны работать быстро. Поддерживаются только хуки `type: "command"` и `type: "mcp_tool"`. О том, когда выполняются хуки `mcp_tool`, см. [Поля хука MCP-инструмента](#mcp-tool-hook-fields).
1257 1280
1258Значение matcher соответствует тому, как была запущена сессия:1281Значение matcher соответствует тому, как была запущена сессия:
1259 1282
1265| `compact` | Автоматическое или ручное сжатие контекста |1288| `compact` | Автоматическое или ручное сжатие контекста |
1266| `fork` | Новая сессия, ответвлённая от существующей: `--fork-session` вместе с `--resume` или `--continue`, фоновая копия `/fork`, `/branch` или диалог, который вы [переводите в фон](/docs/ru/agent-view#from-inside-a-session) |1289| `fork` | Новая сессия, ответвлённая от существующей: `--fork-session` вместе с `--resume` или `--continue`, фоновая копия `/fork`, `/branch` или диалог, который вы [переводите в фон](/docs/ru/agent-view#from-inside-a-session) |
1267 1290
1268До версии v2.1.214 ответвлённые сессии сообщали источник `"resume"`.1291До v2.1.214 ответвлённые сессии сообщали источник `"resume"`.
1269 1292
1270Когда вы запускаете интерактивную сессию, возобновляете диалог при запуске с помощью `--continue` или `--resume` или выполняете `/clear`, хуки SessionStart выполняются в фоне. Вы можете сразу начать печатать, а возобновлённый диалог появляется, не дожидаясь хуков. Первый ответ Claude всё равно ждёт завершения хуков, чтобы их контекст дошёл до Claude.1293Когда вы начинаете интерактивную сессию, возобновляете диалог при запуске с `--continue` или `--resume` или выполняете `/clear`, хуки SessionStart выполняются в фоне. Вы можете сразу начать вводить текст, а возобновлённый диалог появляется, не дожидаясь хуков. Первый ответ Claude всё равно ждёт завершения хуков, чтобы их контекст дошёл до Claude.
1271 1294
1272Когда вы переключаетесь между диалогами с помощью `/resume` внутри сессии, переключение, наоборот, ждёт завершения хуков. Если вы выполните `/clear` или переключитесь на другой диалог, пока фоновые хуки ещё выполняются, ничего из того, что они вернут, не применяется к сессии.1295Когда вы переключаете диалоги с помощью `/resume` внутри сессии, переключение, напротив, ждёт завершения хуков. Если вы выполните `/clear` или переключитесь на другой диалог, пока фоновые хуки ещё выполняются, ничто из того, что они вернут, не применится к сессии.
1273 1296
1274То же ожидание действует и при запуске, включая возобновлённую сессию: промпт, отправленный, пока хуки SessionStart ещё выполняются, не дойдёт до Claude, пока они не завершатся.1297То же ожидание действует и при запуске, включая возобновлённую сессию: промпт, который вы отправляете, пока хуки SessionStart ещё выполняются, не дойдёт до Claude, пока они не завершатся.
1275 1298
1276Во время любого из этих ожиданий нажмите `Esc`, чтобы вернуть промпт в поле ввода, не отправляя его. Хуки продолжают выполняться.1299Во время любого из этих ожиданий нажмите `Esc`, чтобы вернуть промпт в поле ввода, не отправляя его. Хуки продолжат выполняться.
1277 1300
1278<h4 id="sessionstart-input">1301<h4 id="sessionstart-input">
1279 Входные данные SessionStart1302 Входные данные SessionStart
1284| Поле | Описание |1307| Поле | Описание |
1285| :- | :- |1308| :- | :- |
1286| `source` | Как началась сессия: `"startup"` для новых сессий, `"resume"` для возобновлённых сессий, `"clear"` после `/clear`, `"compact"` после сжатия контекста или `"fork"` для новой сессии, ответвлённой от существующей |1309| `source` | Как началась сессия: `"startup"` для новых сессий, `"resume"` для возобновлённых сессий, `"clear"` после `/clear`, `"compact"` после сжатия контекста или `"fork"` для новой сессии, ответвлённой от существующей |
1287| `model` | Идентификатор активной модели. Может отсутствовать, например после `/clear` или когда сессия восстановлена через восстановление диалога, поэтому проверяйте наличие поля перед его чтением |1310| `model` | Идентификатор активной модели. Может отсутствовать, например после `/clear` или когда сессия восстанавливается через восстановление диалога, поэтому проверяйте наличие поля перед чтением |
1288| `agent_type` | Имя агента; присутствует, когда вы запускаете Claude Code с `claude --agent <name>` |1311| `agent_type` | Имя агента; присутствует, когда вы запускаете Claude Code с `claude --agent <name>` |
1289| `session_title` | Пользовательское название сессии; присутствует, если оно задано, например через `--name`, `/rename`, вывод `sessionTitle` хука или `renameSession()` в Agent SDK. Хук, который выдаёт `sessionTitle`, может сначала проверить это поле, чтобы не перезаписать существующее пользовательское название |1312| `session_title` | Пользовательское название сессии; присутствует, когда оно задано, например с помощью `--name`, `/rename`, вывода `sessionTitle` хука или `renameSession()` в Agent SDK. Хук, который выводит `sessionTitle`, может сначала проверить это поле, чтобы не перезаписать существующее пользовательское название |
1290 1313
1291У сессии, которой вы не дали имя, всё равно может быть [сгенерированное название](/docs/ru/sessions#name-your-sessions). Такое название не является пользовательским и не появляется в `session_title`.1314Сессия, которой вы не дали имя, всё равно может иметь [сгенерированное название](/docs/ru/sessions#name-your-sessions). Такое название не является пользовательским и не появляется в `session_title`.
1292 1315
1293Когда `source` равен `"resume"` или `"fork"` и транскрипт содержит хотя бы один ответ Claude, хуки SessionStart также получают четыре поля, перечисленные ниже. Ваш хук может использовать их, чтобы до первого запроса сообщить, во что обойдётся возобновление устаревшего диалога, например в [`systemMessage`](#json-output). Для этих полей требуется Claude Code v2.1.251 или новее.1316Когда `source` равен `"resume"` или `"fork"` и транскрипт содержит хотя бы один ответ Claude, хуки SessionStart также получают четыре поля ниже. Ваш хук может использовать их, чтобы до первого запроса сообщить, во что обойдётся возобновление устаревшего диалога, например в [`systemMessage`](#json-output). Для этих полей требуется Claude Code v2.1.251 или новее.
1294 1317
1295| Поле | Описание |1318| Поле | Описание |
1296| :- | :- |1319| :- | :- |
1297| `seconds_since_last_response` | Реальное время в секундах с момента последнего ответа в возобновлённом транскрипте |1320| `seconds_since_last_response` | Реальное время в секундах с момента последнего ответа в возобновлённом транскрипте |
1298| `context_tokens` | Токены, которые первый запрос возобновлённой сессии повторно отправляет в качестве промпта |1321| `context_tokens` | Токены, которые первый запрос возобновлённой сессии повторно отправляет в качестве промпта |
1299| `prompt_cache_likely_expired` | `true`, когда последний ответ старше [срока жизни кэша промптов](/docs/ru/prompt-caching#cache-lifetime) сессии или когда последующее сжатие контекста заменило кэшированный диалог |1322| `prompt_cache_likely_expired` | `true`, когда последний ответ старше [времени жизни кэша промптов](/docs/ru/prompt-caching#cache-lifetime) сессии или когда последующее сжатие контекста заменило кэшированный диалог |
1300| `estimated_cache_write_usd` | Оценочная стоимость в долларах США записи `context_tokens` в кэш промптов на модели сессии, без учёта ответа |1323| `estimated_cache_write_usd` | Оценочная стоимость в долларах США записи `context_tokens` в кэш промптов на модели сессии, без учёта ответа |
1301 1324
1302В этом примере показаны входные данные для сессии, возобновлённой через 90 минут после её последнего ответа:1325В этом примере показаны входные данные для сессии, возобновлённой через 90 минут после её последнего ответа:
1320 Управление решениями SessionStart1343 Управление решениями SessionStart
1321</h4>1344</h4>
1322 1345
1323Хук SessionStart может добавлять контекст для Claude, задавать первое сообщение пользователя, устанавливать название сессии, отслеживать файлы и перезагружать скиллы. Для каждого из этих действий верните соответствующее поле в дополнение к [полям вывода JSON](#json-output), доступным всем хукам:1346Хук SessionStart может добавить контекст для Claude, задать первое сообщение пользователя, задать название сессии, отслеживать файлы и перезагружать скиллы. Для каждого из этих действий верните соответствующее поле в дополнение к [полям вывода JSON](#json-output), доступным всем хукам:
1324 1347
1325| Поле | Описание |1348| Поле | Описание |
1326| :- | :- |1349| :- | :- |
1327| `additionalContext` | Строка, добавляемая в контекст Claude в начале диалога, до первого промпта. О том, как доставляется текст и что в него помещать, см. [Добавление контекста для Claude](#add-context-for-claude) |1350| `additionalContext` | Строка, добавляемая в контекст Claude в начале диалога, перед первым промптом. О том, как доставляется текст и что в него включать, см. [Добавление контекста для Claude](#add-context-for-claude) |
1328| `initialUserMessage` | Строка, используемая как первое сообщение пользователя в сессии в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. Она становится первым ходом, даже если вы не передаёте промпт. Переданный вами промпт следует за ней как следующий ход |1351| `initialUserMessage` | Строка, используемая как первое сообщение пользователя в сессии в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. Она становится первым ходом, даже если вы не передаёте промпт. Переданный вами промпт следует следующим ходом |
1329| `sessionTitle` | Устанавливает название сессии с тем же эффектом, что и `/rename`. Применяется, когда `source` равно `"startup"`, `"resume"` или `"fork"` |1352| `sessionTitle` | Задаёт название сессии с тем же эффектом, что и `/rename`. Применяется, когда `source` равен `"startup"`, `"resume"` или `"fork"` |
1330| `watchPaths` | Массив абсолютных путей для отслеживания событий [FileChanged](#filechanged) во время этой сессии |1353| `watchPaths` | Массив абсолютных путей для отслеживания событий [FileChanged](#filechanged) в этой сессии |
1331| `reloadSkills` | Логическое значение. Если `true`, Claude Code повторно сканирует каталоги [скиллов](/docs/ru/skills) и команд после завершения хуков SessionStart. См. [Перезагрузка скиллов, устанавливаемых хуком](#reload-skills-that-a-hook-installs) |1354| `reloadSkills` | Логическое значение. Если `true`, Claude Code повторно сканирует каталоги [скиллов](/docs/ru/skills) и команд после завершения хуков SessionStart. См. [Перезагрузка скиллов, которые устанавливает хук](#reload-skills-that-a-hook-installs) |
1332 1355
1333Этот вывод добавляет контекст и даёт сессии название:1356Этот вывод добавляет контекст и даёт сессии имя:
1334 1357
1335```json theme={null}1358```json theme={null}
1336{1359{
1342}1365}
1343```1366```
1344 1367
1345Хук, который только добавляет контекст, может просто вывести его без формирования JSON, поскольку Claude Code добавляет [обычный текстовый stdout](#exit-code-0) хука SessionStart в контекст Claude.1368Хук, который только добавляет контекст, может просто напечатать его, не формируя JSON, поскольку Claude Code добавляет [обычный текстовый stdout](#exit-code-0) хука SessionStart в контекст Claude.
1346 1369
1347Если хук SessionStart вашего плагина предоставляет `initialUserMessage` или `sessionTitle`, установите плагин до начала сессии. Claude Code игнорирует оба поля от плагина, установка которого завершается после того, как хуки SessionStart уже отработали.1370Если хук SessionStart вашего плагина задаёт `initialUserMessage` или `sessionTitle`, установите плагин до начала сессии. Claude Code игнорирует оба поля от плагина, установка которого завершается после того, как хуки SessionStart уже выполнились.
1348 1371
1349<h4 id="reload-skills-that-a-hook-installs">1372<h4 id="reload-skills-that-a-hook-installs">
1350 Перезагрузка скиллов, устанавливаемых хуком1373 Перезагрузка скиллов, которые устанавливает хук
1351</h4>1374</h4>
1352 1375
1353Чтобы скиллы, устанавливаемые хуком SessionStart, стали доступны в той же сессии, верните `reloadSkills`. Обнаружение скиллов обычно выполняется до завершения хуков SessionStart, поэтому без этого поля файлы, которые хук записывает в `~/.claude/skills/` или `.claude/skills/`, могут отсутствовать при выполнении первого промпта.1376Чтобы скиллы, которые устанавливает хук SessionStart, стали доступны в той же сессии, верните `reloadSkills`. Обнаружение скиллов обычно выполняется до завершения хуков SessionStart, поэтому без этого поля файлы, которые хук записывает в `~/.claude/skills/` или `.claude/skills/`, могут отсутствовать при выполнении первого промпта.
1354 1377
1355В этом примере синхронизируется общий репозиторий скиллов и запрашивается повторное сканирование:1378Этот пример синхронизирует общий репозиторий скиллов и запрашивает повторное сканирование:
1356 1379
1357```bash theme={null}1380```bash theme={null}
1358#!/bin/bash1381#!/bin/bash
1363echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1386echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1364```1387```
1365 1388
1366URL репозитория — это заглушка. Замените его адресом вашего собственного репозитория скиллов.1389URL репозитория — это заглушка. Замените его на свой репозиторий скиллов.
1367 1390
1368<h4 id="persist-environment-variables">1391<h4 id="persist-environment-variables">
1369 Сохранение переменных окружения1392 Сохранение переменных окружения
1370</h4>1393</h4>
1371 1394
1372Хуки SessionStart имеют доступ к переменной окружения `CLAUDE_ENV_FILE`, которая предоставляет путь к файлу, где можно сохранить переменные окружения для shell-команд, которые Claude выполняет позже в сессии.1395Хуки SessionStart имеют доступ к переменной окружения `CLAUDE_ENV_FILE`, которая указывает путь к файлу, где можно сохранить переменные окружения для shell-команд, которые Claude выполняет позже в сессии.
1373 1396
1374Чтобы задать отдельные переменные окружения, запишите инструкции `export` в `CLAUDE_ENV_FILE`. Используйте добавление (`>>`), чтобы сохранить переменные, заданные другими хуками:1397Чтобы задать отдельные переменные окружения, запишите операторы `export` в `CLAUDE_ENV_FILE`. Используйте дозапись (`>>`), чтобы сохранить переменные, заданные другими хуками:
1375 1398
1376```bash theme={null}1399```bash theme={null}
1377#!/bin/bash1400#!/bin/bash
1385exit 01408exit 0
1386```1409```
1387 1410
1388Чтобы зафиксировать все изменения окружения, внесённые командами настройки, сравните экспортированные переменные до и после:1411Чтобы зафиксировать все изменения окружения от команд настройки, сравните экспортированные переменные до и после:
1389 1412
1390```bash theme={null}1413```bash theme={null}
1391#!/bin/bash1414#!/bin/bash
1412 Сохранённые переменные в командах PowerShell1435 Сохранённые переменные в командах PowerShell
1413</h5>1436</h5>
1414 1437
1415Команды [PowerShell](/docs/ru/tools-reference#powershell-tool) тоже получают переменные из `CLAUDE_ENV_FILE` в Claude Code v2.1.296 или новее, но PowerShell никогда не выполняет этот файл. Вместо этого Claude Code считывает из него присваивания и копирует их в окружение команды PowerShell. Это происходит, только если каждая строка относится к одному из следующих видов — во всём, что записали все хуки в этой сессии, и в любом скрипте, на который вы [указали `CLAUDE_ENV_FILE`](/docs/ru/env-vars) перед запуском:1438Команды [PowerShell](/docs/ru/tools-reference#powershell-tool) тоже получают переменные из `CLAUDE_ENV_FILE` в Claude Code v2.1.296 или новее, но PowerShell никогда не выполняет этот файл. Вместо этого Claude Code считывает из него присваивания и копирует их в окружение команды PowerShell. Это происходит, только если каждая строка относится к одному из следующих видов — во всём, что записали все хуки в этой сессии, и в любом скрипте, на который вы [установили `CLAUDE_ENV_FILE`](/docs/ru/env-vars) до запуска:
1416 1439
1417* Пустая строка или комментарий `#`1440* Пустая строка или комментарий `#`
1418* Одно присваивание в начале строки в форме `export NAME=value`, `declare -x NAME=value` или `NAME=value` со значением, которое Bash использовал бы ровно в том виде, как оно написано, состоящим из любого сочетания следующих частей: текст без кавычек, содержащий только буквы, цифры и символы `_ @ % + = : , . / -`, текст в одинарных кавычках и текст в двойных кавычках, где любые `$`, обратная кавычка или `"` внутри экранированы обратной косой чертой1441* Одно присваивание в начале строки, записанное как `export NAME=value`, `declare -x NAME=value` или `NAME=value`, со значением, которое Bash использовал бы в точности как написано, составленным из любого сочетания следующих частей: текст без кавычек, использующий только буквы, цифры и символы `_ @ % + = : , . / -`, текст в одинарных кавычках и текст в двойных кавычках, где любые `$`, обратная кавычка или `"` внутри экранированы обратной косой чертой
1419 1442
1420Если какая-либо строка другого вида, например `export PATH="$PATH:./node_modules/.bin"` с неэкранированным `$PATH`, команда `source` или строки `$'...'`, которые выводит `direnv export bash`, команды PowerShell не получают ни одной переменной, а `claude --debug` записывает в лог `Session environment is not all plain assignments`. Команды Bash по-прежнему получают их все. В Windows команды PowerShell также не получают переменную, значение которой содержит `/` или `\`, потому что Git Bash и Windows записывают пути по-разному. Команда PowerShell, [изолированная в песочнице](/docs/ru/sandboxing), не получает ни одной переменной.1443Если какая-либо строка имеет другой вид, например `export PATH="$PATH:./node_modules/.bin"` с неэкранированным `$PATH`, команда `source` или строки `$'...'`, которые печатает `direnv export bash`, команды PowerShell не получают ни одной переменной, а `claude --debug` записывает в лог `Session environment is not all plain assignments`. Команды Bash по-прежнему получают их все. В Windows команды PowerShell также не получают переменную, значение которой содержит `/` или `\`, поскольку Git Bash и Windows записывают пути по-разному. Команда PowerShell, выполняемая [в песочнице](/docs/ru/sandboxing), не получает ни одной переменной.
1421 1444
1422<Note>1445<Note>
1423 `CLAUDE_ENV_FILE` доступна для хуков SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged) и [FileChanged](#filechanged). Другие события хуков не имеют доступа к этой переменной, как и хук, который выполняется в PowerShell — через [`"shell": "powershell"`](#command-hook-fields) или по умолчанию в Windows без Git Bash.1446 `CLAUDE_ENV_FILE` доступна для хуков SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged) и [FileChanged](#filechanged). Другие события хуков не имеют доступа к этой переменной, как и хук, выполняемый в PowerShell, будь то через [`"shell": "powershell"`](#command-hook-fields) или по умолчанию в Windows без Git Bash.
1424</Note>1447</Note>
1425 1448
1426<h3 id="setup">1449<h3 id="setup">
1427 Setup1450 Setup
1428</h3>1451</h3>
1429 1452
1430Срабатывает только при запуске Claude Code с `--init-only` либо с `--init` или `--maintenance` в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. При обычном запуске не срабатывает. Используйте его для одноразовой установки зависимостей или плановой очистки, которую вы явно запускаете из CI или скриптов, отдельно от обычного запуска сессии. Для инициализации на уровне каждой сессии используйте вместо этого [SessionStart](#sessionstart).1453Срабатывает, только когда вы запускаете Claude Code с `--init-only` либо с `--init` или `--maintenance` в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. При обычном запуске не срабатывает. Используйте его для однократной установки зависимостей или плановой очистки, которую вы явно запускаете из CI или скриптов, отдельно от обычного начала сессии. Для инициализации на уровне каждой сессии используйте вместо этого [SessionStart](#sessionstart).
1431 1454
1432Значение matcher соответствует флагу CLI, который вызвал хук:1455Значение matcher соответствует флагу CLI, который запустил хук:
1433 1456
1434| Matcher | Когда срабатывает |1457| Matcher | Когда срабатывает |
1435| :- | :- |1458| :- | :- |
1438 1461
1439Когда вы выполняете `claude --init-only`, Claude Code запускает хуки Setup и хуки `SessionStart` с matcher `startup`, а затем завершает работу, не начиная диалог.1462Когда вы выполняете `claude --init-only`, Claude Code запускает хуки Setup и хуки `SessionStart` с matcher `startup`, а затем завершает работу, не начиная диалог.
1440 1463
1441Когда вы начинаете или продолжаете диалог с `-p`, нужно также передать промпт — в качестве аргумента или через stdin. Промпт можно не передавать, если хук `SessionStart` предоставляет [`initialUserMessage`](#sessionstart-decision-control) или если вы возобновляете сессию с [отложенным вызовом инструмента](#defer-a-tool-call-for-later).1464Когда вы начинаете или продолжаете диалог с `-p`, необходимо также передать промпт — как аргумент или через stdin. Промпт можно не передавать, если хук `SessionStart` задаёт [`initialUserMessage`](#sessionstart-decision-control) или если вы возобновляете сессию с [отложенным вызовом инструмента](#defer-a-tool-call-for-later).
1442 1465
1443При успешном выполнении `--init-only` ничего не выводит в терминал. Чтобы убедиться, что хуки выполнились, запустите `claude --debug-file <path> --init-only`, заменив `<path>` на расположение файла лога, и проверьте в логе записи хуков Setup и SessionStart.1466При успешном выполнении `--init-only` ничего не выводит в терминал. Чтобы убедиться, что хуки выполнились, запустите `claude --debug-file <path> --init-only`, заменив `<path>` расположением файла лога, и проверьте в логе записи хуков Setup и SessionStart.
1444 1467
1445Поскольку Setup срабатывает не при каждом запуске, плагин, которому нужна установленная зависимость, не может полагаться только на Setup. Практичный подход — проверять наличие зависимости при первом использовании и устанавливать её при отсутствии, например хуком или скиллом, который проверяет наличие `${CLAUDE_PLUGIN_DATA}/node_modules` и выполняет `npm install`, если его нет. О том, где хранить установленные зависимости, см. [постоянный каталог данных](/docs/ru/plugins/components#path-variables-and-persistent-data). Если вы распространяете плагин через маркетплейс, этот подход может не понадобиться: Claude Code [автоматически устанавливает подходящие зависимости пакетов Node.js](/docs/ru/plugins/loading#node-js-package-dependencies) при кэшировании плагина.1468Поскольку Setup срабатывает не при каждом запуске, плагин, которому нужна установленная зависимость, не может полагаться только на Setup. Практичный подход — проверять наличие зависимости при первом использовании и устанавливать её при отсутствии, например хук или скилл, который проверяет наличие `${CLAUDE_PLUGIN_DATA}/node_modules` и выполняет `npm install`, если её нет. О том, где хранить установленные зависимости, см. [каталог постоянных данных](/docs/ru/plugins/components#path-variables-and-persistent-data). Если вы распространяете плагин через маркетплейс, этот подход может не понадобиться: Claude Code [автоматически устанавливает подходящие зависимости пакетов Node.js](/docs/ru/plugins/loading#node-js-package-dependencies) при кэшировании плагина.
1446 1469
1447<h4 id="setup-input">1470<h4 id="setup-input">
1448 Входные данные Setup1471 Входные данные Setup
1464 Управление решениями Setup1487 Управление решениями Setup
1465</h4>1488</h4>
1466 1489
1467Хуки Setup не могут блокировать; выполнение продолжается при любом коде выхода. При любом коде выхода Claude Code отбрасывает [поля вывода JSON](#json-output) хука Setup, такие как `systemMessage`, `continue` и `hookSpecificOutput.additionalContext`. С `-p` stdout, stderr и код выхода хука Setup появляются в выводе запуска только как [события `hook_response`](/docs/ru/headless#read-session-metadata), когда вы запускаете с `--output-format stream-json --verbose`.1490Хуки Setup не могут блокировать; выполнение продолжается при любом коде выхода. При любом коде выхода Claude Code отбрасывает [поля вывода JSON](#json-output) хука Setup, такие как `systemMessage`, `continue` и `hookSpecificOutput.additionalContext`. С `-p` stdout, stderr и код выхода хука Setup появляются в выводе запуска только как [события `hook_response`](/docs/ru/headless#read-session-metadata), если вы запускаете с `--output-format stream-json --verbose`.
1468 1491
1469Хуки Setup имеют доступ к `CLAUDE_ENV_FILE`. Переменные, записанные в этот файл, сохраняются для последующих команд Bash в сессии, как и в [хуках SessionStart](#persist-environment-variables). Для `Setup` выполняются только хуки `type: "command"`. Хук `type: "mcp_tool"` для `Setup` всегда пропускается, как описано в разделе [Поля хуков инструментов MCP](#mcp-tool-hook-fields).1492Хуки Setup имеют доступ к `CLAUDE_ENV_FILE`. Переменные, записанные в этот файл, сохраняются для последующих команд Bash в сессии, как в [хуках SessionStart](#persist-environment-variables). На `Setup` выполняются только хуки `type: "command"`. Хук `type: "mcp_tool"` на `Setup` всегда пропускается, как описано в разделе [Поля хука MCP-инструмента](#mcp-tool-hook-fields).
1470 1493
1471<h3 id="instructionsloaded">1494<h3 id="instructionsloaded">
1472 InstructionsLoaded1495 InstructionsLoaded
1473</h3>1496</h3>
1474 1497
1475Срабатывает, когда файл `CLAUDE.md` или `.claude/rules/*.md` загружается в контекст. Это событие срабатывает при запуске сессии для файлов, загружаемых сразу, и повторно позже, когда файлы загружаются отложенно, например когда Claude обращается к подкаталогу, содержащему вложенный `CLAUDE.md`, или когда срабатывают условные правила с frontmatter `paths:`. Хук не поддерживает блокировку или управление решениями. Он выполняется асинхронно в целях наблюдаемости.1498Срабатывает, когда файл `CLAUDE.md` или `.claude/rules/*.md` загружается в контекст. Это событие срабатывает в начале сессии для файлов, загружаемых сразу, и позже при отложенной загрузке файлов, например когда Claude обращается к подкаталогу, содержащему вложенный `CLAUDE.md`, или когда срабатывают условные правила с frontmatter `paths:`. Хук не поддерживает блокировку или управление решениями. Он выполняется асинхронно для целей наблюдаемости.
1476 1499
1477Это событие не срабатывает, когда Claude [читает `AGENTS.md` напрямую](/docs/ru/memory#agents-md) через настройку **Project instructions**. Оно срабатывает, когда `CLAUDE.md` импортирует ваш `AGENTS.md` — с `load_reason`, равным `include`, как и для любого другого импортируемого файла, — а также когда `CLAUDE.md` является символической ссылкой на него, как при обычной загрузке `CLAUDE.md`.1500Это событие не срабатывает, когда Claude [читает `AGENTS.md` напрямую](/docs/ru/memory#agents-md) через настройку **Project instructions**. Оно срабатывает, когда `CLAUDE.md` импортирует ваш `AGENTS.md` — с `load_reason`, равным `include`, как для любого другого импортированного файла, — и когда `CLAUDE.md` является символической ссылкой на него — как обычная загрузка `CLAUDE.md`.
1478 1501
1479Matcher сопоставляется с `load_reason`. Например, используйте `"matcher": "session_start"`, чтобы срабатывать только для файлов, загруженных при запуске сессии, или `"matcher": "path_glob_match|nested_traversal"`, чтобы срабатывать только при отложенной загрузке.1502Matcher сопоставляется с `load_reason`. Например, используйте `"matcher": "session_start"`, чтобы срабатывать только для файлов, загружаемых в начале сессии, или `"matcher": "path_glob_match|nested_traversal"`, чтобы срабатывать только при отложенных загрузках.
1480 1503
1481<h4 id="instructionsloaded-input">1504<h4 id="instructionsloaded-input">
1482 Входные данные InstructionsLoaded1505 Входные данные InstructionsLoaded
1488| :- | :- |1511| :- | :- |
1489| `file_path` | Абсолютный путь к загруженному файлу инструкций |1512| `file_path` | Абсолютный путь к загруженному файлу инструкций |
1490| `memory_type` | Область действия файла: `"User"`, `"Project"`, `"Local"` или `"Managed"` |1513| `memory_type` | Область действия файла: `"User"`, `"Project"`, `"Local"` или `"Managed"` |
1491| `load_reason` | Почему файл был загружен: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` или `"compact"`. Значение `"compact"` используется, когда файлы инструкций повторно загружаются после сжатия контекста |1514| `load_reason` | Почему файл был загружен: `"session_start"`, `"nested_traversal"`, `"path_glob_match"`, `"include"` или `"compact"`. Значение `"compact"` возникает, когда файлы инструкций повторно загружаются после сжатия контекста |
1492| `globs` | Glob-шаблоны путей из frontmatter `paths:` файла, если они есть. Присутствует только при загрузках `path_glob_match` |1515| `globs` | Glob-шаблоны путей из frontmatter `paths:` файла, если есть. Присутствует только для загрузок `path_glob_match` |
1493| `trigger_file_path` | Путь к файлу, обращение к которому вызвало эту загрузку, для отложенных загрузок |1516| `trigger_file_path` | Путь к файлу, обращение к которому вызвало эту загрузку, для отложенных загрузок |
1494| `parent_file_path` | Путь к родительскому файлу инструкций, который включил этот, для загрузок `include` |1517| `parent_file_path` | Путь к родительскому файлу инструкций, который включил этот файл, для загрузок `include` |
1495 1518
1496```json theme={null}1519```json theme={null}
1497{1520{
1516</h3>1539</h3>
1517 1540
1518Выполняется при отправке промпта, до того как Claude его обработает. Это позволяет1541Выполняется при отправке промпта, до того как Claude его обработает. Это позволяет
1519добавлять дополнительный контекст на основе промпта или диалога, проверять промпты или1542добавлять дополнительный контекст на основе промпта/диалога, проверять промпты или
1520блокировать определённые типы промптов.1543блокировать определённые типы промптов.
1521 1544
1522Хуки `UserPromptSubmit` срабатывают не только на промпты, которые вы вводите. Claude Code также запускает их, когда:1545Хуки `UserPromptSubmit` срабатывают не только на промпты, которые вы вводите. Claude Code также запускает их, когда:
1523 1546
1524* срабатывает [запланированная задача](/docs/ru/scheduled-tasks), включая итерацию `/loop`1547* Срабатывает [запланированная задача](/docs/ru/scheduled-tasks), включая итерацию `/loop`
1525* [фоновый субагент](/docs/ru/sub-agents#run-subagents-in-foreground-or-background) отчитывается перед сессией, которая его запустила1548* [Фоновый субагент](/docs/ru/sub-agents#run-subagents-in-foreground-or-background) отчитывается перед сессией, которая его запустила
1526* [другая сессия отправляет сообщение](/docs/ru/cross-session-messaging) в ваш основной диалог1549* [Другая сессия отправляет сообщение](/docs/ru/cross-session-messaging) в ваш основной диалог
1527 1550
1528Хуки `UserPromptSubmit` имеют таймаут по умолчанию 30 секунд для типов `command`, `http` и `mcp_tool` — меньше, чем стандартные 600 секунд для этих типов в большинстве других событий. Поскольку этот хук выполняется перед каждым промптом и блокирует обработку моделью до своего завершения, зависший хук останавливает сессию. Если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.1551Хуки `UserPromptSubmit` имеют таймаут по умолчанию 30 секунд для типов `command`, `http` и `mcp_tool` — меньше, чем 600 секунд по умолчанию для этих типов в большинстве других событий. Поскольку этот хук выполняется перед каждым промптом и блокирует обработку моделью до своего завершения, зависший хук останавливает сессию. Если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.
1529 1552
1530За исключением 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-хука. В транскрипте отображается уведомление с именем хука, сработавшим таймаутом и сообщением о том, что вывод был отброшен.1553За исключением командного хука, запускаемого с [`async: true`](#run-hooks-in-the-background), хук `UserPromptSubmit` типа command, HTTP или MCP-инструмент, достигший таймаута, отменяется, а его вывод, включая любой `additionalContext`, отбрасывается. Промпт всё равно доходит до Claude, но без этого контекста. Чтобы вместо этого заблокировать промпт, задайте [`onFailure: "block"`](#block-the-action-when-a-hook-fails) для командного или HTTP-хука. В транскрипте отображается уведомление с именем хука, сработавшим таймаутом и сообщением о том, что вывод был отброшен.
1531 1554
1532[Хук обратного вызова Agent SDK](/docs/ru/agent-sdk/hooks) для `UserPromptSubmit`, достигший таймаута, блокирует промпт с сообщением, в котором названы хук и таймаут, поскольку обратный вызов в этом месте может выступать в роли шлюза политики, который не должен при сбое пропускать всё подряд. Сессия продолжается. До версии v2.1.208 таймаут обратного вызова для этого события завершал ход с ошибкой выполнения.1555[Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks) на `UserPromptSubmit`, достигший таймаута, блокирует промпт с сообщением, в котором указаны хук и таймаут, поскольку callback в этом месте может выполнять роль контроля политики, который не должен при сбое пропускать всё. Сессия продолжается. До v2.1.208 таймаут callback на этом событии завершал ход с ошибкой выполнения.
1533 1556
1534<h4 id="userpromptsubmit-input">1557<h4 id="userpromptsubmit-input">
1535 Входные данные UserPromptSubmit1558 Входные данные UserPromptSubmit
1536</h4>1559</h4>
1537 1560
1538Помимо [общих входных полей](#common-input-fields), хуки UserPromptSubmit получают поле `prompt`, содержащее отправленный текст. Вставленное содержимое, свёрнутое в заполнитель `[Pasted text #N]`, поступает развёрнутым на своём месте. В сессиях, где Claude Code [помечает вставленный текст для Claude](/docs/ru/terminal-config#how-claude-treats-pasted-text), это развёрнутое содержимое находится между строкой `<pasted_content id="…">` и строкой `</pasted_content id="…">`, поэтому учитывайте эти строки, если ваш хук разбирает промпт.1561Помимо [общих входных полей](#common-input-fields), хуки UserPromptSubmit получают поле `prompt`, содержащее отправленный текст. Вставленное содержимое, свёрнутое в заглушку `[Pasted text #N]`, поступает развёрнутым на своём месте. В сессиях, где Claude Code [помечает вставленный текст для Claude](/docs/ru/terminal-config#how-claude-treats-pasted-text), это развёрнутое содержимое находится между строкой `<pasted_content id="…">` и строкой `</pasted_content id="…">`, поэтому учитывайте эти строки, если ваш хук разбирает промпт.
1539 1562
1540Хуки UserPromptSubmit также получают `session_title`, когда у сессии есть пользовательское название, с тем же значением, что и у [поля `session_title` в SessionStart](#sessionstart-input).1563Хуки UserPromptSubmit также получают `session_title`, когда у сессии есть пользовательское название, с тем же значением, что и [поле `session_title` в SessionStart](#sessionstart-input).
1541 1564
1542```json theme={null}1565```json theme={null}
1543{1566{
1554 Управление решениями UserPromptSubmit1577 Управление решениями UserPromptSubmit
1555</h4>1578</h4>
1556 1579
1557Хуки `UserPromptSubmit` могут управлять тем, будет ли обработан отправленный промпт, и добавлять контекст. Доступны все [поля вывода JSON](#json-output).1580Хуки `UserPromptSubmit` могут управлять тем, обрабатывается ли отправленный промпт, и добавлять контекст. Доступны все [поля вывода JSON](#json-output).
1558 1581
1559Есть два способа добавить контекст в диалог при коде выхода 0:1582Есть два способа добавить контекст в диалог при коде выхода 0:
1560 1583
1561* **Обычный текст в stdout**: Claude Code добавляет в контекст Claude stdout, который он [обрабатывает как обычный текст](#exit-code-0)1584* **Обычный текстовый stdout**: Claude Code добавляет stdout, который он [считает обычным текстом](#exit-code-0), в контекст Claude
1562* **JSON с `additionalContext`**: используйте формат JSON ниже для более тонкого управления. Поле `additionalContext` добавляется как контекст1585* **JSON с `additionalContext`**: используйте формат JSON ниже для большего контроля. Поле `additionalContext` добавляется как контекст
1563 1586
1564Ни один из каналов не создаёт видимой записи в транскрипте. Обычный stdout и значение `additionalContext` внедряются каждый как системное напоминание, начинающееся с имени хука; Claude читает оба. Чтобы убедиться в доставке, проверьте [лог отладки](#debug-hooks).1587Ни один из каналов не создаёт видимой записи в транскрипте. Обычный stdout и значение `additionalContext` внедряются каждое как системное напоминание, начинающееся с имени хука; Claude читает оба. Чтобы подтвердить доставку, проверьте [лог отладки](#debug-hooks).
1565 1588
1566Чтобы заблокировать промпт, верните объект JSON с `decision`, равным `"block"`:1589Чтобы заблокировать промпт, верните объект JSON с `decision`, равным `"block"`:
1567 1590
1568| Поле | Описание |1591| Поле | Описание |
1569| :- | :- |1592| :- | :- |
1570| `decision` | `"block"` останавливает промпт до того, как он дойдёт до Claude. Не указывайте, чтобы разрешить обработку промпта |1593| `decision` | `"block"` останавливает промпт до того, как он дойдёт до Claude. Не указывайте, чтобы разрешить продолжение |
1571| `reason` | Показывается пользователю, когда `decision` равен `"block"`. Не добавляется в контекст |1594| `reason` | Показывается пользователю, когда `decision` равен `"block"`. Не добавляется в контекст |
1572| `additionalContext` | Строка, добавляемая в контекст Claude вместе с отправленным промптом. См. [Добавление контекста для Claude](#add-context-for-claude) |1595| `additionalContext` | Строка, добавляемая в контекст Claude вместе с отправленным промптом. См. [Добавление контекста для Claude](#add-context-for-claude) |
1573| `sessionTitle` | Задаёт название сессии. Используйте, чтобы автоматически именовать сессии на основе содержимого промпта |1596| `sessionTitle` | Задаёт название сессии. Используйте для автоматического именования сессий на основе содержимого промпта |
1574| `suppressOriginalPrompt` | Если `true` и хук блокирует промпт, текст промпта не включается в сообщение о блокировке. См. [Что остаётся после заблокированного промпта](#what-a-blocked-prompt-leaves-behind) |1597| `suppressOriginalPrompt` | Если `true`, когда хук блокирует промпт, текст промпта не включается в сообщение о блокировке. См. [Что остаётся после заблокированного промпта](#what-a-blocked-prompt-leaves-behind) |
1575 1598
1576Хук, который блокирует, завершаясь с кодом 2, обрабатывается так же, как `reason`: сообщение о блокировке показывает пользователю текст из stderr, и он не добавляется в контекст.1599Хук, который блокирует через выход с кодом 2, обрабатывается так же, как `reason`: сообщение о блокировке показывает пользователю текст stderr, и он не добавляется в контекст.
1577 1600
1578```json theme={null}1601```json theme={null}
1579{1602{
1592 Что остаётся после заблокированного промпта1615 Что остаётся после заблокированного промпта
1593</h4>1616</h4>
1594 1617
1595Заблокированный промпт никогда не доходит до Claude, но его текст удаляется не отовсюду. По умолчанию сообщение о блокировке, показываемое пользователю, заканчивается строкой `Original prompt:`, за которой следует отправленный текст, и Claude Code записывает это сообщение в файл транскрипта сессии на диске. Чтобы исключить текст из сообщения, выведите JSON с `"suppressOriginalPrompt": true` внутри `hookSpecificOutput`. Это работает независимо от того, блокирует ли хук через `decision: "block"` или завершением с кодом 2.1618Заблокированный промпт никогда не доходит до Claude, но его текст удаляется не везде. По умолчанию сообщение о блокировке, показываемое пользователю, заканчивается строкой `Original prompt:`, за которой следует отправленный текст, и Claude Code записывает это сообщение в файл транскрипта сессии на диске. Чтобы исключить текст из сообщения, выведите JSON с `"suppressOriginalPrompt": true` внутри `hookSpecificOutput`. Это работает независимо от того, блокирует ли хук через `decision: "block"` или через выход с кодом 2.
1596 1619
1597`suppressOriginalPrompt` изменяет только сообщение о блокировке. Отправленный текст всё равно может оказаться в локальных файлах, таких как транскрипт сессии и история промптов, поэтому блокирующий хук — не способ уберечь секрет от записи на диск. Чтобы ограничить или удалить эти файлы, см. [Хранение в открытом виде](/docs/ru/claude-directory#plaintext-storage) и [Очистка локальных данных](/docs/ru/claude-directory#clear-local-data).1620`suppressOriginalPrompt` изменяет только сообщение о блокировке. Отправленный текст всё равно может оказаться в локальных файлах, таких как транскрипт сессии и история ваших промптов, поэтому блокирующий хук не является способом не допустить попадания секрета на диск. Чтобы ограничить или удалить эти файлы, см. [Хранение в открытом виде](/docs/ru/claude-directory#plaintext-storage) и [Очистка локальных данных](/docs/ru/claude-directory#clear-local-data).
1598 1621
1599<h3 id="userpromptexpansion">1622<h3 id="userpromptexpansion">
1600 UserPromptExpansion1623 UserPromptExpansion
1601</h3>1624</h3>
1602 1625
1603Выполняется, когда введённая пользователем команда разворачивается в промпт до того, как дойти до Claude. Используйте его, чтобы блокировать прямой вызов определённых команд, внедрять контекст для конкретного скилла или логировать, какие команды вызывают пользователи. Например, хук с matcher `deploy` может блокировать `/deploy`, если нет файла одобрения, а хук с matcher для скилла ревью может добавлять чек-лист ревью команды в качестве `additionalContext`.1626Выполняется, когда введённая пользователем команда разворачивается в промпт до того, как дойти до Claude. Используйте это, чтобы блокировать прямой вызов определённых команд, внедрять контекст для конкретного скилла или логировать, какие команды вызывают пользователи. Например, хук с matcher `deploy` может блокировать `/deploy`, если нет файла подтверждения, а хук, соответствующий скиллу ревью, может добавлять чек-лист ревью команды в качестве `additionalContext`.
1604 1627
1605Это событие покрывает путь, который не покрывает `PreToolUse`: хук `PreToolUse`, сопоставленный с инструментом `Skill`, срабатывает только когда Claude вызывает инструмент, а прямой ввод `/skillname` обходит `PreToolUse`. `UserPromptExpansion` срабатывает на этом прямом пути.1628Это событие покрывает путь, который не покрывает `PreToolUse`: хук `PreToolUse`, соответствующий инструменту `Skill`, срабатывает только когда Claude вызывает этот инструмент, а прямой ввод `/skillname` обходит `PreToolUse`. `UserPromptExpansion` срабатывает на этом прямом пути.
1606 1629
1607Сопоставляется с `command_name`. Оставьте matcher пустым, чтобы срабатывать на каждую команду промптового типа.1630Сопоставляется с `command_name`. Оставьте matcher пустым, чтобы срабатывать на каждую команду типа prompt.
1608 1631
1609<h4 id="userpromptexpansion-input">1632<h4 id="userpromptexpansion-input">
1610 Входные данные UserPromptExpansion1633 Входные данные UserPromptExpansion
1611</h4>1634</h4>
1612 1635
1613Помимо [общих входных полей](#common-input-fields), хуки UserPromptExpansion получают `expansion_type`, `command_name`, `command_args`, `command_source` и исходную строку `prompt`. Поле `expansion_type` равно `slash_command` для скиллов и пользовательских команд или `mcp_prompt` для промптов MCP-серверов.1636Помимо [общих входных полей](#common-input-fields), хуки UserPromptExpansion получают `expansion_type`, `command_name`, `command_args`, `command_source` и исходную строку `prompt`. Поле `expansion_type` равно `slash_command` для скиллов и пользовательских команд или `mcp_prompt` для промптов MCP-сервера.
1614 1637
1615```json theme={null}1638```json theme={null}
1616{1639{
1631 Управление решениями UserPromptExpansion1654 Управление решениями UserPromptExpansion
1632</h4>1655</h4>
1633 1656
1634Хуки `UserPromptExpansion` могут блокировать разворачивание или добавлять контекст. Доступны все [поля вывода JSON](#json-output).1657Хуки `UserPromptExpansion` могут блокировать развёртывание или добавлять контекст. Доступны все [поля вывода JSON](#json-output).
1635 1658
1636| Поле | Описание |1659| Поле | Описание |
1637| :- | :- |1660| :- | :- |
1638| `decision` | `"block"` не даёт команде развернуться. Не указывайте, чтобы разрешить продолжение |1661| `decision` | `"block"` предотвращает развёртывание команды. Не указывайте, чтобы разрешить продолжение |
1639| `reason` | Показывается пользователю, когда `decision` равен `"block"` |1662| `reason` | Показывается пользователю, когда `decision` равен `"block"` |
1640| `additionalContext` | Строка, добавляемая в контекст Claude вместе с развёрнутым промптом. См. [Добавление контекста для Claude](#add-context-for-claude) |1663| `additionalContext` | Строка, добавляемая в контекст Claude вместе с развёрнутым промптом. См. [Добавление контекста для Claude](#add-context-for-claude) |
1641 1664
1642Хук, который блокирует, завершаясь с кодом 2, обрабатывается так же, как `reason`: сообщение о блокировке показывает пользователю текст из stderr.1665Хук, который блокирует через выход с кодом 2, обрабатывается так же, как `reason`: сообщение о блокировке показывает пользователю текст stderr.
1643 1666
1644```json theme={null}1667```json theme={null}
1645{1668{
1656 MessageDisplay1679 MessageDisplay
1657</h3>1680</h3>
1658 1681
1659Выполняется во время потокового вывода сообщения ассистента на экран. Claude Code отображает сообщение порциями: каждый раз, когда пакет новых завершённых строк готов к отрисовке, хук выполняется один раз с этими строками, и Claude Code отрисовывает на их месте текст замены, возвращённый хуком. Длинное сообщение порождает несколько вызовов; короткое может породить только один.1682Выполняется, пока сообщение ассистента выводится на экран в потоковом режиме. Claude Code отображает сообщение порциями: каждый раз, когда готова к отрисовке партия только что завершённых строк, хук выполняется один раз с этими строками, и Claude Code отрисовывает на их месте текст замены от хука. Длинное сообщение приводит к нескольким вызовам; короткое может привести только к одному.
1660 1683
1661Используйте MessageDisplay, чтобы:1684Используйте MessageDisplay, чтобы:
1662 1685
1663* удалять разметку markdown для минималистичного отображения1686* убирать markdown для минималистичного отображения
1664* преобразовывать текст, который приложение на Agent SDK показывает своим пользователям1687* преобразовывать текст, который приложение на Agent SDK показывает своим пользователям
1665* скрывать API-ключи или внутренние имена хостов в ответах Claude1688* скрывать API-ключи или внутренние имена хостов из ответов Claude
1666 1689
1667Claude Code удерживает каждый пакет, пока ваш хук не вернёт результат, поэтому хук должен работать быстро. Если хук завершается ошибкой или по таймауту, Claude Code отображает исходный текст. Таймаут по умолчанию для этого события — 10 секунд; если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.1690Claude Code удерживает каждую партию, пока ваш хук не вернёт результат, поэтому хук должен работать быстро. Если хук завершается с ошибкой или по таймауту, Claude Code отображает исходный текст. Таймаут по умолчанию для этого события — 10 секунд; если вашему хуку нужно больше времени, задайте поле `timeout` в записи хука.
1668 1691
1669MessageDisplay влияет только на отображение: текст замены изменяет лишь то, что отрисовывается на экране. Транскрипт и то, что видит Claude, сохраняют исходный текст, поэтому Claude никогда не видит замену, а подробный режим показывает исходный текст. Хук получает только текст сообщений ассистента, поэтому результаты инструментов и вводимый вами текст отображаются без изменений.1692MessageDisplay влияет только на отображение: текст замены меняет только то, что отрисовывается на экране. В транскрипте и в том, что видит Claude, сохраняется исходный текст, поэтому Claude никогда не видит замену, а подробный режим показывает оригинал. Хук получает только текст сообщений ассистента, поэтому результаты инструментов и вводимый вами текст отображаются без изменений.
1670 1693
1671MessageDisplay не поддерживает matcher и срабатывает для каждого сообщения ассистента, которое выводит текст потоком; сообщения без текста, например ответы, состоящие только из вызовов инструментов, его не вызывают.1694MessageDisplay не поддерживает matcher и срабатывает для каждого сообщения ассистента, которое передаёт текст в потоке; сообщения без текста, например ответы, состоящие только из вызовов инструментов, его не вызывают.
1672 1695
1673В неинтерактивных запусках, включая запросы Agent SDK и `claude -p`, MessageDisplay выполняется один раз на сообщение ассистента, а не один раз на пакет строк. Единственный вызов приходит после завершения сообщения и содержит полный текст сообщения: `index` равен `0`, `final` равен `true`, а `delta` содержит всё сообщение. Хук, собирающий текст `delta` для каждого сообщения, получает один и тот же общий текст в обоих режимах.1696В неинтерактивных запусках, включая запросы Agent SDK и `claude -p`, MessageDisplay выполняется один раз на сообщение ассистента, а не один раз на партию строк. Единственный вызов поступает после завершения сообщения и содержит полный текст сообщения: `index` равен `0`, `final` равен `true`, а `delta` содержит всё сообщение. Хук, собирающий текст `delta` для каждого сообщения, получает в обоих режимах одинаковый итоговый текст.
1674 1697
1675<h4 id="messagedisplay-input">1698<h4 id="messagedisplay-input">
1676 Входные данные MessageDisplay1699 Входные данные MessageDisplay
1677</h4>1700</h4>
1678 1701
1679Помимо [общих входных полей](#common-input-fields), хуки MessageDisplay получают идентификаторы хода и сообщения, позицию этого вызова внутри сообщения и новый текст в `delta`. Границы пакетов зависят от того, как поступает поток текста, поэтому используйте `index` и `final` для отслеживания продвижения по сообщению, а не рассчитывайте на определённую группировку строк.1702Помимо [общих входных полей](#common-input-fields), хуки MessageDisplay получают идентификаторы хода и сообщения, позицию этого вызова в сообщении и новый текст в `delta`. Границы партий зависят от того, как передаётся текст в потоке, поэтому используйте `index` и `final` для отслеживания продвижения по сообщению, а не рассчитывайте на определённую группировку строк.
1680 1703
1681| Поле | Описание |1704| Поле | Описание |
1682| :- | :- |1705| :- | :- |
1683| `turn_id` | UUID текущего хода |1706| `turn_id` | UUID текущего хода |
1684| `message_id` | UUID отображаемого сообщения ассистента. Одинаков для всех пакетов одного сообщения. Это не идентификатор API `msg_…`, поэтому его нельзя сопоставить с идентификаторами сообщений в транскрипте |1707| `message_id` | UUID отображаемого сообщения ассистента. Неизменен во всех партиях одного сообщения. Это не id `msg_…` из API, поэтому его нельзя сопоставить с id сообщений в транскрипте |
1685| `index` | Индекс этого пакета внутри сообщения, начиная с нуля |1708| `index` | Индекс этой партии в сообщении, начиная с нуля |
1686| `final` | `true` для последнего пакета сообщения. У каждого сообщения ровно один финальный пакет |1709| `final` | `true` в последней партии сообщения. У каждого сообщения ровно одна финальная партия |
1687| `delta` | Новые завершённые строки с момента предыдущего пакета, включая завершающие символы новой строки. Всегда целые строки, кроме финального пакета, который может заканчиваться посреди строки. В интерактивных запусках delta финального пакета пуста, если сообщение заканчивается символом новой строки, поэтому считайте сигналом конца сообщения `final`, а не непустую delta. В запусках Agent SDK и `claude -p` единственный вызов содержит всё сообщение |1710| `delta` | Строки, завершённые с момента предыдущей партии, включая завершающие символы новой строки. Всегда целые строки, кроме финальной партии, которая может заканчиваться посреди строки. В интерактивных запусках delta финальной партии пуста, если сообщение заканчивается символом новой строки, поэтому считайте сигналом конца сообщения `final`, а не непустую delta. В запусках Agent SDK и `claude -p` единственный вызов содержит всё сообщение |
1688 1711
1689```json theme={null}1712```json theme={null}
1690{1713{
1704 Вывод MessageDisplay1727 Вывод MessageDisplay
1705</h4>1728</h4>
1706 1729
1707Помимо [полей вывода JSON](#json-output), доступных всем хукам, хуки MessageDisplay могут возвращать `displayContent`, чтобы заменить delta на экране:1730Помимо [полей вывода JSON](#json-output), доступных всем хукам, хуки MessageDisplay могут вернуть `displayContent`, чтобы заменить delta на экране:
1708 1731
1709| Поле | Описание |1732| Поле | Описание |
1710| :- | :- |1733| :- | :- |
1711| `displayContent` | Текст, отображаемый вместо delta. Не указывайте, чтобы отобразить исходный текст |1734| `displayContent` | Текст, отображаемый вместо delta. Не указывайте, чтобы отобразить оригинал |
1712 1735
1713Хуки MessageDisplay не имеют управления решениями. Они не могут заблокировать сообщение или изменить то, что хранится в транскрипте или отправляется Claude. Claude Code использует `displayContent` из их вывода JSON и отбрасывает `systemMessage` и `continue`.1736Хуки MessageDisplay не имеют управления решениями. Они не могут блокировать сообщение или изменять то, что сохраняется в транскрипте или отправляется Claude. Claude Code учитывает `displayContent` из их вывода JSON и отбрасывает `systemMessage` и `continue`.
1714 1737
1715Этот пример удаляет форматирование markdown из ответов Claude для отображения обычным текстом. Скрипт читает каждый пакет из stdin, удаляет из `delta` маркеры полужирного начертания и обратные кавычки встроенного кода и возвращает результат в виде `displayContent`.1738Этот пример убирает форматирование markdown из ответов Claude для отображения обычным текстом. Скрипт считывает каждую партию из stdin, удаляет из `delta` маркеры полужирного шрифта и обратные кавычки встроенного кода и возвращает результат как `displayContent`.
1716 1739
1717<Tabs>1740<Tabs>
1718 <Tab title="macOS/Linux">1741 <Tab title="macOS/Linux">
1736 }1759 }
1737 ```1760 ```
1738 1761
1739 Сохраните этот скрипт в `.claude/hooks/plain-display.sh` в вашем проекте и сделайте его исполняемым с помощью `chmod +x`:1762 Сохраните этот скрипт в `.claude/hooks/plain-display.sh` в своём проекте и сделайте его исполняемым с помощью `chmod +x`:
1740 1763
1741 ```bash theme={null}1764 ```bash theme={null}
1742 #!/bin/bash1765 #!/bin/bash
1773 1796
1774 Флаг `-NoProfile` пропускает загрузку вашего профиля PowerShell, чтобы хук запускался быстро, а `-ExecutionPolicy Bypass` позволяет PowerShell выполнить локальный файл скрипта.1797 Флаг `-NoProfile` пропускает загрузку вашего профиля PowerShell, чтобы хук запускался быстро, а `-ExecutionPolicy Bypass` позволяет PowerShell выполнить локальный файл скрипта.
1775 1798
1776 Сохраните этот скрипт в `.claude/hooks/plain-display.ps1` в вашем проекте:1799 Сохраните этот скрипт в `.claude/hooks/plain-display.ps1` в своём проекте:
1777 1800
1778 ```powershell theme={null}1801 ```powershell theme={null}
1779 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json1802 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json
1788 </Tab>1811 </Tab>
1789</Tabs>1812</Tabs>
1790 1813
1791Пакеты без разметки markdown проходят без изменений. Если скрипт завершается ошибкой, например из-за отсутствия `jq`, Claude Code отображает исходный текст и отмечает сбой только в [отладочном выводе](#debug-hooks), а не в сессии.1814Партии без markdown проходят без изменений. Если скрипт завершается с ошибкой, например из-за отсутствия `jq`, Claude Code отображает исходный текст и отмечает сбой только в [выводе отладки](#debug-hooks), а не в сессии.
1792 1815
1793<h3 id="pretooluse">1816<h3 id="pretooluse">
1794 PreToolUse1817 PreToolUse
1795</h3>1818</h3>
1796 1819
1797Выполняется после того, как Claude сформирует параметры инструмента, и до обработки вызова инструмента. Сопоставляется с любым именем инструмента, кроме `EndConversation`: со встроенными инструментами, такими как `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion` и `ExitPlanMode`, а также с любыми [именами инструментов MCP](#match-mcp-tools).1820Выполняется после того, как Claude сформирует параметры инструмента, и до обработки вызова инструмента. Сопоставляется с любым именем инструмента, кроме `EndConversation`: встроенными инструментами, такими как `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion` и `ExitPlanMode`, а также любыми [именами MCP-инструментов](#match-mcp-tools).
1798 1821
1799Чтобы запускать хук при изменении конкретного файла на диске, независимо от того, что его записало, используйте [FileChanged](#filechanged) вместо сопоставления инструментов редактирования файлов по имени. В отличие от PreToolUse, Claude Code запускает хуки FileChanged после изменения, и у них нет управления решениями, поэтому они не могут заблокировать запись.1822Чтобы запускать хук при изменении конкретного файла на диске, независимо от того, что его записало, используйте [FileChanged](#filechanged) вместо сопоставления инструментов редактирования файлов по имени. В отличие от PreToolUse, Claude Code запускает хуки FileChanged после изменения, и у них нет управления решениями, поэтому они не могут заблокировать запись.
1800 1823
1801<Warning>1824<Warning>
1802 PreToolUse выполняется только когда Claude вызывает инструмент. Файлы, на которые вы [ссылаетесь с помощью `@` в промпте](/docs/ru/common-workflows#reference-files-and-directories), добавляются без вызова инструмента: Claude Code вставляет их содержимое при формировании промпта, поэтому для них не срабатывает ни один хук PreToolUse, включая хуки с matcher `Read`. Чтобы запретить определённые пути в ссылках `@`, используйте вместо этого [правило запрета `Read`](/docs/ru/permissions#read-and-edit).1825 PreToolUse выполняется только тогда, когда Claude вызывает инструмент. По умолчанию файлы, на которые вы [ссылаетесь с помощью `@` в промпте](/docs/ru/common-workflows#reference-files-and-directories), добавляются без какого-либо вызова инструмента. Claude Code вставляет их содержимое при формировании промпта, поэтому для них не срабатывает ни один хук PreToolUse, включая хуки, соответствующие `Read`. PreToolUse также не срабатывает для [`EndConversation`](/docs/ru/tools-reference#endconversation-tool-behavior).
1826
1827 Вы можете блокировать определённые пути в ссылках `@` или отключить вставку:
1803 1828
1804 PreToolUse также не срабатывает для [`EndConversation`](/docs/ru/tools-reference#endconversation-tool-behavior).1829 * **Блокировка определённых путей**: добавьте для них [правило запрета `Read`](/docs/ru/permissions#read-and-edit)
1830 * **Отключение вставки**: задайте [`CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`](/docs/ru/env-vars#variables) в своей оболочке, пользовательских настройках или управляемых настройках. Тогда Claude получает упомянутые пути с пометкой прочитать их с помощью своих файловых инструментов. Если он это делает, выполняются соответствующие хуки PreToolUse. Для этой переменной требуется Claude Code v2.1.299 или новее, и Claude Code игнорирует её в настройках проекта и локальных настройках.
1805</Warning>1831</Warning>
1806 1832
1807Используйте [управление решениями PreToolUse](#pretooluse-decision-control), чтобы разрешить, запретить, запросить подтверждение или отложить вызов инструмента.1833Используйте [управление решениями PreToolUse](#pretooluse-decision-control), чтобы разрешить, запретить, запросить подтверждение или отложить вызов инструмента.
1808 1834
1809[Хук обратного вызова Agent SDK](/docs/ru/agent-sdk/hooks) для `PreToolUse`, превысивший свой таймаут, блокирует вызов инструмента, и Claude получает результат с ошибкой, в котором указан таймаут. Явный запрет, возвращённый другим хуком, по-прежнему имеет приоритет.1835[Callback-хук Agent SDK](/docs/ru/agent-sdk/hooks) на `PreToolUse`, превысивший таймаут, блокирует вызов инструмента, и Claude получает результат с ошибкой, указывающий на таймаут. Явный запрет, возвращённый другим хуком, по-прежнему имеет приоритет.
1810 1836
1811<h4 id="pretooluse-input">1837<h4 id="pretooluse-input">
1812 Входные данные PreToolUse1838 Входные данные PreToolUse
1814 1840
1815Помимо [общих входных полей](#common-input-fields), хуки PreToolUse получают `tool_name`, `tool_input` и `tool_use_id`.1841Помимо [общих входных полей](#common-input-fields), хуки PreToolUse получают `tool_name`, `tool_input` и `tool_use_id`.
1816 1842
1817Для [инструмента MCP](#match-mcp-tools) входные данные также содержат `mcp_server` — объект с `name` сервера и полем `source`, указывающим, откуда взято определение сервера. Значения `source` включают `plugin`, `sdk` и области действия конфигурации, такие как `user` и `project`. В [`McpServerProvenance`](/docs/ru/agent-sdk/typescript#mcpserverprovenance) в справочнике Agent SDK перечислены все значения и указано, как обращаться с незнакомым значением. Принимайте решения о доверии на основе `source`, а не `name` или префикса имени инструмента `mcp__<server>__`. Для поля `mcp_server` требуется Claude Code v2.1.274 или новее.1843Для [MCP-инструмента](#match-mcp-tools) входные данные также содержат `mcp_server` — объект с `name` сервера и `source`, указывающим, откуда взято определение сервера. Значения `source` включают `plugin`, `sdk` и области действия конфигурации, такие как `user` и `project`. [`McpServerProvenance`](/docs/ru/agent-sdk/typescript#mcpserverprovenance) в справочнике Agent SDK перечисляет их все и описывает, как обрабатывать нераспознанное значение. Основывайте решения о доверии на `source`, а не на `name` или префиксе имени инструмента `mcp__<server>__`. Для поля `mcp_server` требуется Claude Code v2.1.274 или новее.
1818 1844
1819Для файловых инструментов `Write`, `Edit` и `Read` значение `tool_input.file_path` всегда абсолютное:1845Для файловых инструментов `Write`, `Edit` и `Read` значение `tool_input.file_path` всегда абсолютное:
1820 1846
1821* Claude Code разворачивает `~` и относительные пути до запуска хуков, поэтому хук, сопоставляющий пути, нельзя обойти через `~` или относительное написание того же пути1847* Claude Code раскрывает `~` и относительные пути до выполнения хуков, поэтому хук, сопоставляющий пути, нельзя обойти через `~` или относительную запись того же пути
1822* В Windows путь приходит с разделителями-обратными слешами, даже если ваш хук выполняется в Git Bash, где `$PWD` выглядит как `/c/project`1848* В Windows путь поступает с обратными косыми чертами в качестве разделителей, даже если ваш хук выполняется в Git Bash, где `$PWD` выглядит как `/c/project`
1823* Сравнение, записанное с прямыми слешами, например проверка `/src/`, никогда не совпадёт с путём с обратными слешами, и вызов инструмента продолжится так, будто хуку нечего было блокировать1849* Сравнение, записанное с прямыми косыми чертами, например проверка `/src/`, никогда не совпадёт с путём с обратными косыми чертами, и вызов инструмента продолжится так, будто хуку нечего было блокировать
1824* Нормализуйте разделители перед сравнением: `FILE_PATH="${FILE_PATH//\\//}"` в Bash или `file_path.replace("\\", "/")` в Python, а затем сопоставляйте сегмент пути, например `/src/`, а не привязывайтесь к началу через `^`, поскольку путь абсолютный1850* Нормализуйте разделители перед сравнением: `FILE_PATH="${FILE_PATH//\\//}"` в Bash или `file_path.replace("\\", "/")` в Python, а затем сопоставляйте сегмент пути, например `/src/`, а не привязывайтесь к началу с помощью `^`, поскольку путь абсолютный
1825 1851
1826Вызов `Write` в Windows передаёт:1852Вызов `Write` в Windows передаёт:
1827 1853
1854| `timeout` | number | `120000` | Необязательный таймаут в миллисекундах. Значения выше [максимума](/docs/ru/tools-reference#bash-tool-behavior) уменьшаются до максимума, а не отклоняются |1880| `timeout` | number | `120000` | Необязательный таймаут в миллисекундах. Значения выше [максимума](/docs/ru/tools-reference#bash-tool-behavior) уменьшаются до максимума, а не отклоняются |
1855| `run_in_background` | boolean | `false` | Выполнять ли команду в фоне |1881| `run_in_background` | boolean | `false` | Выполнять ли команду в фоне |
1856 1882
1857Когда команда Bash изменяет файлы в репозитории Git, Claude Code может записывать, что изменилось. Он записывает изменения во всех режимах разрешений, если запись включена настройкой [`bashEditDiffEnabled`](/docs/ru/settings-reference#basheditdiffenabled); в описании этой настройки указано, какие файлы могут её задавать. В противном случае он записывает их только в авторежиме и режиме `bypassPermissions`, и только когда Claude Code направляет Claude редактировать файлы через Bash. Задайте `bashEditDiffEnabled` значение `false`, чтобы отключить запись. Фоновые команды и команды только для чтения не содержат diff.1883Когда команда Bash изменяет файлы в репозитории Git, Claude Code может записывать, что изменилось. Он записывает изменения в любом режиме разрешений, когда это включено настройкой [`bashEditDiffEnabled`](/docs/ru/settings-reference#basheditdiffenabled); в описании этой настройки указано, какие файлы могут её задавать. В противном случае он записывает их только в авторежиме и режиме `bypassPermissions`, и только когда Claude Code направляет Claude редактировать файлы через Bash. Задайте `bashEditDiffEnabled` равным `false`, чтобы отключить запись. Фоновые команды и команды только для чтения не содержат diff.
1858 1884
1859Затем ваш [хук PostToolUse](#posttooluse) получает изменённые файлы в `tool_response.bashEditDiff`. Список охватывает то, что изменилось в репозитории во время выполнения команды. Файлы, игнорируемые Git, и файлы в подмодулях не перечисляются. Требуется Claude Code v2.1.269 или новее.1885Затем ваш [хук PostToolUse](#posttooluse) получает изменённые файлы в `tool_response.bashEditDiff`. Список охватывает то, что изменилось в репозитории во время выполнения команды. Файлы, которые игнорирует Git, и файлы в подмодулях не перечисляются. Требуется Claude Code v2.1.269 или новее.
1860 1886
1861<Note>1887<Note>
1862 Список формируется по возможности и находится в стадии публичной беты. Claude Code может пропустить изменение, включить файл, который одновременно изменил другой процесс, или остановиться на своих ограничениях размера. Структура поля может измениться. Используйте список, чтобы найти, что нужно проверить, а не для применения политики.1888 Список формируется по принципу «насколько возможно» и доступен в публичной бета-версии. Claude Code может пропустить изменение, включить файл, который одновременно изменил другой процесс, или остановиться на своих ограничениях размера. Структура поля может измениться. Используйте список, чтобы найти, что проверить, а не для принудительного применения политики.
1863</Note>1889</Note>
1864 1890
1865`changedFiles` и `files` перечисляют, что изменила команда; остальные поля сообщают, насколько полон и надёжен этот список.1891`changedFiles` и `files` перечисляют то, что изменила команда; остальные поля указывают, насколько полон и надёжен этот список.
1866 1892
1867| Поле | Тип | Пример | Описание |1893| Поле | Тип | Пример | Описание |
1868| :- | :- | :- | :- |1894| :- | :- | :- | :- |
1869| `changedFiles` | array | `["/path/to/src/app.ts"]` | Абсолютные пути файлов, изменённых командой, не более 200. Присутствует, когда `files` содержит diff или `moreFiles` больше нуля |1895| `changedFiles` | array | `["/path/to/src/app.ts"]` | Абсолютные пути файлов, изменённых командой, не более 200. Присутствует всякий раз, когда `files` содержит diff или `moreFiles` больше нуля |
1870| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diff не более 5 изменённых файлов, для отображения. `created` или `deleted` равно `true` для файла, который команда добавила или удалила |1896| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diff до 5 изменённых файлов для отображения. `created` или `deleted` равно `true` для файла, который команда добавила или удалила |
1871| `moreFiles` | number | `2` | Количество изменённых файлов без diff в `files` |1897| `moreFiles` | number | `2` | Количество изменённых файлов без diff в `files` |
1872| `unavailable` | boolean | `true` | Задаётся, когда diff неполон или его не удалось получить |1898| `unavailable` | boolean | `true` | Устанавливается, когда diff неполон или его не удалось получить |
1873| `skipped` | boolean | `true` | Задаётся для команды Git, которая перемещает рабочее дерево, например `git checkout` или `git stash`, поэтому Claude Code не получает diff |1899| `skipped` | boolean | `true` | Устанавливается для команды Git, которая перемещает рабочее дерево, например `git checkout` или `git stash`, поэтому Claude Code не получает diff |
1874| `shared` | boolean | `true` | Задаётся, когда другой вызов инструмента Bash, например вызов субагента, выполнялся в том же репозитории в то же время, поэтому некоторые перечисленные изменения могут относиться к той команде |1900| `shared` | boolean | `true` | Устанавливается, когда другой вызов инструмента Bash, например от субагента, выполнялся в том же репозитории в то же время, поэтому некоторые перечисленные изменения могут принадлежать той команде |
1875 1901
1876<a id="powershell" />1902<a id="powershell" />
1877 1903
1890| `timeout` | number | `120000` | Необязательный таймаут в миллисекундах |1916| `timeout` | number | `120000` | Необязательный таймаут в миллисекундах |
1891| `run_in_background` | boolean | `false` | Выполнять ли команду в фоне |1917| `run_in_background` | boolean | `false` | Выполнять ли команду в фоне |
1892 1918
1893В хуках, которые проверяют shell-команды, используйте matcher `Bash|PowerShell`, чтобы охватить оба инструмента:1919В хуках, проверяющих shell-команды, используйте matcher `Bash|PowerShell`, чтобы они охватывали оба инструмента:
1894 1920
1895* В Windows везде, где включён инструмент PowerShell, Claude считает PowerShell основной оболочкой и направляет shell-команды через неё.1921* В Windows везде, где включён инструмент PowerShell, Claude считает PowerShell основной оболочкой и направляет shell-команды через него.
1896* В Windows без Git Bash инструмент включается автоматически, и Claude Code вообще не регистрирует инструмент Bash.1922* В Windows без Git Bash инструмент включается автоматически, и Claude Code вообще не регистрирует инструмент Bash.
1897* Хук, сопоставленный только с `Bash`, там никогда не сработает.1923* Хук, соответствующий только `Bash`, там никогда не срабатывает.
1898 1924
1899<h5 id="write">1925<h5 id="write">
1900 Write1926 Write
1947 Grep1973 Grep
1948</h5>1974</h5>
1949 1975
1950Ищет по содержимому файлов с помощью регулярных выражений.1976Ищет в содержимом файлов с помощью регулярных выражений.
1951 1977
1952| Поле | Тип | Пример | Описание |1978| Поле | Тип | Пример | Описание |
1953| :- | :- | :- | :- |1979| :- | :- | :- | :- |
1979| Поле | Тип | Пример | Описание |2005| Поле | Тип | Пример | Описание |
1980| :- | :- | :- | :- |2006| :- | :- | :- | :- |
1981| `query` | string | `"react hooks best practices"` | Поисковый запрос |2007| `query` | string | `"react hooks best practices"` | Поисковый запрос |
1982| `allowed_domains` | array | `["docs.example.com"]` | Необязательно: включать только результаты с этих доменов |2008| `allowed_domains` | array | `["docs.example.com"]` | Необязательно: включать результаты только с этих доменов |
1983| `blocked_domains` | array | `["spam.example.com"]` | Необязательно: исключать результаты с этих доменов |2009| `blocked_domains` | array | `["spam.example.com"]` | Необязательно: исключать результаты с этих доменов |
1984 2010
1985<h5 id="agent">2011<h5 id="agent">
1995| `subagent_type` | string | `"Explore"` | Тип используемого специализированного агента |2021| `subagent_type` | string | `"Explore"` | Тип используемого специализированного агента |
1996| `model` | string | `"sonnet"` | Необязательный псевдоним модели для переопределения модели по умолчанию |2022| `model` | string | `"sonnet"` | Необязательный псевдоним модели для переопределения модели по умолчанию |
1997 2023
1998Когда вызов Agent на переднем плане завершается, ваш [хук PostToolUse](#posttooluse) получает результат субагента и телеметрию запуска в `tool_response`. Читайте эти поля, чтобы изучить запуск; для сводок по токенам и стоимости по всем субагентам используйте [счётчики токенов и стоимости](/docs/ru/monitoring-usage#token-counter) с фильтром `query_source` `"subagent"`, поскольку `totalTokens` и `usage` охватывают только последний запрос:2024Когда вызов Agent на переднем плане завершается, ваш [хук PostToolUse](#posttooluse) получает результат субагента и телеметрию запуска в `tool_response`. Читайте эти поля, чтобы проанализировать запуск; для сводных данных по токенам и стоимости по всем субагентам используйте [счётчики токенов и стоимости](/docs/ru/monitoring-usage#token-counter), отфильтрованные по `query_source` `"subagent"`, поскольку `totalTokens` и `usage` охватывают только последний запрос:
1999 2025
2000| Поле | Тип | Пример | Описание |2026| Поле | Тип | Пример | Описание |
2001| :- | :- | :- | :- |2027| :- | :- | :- | :- |
2002| `status` | string | `"completed"` | `"completed"` для субагентов на переднем плане, `"async_launched"` для фоновых субагентов. Субагенты по умолчанию выполняются в фоне, поэтому вызов Agent без `run_in_background` также даёт `"async_launched"` |2028| `status` | string | `"completed"` | `"completed"` для субагентов на переднем плане, `"async_launched"` для фоновых субагентов. Субагенты по умолчанию выполняются в фоне, поэтому вызов Agent без `run_in_background` также даёт `"async_launched"` |
2003| `agentId` | string | `"a4d2c8f1e0b3a297"` | Идентификатор запуска субагента |2029| `agentId` | string | `"a4d2c8f1e0b3a297"` | Идентификатор запуска субагента |
2004| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Финальные текстовые блоки субагента или, для субагента, чей отчёт передаётся через `SubagentHandback`, вместо них краткая заметка об этой передаче |2030| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Финальные текстовые блоки субагента или, для субагента, чей отчёт передаётся через `SubagentHandback`, вместо них — краткая заметка об этой передаче |
2005| `resolvedModel` | string | `"claude-sonnet-4-5"` | Модель, на которой субагент начал работу; может отличаться от запрошенной модели |2031| `resolvedModel` | string | `"claude-sonnet-4-5"` | Модель, на которой запустился субагент; может отличаться от запрошенной модели |
2006| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Использованные модели по порядку, с объединением последовательных повторов; задаётся только когда модель сменилась во время запуска. Требуется Claude Code v2.1.212 или новее |2032| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Использованные модели по порядку, с объединением последовательных повторов; задаётся только если модель менялась во время запуска. Требуется Claude Code v2.1.212 или новее |
2007| `totalTokens` | number | `12450` | Количество токенов из последнего запроса API субагента: входные, выходные и кэш-токены вместе. Это не итог за весь запуск |2033| `totalTokens` | number | `12450` | Количество токенов из последнего API-запроса субагента: входные, выходные и кэш-токены вместе. Это не итог за весь запуск |
2008| `totalDurationMs` | number | `48211` | Реальная длительность запуска субагента |2034| `totalDurationMs` | number | `48211` | Реальная длительность запуска субагента |
2009| `totalToolUseCount` | number | `7` | Количество вызовов инструментов, сделанных субагентом |2035| `totalToolUseCount` | number | `7` | Количество вызовов инструментов, сделанных субагентом |
2010| `usage` | object | `{"input_tokens": 8320, ...}` | Разбивка токенов по типам для последнего запроса API: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |2036| `usage` | object | `{"input_tokens": 8320, ...}` | Разбивка токенов последнего API-запроса по типам: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |
2011 2037
2012В Claude Code v2.1.271 или новее субагент, работающий с инструментом [`SubagentHandback`](/docs/ru/tools-reference), который Claude Code предоставляет в [авторежиме](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), передаёт свой отчёт через этот инструмент, а не возвращает его текстом. Поле `content` его результата `completed` тогда содержит краткую заметку об этой передаче, а не сам отчёт. Чтобы прочитать отчёт, сопоставьте хук `PreToolUse` или `PostToolUse` с `SubagentHandback` и прочитайте `tool_input.message`.2038В Claude Code v2.1.271 или новее субагент, работающий с инструментом [`SubagentHandback`](/docs/ru/tools-reference), который Claude Code предоставляет в [авторежиме](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), передаёт свой отчёт через этот инструмент, а не возвращает его как текст. Тогда поле `content` его результата `completed` содержит краткую заметку об этой передаче, а не сам отчёт. Чтобы прочитать отчёт, настройте хук `PreToolUse` или `PostToolUse` с matcher `SubagentHandback` и читайте `tool_input.message`.
2013 2039
2014Для фоновых субагентов инструмент возвращает результат, когда задача переходит в фон, поэтому `tool_response` не содержит полей использования: фоновый запуск возвращается немедленно, а задача на переднем плане, которую Claude Code переводит в фон во время выполнения, возвращается в момент этого перехода. Он содержит `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` и `resolvedModel`.2040Для фоновых субагентов инструмент возвращает результат, когда задача переходит в фон, поэтому `tool_response` не содержит полей использования: фоновый запуск возвращается сразу, а задача на переднем плане, которую Claude Code переводит в фон во время выполнения, возвращается в момент этого перехода. Он содержит `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile` и `resolvedModel`.
2015 2041
2016В ответе `completed` поле `resolvedModel` называет модель, на которой субагент начал работу; она может отличаться от значения `model` в `tool_input`, например когда применяется `availableModels` или другое переопределение. В ответе `async_launched` поле `resolvedModel` называет модель, использовавшуюся в момент перевода агента в фон, поэтому смена модели, произошедшая до перевода в фон, отражается там. Для `modelsUsed` и поведения `resolvedModel` на момент перевода в фон требуется Claude Code v2.1.212 или новее.2042В ответе `completed` поле `resolvedModel` указывает модель, на которой запустился субагент; она может отличаться от значения `model` в `tool_input`, например когда применяется `availableModels` или другое переопределение. В ответе `async_launched` поле `resolvedModel` указывает модель, использовавшуюся в момент перехода агента в фон, поэтому смена модели, произошедшая до перехода в фон, отражается там. Для `modelsUsed` и поведения `resolvedModel` на момент перехода в фон требуется Claude Code v2.1.212 или новее.
2017 2043
2018<a id="askuserquestion" />2044<a id="askuserquestion" />
2019 2045
2026| Поле | Тип | Пример | Описание |2052| Поле | Тип | Пример | Описание |
2027| :- | :- | :- | :- |2053| :- | :- | :- | :- |
2028| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Вопросы для показа, каждый со строкой `question`, кратким `header`, массивом `options` и необязательным флагом `multiSelect` |2054| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Вопросы для показа, каждый со строкой `question`, кратким `header`, массивом `options` и необязательным флагом `multiSelect` |
2029| `answers` | object | `{"Which framework?": "React"}` | Необязательно. Сопоставляет текст вопроса с меткой выбранного варианта. В ответах с множественным выбором метки объединяются через запятые. Claude не задаёт это поле; передайте его через `updatedInput`, чтобы отвечать программно |2055| `answers` | object | `{"Which framework?": "React"}` | Необязательно. Сопоставляет текст вопроса с меткой выбранного варианта. Ответы с множественным выбором объединяют метки через запятые. Claude не задаёт это поле; передайте его через `updatedInput`, чтобы отвечать программно |
2030 2056
2031<h5 id="exitplanmode">2057<h5 id="exitplanmode">
2032 ExitPlanMode2058 ExitPlanMode
2038| :- | :- | :- | :- |2064| :- | :- | :- | :- |
2039| `plan` | string | `"## Refactor auth\n1. Extract..."` | Содержимое плана в Markdown. Внедряется из файла плана на диске |2065| `plan` | string | `"## Refactor auth\n1. Extract..."` | Содержимое плана в Markdown. Внедряется из файла плана на диске |
2040| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Путь к файлу плана. Внедряется |2066| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Путь к файлу плана. Внедряется |
2041| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Устаревшее. Claude Code принимает это поле, но игнорирует его. До версии v2.1.205 оно содержало разрешения на основе промптов, которые Claude запрашивал для реализации плана |2067| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Устаревшее. Claude Code принимает поле, но игнорирует его. До v2.1.205 оно содержало разрешения на основе промптов, которые Claude запрашивал для реализации плана |
2042 2068
2043В `PostToolUse` поле `tool_response` — это объект с полями `plan` и `filePath`, содержащими утверждённый план, а также внутренними флагами состояния. Читайте содержимое плана из `tool_response.plan`, а не перечитывайте файл с диска.2069В `PostToolUse` `tool_response` — это объект с полями `plan` и `filePath`, содержащими утверждённый план, а также внутренними флагами статуса. Читайте содержимое плана из `tool_response.plan`, а не перечитывайте файл с диска.
2044 2070
2045<h4 id="pretooluse-decision-control">2071<h4 id="pretooluse-decision-control">
2046 Управление решениями PreToolUse2072 Управление решениями PreToolUse
2047</h4>2073</h4>
2048 2074
2049Хуки `PreToolUse` могут управлять тем, будет ли выполнен вызов инструмента. В отличие от других хуков, использующих поле `decision` верхнего уровня, PreToolUse возвращает своё решение внутри объекта `hookSpecificOutput`. Это даёт более богатые возможности управления: четыре исхода (разрешить, запретить, запросить подтверждение или отложить), а также возможность изменить входные данные инструмента перед выполнением.2075Хуки `PreToolUse` могут управлять тем, будет ли выполнен вызов инструмента. В отличие от других хуков, использующих поле `decision` верхнего уровня, PreToolUse возвращает своё решение внутри объекта `hookSpecificOutput`. Это даёт более богатые возможности управления: четыре исхода (allow, deny, ask или defer), а также возможность изменять входные данные инструмента перед выполнением.
2050 2076
2051| Поле | Описание |2077| Поле | Описание |
2052| :- | :- |2078| :- | :- |
2053| `permissionDecision` | `"allow"` пропускает запрос разрешения, за исключением [действий, которые не подтверждаются автоматически ни в одном режиме](/docs/ru/permission-modes#actions-no-mode-auto-approves), [чтения с сетевых путей](/docs/ru/permissions#network-paths), а также `AskUserQuestion` и `ExitPlanMode`, которым нужен [`updatedInput` в паре с ним](#allow-with-updatedinput). `"deny"` предотвращает вызов инструмента. `"ask"` просит пользователя подтвердить. `"defer"` корректно завершает работу, чтобы инструмент можно было возобновить позже. [Правила запрета и подтверждения](/docs/ru/permissions#manage-permissions) по-прежнему проверяются независимо от того, что возвращает хук |2079| `permissionDecision` | `"allow"` пропускает запрос разрешения, за исключением [действий, которые не одобряет автоматически ни один режим](/docs/ru/permission-modes#actions-no-mode-auto-approves), [чтения по сетевым путям](/docs/ru/permissions#network-paths), а также `AskUserQuestion` и `ExitPlanMode`, для которых нужен [`updatedInput` в паре с ним](#allow-with-updatedinput). `"deny"` предотвращает вызов инструмента. `"ask"` просит пользователя подтвердить. `"defer"` корректно завершает работу, чтобы инструмент можно было возобновить позже. [Правила запрета и запроса](/docs/ru/permissions#manage-permissions) всё равно оцениваются независимо от того, что возвращает хук |
2054| `permissionDecisionReason` | Для `"ask"` показывается пользователю в запросе разрешения. Когда Claude Code [отклоняет вызов](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs) в запуске `-p`, где никто не может ответить на этот запрос, Claude вместо этого читает причину в результате инструмента. Для `"deny"` показывается Claude. Для `"allow"` и `"defer"` записывается только в [лог отладки](#debug-hooks) |2080| `permissionDecisionReason` | Для `"ask"` показывается пользователю в запросе разрешения. Когда Claude Code [запрещает вызов](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs) в запуске `-p`, где никто не может ответить на этот запрос, Claude вместо этого читает причину в результате инструмента. Для `"deny"` показывается Claude. Для `"allow"` и `"defer"` записывается только в [лог отладки](#debug-hooks) |
2055| `updatedInput` | Изменяет входные параметры инструмента перед выполнением. Заменяет весь объект входных данных, поэтому включайте неизменённые поля вместе с изменёнными. Claude Code проверяет правила разрешений и [пригодность к автоматическому переводу в фон](/docs/ru/tools-reference#foreground-commands-that-move-to-the-background) команды Bash по входным данным, которые возвращает ваш хук, а не по тем, что отправил Claude. Сочетайте с `"allow"` для автоматического одобрения или с `"ask"`, чтобы показать пользователю изменённые входные данные. Для `"defer"` игнорируется |2081| `updatedInput` | Изменяет входные параметры инструмента перед выполнением. Заменяет весь объект входных данных, поэтому включайте неизменённые поля вместе с изменёнными. Claude Code оценивает правила разрешений и [пригодность команды Bash для автоматического перевода в фон](/docs/ru/tools-reference#foreground-commands-that-move-to-the-background) по входным данным, которые возвращает ваш хук, а не по тем, что отправил Claude. Сочетайте с `"allow"` для автоматического одобрения или с `"ask"`, чтобы показать пользователю изменённые входные данные. Для `"defer"` игнорируется |
2056| `additionalContext` | Строка, добавляемая в контекст Claude вместе с результатом инструмента. Игнорируется, когда `permissionDecision` равен `"defer"`. См. [Добавление контекста для Claude](#add-context-for-claude) |2082| `additionalContext` | Строка, добавляемая в контекст Claude вместе с результатом инструмента. Игнорируется, когда `permissionDecision` равен `"defer"`. См. [Добавление контекста для Claude](#add-context-for-claude) |
2057 2083
2058Когда несколько хуков PreToolUse возвращают разные решения, приоритет такой: `deny` > `defer` > `ask` > `allow`.2084Когда несколько хуков PreToolUse возвращают разные решения, приоритет таков: `deny` > `defer` > `ask` > `allow`.
2059 2085
2060Хук, который блокирует, завершаясь с кодом 2, обрабатывается так же, как `"deny"`: Claude видит сообщение из stderr как причину отказа.2086Хук, который блокирует через выход с кодом 2, обрабатывается так же, как `"deny"`: Claude видит сообщение stderr как причину запрета.
2061 2087
2062Когда хук возвращает `"ask"`, запрос разрешения, показываемый пользователю, содержит метку, указывающую, откуда взялся хук: `[settings]` для хука из любого файла настроек или из frontmatter агента, `[plugin:<name>]` для хука плагина или `[skill]` для хука из frontmatter скилла. Это помогает пользователям понять, какой источник конфигурации запрашивает подтверждение.2088Когда хук возвращает `"ask"`, запрос разрешения, показываемый пользователю, содержит метку, указывающую, откуда взят хук: `[settings]` для хука из любого файла настроек или из frontmatter агента, `[plugin:<name>]` для хука плагина или `[skill]` для хука из frontmatter скилла. Это помогает пользователям понять, какой источник конфигурации запрашивает подтверждение.
2063 2089
2064`"ask"` от хука также принудительно вызывает запрос разрешения в [авторежиме](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode): классификатор по-прежнему может отклонить вызов инструмента, но не может одобрить его молча. До версии v2.1.211 классификатор мог одобрить команду Bash, выполняемую вне [песочницы](/docs/ru/sandboxing), не показывая запрос, затребованный хуком; при этом классификатор всё равно применял к этой команде собственные правила безопасности, а `"deny"` от хука всегда соблюдался.2090`"ask"` хука также принудительно вызывает запрос разрешения в [авторежиме](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode): классификатор по-прежнему может запретить вызов инструмента, но не может молча его одобрить. До v2.1.211 классификатор мог одобрить команду Bash, выполняемую вне [песочницы](/docs/ru/sandboxing), не показывая запрос, которого требовал хук; классификатор всё равно применял к этой команде собственные правила безопасности, а `"deny"` хука всегда соблюдался.
2065 2091
2066```json theme={null}2092```json theme={null}
2067{2093{
2078```2104```
2079 2105
2080<Note>2106<Note>
2081 Ранее PreToolUse использовал поля верхнего уровня `decision` и `reason`, но для этого события они объявлены устаревшими. Используйте вместо них `hookSpecificOutput.permissionDecision` и `hookSpecificOutput.permissionDecisionReason`. Устаревшие значения `"approve"` и `"block"` соответствуют `"allow"` и `"deny"`. Другие события, такие как PostToolUse и Stop, продолжают использовать поля верхнего уровня `decision` и `reason` в качестве текущего формата.2107 Ранее PreToolUse использовал поля `decision` и `reason` верхнего уровня, но для этого события они объявлены устаревшими. Используйте вместо них `hookSpecificOutput.permissionDecision` и `hookSpecificOutput.permissionDecisionReason`. Устаревшие значения `"approve"` и `"block"` соответствуют `"allow"` и `"deny"`. Другие события, такие как PostToolUse и Stop, по-прежнему используют `decision` и `reason` верхнего уровня в качестве текущего формата.
2082</Note>2108</Note>
2083 2109
2084<h4 id="allow-with-updatedinput">2110<h4 id="allow-with-updatedinput">
2085 Инструменты, требующие взаимодействия с пользователем2111 Инструменты, требующие взаимодействия с пользователем
2086</h4>2112</h4>
2087 2113
2088`AskUserQuestion` и `ExitPlanMode` требуют взаимодействия с пользователем. В [неинтерактивном режиме](/docs/ru/headless) с флагом `-p` Claude Code предлагает их только когда у запуска есть [хост разрешений](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs), который принимает запрос, например обратный вызов `canUseTool` в Agent SDK.2114`AskUserQuestion` и `ExitPlanMode` требуют взаимодействия с пользователем. В [неинтерактивном режиме](/docs/ru/headless) с флагом `-p` Claude Code предлагает их, только если у запуска есть [хост разрешений](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs), принимающий запрос, например callback `canUseTool` в Agent SDK.
2089 2115
2090Хук `PreToolUse` удовлетворяет этому требованию, если делает следующее:2116Хук `PreToolUse` удовлетворяет этому требованию, если он делает следующее:
2091 2117
20921. Читает входные данные инструмента из stdin21181. Считывает входные данные инструмента из stdin
20932. Собирает ответ через ваш собственный интерфейс21192. Собирает ответ через ваш собственный интерфейс
20943. Возвращает `permissionDecision: "allow"` вместе с `updatedInput`, содержащим ответ, чтобы инструмент выполнился без запроса21203. Возвращает `permissionDecision: "allow"` вместе с `updatedInput`, содержащим ответ, чтобы инструмент выполнился без запроса
2095 2121
2117}2143}
2118```2144```
2119 2145
2120Инструмент MCP, который сервер помечает с помощью [`_meta["anthropic/requiresUserInteraction"]`](/docs/ru/mcp#require-approval-for-a-specific-tool), устроен строже: хук не может пропустить его запрос подтверждения с помощью `"allow"`, с `updatedInput` или без него, поскольку Claude Code не может убедиться, что хук провёл взаимодействие, необходимое инструменту.2146MCP-инструмент, который сервер помечает с помощью [`_meta["anthropic/requiresUserInteraction"]`](/docs/ru/mcp#require-approval-for-a-specific-tool), обрабатывается строже: хук не может пропустить его запрос подтверждения с помощью `"allow"`, с `updatedInput` или без, поскольку Claude Code не может убедиться, что хук собрал взаимодействие, необходимое инструменту.
2121 2147
2122<h4 id="defer-a-tool-call-for-later">2148<h4 id="defer-a-tool-call-for-later">
2123 Отложить вызов инструмента на потом2149 Отложить вызов инструмента на потом
2124</h4>2150</h4>
2125 2151
2126`"defer"` предназначен для интеграций, которые запускают `claude -p` как подпроцесс и читают его вывод JSON, например приложения на Agent SDK или пользовательского интерфейса, построенного поверх Claude Code. Он позволяет вызывающему процессу приостановить Claude на вызове инструмента, собрать входные данные через собственный интерфейс и продолжить с того же места. Claude Code учитывает это значение только в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. В интерактивных сессиях он записывает в лог предупреждение и игнорирует результат хука.2152`"defer"` предназначен для интеграций, которые запускают `claude -p` как подпроцесс и читают его вывод JSON, например приложение на Agent SDK или пользовательский интерфейс, построенный поверх Claude Code. Он позволяет вызывающему процессу приостановить Claude на вызове инструмента, собрать входные данные через свой интерфейс и продолжить с того же места. Claude Code учитывает это значение только в [неинтерактивном режиме](/docs/ru/headless) с флагом `-p`. В интерактивных сессиях он записывает в лог предупреждение и игнорирует результат хука.
2127 2153
2128Типичный случай — инструмент `AskUserQuestion`: Claude хочет что-то спросить у пользователя, но нет терминала, в котором можно ответить. Запуск `-p` предлагает `AskUserQuestion` только когда у него есть [хост разрешений](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs), например инструмент MCP, передаваемый через `--permission-prompt-tool`, поэтому начинайте запуск с ним. Цикл работает так:2154Типичный случай — инструмент `AskUserQuestion`: Claude хочет что-то спросить у пользователя, но терминала для ответа нет. Запуск `-p` предлагает `AskUserQuestion` только при наличии [хоста разрешений](/docs/ru/headless#turn-off-permission-prompts-in-unattended-runs), например MCP-инструмента, который вы передаёте через `--permission-prompt-tool`, поэтому начинайте запуск с ним. Цикл работает так:
2129 2155
21301. Claude вызывает `AskUserQuestion`. Срабатывает хук `PreToolUse`.21561. Claude вызывает `AskUserQuestion`. Срабатывает хук `PreToolUse`.
21312. Хук возвращает `permissionDecision: "defer"`. Инструмент не выполняется. Процесс завершается с `stop_reason: "tool_deferred"`, а ожидающий вызов инструмента сохраняется в транскрипте.21572. Хук возвращает `permissionDecision: "defer"`. Инструмент не выполняется. Процесс завершается с `stop_reason: "tool_deferred"`, а ожидающий вызов инструмента сохраняется в транскрипте.
21323. Вызывающий процесс читает `deferred_tool_use` из результата SDK, показывает вопрос в собственном интерфейсе и ждёт ответа.21583. Вызывающий процесс читает `deferred_tool_use` из результата SDK, показывает вопрос в своём интерфейсе и ждёт ответа.
21334. Вызывающий процесс выполняет `claude -p --resume <session-id>` с тем же хостом разрешений. Тот же вызов инструмента снова вызывает `PreToolUse`.21594. Вызывающий процесс выполняет `claude -p --resume <session-id>` с тем же хостом разрешений. Тот же вызов инструмента снова вызывает `PreToolUse`.
21345. Хук возвращает `permissionDecision: "allow"` с ответом в `updatedInput`. Инструмент выполняется, и Claude продолжает работу.21605. Хук возвращает `permissionDecision: "allow"` с ответом в `updatedInput`. Инструмент выполняется, и Claude продолжает работу.
2135 2161
2149}2175}
2150```2176```
2151 2177
2152Ограничений по таймауту или количеству повторных попыток нет. Сессия хранится на диске, пока вы её не возобновите, с учётом очистки по сроку хранения [`cleanupPeriodDays`](/docs/ru/settings-reference#cleanupperioddays), которая по умолчанию удаляет файлы сессий через 30 дней в соответствии с [правилами очистки по сроку хранения](/docs/ru/claude-directory#cleaned-up-automatically). Если ответ не готов к моменту возобновления, хук может снова вернуть `"defer"`, и процесс завершится так же. Вызывающий процесс сам решает, когда выйти из цикла, в итоге вернув из хука `"allow"` или `"deny"`.2178Нет ни таймаута, ни ограничения на повторные попытки. Сессия остаётся на диске, пока вы её не возобновите, с учётом очистки по сроку хранения [`cleanupPeriodDays`](/docs/ru/settings-reference#cleanupperioddays), которая по умолчанию удаляет файлы сессий через 30 дней согласно [правилам очистки по сроку хранения](/docs/ru/claude-directory#cleaned-up-automatically). Если ответ не готов к моменту возобновления, хук может снова вернуть `"defer"`, и процесс завершится так же. Вызывающий процесс сам решает, когда выйти из цикла, в конечном итоге возвращая из хука `"allow"` или `"deny"`.
2153 2179
2154`"defer"` работает, только когда Claude делает в ходе один вызов инструмента. Если Claude делает несколько вызовов инструментов одновременно, `"defer"` игнорируется с предупреждением, и инструмент проходит обычный процесс проверки разрешений. Это ограничение существует потому, что при возобновлении можно повторно выполнить только один инструмент: нельзя отложить один вызов из пакета, не оставив остальные неразрешёнными.2180`"defer"` работает, только когда Claude делает один вызов инструмента за ход. Если Claude делает несколько вызовов инструментов одновременно, `"defer"` игнорируется с предупреждением, и инструмент проходит обычную процедуру проверки разрешений. Это ограничение существует потому, что при возобновлении можно повторно выполнить только один инструмент: нет способа отложить один вызов из пакета, не оставив остальные неразрешёнными.
2155 2181
2156Если отложенный инструмент больше недоступен при возобновлении, процесс завершается с `stop_reason: "tool_deferred_unavailable"` и `is_error: true` до срабатывания хука. Это происходит, когда MCP-сервер, предоставлявший инструмент, не подключён в возобновлённой сессии. Данные `deferred_tool_use` всё равно включаются, чтобы вы могли определить, какой инструмент пропал.2182Если отложенный инструмент больше недоступен при возобновлении, процесс завершается с `stop_reason: "tool_deferred_unavailable"` и `is_error: true` до срабатывания хука. Это происходит, когда MCP-сервер, предоставлявший инструмент, не подключён для возобновлённой сессии. Данные `deferred_tool_use` всё равно включаются, чтобы вы могли определить, какой инструмент пропал.
2157 2183
2158<Note>2184<Note>
2159 Чтобы возобновить отложенную сессию в режиме планирования, передайте [`--permission-prompt-tool`](/docs/ru/cli-reference#cli-flags) вместе с `--resume`, чтобы Claude Code мог представить план на утверждение. Другие условия см. в разделе [Возобновление в режиме планирования с `-p`](/docs/ru/sessions#resume-in-plan-mode-with-p). Требуется Claude Code v2.1.246 или новее.2185 Чтобы возобновить отложенную сессию в режиме планирования, передайте [`--permission-prompt-tool`](/docs/ru/cli-reference#cli-flags) вместе с `--resume`, чтобы Claude Code мог представить план на утверждение. Прочие условия см. в разделе [Возобновление в режиме планирования с `-p`](/docs/ru/sessions#resume-in-plan-mode-with-p). Требуется Claude Code v2.1.246 или новее.
2160 2186
2161 При возобновлении с `-p` Claude Code не восстанавливает никакой другой сохранённый режим разрешений. Он запускается в том режиме разрешений, в котором запустился бы новый запуск `claude -p`, поэтому снова передайте `--permission-mode` или `--dangerously-skip-permissions`, если отложенная сессия их использовала. При возобновлении с `claude --resume <session-id>` без `-p` Claude Code восстанавливает сохранённый режим разрешений, за исключениями, перечисленными в разделе [режим разрешений при возобновлении](/docs/ru/sessions#permission-mode-on-resume).2187 При возобновлении с `-p` Claude Code не восстанавливает никакой другой сохранённый режим разрешений. Он начинает запуск в том режиме разрешений, в котором начался бы новый запуск `claude -p`, поэтому снова передайте `--permission-mode` или `--dangerously-skip-permissions`, если отложенная сессия их использовала. При возобновлении с `claude --resume <session-id>` без `-p` Claude Code восстанавливает сохранённый режим разрешений, за исключениями, перечисленными в разделе [режим разрешений при возобновлении](/docs/ru/sessions#permission-mode-on-resume).
2162</Note>2188</Note>
2163 2189
2164<h3 id="permissionrequest">2190<h3 id="permissionrequest">
2165 PermissionRequest2191 PermissionRequest
2166</h3>2192</h3>
2167 2193
2168Выполняется, когда Claude Code собирается запросить у вас разрешение на использование инструмента. В сессиях, которые не могут показать запрос, например у фоновых субагентов в [неинтерактивном режиме](/docs/ru/headless), Claude Code всё равно запускает эти хуки, и если ни один хук не возвращает решение, он отклоняет вызов инструмента. Для вызова, который доходит до `--permission-prompt-tool` или [обратного вызова `canUseTool`](/docs/ru/agent-sdk/permissions) в Agent SDK, хуки выполняются параллельно с вашим хостом, и применяется решение того, кто решит первым.2194Выполняется, когда Claude Code собирается запросить у вас разрешение на использование инструмента. В сессиях, которые не могут показать запрос, например у фоновых субагентов в [неинтерактивном режиме](/docs/ru/headless), Claude Code всё равно запускает эти хуки, и если ни один хук не вернёт решение, он запрещает вызов инструмента. Для вызова, который доходит до `--permission-prompt-tool` или [callback `canUseTool`](/docs/ru/agent-sdk/permissions) в Agent SDK, хуки выполняются параллельно с вашим хостом, и применяется решение того, кто примет его первым.
2169Используйте [управление решениями PermissionRequest](#permissionrequest-decision-control), чтобы разрешать или запрещать от имени пользователя.2195Используйте [управление решениями PermissionRequest](#permissionrequest-decision-control), чтобы разрешать или запрещать от имени пользователя.
2170 2196
2171Используйте это событие, когда вам нужен сигнал в тот момент, когда Claude запрашивает разрешение на использование инструмента. Claude Code запускает хук [Notification](#notification) с типом `permission_prompt` только после того, как запрос прождёт около шести секунд.2197Используйте это событие, когда вам нужен сигнал в тот момент, когда Claude запрашивает разрешение на использование инструмента. Claude Code запускает хук [Notification](#notification) с типом `permission_prompt` только после того, как запрос прождёт около шести секунд.
2172 2198
2173Claude Code не запускает хуки PermissionRequest для [сетевого запроса](/docs/ru/sandboxing#network-isolation) команды в песочнице. Чтобы получить сигнал об этом запросе, используйте тип уведомления `permission_prompt`.2199Claude Code не запускает хуки PermissionRequest для [сетевого запроса](/docs/ru/sandboxing#network-isolation) команды, выполняемой в песочнице. Чтобы получить сигнал для такого запроса, используйте тип уведомления `permission_prompt`.
2174 2200
2175Сопоставляется с именем инструмента, с теми же значениями, что и PreToolUse.2201Сопоставляется с именем инструмента, с теми же значениями, что и PreToolUse.
2176 2202
2178 Входные данные PermissionRequest2204 Входные данные PermissionRequest
2179</h4>2205</h4>
2180 2206
2181Хуки PermissionRequest получают поля `tool_name` и `tool_input`, как хуки PreToolUse, но без `tool_use_id`. Для инструмента MCP они также получают объект [`mcp_server`](#pretooluse-input). Необязательный массив `permission_suggestions` содержит [обновления разрешений](#permission-update-entries), которые Claude Code предлагает для этого запроса, например добавление правила разрешения или изменение режима разрешений.2207Хуки PermissionRequest получают поля `tool_name` и `tool_input`, как и хуки PreToolUse, но без `tool_use_id`. Для инструмента MCP они также получают объект [`mcp_server`](#pretooluse-input). Необязательный массив `permission_suggestions` содержит [обновления разрешений](#permission-update-entries), которые Claude Code предлагает для этого запроса, например добавление разрешающего правила или изменение режима разрешений.
2182 2208
2183Массив `permission_suggestions` не является точным списком вариантов, которые вы видите, поскольку каждое диалоговое окно разрешения формирует собственные варианты. Некоторые диалоговые окна, например для редактирования файлов, вообще не читают этот массив и выводят варианты из самого запроса. Диалоговое окно, которое его читает, всё равно может скрыть вариант, предложение для которого остаётся в массиве, например когда [`allowManagedPermissionRulesOnly`](/docs/ru/settings-reference#allowmanagedpermissionrulesonly) скрывает варианты сохранения правил. Оно также может предлагать варианты без соответствующей записи предложения, например [**Yes, and switch to auto mode**](/docs/ru/permission-modes#switch-permission-modes), который меняет режим разрешений напрямую, а не через обновление разрешений.2209Массив `permission_suggestions` не является точным списком вариантов, которые вы видите, поскольку каждое диалоговое окно разрешения формирует собственные варианты. Некоторые диалоговые окна, например окно для правок файлов, вообще не читают этот массив и получают варианты из самого запроса. Диалоговое окно, которое читает массив, всё равно может скрыть вариант, предложение для которого остаётся в массиве, например когда [`allowManagedPermissionRulesOnly`](/docs/ru/settings-reference#allowmanagedpermissionrulesonly) скрывает варианты сохранения правил. Оно также может предлагать варианты, для которых нет записи в предложениях, например [**Yes, and switch to auto mode**](/docs/ru/permission-modes#switch-permission-modes), который меняет режим разрешений напрямую, а не через обновление разрешений.
2184 2210
2185Хуки PreToolUse выполняются перед каждым вызовом инструмента, независимо от того, требуется ли разрешение. Хуки PermissionRequest выполняются только когда Claude Code собирается запросить у вас разрешение или когда он иначе автоматически отклонил бы вызов, который не может показать запрос. Ни одно из этих событий не срабатывает для [`EndConversation`](/docs/ru/tools-reference#endconversation-tool-behavior).2211Хуки PreToolUse запускаются перед каждым вызовом инструмента, независимо от того, требуется ли для него разрешение. Хуки PermissionRequest запускаются только тогда, когда Claude Code собирается запросить у вас разрешение, или когда он в противном случае автоматически отклонил бы вызов, для которого невозможно показать запрос. Ни одно из этих событий не срабатывает для [`EndConversation`](/docs/ru/tools-reference#endconversation-tool-behavior).
2186 2212
2187```json theme={null}2213```json theme={null}
2188{2214{
2211 Управление решениями PermissionRequest2237 Управление решениями PermissionRequest
2212</h4>2238</h4>
2213 2239
2214Хуки `PermissionRequest` могут разрешать или отклонять запросы разрешений. Помимо [полей вывода JSON](#json-output), доступных всем хукам, скрипт хука может возвращать объект `decision` со следующими полями, специфичными для события:2240Хуки `PermissionRequest` могут разрешать или отклонять запросы разрешений. Помимо [полей вывода JSON](#json-output), доступных всем хукам, ваш скрипт хука может вернуть объект `decision` со следующими полями, специфичными для события:
2215 2241
2216| Поле | Описание |2242| Поле | Описание |
2217| :- | :- |2243| :- | :- |
2218| `behavior` | `"allow"` предоставляет разрешение, `"deny"` отклоняет его. [Правила запрета и подтверждения](/docs/ru/permissions#manage-permissions) всё равно применяются, поэтому хук, вернувший `"allow"`, не переопределяет подходящее правило запрета |2244| `behavior` | `"allow"` предоставляет разрешение, `"deny"` отклоняет его. [Правила запрета и запроса](/docs/ru/permissions#manage-permissions) всё равно проверяются, поэтому хук, возвращающий `"allow"`, не переопределяет совпадающее правило запрета |
2219| `updatedInput` | Только для `"allow"`: изменяет входные параметры инструмента перед выполнением. Заменяет весь объект входных данных, поэтому включайте неизменённые поля вместе с изменёнными. Изменённые входные данные повторно проверяются по правилам запрета и подтверждения |2245| `updatedInput` | Только для `"allow"`: изменяет входные параметры инструмента перед выполнением. Заменяет весь входной объект, поэтому включайте неизменённые поля вместе с изменёнными. Изменённые входные данные повторно проверяются на соответствие правилам запрета и запроса |
2220| `updatedPermissions` | Только для `"allow"`: массив [записей обновления разрешений](#permission-update-entries) для применения, например добавление правила разрешения или изменение режима разрешений сессии |2246| `updatedPermissions` | Только для `"allow"`: массив [записей обновления разрешений](#permission-update-entries) для применения, например добавление разрешающего правила или изменение режима разрешений сессии |
2221| `message` | Только для `"deny"`: сообщает Claude, почему в разрешении отказано |2247| `message` | Только для `"deny"`: сообщает Claude, почему разрешение было отклонено |
2222| `interrupt` | Только для `"deny"`: если `true`, останавливает Claude |2248| `interrupt` | Только для `"deny"`: если `true`, останавливает Claude |
2223 2249
2224Хук, завершающийся с кодом 2 без объекта `decision`, оставляет процесс разрешений без изменений, а его stderr отбрасывается. Чтобы предоставить или отклонить запрос, верните объект `decision`.2250Хук, завершающийся с кодом 2 без объекта `decision`, оставляет процесс обработки разрешения без изменений, а его stderr отбрасывается. Чтобы предоставить или отклонить запрос, верните объект `decision`.
2225 2251
2226```json theme={null}2252```json theme={null}
2227{2253{
2241 Записи обновления разрешений2267 Записи обновления разрешений
2242</h4>2268</h4>
2243 2269
2244Выходное поле `updatedPermissions` и [входное поле `permission_suggestions`](#permissionrequest-input) используют один и тот же массив объектов-записей. У каждой записи есть поле `type`, которое определяет остальные её поля, и поле `destination`, которое определяет, куда записывается изменение.2270Поле вывода `updatedPermissions` и [поле ввода `permission_suggestions`](#permissionrequest-input) используют один и тот же массив объектов-записей. Каждая запись имеет поле `type`, определяющее её остальные поля, и поле `destination`, которое управляет тем, куда записывается изменение.
2245 2271
2246| `type` | Поля | Действие |2272| `type` | Поля | Эффект |
2247| :- | :- | :- |2273| :- | :- | :- |
2248| `addRules` | `rules`, `behavior`, `destination` | Добавляет правила разрешений. `rules` — это массив объектов `{toolName, ruleContent?}`. Опустите `ruleContent`, чтобы правило соответствовало всему инструменту. `behavior` принимает значение `"allow"`, `"deny"` или `"ask"` |2274| `addRules` | `rules`, `behavior`, `destination` | Добавляет правила разрешений. `rules` — массив объектов `{toolName, ruleContent?}`. Опустите `ruleContent`, чтобы правило соответствовало всему инструменту. `behavior` принимает значения `"allow"`, `"deny"` или `"ask"` |
2249| `replaceRules` | `rules`, `behavior`, `destination` | Заменяет все правила с указанным `behavior` в `destination` на переданные `rules` |2275| `replaceRules` | `rules`, `behavior`, `destination` | Заменяет все правила с указанным `behavior` в `destination` на переданные `rules` |
2250| `removeRules` | `rules`, `behavior`, `destination` | Удаляет совпадающие правила с указанным `behavior` |2276| `removeRules` | `rules`, `behavior`, `destination` | Удаляет совпадающие правила с указанным `behavior` |
2251| `setMode` | `mode`, `destination` | Изменяет режим разрешений. Допустимые режимы: `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, а также `manual` как псевдоним для `default` |2277| `setMode` | `mode`, `destination` | Изменяет режим разрешений. Допустимые режимы: `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, а также `manual` как псевдоним для `default` |
2252| `addDirectories` | `directories`, `destination` | Добавляет рабочие каталоги. `directories` — это массив строк с путями |2278| `addDirectories` | `directories`, `destination` | Добавляет рабочие каталоги. `directories` — массив строк с путями |
2253| `removeDirectories` | `directories`, `destination` | Удаляет рабочие каталоги |2279| `removeDirectories` | `directories`, `destination` | Удаляет рабочие каталоги |
2254 2280
2255<Note>2281<Note>
2256 `setMode` со значением `bypassPermissions` действует только в том случае, если вы запустили сессию с уже доступным режимом обхода: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions` или `permissions.defaultMode: "bypassPermissions"` в [пользовательских настройках, `--settings` или управляемых настройках](/docs/ru/settings-reference#permissions-defaultmode). В противном случае обновление ничего не делает. Обновление также ничего не делает, когда [`permissions.disableBypassPermissionsMode`](/docs/ru/permissions#managed-settings) отключает этот режим или когда сессия запускается в [ограниченном режиме](/docs/ru/cli-reference#cli-flags).2282 `setMode` с `bypassPermissions` вступает в силу, только если вы запустили сессию, когда режим обхода уже был доступен: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions` или `permissions.defaultMode: "bypassPermissions"` в [пользовательских настройках, `--settings` или управляемых настройках](/docs/ru/settings-reference#permissions-defaultmode). В противном случае обновление ничего не делает. Обновление также ничего не делает, когда [`permissions.disableBypassPermissionsMode`](/docs/ru/permissions#managed-settings) отключает этот режим или когда сессия запускается в [ограниченном режиме](/docs/ru/cli-reference#cli-flags).
2257 2283
2258 `bypassPermissions` никогда не сохраняется как `defaultMode`, независимо от `destination`.2284 `bypassPermissions` никогда не сохраняется как `defaultMode`, независимо от `destination`.
2259</Note>2285</Note>
2260 2286
2261Поле `destination` в каждой записи определяет, останется ли изменение только в памяти или будет сохранено в файл настроек.2287Поле `destination` в каждой записи определяет, останется ли изменение в памяти или будет сохранено в файл настроек.
2262 2288
2263| `destination` | Куда записывается |2289| `destination` | Куда записывается |
2264| :- | :- |2290| :- | :- |
2265| `session` | только в памяти, отбрасывается при завершении сессии |2291| `session` | только в памяти, отбрасывается по завершении сессии |
2266| `localSettings` | `.claude/settings.local.json` |2292| `localSettings` | `.claude/settings.local.json` |
2267| `projectSettings` | `.claude/settings.json` |2293| `projectSettings` | `.claude/settings.json` |
2268| `userSettings` | `~/.claude/settings.json` |2294| `userSettings` | `~/.claude/settings.json` |
2269 2295
2270Хук может вернуть одну из полученных `permission_suggestions` в качестве собственного вывода `updatedPermissions`.2296Хук может вернуть одно из полученных `permission_suggestions` в качестве собственного вывода `updatedPermissions`.
2271 2297
2272<h3 id="posttooluse">2298<h3 id="posttooluse">
2273 PostToolUse2299 PostToolUse
2274</h3>2300</h3>
2275 2301
2276Выполняется сразу после успешного завершения инструмента.2302Запускается сразу после успешного завершения инструмента.
2277 2303
2278Сопоставляется по имени инструмента, значения те же, что и для PreToolUse.2304Сопоставляется по имени инструмента, с теми же значениями, что и PreToolUse.
2279 2305
2280Используйте более широкое сопоставление, когда имя инструмента не подходит в качестве фильтра:2306Используйте более широкое сопоставление, когда имя инструмента не подходит в качестве фильтра:
2281 2307
2282* Чтобы запускать хук после успешного завершения любого инструмента, опустите `matcher` или задайте ему значение `"*"`. Тогда ваш хук может сам определить, что изменилось, например выполнив `git status --porcelain`, который также выводит неотслеживаемые файлы, пропускаемые `git diff`. Для неудавшихся вызовов инструментов добавьте тот же хук в [PostToolUseFailure](#posttoolusefailure).2308* Чтобы запускать хук после успешного завершения любого инструмента, опустите `matcher` или установите его в `"*"`. Тогда ваш хук может сам определить, что изменилось, например выполнив `git status --porcelain`, который также перечисляет неотслеживаемые файлы, пропускаемые `git diff`. Для вызовов инструментов, завершившихся с ошибкой, добавьте тот же хук в [PostToolUseFailure](#posttoolusefailure).
2283* Чтобы запускать хук при изменении определённого файла на диске, независимо от того, что его записало, используйте [FileChanged](#filechanged). Claude Code не запускает хук `PostToolUse` с matcher `Edit|Write`, когда тот же файл перезаписывает команда `Bash` или процесс вне Claude Code.2309* Чтобы запускать хук при изменении определённого файла на диске, независимо от того, кто его записал, используйте [FileChanged](#filechanged). Claude Code не запускает хук `PostToolUse` с matcher `Edit|Write`, когда тот же файл перезаписывает команда `Bash` или процесс вне Claude Code.
2284 2310
2285<h4 id="posttooluse-input">2311<h4 id="posttooluse-input">
2286 Входные данные PostToolUse2312 Входные данные PostToolUse
2287</h4>2313</h4>
2288 2314
2289Хуки `PostToolUse` срабатывают после того, как инструмент уже успешно выполнился. Входные данные включают как `tool_input` — аргументы, переданные инструменту, — так и `tool_response` — возвращённый им результат. Точная схема обоих полей зависит от инструмента. Пути в `tool_input` для файловых инструментов приходят в том же формате, что и для [PreToolUse](#pretooluse-input): всегда абсолютные, с нативными разделителями платформы, то есть с обратными слешами в Windows. Для инструмента MCP входные данные также содержат объект [`mcp_server`](#pretooluse-input).2315Хуки `PostToolUse` срабатывают после того, как инструмент уже успешно выполнился. Входные данные включают как `tool_input` — аргументы, переданные инструменту, так и `tool_response` — возвращённый им результат. Точная схема обоих полей зависит от инструмента. Пути в `tool_input` файловых инструментов приходят в том же формате, что и для [PreToolUse](#pretooluse-input): всегда абсолютные, с нативными разделителями платформы, то есть с обратными слешами в Windows. Для инструмента MCP входные данные также содержат объект [`mcp_server`](#pretooluse-input).
2290 2316
2291```json theme={null}2317```json theme={null}
2292{2318{
2311 2337
2312| Поле | Описание |2338| Поле | Описание |
2313| :- | :- |2339| :- | :- |
2314| `duration_ms` | Необязательное. Время выполнения инструмента в миллисекундах. Не включает время, проведённое в запросах разрешения и хуках PreToolUse |2340| `duration_ms` | Необязательное. Время выполнения инструмента в миллисекундах. Не включает время, проведённое в запросах разрешений и хуках PreToolUse |
2315 2341
2316<h4 id="posttooluse-decision-control">2342<h4 id="posttooluse-decision-control">
2317 Управление решениями PostToolUse2343 Управление решениями PostToolUse
2318</h4>2344</h4>
2319 2345
2320Хуки `PostToolUse` могут передавать Claude обратную связь после выполнения инструмента. Помимо [выходных полей JSON](#json-output), доступных всем хукам, ваш скрипт хука может возвращать следующие поля, специфичные для события:2346Хуки `PostToolUse` могут предоставлять Claude обратную связь после выполнения инструмента. Помимо [полей вывода JSON](#json-output), доступных всем хукам, ваш скрипт хука может вернуть следующие поля, специфичные для события:
2321 2347
2322| Поле | Описание |2348| Поле | Описание |
2323| :- | :- |2349| :- | :- |
2324| `decision` | `"block"` добавляет `reason` рядом с результатом инструмента. Claude по-прежнему видит исходный вывод; чтобы заменить его, используйте `updatedToolOutput` |2350| `decision` | `"block"` добавляет `reason` рядом с результатом инструмента. Claude по-прежнему видит исходный вывод; чтобы заменить его, используйте `updatedToolOutput` |
2325| `reason` | Пояснение, показываемое Claude, когда `decision` равно `"block"` |2351| `reason` | Объяснение, показываемое Claude, когда `decision` равно `"block"` |
2326| `additionalContext` | Строка, добавляемая в контекст Claude вместе с результатом инструмента. См. [Добавление контекста для Claude](#add-context-for-claude) |2352| `additionalContext` | Строка, добавляемая в контекст Claude вместе с результатом инструмента. См. [Добавление контекста для Claude](#add-context-for-claude) |
2327| `classifierContext` | Короткая заметка о результате этого вызова для классификатора [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), а не для Claude. См. [Аннотирование результата для классификатора авторежима](#annotate-a-result-for-the-auto-mode-classifier). Требуется Claude Code v2.1.236 или новее |2353| `classifierContext` | Краткое примечание о результате этого вызова, предназначенное для классификатора [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), а не для Claude. См. [Аннотирование результата для классификатора авторежима](#annotate-a-result-for-the-auto-mode-classifier). Требуется Claude Code v2.1.236 или новее |
2328| `updatedToolOutput` | Заменяет вывод инструмента переданным значением до того, как он будет отправлен Claude. Значение должно соответствовать форме вывода инструмента |2354| `updatedToolOutput` | Заменяет вывод инструмента указанным значением до отправки его Claude. Значение должно соответствовать форме вывода инструмента |
2329| `updatedMCPToolOutput` | Заменяет вывод только для [инструментов MCP](#match-mcp-tools). Предпочтительнее использовать `updatedToolOutput`, который работает для всех инструментов |2355| `updatedMCPToolOutput` | Заменяет вывод только для [инструментов MCP](#match-mcp-tools). Предпочтительнее использовать `updatedToolOutput`, который работает для всех инструментов |
2330 2356
2331В примере ниже заменяется вывод вызова `Bash`. Значение замены соответствует форме вывода инструмента `Bash`:2357Пример ниже заменяет вывод вызова `Bash`. Значение замены соответствует форме вывода инструмента `Bash`:
2332 2358
2333```json theme={null}2359```json theme={null}
2334{2360{
2346```2372```
2347 2373
2348<Warning>2374<Warning>
2349 `updatedToolOutput` меняет только то, что видит Claude. К моменту срабатывания хука инструмент уже выполнился, поэтому все записанные файлы, выполненные команды или отправленные сетевые запросы уже вступили в силу. Телеметрия, такая как спаны инструментов OpenTelemetry и аналитические события, также фиксирует исходный вывод до запуска хука. Чтобы предотвратить или изменить вызов инструмента до его выполнения, используйте вместо этого хук [PreToolUse](#pretooluse).2375 `updatedToolOutput` изменяет только то, что видит Claude. К моменту срабатывания хука инструмент уже выполнился, поэтому все записанные файлы, выполненные команды или отправленные сетевые запросы уже вступили в силу. Телеметрия, такая как спаны инструментов OpenTelemetry и аналитические события, также фиксирует исходный вывод до запуска хука. Чтобы предотвратить или изменить вызов инструмента до его выполнения, используйте вместо этого хук [PreToolUse](#pretooluse).
2350 2376
2351 Значение замены должно соответствовать форме вывода инструмента. Встроенные инструменты возвращают структурированные объекты, а не простые строки. Например, `Bash` возвращает объект с полями `stdout`, `stderr`, `interrupted` и `isImage`. Для встроенных инструментов значение, не соответствующее схеме вывода инструмента, игнорируется, и используется исходный вывод. Вывод инструментов MCP передаётся без проверки схемы. Удаление сведений об ошибках, которые нужны Claude, может привести к тому, что он продолжит работу на основе ложного предположения.2377 Значение замены должно соответствовать форме вывода инструмента. Встроенные инструменты возвращают структурированные объекты, а не простые строки. Например, `Bash` возвращает объект с полями `stdout`, `stderr`, `interrupted` и `isImage`. Для встроенных инструментов значение, не соответствующее схеме вывода инструмента, игнорируется, и используется исходный вывод. Вывод инструментов MCP передаётся без проверки схемы. Удаление сведений об ошибках, которые нужны Claude, может привести к тому, что он продолжит работу на основе ложного предположения.
2352</Warning>2378</Warning>
2355 Аннотирование результата для классификатора авторежима2381 Аннотирование результата для классификатора авторежима
2356</h4>2382</h4>
2357 2383
2358Верните `classifierContext`, чтобы отправить короткую заметку о результате вызова инструмента классификатору [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), а не Claude. Классификатор [никогда не получает сами результаты инструментов](/docs/ru/permission-modes#how-the-classifier-evaluates-actions), поэтому это поле — поддерживаемый способ сообщить ему что-либо о том, что вернул вызов, прежде чем он будет проверять последующие действия. Для этого поля требуется Claude Code v2.1.236 или новее.2384Верните `classifierContext`, чтобы отправить краткое примечание о результате вызова инструмента классификатору [авторежима](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode), а не Claude. Классификатор [никогда не получает сами результаты инструментов](/docs/ru/permission-modes#how-the-classifier-evaluates-actions), поэтому это поле — поддерживаемый способ сообщить ему что-то о том, что вернул вызов, прежде чем он будет проверять последующие действия. Для этого поля требуется Claude Code v2.1.236 или новее.
2359 2385
2360В примере ниже классификатору сообщается, откуда получен вывод запроса:2386Пример ниже сообщает классификатору, откуда получен вывод запроса:
2361 2387
2362```json theme={null}2388```json theme={null}
2363{2389{
2368}2394}
2369```2395```
2370 2396
2371Какой вес классификатор придаёт заметке, зависит от того, где вы настроили хук:2397Какой вес классификатор придаёт примечанию, зависит от того, где вы настроили хук:
2372 2398
2373* **Хуки, настроенные в Claude Code**: для хуков из файлов настроек, плагинов, скиллов и frontmatter агентов классификатор рассматривает заметку как непроверенный контекст, предоставленный приложением. Заметка никогда не устанавливает намерение пользователя, и если в ней утверждается, что вы что-то одобрили или запросили, классификатор сверяет это утверждение с вашими собственными сообщениями в диалоге2399* **Хуки, настроенные в Claude Code**: для хуков из файлов настроек, плагинов, скиллов и frontmatter агентов классификатор рассматривает примечание как непроверенный контекст, предоставленный приложением. Примечание никогда не устанавливает намерение пользователя, и если оно утверждает, что вы что-то одобрили или запросили, классификатор сверяет это утверждение с вашими собственными сообщениями в диалоге
2374* **Внутрипроцессные обратные вызовы Agent SDK**: когда приложение, встраивающее Claude Code, регистрирует хук как [обратный вызов TypeScript SDK](/docs/ru/agent-sdk/hooks) и возвращает заметку во время активной сессии, классификатор может рассматривать переданное в заметке утверждение пользователя как намерение пользователя. Такое утверждение может удовлетворить требование согласия, которое классификатор принял бы из отправленного вами сообщения, но оно никогда не снимает блокировку, которую не смогло бы снять и ваше собственное сообщение. После возобновления сессии Claude Code рассматривает восстановленные заметки как непроверенный контекст. Когда хуки из обеих групп аннотируют один и тот же вызов, классификатор рассматривает объединённую заметку как непроверенную2400* **Внутрипроцессные обратные вызовы Agent SDK**: когда приложение, встраивающее Claude Code, регистрирует хук как [обратный вызов TypeScript SDK](/docs/ru/agent-sdk/hooks) и возвращает примечание во время активной сессии, классификатор может учитывать переданное в примечании утверждение пользователя как намерение пользователя. Такое утверждение может удовлетворить требование согласия, которое классификатор принял бы от отправленного вами сообщения, но оно никогда не снимает блокировку, которую не смогло бы снять и ваше собственное сообщение. После возобновления сессии Claude Code рассматривает восстановленные примечания как непроверенный контекст. Когда хуки из обеих групп аннотируют один и тот же вызов, классификатор рассматривает объединённое примечание как непроверенное
2375 2401
2376Claude Code применяет следующие ограничения при доставке заметки:2402При доставке примечания Claude Code применяет следующие ограничения:
2377 2403
2378* **Длина**: Claude Code ограничивает заметки для одного вызова инструмента 2000 символами и обрезает остальное. Ограничение общее для всех хуков, отвечающих на этот вызов2404* **Длина**: Claude Code ограничивает примечания для одного вызова инструмента 2000 символами и обрезает остальное. Ограничение общее для всех хуков, отвечающих на этот вызов
2379* **Только синхронные ответы**: Claude Code игнорирует это поле в ответе хука, который [выполняется в фоне](#run-hooks-in-the-background), потому что такой ответ приходит уже после того, как Claude Code зафиксирует результат инструмента2405* **Только синхронные ответы**: Claude Code игнорирует это поле в ответе хука, который [выполняется в фоне](#run-hooks-in-the-background), поскольку такой ответ приходит после того, как Claude Code записал результат инструмента
2380* **Вызовы, которые классификатор не фиксирует**: транскрипт классификатора опускает поиск только для чтения, такой как чтение файлов и поиск. Claude Code отбрасывает заметку, прикреплённую к одному из таких вызовов2406* **Вызовы, которые классификатор не записывает**: транскрипт классификатора не включает операции только для чтения, такие как чтение файлов и поиск. Claude Code отбрасывает примечание, прикреплённое к одному из таких вызовов
2381* **Взаимодействие с перезаписью**: когда заметка описывает вывод, который вы заменяете с помощью `updatedToolOutput`, возвращайте оба поля в одном и том же ответе хука. Claude Code отбрасывает заметку, если эта перезапись отклонена или её заменяет перезапись другого хука. Claude Code доставляет заметку, возвращённую без перезаписи, даже если другой хук перезаписывает вывод2407* **Взаимодействие с перезаписью**: когда примечание описывает вывод, который вы заменяете с помощью `updatedToolOutput`, возвращайте оба поля в одном ответе хука. Claude Code отбрасывает примечание, если эта перезапись отклонена или её заменяет перезапись другого хука. Claude Code доставляет примечание, возвращённое без перезаписи, даже если другой хук перезаписывает вывод
2382 2408
2383<Warning>2409<Warning>
2384 Классификатор воспринимает содержимое, которое вы помещаете в `classifierContext`, как информацию от приложения, в котором размещена сессия, поэтому не копируйте туда недоверенный вывод инструментов или сторонний текст. Ограничьте заметку коротким утверждением об этом одном вызове, например фактом о его происхождении или утверждением пользователя о нём; не используйте это поле для доставки несвязанных сообщений или потока событий.2410 Классификатор читает содержимое, помещённое вами в `classifierContext`, как информацию от приложения, в котором размещена сессия, поэтому не копируйте в него ненадёжный вывод инструментов или сторонний текст. Ограничивайте примечание кратким утверждением об этом одном вызове, например фактом о его происхождении или утверждением пользователя о нём; не используйте это поле для доставки посторонних сообщений или потока событий.
2385</Warning>2411</Warning>
2386 2412
2387<h3 id="posttoolusefailure">2413<h3 id="posttoolusefailure">
2388 PostToolUseFailure2414 PostToolUseFailure
2389</h3>2415</h3>
2390 2416
2391Выполняется, когда инструмент, начавший выполнение, завершается с ошибкой: инструмент выбросил ошибку или инструмент MCP вернул результат с ошибкой. Используйте его, чтобы логировать сбои, отправлять оповещения или давать Claude корректирующую обратную связь.2417Запускается, когда инструмент, начавший выполнение, завершается с ошибкой: инструмент выбросил ошибку или инструмент MCP вернул результат с ошибкой. Используйте это для логирования сбоев, отправки оповещений или предоставления Claude корректирующей обратной связи.
2392 2418
2393Сопоставляется по имени инструмента, значения те же, что и для PreToolUse.2419Сопоставляется по имени инструмента, с теми же значениями, что и PreToolUse.
2394 2420
2395<Note>2421<Note>
2396 Это событие не срабатывает для вызовов инструментов, отклонённых до выполнения: неизвестное имя инструмента, входные данные, не прошедшие проверку схемы или специфичную для инструмента проверку, либо отказ в разрешении. Отклонения при проверке возвращаются как результаты `tool_use_error` и происходят до запуска хуков, поэтому они не вызывают ни `PreToolUse`, ни `PostToolUseFailure`. Отказы в разрешении вызывают `PreToolUse`, но не это событие; см. [PermissionDenied](#permissiondenied).2422 Это событие не срабатывает для вызовов инструментов, отклонённых до выполнения: неизвестное имя инструмента, входные данные, не прошедшие проверку схемы или специфичную для инструмента валидацию, или отказ в разрешении. Отклонения при валидации возвращаются как результаты `tool_use_error` и происходят до запуска хуков, поэтому не вызывают ни `PreToolUse`, ни `PostToolUseFailure`. Отказы в разрешении вызывают `PreToolUse`, но не это событие; см. [PermissionDenied](#permissiondenied).
2397</Note>2423</Note>
2398 2424
2399<h4 id="posttoolusefailure-input">2425<h4 id="posttoolusefailure-input">
2423 2449
2424| Поле | Описание |2450| Поле | Описание |
2425| :- | :- |2451| :- | :- |
2426| `error` | Строка с описанием того, что пошло не так. Формат зависит от инструмента, завершившегося с ошибкой |2452| `error` | Строка, описывающая, что пошло не так. Формат зависит от инструмента, завершившегося с ошибкой |
2427| `is_interrupt` | Необязательное логическое значение. True, когда сбой дошёл до Claude Code как прерывание, а не как ошибка, о которой сообщил инструмент. Отмена работающего инструмента не вызывает этот хук; вместо этого результат инструмента содержит сообщение о прерывании |2453| `is_interrupt` | Необязательное логическое значение. True, когда сбой дошёл до Claude Code как прерывание, а не как ошибка, о которой сообщил инструмент. Отмена выполняющегося инструмента не вызывает этот хук; вместо этого результат инструмента содержит сообщение о прерывании |
2428| `duration_ms` | Необязательное. Время выполнения инструмента в миллисекундах. Не включает время, проведённое в запросах разрешения и хуках PreToolUse |2454| `duration_ms` | Необязательное. Время выполнения инструмента в миллисекундах. Не включает время, проведённое в запросах разрешений и хуках PreToolUse |
2429 2455
2430Строка `error`, как правило, совпадает с текстом, который Claude получает в качестве результата неудавшегося инструмента. Её формат зависит от инструмента и типа сбоя. Ориентируйте логику хука на `tool_name`, `is_interrupt` и первую строку `Exit code N`; остальную часть строки рассматривайте как текст для отображения, а не как стабильный формат.2456Строка `error` обычно совпадает с текстом, который Claude получает как результат неудавшегося инструмента. Её формат зависит от инструмента и сбоя. Ориентируйте свой хук на `tool_name`, `is_interrupt` и первую строку `Exit code N`; остальную часть строки рассматривайте как текст для отображения, а не как стабильный формат.
2431 2457
2432* Для Bash и PowerShell команда, которая выполнилась и завершилась, даёт первую строку `Exit code N`, а затем весь вывод команды одним блоком, в котором stdout и stderr перемешаны2458* Для Bash и PowerShell команда, которая выполнилась и завершилась, даёт первую строку `Exit code N`, а затем любой вывод команды одним блоком, где stdout и stderr перемежаются
2433* Данные события также могут содержать просто сообщение о сбое без строки с кодом выхода, если Claude Code не смог запустить сам процесс оболочки2459* Данные события также могут содержать просто сообщение о сбое без строки с кодом выхода, когда Claude Code не смог запустить сам процесс оболочки
2434* Claude Code обрезает середину длинных строк, вставляя маркер `... [N characters truncated] ...`, и может добавлять собственные строки, например `Command timed out after 2m 0s`2460* Claude Code обрезает длинные строки посередине вокруг маркера `... [N characters truncated] ...` и может вставлять собственные строки, например `Command timed out after 2m 0s`
2435 2461
2436<h4 id="posttoolusefailure-decision-control">2462<h4 id="posttoolusefailure-decision-control">
2437 Управление решениями PostToolUseFailure2463 Управление решениями PostToolUseFailure
2438</h4>2464</h4>
2439 2465
2440Хуки `PostToolUseFailure` могут передавать Claude контекст после сбоя инструмента. Помимо [выходных полей JSON](#json-output), доступных всем хукам, ваш скрипт хука может возвращать следующие поля, специфичные для события:2466Хуки `PostToolUseFailure` могут предоставлять Claude контекст после сбоя инструмента. Помимо [полей вывода JSON](#json-output), доступных всем хукам, ваш скрипт хука может вернуть следующие поля, специфичные для события:
2441 2467
2442| Поле | Описание |2468| Поле | Описание |
2443| :- | :- |2469| :- | :- |
2456 PostToolBatch2482 PostToolBatch
2457</h3>2483</h3>
2458 2484
2459Выполняется один раз после того, как все вызовы инструментов в пакете завершены, перед тем как Claude Code отправит следующий запрос модели. `PostToolUse` срабатывает один раз для каждого инструмента, а значит, срабатывает параллельно, когда Claude делает параллельные вызовы инструментов. `PostToolBatch` срабатывает ровно один раз с полным пакетом, поэтому это подходящее место для внедрения контекста, который зависит от набора выполненных инструментов, а не от какого-то одного инструмента. Для этого события нет matcher.2485Запускается один раз после того, как все вызовы инструментов в пакете завершены, до того как Claude Code отправит следующий запрос модели. `PostToolUse` срабатывает один раз для каждого инструмента, а значит, срабатывает параллельно, когда Claude делает параллельные вызовы инструментов. `PostToolBatch` срабатывает ровно один раз со всем пакетом, поэтому это подходящее место для внедрения контекста, который зависит от набора выполненных инструментов, а не от какого-либо одного инструмента. Для этого события нет matcher.
2460 2486
2461<h4 id="posttoolbatch-input">2487<h4 id="posttoolbatch-input">
2462 Входные данные PostToolBatch2488 Входные данные PostToolBatch
2463</h4>2489</h4>
2464 2490
2465Помимо [общих входных полей](#common-input-fields), хуки PostToolBatch получают `tool_calls` — массив, описывающий каждый вызов инструмента в пакете:2491Помимо [общих полей входных данных](#common-input-fields), хуки PostToolBatch получают `tool_calls` — массив, описывающий каждый вызов инструмента в пакете:
2466 2492
2467```json theme={null}2493```json theme={null}
2468{2494{
2488}2514}
2489```2515```
2490 2516
2491`tool_response` содержит то же содержимое, которое модель получает в соответствующем блоке `tool_result`. Значение — это сериализованная строка или массив блоков содержимого, точно в том виде, в каком его выдал инструмент. Для `Read` это означает текст с префиксами номеров строк, а не сырое содержимое файла. Ответы могут быть большими, поэтому разбирайте только нужные вам поля.2517`tool_response` содержит то же содержимое, которое модель получает в соответствующем блоке `tool_result`. Значение — это сериализованная строка или массив блоков содержимого, ровно в том виде, в каком его выдал инструмент. Для `Read` это означает текст с префиксами номеров строк, а не необработанное содержимое файла. Ответы могут быть большими, поэтому разбирайте только нужные поля.
2492 2518
2493<Note>2519<Note>
2494 Форма `tool_response` отличается от формы в `PostToolUse`. `PostToolUse` передаёт структурированный объект `Output` инструмента, например `{filePath: "...", type: "create"}` для `Write`; `PostToolBatch` передаёт сериализованное содержимое `tool_result`, которое видит модель.2520 Форма `tool_response` отличается от формы в `PostToolUse`. `PostToolUse` передаёт структурированный объект `Output` инструмента, например `{filePath: "...", type: "create"}` для `Write`; `PostToolBatch` передаёт сериализованное содержимое `tool_result`, которое видит модель.
2498 Управление решениями PostToolBatch2524 Управление решениями PostToolBatch
2499</h4>2525</h4>
2500 2526
2501Хуки `PostToolBatch` могут внедрять контекст для Claude. Помимо [выходных полей JSON](#json-output), доступных всем хукам, ваш скрипт хука может возвращать следующие поля, специфичные для события:2527Хуки `PostToolBatch` могут внедрять контекст для Claude. Помимо [полей вывода JSON](#json-output), доступных всем хукам, ваш скрипт хука может вернуть следующие поля, специфичные для события:
2502 2528
2503| Поле | Описание |2529| Поле | Описание |
2504| :- | :- |2530| :- | :- |
2505| `additionalContext` | Строка контекста, внедряемая один раз перед следующим вызовом модели. Подробности доставки, что в неё помещать и как возобновлённые сессии обрабатывают прошлые значения, см. в разделе [Добавление контекста для Claude](#add-context-for-claude) |2531| `additionalContext` | Строка контекста, внедряемая один раз перед следующим вызовом модели. См. [Добавление контекста для Claude](#add-context-for-claude), где описаны подробности доставки, что в неё помещать и как возобновлённые сессии обрабатывают прошлые значения |
2506 2532
2507```json theme={null}2533```json theme={null}
2508{2534{
2513}2539}
2514```2540```
2515 2541
2516Возврат `decision: "block"` или `continue: false` останавливает агентный цикл перед следующим вызовом модели. Сообщение о блокировке берётся из JSON-поля `reason` или `stopReason` либо из stderr при коде выхода 2. Вы видите его как предупреждение в транскрипте, и оно остаётся в диалоге, поэтому Claude видит его, когда диалог продолжается.2542Возврат `decision: "block"` или `continue: false` останавливает агентный цикл перед следующим вызовом модели. Сообщение о блокировке берётся из JSON-поля `reason` или `stopReason` либо из stderr при коде выхода 2. Вы видите его как предупреждение в транскрипте, и оно остаётся в диалоге, поэтому Claude видит его при продолжении диалога.
2517 2543
2518<h3 id="permissiondenied">2544<h3 id="permissiondenied">
2519 PermissionDenied2545 PermissionDenied
2520</h3>2546</h3>
2521 2547
2522Выполняется, когда [авторежим](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode) отклоняет вызов инструмента, в том числе когда он отклоняет вызов без вердикта классификатора, потому что [проверка безопасности, отдельная от авторежима, отклонила собственный запрос классификатора](/docs/ru/errors#auto-mode-cannot-determine-the-safety-of-an-action) или его ответ не удалось разобрать. Этот хук срабатывает только в авторежиме: он не запускается, когда вы вручную отклоняете диалоговое окно разрешения, когда хук `PreToolUse` блокирует вызов или когда срабатывает правило `deny`. Используйте его, чтобы логировать отказы, корректировать конфигурацию или сообщать модели, что она может повторить попытку вызова инструмента.2548Запускается, когда [авторежим](/docs/ru/permission-modes#eliminate-prompts-with-auto-mode) отклоняет вызов инструмента, в том числе когда он отклоняет его без вердикта классификатора, потому что [проверка безопасности, отдельная от авторежима, отклонила собственный запрос классификатора](/docs/ru/errors#auto-mode-cannot-determine-the-safety-of-an-action) или его ответ не удалось разобрать. Этот хук срабатывает только в авторежиме: он не запускается, когда вы вручную отклоняете диалоговое окно разрешения, когда хук `PreToolUse` блокирует вызов или когда срабатывает правило `deny`. Используйте его для логирования отказов, корректировки конфигурации или для того, чтобы сообщить модели, что она может повторить попытку вызова инструмента.
2523 2549
2524Сопоставляется по имени инструмента, значения те же, что и для PreToolUse.2550Сопоставляется по имени инструмента, с теми же значениями, что и PreToolUse.
2525 2551
2526<h4 id="permissiondenied-input">2552<h4 id="permissiondenied-input">
2527 Входные данные PermissionDenied2553 Входные данные PermissionDenied
2528</h4>2554</h4>
2529 2555
2530Помимо [общих входных полей](#common-input-fields), хуки PermissionDenied получают `tool_name`, `tool_input`, `tool_use_id` и `reason`. Для инструмента MCP они также получают объект [`mcp_server`](#pretooluse-input).2556Помимо [общих полей входных данных](#common-input-fields), хуки PermissionDenied получают `tool_name`, `tool_input`, `tool_use_id` и `reason`. Для инструмента MCP они также получают объект [`mcp_server`](#pretooluse-input).
2531 2557
2532```json theme={null}2558```json theme={null}
2533{2559{
2548 2574
2549| Поле | Описание |2575| Поле | Описание |
2550| :- | :- |2576| :- | :- |
2551| `reason` | Причина отказа. Для вердикта классификатора в большинстве сессий в ней указывается сработавшее правило в квадратных скобках, например `[Data Exfiltration]`; другие формы см. в разделе [Просмотр отказов](/docs/ru/auto-mode-config#review-denials). Для [отказа без вердикта](#permissiondenied-decision-control) она начинается с `Auto mode could not evaluate this action and is blocking it for safety`. Для отказа из-за недоступности модели классификатора это фиксированный текст `Classifier unavailable` |2577| `reason` | Причина отказа. Для вердикта классификатора в большинстве сессий содержит название сработавшего правила в квадратных скобках, например `[Data Exfiltration]`; другие формы см. в разделе [Просмотр отказов](/docs/ru/auto-mode-config#review-denials). Для [отказа без вердикта](#permissiondenied-decision-control) начинается с `Auto mode could not evaluate this action and is blocking it for safety`. Для отказа из-за недоступности модели классификатора это фиксированный текст `Classifier unavailable` |
2552 2578
2553<h4 id="permissiondenied-decision-control">2579<h4 id="permissiondenied-decision-control">
2554 Управление решениями PermissionDenied2580 Управление решениями PermissionDenied
2555</h4>2581</h4>
2556 2582
2557Хуки PermissionDenied могут сообщить модели, что она может повторить попытку отклонённого вызова инструмента. Верните JSON-объект с `hookSpecificOutput.retry`, равным `true`:2583Хуки PermissionDenied могут сообщить модели, что она может повторить попытку отклонённого вызова инструмента. Верните JSON-объект с `hookSpecificOutput.retry`, установленным в `true`:
2558 2584
2559```json theme={null}2585```json theme={null}
2560{2586{
2567 2593
2568Когда `retry` равно `true`, Claude Code добавляет в диалог сообщение, сообщающее модели, что она может повторить попытку вызова инструмента. Сам отказ Claude Code не отменяет. Если ваш хук не возвращает JSON или возвращает `retry: false`, отказ остаётся в силе, и модель получает исходное сообщение об отклонении.2594Когда `retry` равно `true`, Claude Code добавляет в диалог сообщение, сообщающее модели, что она может повторить попытку вызова инструмента. Сам отказ Claude Code не отменяет. Если ваш хук не возвращает JSON или возвращает `retry: false`, отказ остаётся в силе, и модель получает исходное сообщение об отклонении.
2569 2595
2570Claude Code игнорирует `retry: true`, когда классификатор не вынес [вердикта по действию](/docs/ru/errors#auto-mode-cannot-determine-the-safety-of-an-action): его ответ не удалось разобрать или проверка безопасности, отдельная от авторежима, отклонила собственный запрос классификатора. Для таких отказов Claude Code уже сообщает модели в сообщении об отклонении, следует ли повторить попытку позже или двигаться дальше.2596Claude Code игнорирует `retry: true`, когда классификатор [не вынес вердикта по действию](/docs/ru/errors#auto-mode-cannot-determine-the-safety-of-an-action): его ответ не удалось разобрать или проверка безопасности, отдельная от авторежима, отклонила собственный запрос классификатора. Для таких отказов Claude Code уже сообщает модели в сообщении об отклонении, следует ли повторить попытку позже или двигаться дальше.
2571 2597
2572<h3 id="notification">2598<h3 id="notification">
2573 Notification2599 Notification
2574</h3>2600</h3>
2575 2601
2576Выполняется, когда Claude Code отправляет уведомления. Сопоставляется по типу уведомления. Опустите matcher, чтобы запускать хуки для всех типов уведомлений.2602Запускается, когда Claude Code отправляет уведомления. Сопоставляется по типу уведомления. Опустите matcher, чтобы запускать хуки для всех типов уведомлений.
2577 2603
2578Вы получаете эти события хуков даже при отключённых уведомлениях рабочего стола: настройка `preferredNotifChannel`, включая `notifications_disabled`, меняет только способ оповещения, а не то, запускается ли ваш хук.2604Вы получаете эти события хуков даже при отключённых уведомлениях на рабочем столе: настройка `preferredNotifChannel`, включая `notifications_disabled`, меняет только способ оповещения, но не то, запускается ли ваш хук.
2579 2605
2580| Matcher | Когда срабатывает |2606| Matcher | Когда срабатывает |
2581| :- | :- |2607| :- | :- |
2582| `permission_prompt` | Claude нужно, чтобы вы подтвердили использование инструмента или [сетевой запрос](/docs/ru/sandboxing#network-isolation) команды в песочнице, и запрос ожидает около шести секунд |2608| `permission_prompt` | Claude нужно ваше подтверждение для использования инструмента или [сетевого запроса](/docs/ru/sandboxing#network-isolation) команды в песочнице, и запрос ожидает около шести секунд |
2583| `idle_prompt` | Claude закончил отвечать около 60 секунд назад, и с тех пор вы ничего не вводили |2609| `idle_prompt` | Claude закончил отвечать около 60 секунд назад, и с тех пор вы ничего не вводили |
2584| `auth_success` | Аутентификация завершена |2610| `auth_success` | Аутентификация завершена |
2585| `elicitation_dialog` | MCP-сервер открывает форму запроса данных, и вы ничего не вводили около шести секунд |2611| `elicitation_dialog` | MCP-сервер открывает форму запроса данных, и вы ничего не вводили около шести секунд |
2586| `elicitation_url_dialog` | MCP-сервер просит вас открыть URL в браузере, и вы ничего не вводили около шести секунд |2612| `elicitation_url_dialog` | MCP-сервер просит вас открыть URL в браузере, и вы ничего не вводили около шести секунд |
2587| `elicitation_complete` | MCP-сервер сообщает, что [запрос данных в режиме URL](#elicitation-input) завершён |2613| `elicitation_complete` | MCP-сервер сообщает, что [запрос данных в режиме URL](#elicitation-input) завершён |
2588| `elicitation_response` | Ответ на запрос данных MCP отправлен обратно серверу |2614| `elicitation_response` | Ответ на запрос данных MCP отправлен обратно на сервер |
2589| `agent_needs_input` | Фоновая сессия начинает ждать вашего ввода, пока в терминале открыт [вид агентов](/docs/ru/agent-view). Также срабатывает, когда терминальная сессия показывает вам [вопрос о настройке терминала участника команды агентов](/docs/ru/agent-teams#choose-a-display-mode) или уведомление авторежима о [плате за запросы классификатора](/docs/ru/auto-mode-classifier-billing), и вы ничего не вводили около шести секунд |2615| `agent_needs_input` | Фоновая сессия начинает ожидать вашего ввода, пока в терминале открыт [вид агентов](/docs/ru/agent-view). Также срабатывает, когда терминальная сессия показывает вам [вопрос о настройке терминала от участника команды агентов](/docs/ru/agent-teams#choose-a-display-mode) или уведомление авторежима о [плате за запросы классификатора](/docs/ru/auto-mode-classifier-billing), и вы ничего не вводили около шести секунд |
2590| `agent_completed` | Фоновая сессия завершается или завершается со сбоем. Срабатывает только пока в терминале открыт [вид агентов](/docs/ru/agent-view) |2616| `agent_completed` | Фоновая сессия завершается или завершается с ошибкой. Срабатывает, только пока в терминале открыт [вид агентов](/docs/ru/agent-view) |
2591| `quota_auto_resume_fired` | Claude Code продолжает вашу задачу после того, как её приостановил лимит использования claude.ai: в момент сброса или раньше, если какое-то ваше действие в Claude Code во время ожидания, например добавление кредитов использования, повышение тарифа или смена модели, снова делает использование доступным, с [исключением для настройки модели](/docs/ru/interactive-mode#wait-for-a-usage-limit-to-reset) |2617| `quota_auto_resume_fired` | Claude Code продолжает вашу задачу после того, как её приостановил лимит использования claude.ai: в момент сброса или раньше, когда какое-то ваше действие в Claude Code во время ожидания, например добавление кредитов использования, повышение тарифа или смена модели, снова делает использование доступным, с [исключением для настройки модели](/docs/ru/interactive-mode#wait-for-a-usage-limit-to-reset) |
2592| `quota_auto_resume_stale` | Лимит использования claude.ai сбросился, пока ваш компьютер находился в спящем режиме более 30 минут. Claude Code ждёт, пока вы нажмёте `Enter`, вместо того чтобы продолжить. После более короткого сна он продолжает работу и вместо этого вызывает `quota_auto_resume_fired` |2618| `quota_auto_resume_stale` | Лимит использования claude.ai сбросился, пока ваш компьютер находился в спящем режиме более 30 минут. Claude Code ждёт, пока вы нажмёте `Enter`, вместо того чтобы продолжить. После более короткого сна он продолжает работу и вместо этого срабатывает `quota_auto_resume_fired` |
2593| `quota_auto_resume_disabled` | Claude Code прекращает ожидание сброса лимита использования claude.ai, не продолжая вашу задачу: [`autoContinueAtUsageLimit`](/docs/ru/settings-reference#autocontinueatusagelimit) отключена или сброс сместился более чем на 24 часа вперёд во время ожидания, начатого Claude Code самостоятельно, продолженная задача снова и снова упиралась в лимит или продолжение было заблокировано до того, как дошло до модели. Не срабатывает, когда вы нажимаете `Esc` или `Ctrl+C` или выбираете **Don't continue automatically** |2619| `quota_auto_resume_disabled` | Claude Code прекращает ожидание лимита использования claude.ai, не продолжая вашу задачу: [`autoContinueAtUsageLimit`](/docs/ru/settings-reference#autocontinueatusagelimit) был отключён или сброс сместился более чем на 24 часа вперёд во время ожидания, которое Claude Code начал самостоятельно, продолженная задача продолжала упираться в лимит, или продолжение было заблокировано до того, как дошло до модели. Не срабатывает, когда вы нажимаете `Esc` или `Ctrl+C` или выбираете **Don't continue automatically** |
2594 2620
2595Для типов `quota_auto_resume_fired`, `quota_auto_resume_stale` и `quota_auto_resume_disabled` требуется Claude Code v2.1.234 или новее.2621Для типов `quota_auto_resume_fired`, `quota_auto_resume_stale` и `quota_auto_resume_disabled` требуется Claude Code v2.1.234 или новее.
2596 2622
2597В терминальных сессиях для `permission_prompt` при сетевом запросе команды в песочнице требуется Claude Code v2.1.246 или новее.2623В терминальных сессиях для `permission_prompt` при сетевом запросе команды в песочнице требуется Claude Code v2.1.246 или новее.
2598 2624
2599Для `agent_needs_input` при вопросе о настройке терминала участника команды требуется Claude Code v2.1.248 или новее.2625Для `agent_needs_input` при вопросе участника команды о настройке терминала требуется Claude Code v2.1.248 или новее.
2600 2626
2601<Note>2627<Note>
2602 Типы `permission_prompt`, `idle_prompt`, `elicitation_dialog` и `elicitation_url_dialog` используют те же тайминги, что и уведомления рабочего стола, поэтому в терминальных сессиях вы увидите их, только если кажется, что вы отошли от терминала:2628 Типы `permission_prompt`, `idle_prompt`, `elicitation_dialog` и `elicitation_url_dialog` используют то же время срабатывания, что и уведомления на рабочем столе, поэтому в терминальных сессиях вы видите их, только когда кажется, что вы отошли от терминала:
2603 2629
2604 * Ожидайте `permission_prompt`, когда вы ничего не вводили около шести секунд. Таймер запускается при появлении запроса разрешения, и каждое нажатие клавиши откладывает его. Чтобы запускать хук сразу, когда Claude запрашивает разрешение на использование инструмента, используйте вместо этого [PermissionRequest](#permissionrequest).2630 * Ожидайте `permission_prompt`, когда вы ничего не вводили около шести секунд. Таймер запускается при появлении запроса разрешения, и каждое нажатие клавиши откладывает его. Чтобы запускать хук сразу, когда Claude запрашивает разрешение на использование инструмента, используйте вместо этого [PermissionRequest](#permissionrequest).
2605 * Ожидайте `idle_prompt` примерно через 60 секунд после того, как Claude закончит отвечать, и только если вы с тех пор ничего не вводили и ни один фоновый агент, например фоновый [субагент](/docs/ru/sub-agents), больше не работает. Claude Code не отправляет `idle_prompt`, пока ждёт сброса лимита использования claude.ai. Когда ожидание заканчивается само, вместо этого срабатывает один из типов `quota_auto_resume_*`.2631 * Ожидайте `idle_prompt` примерно через 60 секунд после того, как Claude закончит отвечать, и только если вы с тех пор ничего не вводили и ни один фоновый агент, например фоновый [субагент](/docs/ru/sub-agents), всё ещё не выполняется. Claude Code не отправляет `idle_prompt`, пока ожидает сброса лимита использования claude.ai. Когда ожидание завершается само по себе, вместо этого срабатывает один из типов `quota_auto_resume_*`.
2606 * Ожидайте `elicitation_dialog` для формы запроса данных или `elicitation_url_dialog` для запроса URL в браузере, когда вы ничего не вводили около шести секунд. Оба используют тот же шестисекундный порог, что и `permission_prompt`: таймер запускается при появлении диалогового окна, и каждое нажатие клавиши откладывает его.2632 * Ожидайте `elicitation_dialog` для формы запроса данных или `elicitation_url_dialog` для запроса URL в браузере, когда вы ничего не вводили около шести секунд. Оба используют тот же шестисекундный порог, что и `permission_prompt`: таймер запускается при появлении диалогового окна, и каждое нажатие клавиши откладывает его.
2607 2633
2608 Запрос разрешения или запрос данных, который поступает, пока на экране открыто другое диалоговое окно, сохраняет тот же шестисекундный порог, отсчитываемый с момента поступления запроса. Уведомление о нём может дойти до вас, пока запрос всё ещё ждёт за открытым диалоговым окном.2634 Запрос разрешения или запрос данных, поступивший, пока на экране открыто другое диалоговое окно, сохраняет тот же шестисекундный порог, отсчитываемый от момента поступления запроса. Его уведомление может дойти до вас, пока запрос ещё ожидает за открытым диалоговым окном.
2609</Note>2635</Note>
2610 2636
2611Claude Code иначе рассчитывает время для `permission_prompt` в сессиях, где он отправляет запросы разрешения в [обратный вызов `canUseTool`](/docs/ru/agent-sdk/user-input) Agent SDK — именно так Claude Desktop и расширение VS Code размещают Claude Code:2637Claude Code иначе определяет время срабатывания `permission_prompt` в сессиях, где он отправляет запросы разрешений в [обратный вызов `canUseTool`](/docs/ru/agent-sdk/user-input) Agent SDK — именно так Claude Desktop и расширение VS Code размещают Claude Code:
2612 2638
2613* Ожидайте `permission_prompt` примерно через шесть секунд после того, как Claude запросит разрешение. Claude Code не откладывает его, пока вы вводите текст.2639* Ожидайте `permission_prompt` примерно через шесть секунд после того, как Claude запросит разрешение. Claude Code не откладывает его, пока вы вводите текст.
2614* Если вы или хук [PermissionRequest](#permissionrequest) ответите раньше, Claude Code не запускает `permission_prompt`.2640* Если вы или хук [PermissionRequest](#permissionrequest) ответите раньше, Claude Code не запускает `permission_prompt`.
2615* Задайте [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/ru/env-vars) значение `1`, чтобы отключить `permission_prompt` в этих сессиях.2641* Установите [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/ru/env-vars) в `1`, чтобы отключить `permission_prompt` в этих сессиях.
2616 2642
2617До v2.1.233 `permission_prompt` в этих сессиях не срабатывал.2643До v2.1.233 `permission_prompt` в этих сессиях не срабатывал.
2618 2644
2619Используйте отдельные matcher, чтобы запускать разные обработчики в зависимости от типа уведомления. Эта конфигурация запускает скрипт оповещения о разрешениях, когда Claude нужно подтверждение разрешения, и другое уведомление, когда Claude простаивает:2645Используйте отдельные matcher, чтобы запускать разные обработчики в зависимости от типа уведомления. Эта конфигурация запускает скрипт оповещения, специфичный для разрешений, когда Claude нужно подтверждение разрешения, и другое уведомление, когда Claude бездействует:
2620 2646
2621```json theme={null}2647```json theme={null}
2622{2648{
2649 Входные данные Notification2675 Входные данные Notification
2650</h4>2676</h4>
2651 2677
2652Помимо [общих входных полей](#common-input-fields), хуки Notification получают `message` с текстом уведомления, необязательный `title` и `notification_type`, указывающий, какой тип сработал.2678Помимо [общих полей входных данных](#common-input-fields), хуки Notification получают `message` с текстом уведомления, необязательный `title` и `notification_type`, указывающий, какой тип сработал.
2653 2679
2654```json theme={null}2680```json theme={null}
2655{2681{
2663}2689}
2664```2690```
2665 2691
2666Хуки Notification не могут блокировать или изменять уведомления. Claude Code отбрасывает их поля `systemMessage` и `continue`, но по-прежнему выводит [`terminalSequence`](#emit-terminal-notifications), на чём основан пример с уведомлением рабочего стола. Хуки Notification предназначены для побочных действий, например для пересылки уведомления во внешний сервис.2692Хуки Notification не могут блокировать или изменять уведомления. Claude Code отбрасывает их поля `systemMessage` и `continue`, но по-прежнему выводит [`terminalSequence`](#emit-terminal-notifications), на что и опирается пример уведомления на рабочем столе. Хуки Notification предназначены для побочных эффектов, например пересылки уведомления во внешний сервис.
2667 2693
2668<h3 id="subagentstart">2694<h3 id="subagentstart">
2669 SubagentStart2695 SubagentStart
2670</h3>2696</h3>
2671 2697
2672Выполняется, когда Claude запускает субагента с помощью инструмента Agent, когда Claude [возобновляет субагента](/docs/ru/sub-agents#resume-subagents), а также каждый раз, когда внутрипроцессный участник [команды агентов](/docs/ru/agent-teams) обрабатывает новое сообщение. Поддерживает matcher для фильтрации по имени типа агента. Для встроенных агентов это имя агента, например `general-purpose`, `Explore` или `Plan`. Для [пользовательских субагентов](/docs/ru/sub-agents) это поле `name` из frontmatter агента, а не имя файла.2698Запускается, когда Claude порождает субагента с помощью инструмента Agent, когда Claude [возобновляет субагента](/docs/ru/sub-agents#resume-subagents), а также каждый раз, когда внутрипроцессный участник [команды агентов](/docs/ru/agent-teams) обрабатывает новое сообщение. Поддерживает matcher для фильтрации по имени типа агента. Для встроенных агентов это имя агента, например `general-purpose`, `Explore` или `Plan`. Для [пользовательских субагентов](/docs/ru/sub-agents) это поле `name` из frontmatter агента, а не имя файла.
2673 2699
2674Для субагентов, поставляемых [плагином](/docs/ru/plugins/overview), тип агента — это идентификатор в области плагина, например `my-plugin:reviewer`, а не просто имя из frontmatter. Двоеточие переводит имя в области плагина на путь регулярных выражений, поэтому для точного совпадения закрепите matcher с помощью `^` и `$`: `^my-plugin:reviewer$`.2700Для субагентов, поставляемых [плагином](/docs/ru/plugins/overview), тип агента — это идентификатор в области плагина, например `my-plugin:reviewer`, а не просто имя из frontmatter. Двоеточие переводит имя в области плагина на путь регулярных выражений, поэтому для точного совпадения привяжите matcher с помощью `^` и `$`: `^my-plugin:reviewer$`.
2675 2701
2676<h4 id="subagentstart-input">2702<h4 id="subagentstart-input">
2677 Входные данные SubagentStart2703 Входные данные SubagentStart
2678</h4>2704</h4>
2679 2705
2680Помимо [общих входных полей](#common-input-fields), хуки SubagentStart получают `agent_id` с уникальным идентификатором субагента и `agent_type` с именем агента, по которому фильтрует matcher.2706Помимо [общих полей входных данных](#common-input-fields), хуки SubagentStart получают `agent_id` с уникальным идентификатором субагента и `agent_type` с именем агента, по которому фильтрует matcher.
2681 2707
2682```json theme={null}2708```json theme={null}
2683{2709{
2690}2716}
2691```2717```
2692 2718
2693Хуки SubagentStart не могут блокировать создание субагента, но могут внедрять контекст в субагента. Помимо [выходных полей JSON](#json-output), доступных всем хукам, вы можете вернуть:2719Хуки SubagentStart не могут блокировать создание субагента, но могут внедрять контекст в субагента. Помимо [полей вывода JSON](#json-output), доступных всем хукам, вы можете вернуть:
2694 2720
2695| Поле | Описание |2721| Поле | Описание |
2696| :- | :- |2722| :- | :- |
2705}2731}
2706```2732```
2707 2733
2708Когда хук снова запускается для того же субагента, Claude Code внедряет возвращённый контекст только в том случае, если контекст субагента ещё не содержит копию из предыдущего запуска. Копия, внедрённая при запуске, остаётся на месте, сохраняя [кэш промптов](/docs/ru/prompt-caching#subagents-and-the-cache) субагента нетронутым. После того как [автосжатие](/docs/ru/sub-agents#auto-compaction) отбросит эту копию, Claude Code снова внедряет контекст следующего запуска.2734Когда хук снова запускается для того же субагента, Claude Code внедряет возвращённый контекст, только если контекст субагента ещё не содержит копию из предыдущего запуска. Копия, внедрённая при запуске, остаётся на месте, сохраняя [кэш промптов](/docs/ru/prompt-caching#subagents-and-the-cache) субагента нетронутым. После того как [автосжатие](/docs/ru/sub-agents#auto-compaction) отбросит эту копию, Claude Code снова внедряет контекст следующего запуска.
2709 2735
2710<h3 id="subagentstop">2736<h3 id="subagentstop">
2711 SubagentStop2737 SubagentStop
2712</h3>2738</h3>
2713 2739
2714Выполняется, когда субагент Claude Code закончил отвечать. Сопоставляется по типу агента, значения те же, что и для SubagentStart.2740Запускается, когда субагент Claude Code закончил отвечать. Сопоставляется по типу агента, с теми же значениями, что и SubagentStart.
2715 2741
2716<h4 id="subagentstop-input">2742<h4 id="subagentstop-input">
2717 Входные данные SubagentStop2743 Входные данные SubagentStop
2718</h4>2744</h4>
2719 2745
2720Помимо [общих входных полей](#common-input-fields), хуки SubagentStop получают `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path` и `last_assistant_message`. Поле `agent_type` — это значение, используемое для фильтрации matcher. `transcript_path` — это транскрипт основной сессии, а `agent_transcript_path` — собственный транскрипт субагента, хранящийся во вложенной папке `subagents/`. Поле `last_assistant_message` содержит текстовое содержимое финального ответа субагента, поэтому хуки могут получить к нему доступ без разбора файла транскрипта.2746Помимо [общих полей входных данных](#common-input-fields), хуки SubagentStop получают `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path` и `last_assistant_message`. Поле `agent_type` — это значение, используемое для фильтрации через matcher. `transcript_path` — это транскрипт основной сессии, а `agent_transcript_path` — собственный транскрипт субагента, хранящийся во вложенной папке `subagents/`. Поле `last_assistant_message` содержит текстовое содержимое финального ответа субагента, поэтому хуки могут получить к нему доступ без разбора файла транскрипта.
2721 2747
2722Не каждое событие SubagentStop исходит от субагента, запущенного Claude. Claude Code также запускает внутренних агентов для некоторых собственных функций, таких как [предложения промптов](/docs/ru/interactive-mode#prompt-suggestions) и [побочные вопросы `/btw`](/docs/ru/interactive-mode#side-questions-with-%2Fbtw), и SubagentStop срабатывает и при завершении одного из них. Для таких событий `agent_type` — это имя агента, от имени которого работает сама сессия, например заданное с помощью [`--agent`](/docs/ru/cli-reference#cli-flags) или [настройки `agent`](/docs/ru/settings-reference#agent), и пустая строка, если сессия работает без него.2748Не каждое событие SubagentStop исходит от субагента, порождённого Claude. Claude Code также запускает внутренних агентов для некоторых своих функций, таких как [предложения промптов](/docs/ru/interactive-mode#prompt-suggestions) и [побочные вопросы `/btw`](/docs/ru/interactive-mode#side-questions-with-%2Fbtw), и SubagentStop срабатывает и тогда, когда один из них завершается. Для таких событий `agent_type` — это имя агента, под которым выполняется сама сессия, например заданное с помощью [`--agent`](/docs/ru/cli-reference#cli-flags) или [настройки `agent`](/docs/ru/settings-reference#agent), и пустая строка, когда сессия выполняется без него.
2723 2749
2724`matcher`, в котором указаны типы агентов, не соответствует пустому `agent_type`. Хук, у которого matcher опущен, равен `""` или `"*"` либо является регулярным выражением, соответствующим пустой строке, запускается и для событий с пустым `agent_type`.2750`matcher`, в котором указаны типы агентов, не совпадает с пустым `agent_type`. Хук, у которого matcher опущен, равен `""` или `"*"` либо является регулярным выражением, совпадающим с пустой строкой, запускается и для событий с пустым `agent_type`.
2725 2751
2726В Claude Code v2.1.271 или новее субагент, работающий с инструментом [`SubagentHandback`](/docs/ru/tools-reference), доставляет свой отчёт через этот инструмент перед остановкой. Поле `last_assistant_message` в этом случае содержит заключительный текст субагента, если он есть, и это не доставленный отчёт. Отчёт — это входное поле `message` этого вызова, которое хук `PreToolUse` или `PostToolUse` с matcher `SubagentHandback` получает как `tool_input.message`.2752В Claude Code v2.1.271 или новее субагент, работающий с инструментом [`SubagentHandback`](/docs/ru/tools-reference), передаёт свой отчёт через этот инструмент перед остановкой. Тогда поле `last_assistant_message` содержит заключительный текст субагента, если он есть, который не является переданным отчётом. Отчёт — это входной параметр `message` того вызова, который хук `PreToolUse` или `PostToolUse` с matcher на `SubagentHandback` получает как `tool_input.message`.
2727 2753
2728Хуки SubagentStop также получают массивы `background_tasks` и `session_crons`, описанные в разделе [Входные данные Stop](#stop-input). Оба массива относятся к родительской сессии, а не к субагенту.2754Хуки SubagentStop также получают массивы `background_tasks` и `session_crons`, описанные в разделе [Входные данные Stop](#stop-input). Оба массива относятся к родительской сессии, а не к субагенту.
2729 2755
2744}2770}
2745```2771```
2746 2772
2747Хуки SubagentStop используют тот же формат управления решениями, что и [хуки Stop](#stop-decision-control), включая `hookSpecificOutput.additionalContext` с `hookEventName`, равным `"SubagentStop"`, для обратной связи без ошибки, которая продолжает работу субагента. Возврат `decision: "block"` с `reason` продолжает работу субагента и передаёт ему `reason` в качестве следующей инструкции. Хук, который блокирует, завершаясь с кодом 2, передаёт своё сообщение из stderr тем же способом. Чтобы внедрить контекст в родительскую сессию после возврата субагента, используйте вместо этого хук [`PostToolUse`](#posttooluse) для инструмента `Agent`.2773Хуки SubagentStop используют тот же формат управления решениями, что и [хуки Stop](#stop-decision-control), включая `hookSpecificOutput.additionalContext` с `hookEventName`, установленным в `"SubagentStop"`, для обратной связи, не являющейся ошибкой, которая продолжает работу субагента. Возврат `decision: "block"` с `reason` продолжает работу субагента и передаёт `reason` субагенту как его следующую инструкцию. Хук, блокирующий с кодом выхода 2, передаёт своё сообщение из stderr тем же способом. Чтобы внедрить контекст в родительскую сессию после возврата субагента, используйте вместо этого хук [`PostToolUse`](#posttooluse) на инструменте `Agent`.
2748 2774
2749<h3 id="taskcreated">2775<h3 id="taskcreated">
2750 TaskCreated2776 TaskCreated
2751</h3>2777</h3>
2752 2778
2753Выполняется, когда задача создаётся с помощью инструмента `TaskCreate`. Используйте его, чтобы обеспечивать соблюдение соглашений об именовании, требовать описания задач или предотвращать создание определённых задач. В [сессии без инструментов Task](/docs/ru/tools-reference#task-tool-availability) это событие не срабатывает.2779Запускается, когда задача создаётся с помощью инструмента `TaskCreate`. Используйте это для соблюдения соглашений об именовании, требования описаний задач или предотвращения создания определённых задач. В [сессии без инструментов Task](/docs/ru/tools-reference#task-tool-availability) это событие не срабатывает.
2754 2780
2755Хуки TaskCreated не поддерживают matcher и срабатывают при каждом возникновении события.2781Хуки TaskCreated не поддерживают matcher и срабатывают при каждом возникновении события.
2756 2782
2758 Входные данные TaskCreated2784 Входные данные TaskCreated
2759</h4>2785</h4>
2760 2786
2761Помимо [общих входных полей](#common-input-fields), хуки TaskCreated получают `task_id`, `task_subject` и, при наличии, `task_description`, `teammate_name` и `team_name`.2787Помимо [общих полей входных данных](#common-input-fields), хуки TaskCreated получают `task_id`, `task_subject` и, при наличии, `task_description`, `teammate_name` и `team_name`.
2762 2788
2763```json theme={null}2789```json theme={null}
2764{2790{
2780| `task_subject` | Заголовок задачи |2806| `task_subject` | Заголовок задачи |
2781| `task_description` | Подробное описание задачи. Может отсутствовать |2807| `task_description` | Подробное описание задачи. Может отсутствовать |
2782| `teammate_name` | Имя участника команды, создающего задачу. Может отсутствовать |2808| `teammate_name` | Имя участника команды, создающего задачу. Может отсутствовать |
2783| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в одном из будущих выпусков |2809| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в будущем выпуске |
2784| `agent_id` | В этом событии [общее входное поле](#common-input-fields) идентифицирует субагента или [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), создающего задачу. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |2810| `agent_id` | Для этого события [общее поле входных данных](#common-input-fields) идентифицирует субагента или [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), создающего задачу. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |
2785 2811
2786<h4 id="taskcreated-decision-control">2812<h4 id="taskcreated-decision-control">
2787 Управление решениями TaskCreated2813 Управление решениями TaskCreated
2788</h4>2814</h4>
2789 2815
2790Хук TaskCreated может заблокировать создание с помощью кода выхода 2 или решения в JSON. В обоих случаях Claude Code удаляет задачу и возвращает ваше сообщение Claude как ошибку инструмента. Claude Code игнорирует `continue: false` от этого события, и Claude продолжает работу.2816Хук TaskCreated может заблокировать создание с помощью кода выхода 2 или решения в JSON. В любом случае Claude Code удаляет задачу и возвращает ваше сообщение Claude как ошибку инструмента. Claude Code игнорирует `continue: false` от этого события, и Claude продолжает работу.
2791 2817
2792* **Код выхода 2**: Claude Code возвращает текст из stderr в качестве сообщения.2818* **Код выхода 2**: Claude Code возвращает текст из stderr в качестве сообщения.
2793* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code возвращает `reason` в качестве сообщения.2819* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code возвращает `reason` в качестве сообщения.
2794 2820
2795В этом примере блокируются задачи, заголовки которых не соответствуют требуемому формату:2821Этот пример блокирует задачи, заголовки которых не соответствуют требуемому формату:
2796 2822
2797```bash theme={null}2823```bash theme={null}
2798#!/bin/bash2824#!/bin/bash
2811 TaskCompleted2837 TaskCompleted
2812</h3>2838</h3>
2813 2839
2814Выполняется, когда задача помечается как выполненная. Это происходит в двух ситуациях: когда любой агент явно помечает задачу как выполненную с помощью инструмента TaskUpdate или когда участник [команды агентов](/docs/ru/agent-teams) завершает свой ход с задачами в процессе выполнения. Используйте его, чтобы обеспечивать соблюдение критериев завершения, например прохождение тестов или проверок линтера, прежде чем задачу можно будет закрыть.2840Запускается, когда задача помечается как завершённая. Это происходит в двух ситуациях: когда любой агент явно помечает задачу как завершённую через инструмент TaskUpdate или когда участник [команды агентов](/docs/ru/agent-teams) заканчивает свой ход с задачами в процессе выполнения. Используйте это для соблюдения критериев завершения, таких как прохождение тестов или проверок линтера, прежде чем задачу можно будет закрыть.
2815 2841
2816Хуки TaskCompleted не поддерживают matcher и срабатывают при каждом возникновении события.2842Хуки TaskCompleted не поддерживают matcher и срабатывают при каждом возникновении события.
2817 2843
2819 Входные данные TaskCompleted2845 Входные данные TaskCompleted
2820</h4>2846</h4>
2821 2847
2822Помимо [общих входных полей](#common-input-fields), хуки TaskCompleted получают `task_id`, `task_subject` и, при наличии, `task_description`, `teammate_name` и `team_name`.2848Помимо [общих полей входных данных](#common-input-fields), хуки TaskCompleted получают `task_id`, `task_subject` и, при наличии, `task_description`, `teammate_name` и `team_name`.
2823 2849
2824```json theme={null}2850```json theme={null}
2825{2851{
2842| `task_subject` | Заголовок задачи |2868| `task_subject` | Заголовок задачи |
2843| `task_description` | Подробное описание задачи. Может отсутствовать |2869| `task_description` | Подробное описание задачи. Может отсутствовать |
2844| `teammate_name` | Имя участника команды, завершающего задачу. Может отсутствовать |2870| `teammate_name` | Имя участника команды, завершающего задачу. Может отсутствовать |
2845| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в одном из будущих выпусков |2871| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в будущем выпуске |
2846| `agent_id` | В этом событии [общее входное поле](#common-input-fields) идентифицирует субагента или [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), завершающего задачу. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |2872| `agent_id` | Для этого события [общее поле входных данных](#common-input-fields) идентифицирует субагента или [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), завершающего задачу. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |
2847 2873
2848<h4 id="taskcompleted-decision-control">2874<h4 id="taskcompleted-decision-control">
2849 Управление решениями TaskCompleted2875 Управление решениями TaskCompleted
2851 2877
2852Хуки TaskCompleted поддерживают два способа управления завершением задачи:2878Хуки TaskCompleted поддерживают два способа управления завершением задачи:
2853 2879
2854* **Код выхода 2**: задача не помечается как выполненная, а сообщение из stderr передаётся модели в качестве обратной связи.2880* **Код выхода 2**: задача не помечается как завершённая, а сообщение из stderr передаётся модели в качестве обратной связи.
2855* **JSON `{"continue": false, "stopReason": "..."}`**: когда событие вызвано завершением хода участника команды, полностью останавливает участника команды, аналогично поведению хука `Stop`. `stopReason` показывается пользователю. Когда событие вызвано инструментом `TaskUpdate`, Claude Code игнорирует `continue: false`; код выхода 2 по-прежнему блокирует завершение.2881* **JSON `{"continue": false, "stopReason": "..."}`**: когда событие вызвано завершением хода участника команды, полностью останавливает участника команды, аналогично поведению хука `Stop`. `stopReason` показывается пользователю. Когда событие вызвано инструментом `TaskUpdate`, Claude Code игнорирует `continue: false`; код выхода 2 по-прежнему блокирует завершение.
2856 2882
2857В этом примере запускаются тесты и блокируется завершение задачи, если они не проходят:2883Этот пример запускает тесты и блокирует завершение задачи, если они не проходят:
2858 2884
2859```bash theme={null}2885```bash theme={null}
2860#!/bin/bash2886#!/bin/bash
2874 Stop2900 Stop
2875</h3>2901</h3>
2876 2902
2877Выполняется, когда основной агент Claude Code закончил отвечать. Не выполняется, если2903Запускается, когда основной агент Claude Code закончил отвечать. Не запускается, если
2878остановка произошла из-за прерывания пользователем. Ошибки API вместо этого вызывают2904остановка произошла из-за прерывания пользователем. Ошибки API вместо этого вызывают
2879[StopFailure](#stopfailure).2905[StopFailure](#stopfailure).
2880 2906
2881<Tip>2907<Tip>
2882 Команда [`/goal`](/docs/ru/goal) — это встроенное сокращение для хука Stop на основе промпта, действующего в рамках сессии. Используйте её, когда хотите, чтобы Claude продолжал работать до выполнения условия, не создавая конфигурацию хука.2908 Команда [`/goal`](/docs/ru/goal) — это встроенный быстрый способ создать хук Stop на основе промпта в рамках сессии. Используйте её, когда хотите, чтобы Claude продолжал работать до достижения условия, не создавая конфигурацию хука.
2883</Tip>2909</Tip>
2884 2910
2885<h4 id="stop-input">2911<h4 id="stop-input">
2886 Входные данные Stop2912 Входные данные Stop
2887</h4>2913</h4>
2888 2914
2889Помимо [общих входных полей](#common-input-fields), хуки Stop получают `stop_hook_active`, `last_assistant_message`, `background_tasks` и `session_crons`. Поле `stop_hook_active` равно `true`, когда Claude Code уже продолжает работу в результате хука остановки. Проверяйте это значение или обрабатывайте транскрипт, чтобы избежать блокировки по условию, которое никогда не будет выполнено.2915Помимо [общих полей входных данных](#common-input-fields), хуки Stop получают `stop_hook_active`, `last_assistant_message`, `background_tasks` и `session_crons`. Поле `stop_hook_active` равно `true`, когда Claude Code уже продолжает работу в результате хука остановки. Проверяйте это значение или обрабатывайте транскрипт, чтобы избежать блокировки по условию, которое никогда не выполнится.
2890 2916
2891Claude Code применяет ограничение в 8 последовательных продолжений: после того как хуки остановки продолжили ход восемь раз подряд, Claude Code переопределяет следующую блокировку и завершает ход. Счётчик последовательных продолжений сбрасывается каждый раз, когда Claude вызывает инструмент. Чтобы повысить ограничение, задайте [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/ru/env-vars).2917Claude Code применяет ограничение в 8 последовательных продолжений: после того как хуки остановки продолжили ход восемь раз подряд, Claude Code переопределяет следующую блокировку и завершает ход. Счётчик последовательных продолжений сбрасывается каждый раз, когда Claude вызывает инструмент. Чтобы повысить ограничение, установите [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/ru/env-vars).
2892 2918
2893Поле `last_assistant_message` содержит текстовое содержимое финального ответа Claude, поэтому хуки могут получить к нему доступ без разбора файла транскрипта. Для хуков, работающих с только что завершённым ходом, например хуков чтения вслух или уведомлений, используйте это поле, а не чтение `transcript_path`: не во всех версиях гарантируется, что файл транскрипта содержит финальное сообщение в момент Stop.2919Поле `last_assistant_message` содержит текстовое содержимое финального ответа Claude, поэтому хуки могут получить к нему доступ без разбора файла транскрипта. Для хуков, которые работают с только что завершённым ходом, например хуков чтения вслух или уведомлений, используйте это поле, а не чтение `transcript_path`: не во всех версиях гарантируется, что файл транскрипта содержит финальное сообщение в момент Stop.
2894 2920
2895Массивы `background_tasks` и `session_crons` позволяют хукам отличать ситуацию «сессия завершена» от ситуации «сессия приостановлена в ожидании фоновой работы, которая её снова разбудит». Оба массива присутствуют, когда реестр задач доступен, и пусты, когда ничего не выполняется и не запланировано.2921Массивы `background_tasks` и `session_crons` позволяют хукам отличать «сессия завершена» от «сессия приостановлена в ожидании фоновой работы, которая её разбудит». Оба массива присутствуют, когда реестр задач доступен, и пусты, когда ничего не выполняется и не запланировано.
2896 2922
2897Каждая запись в `background_tasks` описывает одну выполняемую задачу и использует следующие поля:2923Каждая запись в `background_tasks` описывает одну выполняющуюся задачу и использует следующие поля:
2898 2924
2899| Поле | Описание |2925| Поле | Описание |
2900| :- | :- |2926| :- | :- |
2901| `id` | Идентификатор задачи |2927| `id` | Идентификатор задачи |
2902| `type` | Понятная метка типа задачи, например `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session` или `MCP task`. Каждая метка указывает, какая функция Claude Code создала задачу. Для нераспознанных типов используется исходный дискриминант |2928| `type` | Понятная метка типа задачи, например `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session` или `MCP task`. Каждая метка указывает, какая функция Claude Code создала задачу. Для нераспознанных типов используется необработанный дискриминант |
2903| `status` | Текущий статус задачи |2929| `status` | Текущий статус задачи |
2904| `description` | Описание в свободной форме, ограниченное 1000 символами, с маркером `… [+N chars]` внутри строки при обрезке |2930| `description` | Текстовое описание, ограниченное 1000 символами, с маркером `… [+N chars]` внутри строки при обрезке |
2905| `command` | Командная строка оболочки, ограниченная 1000 символами. Присутствует только для задач `shell` |2931| `command` | Командная строка оболочки, ограниченная 1000 символами. Присутствует только для задач `shell` |
2906| `agent_type` | Имя типа субагента. Присутствует только для задач `subagent` |2932| `agent_type` | Имя типа субагента. Присутствует только для задач `subagent` |
2907| `server` | Имя MCP-сервера. Присутствует только для задач `monitor` и `MCP task` |2933| `server` | Имя MCP-сервера. Присутствует только для задач `monitor` и `MCP task` |
2908| `tool` | Имя инструмента MCP. Присутствует только для задач `monitor` и `MCP task` |2934| `tool` | Имя инструмента MCP. Присутствует только для задач `monitor` и `MCP task` |
2909| `name` | Имя workflow. Присутствует только для задач `workflow` |2935| `name` | Имя workflow. Присутствует только для задач `workflow` |
2910 2936
2911Каждая запись в `session_crons` описывает одно запланированное пробуждение в рамках сессии, полученное из `CronCreate`, `ScheduleWakeup` и `/loop`:2937Каждая запись в `session_crons` описывает одно запланированное пробуждение в рамках сессии, созданное через `CronCreate`, `ScheduleWakeup` и `/loop`:
2912 2938
2913| Поле | Описание |2939| Поле | Описание |
2914| :- | :- |2940| :- | :- |
2915| `id` | Идентификатор задачи cron |2941| `id` | Идентификатор задачи cron |
2916| `schedule` | Выражение cron, например `0 9 * * 1-5` |2942| `schedule` | Выражение cron, например `0 9 * * 1-5` |
2917| `recurring` | `false` для одноразовых пробуждений, расписание которых задаёт одно время срабатывания, `true` для задач, срабатывающих повторно при каждом совпадении |2943| `recurring` | `false` для одноразовых пробуждений, расписание которых кодирует единственное время срабатывания, `true` для задач, повторно срабатывающих при каждом совпадении |
2918| `prompt` | Промпт, отправляемый при срабатывании cron, ограниченный 1000 символами с тем же маркером `… [+N chars]` |2944| `prompt` | Промпт, отправляемый при срабатывании cron, ограниченный 1000 символами с тем же маркером `… [+N chars]` |
2919 2945
2920В этом примере показаны входные данные Stop с одной выполняемой задачей оболочки и одним повторяющимся cron:2946Этот пример показывает входные данные Stop с одной выполняющейся задачей оболочки и одним повторяющимся cron:
2921 2947
2922```json theme={null}2948```json theme={null}
2923{2949{
2952 Управление решениями Stop2978 Управление решениями Stop
2953</h4>2979</h4>
2954 2980
2955Хуки `Stop` и `SubagentStop` могут управлять тем, продолжит ли Claude работу. Помимо [выходных полей JSON](#json-output), доступных всем хукам, ваш скрипт хука может возвращать следующие поля, специфичные для события:2981Хуки `Stop` и `SubagentStop` могут управлять тем, продолжит ли Claude работу. Помимо [полей вывода JSON](#json-output), доступных всем хукам, ваш скрипт хука может вернуть следующие поля, специфичные для события:
2956 2982
2957| Поле | Описание |2983| Поле | Описание |
2958| :- | :- |2984| :- | :- |
2959| `decision` | `"block"` не даёт Claude остановиться. Опустите, чтобы разрешить Claude остановиться |2985| `decision` | `"block"` не даёт Claude остановиться. Опустите, чтобы позволить Claude остановиться |
2960| `reason` | Обязательно, когда `decision` равно `"block"`. Сообщает Claude, почему ему следует продолжить |2986| `reason` | Обязательно, когда `decision` равно `"block"`. Сообщает Claude, почему он должен продолжить |
2961| `hookSpecificOutput.additionalContext` | Обратная связь для Claude, не являющаяся ошибкой. Диалог продолжается, чтобы Claude мог на неё отреагировать, но, в отличие от `decision: "block"`, в транскрипте она отображается как обратная связь хука, а не как ошибка хука |2987| `hookSpecificOutput.additionalContext` | Обратная связь для Claude, не являющаяся ошибкой. Диалог продолжается, чтобы Claude мог на неё отреагировать, но, в отличие от `decision: "block"`, она показывается в транскрипте как обратная связь хука, а не как ошибка хука |
2962 2988
2963Хук, который блокирует, завершаясь с кодом 2, обрабатывается так же, как `reason`: Claude получает сообщение из stderr в качестве пояснения, почему ему следует продолжить.2989Хук, блокирующий с кодом выхода 2, обрабатывается так же, как `reason`: Claude получает сообщение из stderr в качестве объяснения, почему он должен продолжить.
2964 2990
2965```json theme={null}2991```json theme={null}
2966{2992{
2969}2995}
2970```2996```
2971 2997
2972Используйте `additionalContext`, когда хук работает как задумано и даёт Claude указания, например «запусти набор тестов перед завершением». Он продолжает диалог с теми же защитами от зацикливания, что и `decision: "block"`, а именно входным полем `stop_hook_active` и ограничением в 8 последовательных продолжений, но транскрипт помечает его как `Stop hook feedback`, и уведомление об ошибке хука не показывается:2998Используйте `additionalContext`, когда хук работает так, как задумано, и даёт Claude указания, например «запусти набор тестов перед завершением». Он продолжает диалог с теми же защитами от зацикливания, что и `decision: "block"`, а именно входным полем `stop_hook_active` и ограничением в 8 последовательных продолжений, но транскрипт помечает его как `Stop hook feedback`, и уведомление об ошибке хука не показывается:
2973 2999
2974```json theme={null}3000```json theme={null}
2975{3001{
2984 StopFailure3010 StopFailure
2985</h3>3011</h3>
2986 3012
2987Выполняется вместо [Stop](#stop), когда ход завершается из-за ошибки API. Claude Code игнорирует вывод и код выхода хука, за исключением [`terminalSequence`](#emit-terminal-notifications). Используйте его, чтобы логировать сбои, отправлять оповещения или выполнять действия по восстановлению, когда Claude не может завершить ответ из-за ограничений частоты запросов, проблем с аутентификацией или других ошибок API.3013Запускается вместо [Stop](#stop), когда ход завершается из-за ошибки API. Claude Code игнорирует вывод и код выхода хука, за исключением [`terminalSequence`](#emit-terminal-notifications). Используйте это для логирования сбоев, отправки оповещений или выполнения действий по восстановлению, когда Claude не может завершить ответ из-за ограничений частоты запросов, проблем с аутентификацией или других ошибок API.
2988 3014
2989<h4 id="stopfailure-input">3015<h4 id="stopfailure-input">
2990 Входные данные StopFailure3016 Входные данные StopFailure
2991</h4>3017</h4>
2992 3018
2993Помимо [общих входных полей](#common-input-fields), хуки StopFailure получают `error`, необязательное `error_details` и необязательное `last_assistant_message`. Поле `error` определяет тип ошибки и используется для фильтрации matcher.3019Помимо [общих полей входных данных](#common-input-fields), хуки StopFailure получают `error`, необязательное `error_details` и необязательное `last_assistant_message`. Поле `error` определяет тип ошибки и используется для фильтрации через matcher.
2994 3020
2995| Поле | Описание |3021| Поле | Описание |
2996| :- | :- |3022| :- | :- |
2997| `error` | Тип ошибки: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` или `unknown` |3023| `error` | Тип ошибки: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error` или `unknown` |
2998| `error_details` | Дополнительные сведения об ошибке, если они доступны |3024| `error_details` | Дополнительные сведения об ошибке, если доступны |
2999| `last_assistant_message` | Отрисованный текст ошибки, показанный в диалоге. В отличие от `Stop` и `SubagentStop`, где это поле содержит разговорный вывод Claude, для `StopFailure` оно содержит саму строку ошибки API, например `"API Error: Rate limit reached"` |3025| `last_assistant_message` | Отображаемый текст ошибки, показанный в диалоге. В отличие от `Stop` и `SubagentStop`, где это поле содержит разговорный вывод Claude, для `StopFailure` оно содержит саму строку ошибки API, например `"API Error: Rate limit reached"` |
3000 3026
3001```json theme={null}3027```json theme={null}
3002{3028{
3016 TeammateIdle3042 TeammateIdle
3017</h3>3043</h3>
3018 3044
3019Выполняется, когда участник [команды агентов](/docs/ru/agent-teams) вот-вот перейдёт в режим простоя после завершения своего хода. Используйте его, чтобы обеспечивать контроль качества до того, как участник команды прекратит работу, например требовать прохождения проверок линтера или проверять наличие выходных файлов.3045Запускается, когда участник [команды агентов](/docs/ru/agent-teams) собирается перейти в режим простоя после завершения своего хода. Используйте это для применения контрольных проверок качества до того, как участник команды прекратит работу, например для требования прохождения проверок линтера или проверки наличия выходных файлов.
3020 3046
3021Хуки TeammateIdle не поддерживают matcher и срабатывают при каждом возникновении события.3047Хуки TeammateIdle не поддерживают matcher и срабатывают при каждом возникновении события.
3022 3048
3024 Входные данные TeammateIdle3050 Входные данные TeammateIdle
3025</h4>3051</h4>
3026 3052
3027Помимо [общих входных полей](#common-input-fields), хуки TeammateIdle получают `teammate_name` и `team_name`.3053Помимо [общих полей входных данных](#common-input-fields), хуки TeammateIdle получают `teammate_name` и `team_name`.
3028 3054
3029```json theme={null}3055```json theme={null}
3030{3056{
3040 3066
3041| Поле | Описание |3067| Поле | Описание |
3042| :- | :- |3068| :- | :- |
3043| `teammate_name` | Имя участника команды, который вот-вот перейдёт в режим простоя |3069| `teammate_name` | Имя участника команды, который собирается перейти в режим простоя |
3044| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в одном из будущих выпусков |3070| `team_name` | Устаревшее. Имя команды, производное от сессии; будет удалено в будущем выпуске |
3045| `agent_id` | В этом событии [общее входное поле](#common-input-fields) идентифицирует [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), который вот-вот перейдёт в режим простоя. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |3071| `agent_id` | Для этого события [общее поле входных данных](#common-input-fields) идентифицирует [внутрипроцессного участника команды](/docs/ru/agent-teams#choose-a-display-mode), который собирается перейти в режим простоя. Может отсутствовать. Требуется Claude Code v2.1.290 или новее |
3046 3072
3047<h4 id="teammateidle-decision-control">3073<h4 id="teammateidle-decision-control">
3048 Управление решениями TeammateIdle3074 Управление решениями TeammateIdle
3053* **Код выхода 2**: участник команды получает сообщение из stderr в качестве обратной связи и продолжает работу вместо перехода в режим простоя.3079* **Код выхода 2**: участник команды получает сообщение из stderr в качестве обратной связи и продолжает работу вместо перехода в режим простоя.
3054* **JSON `{"continue": false, "stopReason": "..."}`**: полностью останавливает участника команды, аналогично поведению хука `Stop`. `stopReason` показывается пользователю.3080* **JSON `{"continue": false, "stopReason": "..."}`**: полностью останавливает участника команды, аналогично поведению хука `Stop`. `stopReason` показывается пользователю.
3055 3081
3056В этом примере проверяется наличие артефакта сборки, прежде чем разрешить участнику команды перейти в режим простоя:3082Этот пример проверяет наличие артефакта сборки, прежде чем позволить участнику команды перейти в режим простоя:
3057 3083
3058```bash theme={null}3084```bash theme={null}
3059#!/bin/bash3085#!/bin/bash
3070 ConfigChange3096 ConfigChange
3071</h3>3097</h3>
3072 3098
3073Выполняется, когда файл конфигурации изменяется во время сессии. Используйте его для аудита изменений настроек, обеспечения соблюдения политик безопасности или блокировки несанкционированных изменений файлов конфигурации.3099Запускается, когда файл конфигурации изменяется во время сессии. Используйте это для аудита изменений настроек, применения политик безопасности или блокировки несанкционированных изменений файлов конфигурации.
3074 3100
3075Claude Code запускает хуки ConfigChange, когда изменяется файл настроек, файл управляемой политики или файл скилла. Для управляемой политики он запускает их только при изменении `managed-settings.json` или файла в `managed-settings.d/`. [Настройки, управляемые сервером](/docs/ru/server-managed-settings), и изменения управляемых настроек macOS или политики реестра Windows он применяет без запуска хуков. В WSL с [`wslInheritsWindowsSettings`](/docs/ru/settings-reference#wslinheritswindowssettings) он также применяет изменённый файл управляемых настроек на стороне Windows при опросе политики без запуска хуков.3101Claude Code запускает хуки ConfigChange, когда изменяется файл настроек, файл управляемой политики или файл скилла. Для управляемой политики он запускает их, только когда изменяется `managed-settings.json` или файл в `managed-settings.d/`. [Настройки, управляемые сервером](/docs/ru/server-managed-settings), а также изменения управляемых настроек macOS или политики реестра Windows он применяет без запуска хуков. В WSL с [`wslInheritsWindowsSettings`](/docs/ru/settings-reference#wslinheritswindowssettings) он также применяет изменённый файл управляемых настроек на стороне Windows при опросе политики без запуска хуков.
3076 3102
3077Matcher фильтрует по источнику конфигурации:3103Matcher фильтрует по источнику конфигурации:
3078 3104
3084| `policy_settings` | Изменяется `managed-settings.json` или файл в `managed-settings.d/` |3110| `policy_settings` | Изменяется `managed-settings.json` или файл в `managed-settings.d/` |
3085| `skills` | Изменяется файл скилла в `.claude/skills/` |3111| `skills` | Изменяется файл скилла в `.claude/skills/` |
3086 3112
3087В этом примере все изменения конфигурации записываются в журнал для аудита безопасности:3113Этот пример записывает в лог все изменения конфигурации для аудита безопасности:
3088 3114
3089```json theme={null}3115```json theme={null}
3090{3116{
3108 Входные данные ConfigChange3134 Входные данные ConfigChange
3109</h4>3135</h4>
3110 3136
3111Помимо [общих входных полей](#common-input-fields), хуки ConfigChange получают `source` и, при наличии, `file_path`. Поле `source` указывает, какой тип конфигурации изменился, а `file_path` содержит путь к конкретному изменённому файлу.3137Помимо [общих полей входных данных](#common-input-fields), хуки ConfigChange получают `source` и, при наличии, `file_path`. Поле `source` указывает, какой тип конфигурации изменился, а `file_path` содержит путь к конкретному изменённому файлу.
3112 3138
3113```json theme={null}3139```json theme={null}
3114{3140{
3125 Управление решениями ConfigChange3151 Управление решениями ConfigChange
3126</h4>3152</h4>
3127 3153
3128Хуки ConfigChange могут блокировать вступление изменений конфигурации в силу. Используйте код выхода 2 или JSON-поле `decision`, чтобы предотвратить изменение. При блокировке новые настройки не применяются к текущей сессии.3154Хуки ConfigChange могут блокировать вступление изменений конфигурации в силу. Используйте код выхода 2 или JSON-поле `decision`, чтобы предотвратить изменение. При блокировке новые настройки не применяются к работающей сессии.
3129 3155
3130| Поле | Описание |3156| Поле | Описание |
3131| :- | :- |3157| :- | :- |
3139}3165}
3140```3166```
3141 3167
3142Изменения `policy_settings` нельзя заблокировать. Хуки по-прежнему срабатывают для источников `policy_settings`, когда изменяется файл управляемых настроек на компьютере, поэтому вы можете использовать их для записи этих изменений в журнал, но любое решение о блокировке игнорируется. Это гарантирует, что настройки, управляемые организацией, всегда вступают в силу. Claude Code не запускает хуки `ConfigChange`, когда [настройки, управляемые сервером](/docs/ru/server-managed-settings), поступают или обновляются.3168Изменения `policy_settings` нельзя заблокировать. Хуки по-прежнему срабатывают для источников `policy_settings`, когда изменяется файл управляемых настроек на машине, поэтому вы можете использовать их для записи этих правок в лог, но любое решение о блокировке игнорируется. Это гарантирует, что корпоративные управляемые настройки всегда вступают в силу. Claude Code не запускает хуки `ConfigChange`, когда [настройки, управляемые сервером](/docs/ru/server-managed-settings), поступают или обновляются.
3143 3169
3144Claude Code учитывает решение о блокировке из JSON-вывода хука ConfigChange и отбрасывает `systemMessage` и `continue`. Заблокированное изменение не выводит никакого сообщения ни вам, ни Claude, независимо от того, блокируете ли вы с помощью `reason` или через stderr с кодом выхода 2. Claude Code лишь записывает строку в отладочный лог.3170Claude Code выполняет решение о блокировке из JSON-вывода хука ConfigChange и отбрасывает `systemMessage` и `continue`. Заблокированное изменение не выводит никакого сообщения ни вам, ни Claude, независимо от того, блокируете ли вы его с помощью `reason` или через stderr с кодом выхода 2. Claude Code лишь записывает строку в отладочный лог.
3145 3171
3146<h3 id="cwdchanged">3172<h3 id="cwdchanged">
3147 CwdChanged3173 CwdChanged
3148</h3>3174</h3>
3149 3175
3150Выполняется, когда shell-команда в основном диалоге изменяет рабочий каталог, например когда Claude выполняет команду `cd`. Используйте его, чтобы реагировать на смену каталога: перезагружать переменные окружения, активировать наборы инструментов для конкретного проекта или автоматически запускать скрипты настройки. Работает в паре с [FileChanged](#filechanged) для таких инструментов, как [direnv](https://direnv.net/), которые управляют окружением для каждого каталога.3176Запускается, когда shell-команда в основном диалоге изменяет рабочий каталог, например когда Claude выполняет команду `cd`. Используйте это для реакции на смену каталога: перезагрузки переменных окружения, активации специфичных для проекта наборов инструментов или автоматического запуска скриптов настройки. Работает в паре с [FileChanged](#filechanged) для таких инструментов, как [direnv](https://direnv.net/), которые управляют окружением для каждого каталога.
3151 3177
3152Хуки CwdChanged имеют доступ к [`CLAUDE_ENV_FILE`](#persist-environment-variables). Переменные, записанные в этот файл, сохраняются для последующих команд Bash до следующего события CwdChanged, когда Claude Code их очищает.3178Хуки CwdChanged имеют доступ к [`CLAUDE_ENV_FILE`](#persist-environment-variables). Переменные, записанные в этот файл, сохраняются в последующих командах Bash до следующего события CwdChanged, когда Claude Code очищает их.
3153 3179
3154CwdChanged не поддерживает matcher и срабатывает при каждом возникновении события.3180CwdChanged не поддерживает matcher и срабатывает при каждом возникновении события.
3155 3181
3157 Входные данные CwdChanged3183 Входные данные CwdChanged
3158</h4>3184</h4>
3159 3185
3160Помимо [общих входных полей](#common-input-fields), хуки CwdChanged получают `old_cwd` и `new_cwd`.3186Помимо [общих полей входных данных](#common-input-fields), хуки CwdChanged получают `old_cwd` и `new_cwd`.
3161 3187
3162```json theme={null}3188```json theme={null}
3163{3189{
3174 Вывод CwdChanged3200 Вывод CwdChanged
3175</h4>3201</h4>
3176 3202
3177Помимо [выходных полей JSON](#json-output), доступных всем хукам, хуки CwdChanged могут возвращать `watchPaths`, чтобы динамически задавать, за какими путями к файлам следит [FileChanged](#filechanged):3203Помимо [полей вывода JSON](#json-output), доступных всем хукам, хуки CwdChanged могут вернуть `watchPaths`, чтобы динамически задать, за какими путями к файлам следит [FileChanged](#filechanged):
3178 3204
3179| Поле | Описание |3205| Поле | Описание |
3180| :- | :- |3206| :- | :- |
3181| `watchPaths` | Массив абсолютных путей. Заменяет текущий динамический список наблюдения. За путями из вашей конфигурации `matcher` наблюдение ведётся всегда. Возврат пустого массива очищает динамический список, что типично при входе в новый каталог |3207| `watchPaths` | Массив абсолютных путей. Заменяет текущий динамический список отслеживания. Пути из вашей конфигурации `matcher` отслеживаются всегда. Возврат пустого массива очищает динамический список, что типично при входе в новый каталог |
3182 3208
3183У хуков CwdChanged нет управления решениями. Они не могут заблокировать смену каталога.3209У хуков CwdChanged нет управления решениями. Они не могут заблокировать смену каталога.
3184 3210
3185Claude Code считывает `watchPaths` и `systemMessage` из их JSON-вывода и отбрасывает `continue`. В интерактивных сессиях он показывает `systemMessage` как короткое уведомление в терминале. Сообщение не попадает в поток сообщений SDK.3211Claude Code читает `watchPaths` и `systemMessage` из их JSON-вывода и отбрасывает `continue`. В интерактивных сессиях он показывает `systemMessage` как короткое уведомление в терминале. Сообщение не попадает в поток сообщений SDK.
3186 3212
3187<h3 id="directoryadded">3213<h3 id="directoryadded">
3188 DirectoryAdded3214 DirectoryAdded
3189</h3>3215</h3>
3190 3216
3191Выполняется после того, как вы добавляете рабочий каталог посреди сессии с помощью команды `/add-dir` или после того, как клиент SDK добавляет его с помощью управляющего запроса `register_repo_root`. Используйте его, чтобы подготовить только что добавленный репозиторий, например установить его зависимости.3217Запускается после того, как вы добавляете рабочий каталог посреди сессии с помощью команды `/add-dir`, или после того, как SDK-клиент добавляет его с помощью управляющего запроса `register_repo_root`. Используйте это для подготовки только что добавленного репозитория, например для установки его зависимостей.
3192 3218
3193Claude Code не вызывает это событие, когда:3219Claude Code не вызывает это событие, когда:
3194 3220
3195* Вы передаёте каталог с помощью флага запуска `--add-dir`; такие каталоги покрывает [SessionStart](#sessionstart)3221* Вы передаёте каталог с флагом запуска `--add-dir`; эти каталоги охватывает [SessionStart](#sessionstart)
3196* Вы добавляете каталог на вкладке Workspace в `/permissions`3222* Вы добавляете каталог на вкладке Workspace в `/permissions`
3197* Вы добавляете каталог, который уже является рабочим каталогом или находится внутри него3223* Вы добавляете каталог, который уже является рабочим каталогом или находится внутри него
3198 3224
3205| Matcher | Когда срабатывает |3231| Matcher | Когда срабатывает |
3206| :- | :- |3232| :- | :- |
3207| `slash_command` | Вы добавляете каталог с помощью `/add-dir` |3233| `slash_command` | Вы добавляете каталог с помощью `/add-dir` |
3208| `register_repo_root` | Клиент SDK добавляет каталог с помощью управляющего запроса `register_repo_root` |3234| `register_repo_root` | SDK-клиент добавляет каталог с помощью управляющего запроса `register_repo_root` |
3209 3235
3210<h4 id="directoryadded-input">3236<h4 id="directoryadded-input">
3211 Входные данные DirectoryAdded3237 Входные данные DirectoryAdded
3212</h4>3238</h4>
3213 3239
3214Помимо [общих входных полей](#common-input-fields), хуки DirectoryAdded получают `directory` и `source`.3240Помимо [общих полей входных данных](#common-input-fields), хуки DirectoryAdded получают `directory` и `source`.
3215 3241
3216| Поле | Описание |3242| Поле | Описание |
3217| :- | :- |3243| :- | :- |
3229}3255}
3230```3256```
3231 3257
3232У хуков DirectoryAdded нет управления решениями. Они не могут заблокировать добавление, которое уже завершено к моменту запуска хука. Claude Code отбрасывает поле `continue` из их JSON-вывода, а остальное выводит по-разному в зависимости от источника:3258У хуков DirectoryAdded нет управления решениями. Они не могут заблокировать добавление, которое уже завершено к моменту запуска хука. Claude Code отбрасывает поле `continue` из их JSON-вывода, а остальное обрабатывает по-разному в зависимости от источника:
3233 3259
3234* `slash_command`: Claude Code передаёт `systemMessage` хука Claude в качестве контекста на следующем ходе диалога, а не показывает его вам. Количество неудавшихся хуков отображается в транскрипте. Полный вывод сбоев записывается в отладочный лог3260* `slash_command`: Claude Code передаёт `systemMessage` хука Claude как контекст на следующем ходе диалога, а не показывает его вам. В транскрипте появляется количество хуков, завершившихся с ошибкой. Полный вывод ошибок записывается в отладочный лог
3235* `register_repo_root`: Claude Code записывает вывод `systemMessage` и вывод сбоев только в отладочный лог3261* `register_repo_root`: Claude Code записывает вывод `systemMessage` и вывод ошибок только в отладочный лог
3236 3262
3237<h3 id="filechanged">3263<h3 id="filechanged">
3238 FileChanged3264 FileChanged
3239</h3>3265</h3>
3240 3266
3241Выполняется, когда отслеживаемый файл изменяется на диске. Claude Code обнаруживает изменения с помощью наблюдателя файловой системы, а не путём проверки вызовов инструментов, поэтому он запускает хук независимо от того, что изменило файл: вызов инструмента `Edit` или `Write`, скрипт, который Claude запускает с помощью `Bash`, или процесс полностью вне Claude Code. Типичное применение — перезагрузка переменных окружения при изменении файлов конфигурации проекта.3267Запускается, когда отслеживаемый файл изменяется на диске. Claude Code обнаруживает изменения с помощью наблюдателя файловой системы, а не путём анализа вызовов инструментов, поэтому запускает хук независимо от того, что изменило файл: вызов инструмента `Edit` или `Write`, скрипт, который Claude запускает через `Bash`, или процесс полностью вне Claude Code. Типичный сценарий использования — перезагрузка переменных окружения при изменении файлов конфигурации проекта.
3242 3268
3243`matcher` для этого события выполняет две роли:3269`matcher` для этого события выполняет две роли:
3244 3270
3245* **Построение списка наблюдения**: значение разбивается по `|`, и каждый сегмент регистрируется как буквальное имя файла в рабочем каталоге, поэтому `".envrc|.env"` отслеживает ровно эти два файла. Шаблоны регулярных выражений здесь бесполезны: значение вроде `^\.env` будет отслеживать файл с буквальным именем `^\.env`.3271* **Формирование списка отслеживания**: значение разбивается по `|`, и каждый сегмент регистрируется как буквальное имя файла в рабочем каталоге, поэтому `".envrc|.env"` отслеживает ровно эти два файла. Регулярные выражения здесь бесполезны: значение вроде `^\.env` будет отслеживать файл с буквальным именем `^\.env`.
3246* **Фильтрация запускаемых хуков**: когда отслеживаемый файл изменяется, то же значение фильтрует, какие группы хуков запускаются, по стандартным [правилам matcher](#matcher-patterns) относительно базового имени изменённого файла.3272* **Фильтрация запускаемых хуков**: когда отслеживаемый файл изменяется, то же значение фильтрует, какие группы хуков запускаются, по стандартным [правилам matcher](#matcher-patterns) применительно к базовому имени изменённого файла.
3247 3273
3248В этом примере нормализуются окончания строк в `data.csv` после любого изменения, включая перезапись файла командой `Bash` или внешним скриптом:3274Этот пример нормализует окончания строк в `data.csv` после любого изменения, включая перезапись файла командой `Bash` или внешним скриптом:
3249 3275
3250```json theme={null}3276```json theme={null}
3251{3277{
3265}3291}
3266```3292```
3267 3293
3268Хук считывает абсолютный путь к изменённому файлу из поля `file_path` [входных данных JSON](#filechanged-input) в stdin. Его проверка с помощью `grep` ищет то же, что удаляет `perl`, — CR в конце строки, поэтому запуск после нормализации завершается, не трогая файл. Менее строгая проверка приводит к бесконечному циклу, потому что `perl -i` перезаписывает файл, даже если ничего не заменяет, а Claude Code снова запускает хук после каждой перезаписи. Сохраните этот скрипт в `/path/to/normalize-line-endings.sh` и сделайте его исполняемым:3294Хук считывает абсолютный путь изменённого файла из поля `file_path` [входных данных JSON](#filechanged-input) на stdin. Его проверка `grep` ищет то же, что удаляет `perl`, — символ CR в конце строки, поэтому запуск после нормализации завершается, не затрагивая файл. Более мягкая проверка приводит к бесконечному циклу, потому что `perl -i` перезаписывает файл, даже если ничего не заменяет, а Claude Code запускает хук снова после каждой перезаписи. Сохраните этот скрипт по пути `/path/to/normalize-line-endings.sh` и сделайте его исполняемым:
3269 3295
3270```bash theme={null}3296```bash theme={null}
3271#!/bin/bash3297#!/bin/bash
3275fi3301fi
3276```3302```
3277 3303
3278Чтобы убедиться, что хук работает, попросите Claude дописать строку с CRLF в `data.csv` с помощью команды `Bash`. Claude Code запустит хук, и в итоге файл будет содержать окончания строк LF.3304Чтобы убедиться, что хук работает, попросите Claude добавить строку с CRLF в `data.csv` командой `Bash`. Claude Code запустит хук, и в файле останутся окончания LF.
3279 3305
3280Чтобы отслеживать файлы, которые нельзя назвать заранее, возвращайте из хука [`watchPaths`](#filechanged-output) для динамического обновления списка наблюдения. Claude Code запускает наблюдателя только тогда, когда что-то называет файл для отслеживания, поэтому заполните список группой FileChanged, matcher которой называет хотя бы один файл, или хуком [SessionStart](#sessionstart-decision-control) либо [CwdChanged](#cwdchanged), который возвращает `watchPaths`. Matcher по-прежнему фильтрует, какие группы хуков запускаются при изменении отслеживаемого файла, поэтому для группы, обрабатывающей динамические пути, опустите matcher: такой matcher соответствует каждому отслеживаемому файлу и ничего не добавляет в список наблюдения. Matcher `"*"` также соответствует каждому файлу, но Claude Code регистрирует его в списке наблюдения, как и любое другое значение, — как буквальный файл с именем `*`.3306Чтобы отслеживать файлы, имена которых нельзя указать заранее, возвращайте [`watchPaths`](#filechanged-output) из хука для динамического обновления списка отслеживания. Claude Code запускает наблюдатель только тогда, когда что-то указывает файл для отслеживания, поэтому заполните список группой FileChanged, matcher которой называет хотя бы один файл, или хуком [SessionStart](#sessionstart-decision-control) или [CwdChanged](#cwdchanged), возвращающим `watchPaths`. Matcher по-прежнему фильтрует, какие группы хуков запускаются при изменении отслеживаемого файла, поэтому для группы, обрабатывающей динамические пути, не указывайте matcher: тогда он соответствует каждому отслеживаемому файлу и ничего не добавляет в список отслеживания. Matcher `"*"` тоже соответствует каждому файлу, но Claude Code регистрирует его в списке отслеживания как любое другое значение — как файл с буквальным именем `*`.
3281 3307
3282Хуки FileChanged имеют доступ к [`CLAUDE_ENV_FILE`](#persist-environment-variables). Переменные, записанные в этот файл, сохраняются для последующих команд Bash до следующего события [CwdChanged](#cwdchanged), когда Claude Code их очищает.3308Хуки FileChanged имеют доступ к [`CLAUDE_ENV_FILE`](#persist-environment-variables). Переменные, записанные в этот файл, сохраняются для последующих команд Bash до следующего события [CwdChanged](#cwdchanged), когда Claude Code их очищает.
3283 3309
3304```3330```
3305 3331
3306<h4 id="filechanged-output">3332<h4 id="filechanged-output">
3307 Вывод FileChanged3333 Выходные данные FileChanged
3308</h4>3334</h4>
3309 3335
3310Помимо [выходных полей JSON](#json-output), доступных всем хукам, хуки FileChanged могут возвращать `watchPaths`, чтобы динамически обновлять, за какими путями к файлам ведётся наблюдение:3336Помимо [полей вывода JSON](#json-output), доступных всем хукам, хуки FileChanged могут возвращать `watchPaths` для динамического обновления отслеживаемых путей файлов:
3311 3337
3312| Поле | Описание |3338| Поле | Описание |
3313| :- | :- |3339| :- | :- |
3314| `watchPaths` | Массив абсолютных путей. Заменяет текущий динамический список наблюдения. За путями из вашей конфигурации `matcher` наблюдение ведётся всегда. Используйте это, когда ваш скрипт хука обнаруживает дополнительные файлы для отслеживания на основе изменённого файла |3340| `watchPaths` | Массив абсолютных путей. Заменяет текущий динамический список отслеживания. Пути из конфигурации `matcher` отслеживаются всегда. Используйте это, когда скрипт хука обнаруживает дополнительные файлы для отслеживания на основе изменённого файла |
3315 3341
3316У хуков FileChanged нет управления решениями. Они не могут предотвратить изменение файла.3342Хуки FileChanged не управляют решениями. Они не могут предотвратить изменение файла.
3317 3343
3318Claude Code считывает `watchPaths` и `systemMessage` из их JSON-вывода и отбрасывает `continue`. В интерактивных сессиях он показывает `systemMessage` как короткое уведомление в терминале. Сообщение не попадает в поток сообщений SDK.3344Claude Code считывает `watchPaths` и `systemMessage` из их вывода JSON и отбрасывает `continue`. В интерактивных сессиях `systemMessage` показывается как краткое уведомление в терминале. Сообщение не попадает в поток сообщений SDK.
3319 3345
3320<h3 id="worktreecreate">3346<h3 id="worktreecreate">
3321 WorktreeCreate3347 WorktreeCreate
3323 3349
3324Запускается, когда Claude Code создаёт worktree, например в таких случаях:3350Запускается, когда Claude Code создаёт worktree, например в таких случаях:
3325 3351
3326* Вы запускаете сессию с помощью `claude --worktree`3352* Вы запускаете сессию командой `claude --worktree`
3327* Claude создаёт worktree во время сессии и переключается в него с помощью инструмента [`EnterWorktree`](/docs/ru/tools-reference)3353* Claude создаёт worktree во время сессии и переключается в него с помощью инструмента [`EnterWorktree`](/docs/ru/tools-reference)
3328* [Субагент использует `isolation: "worktree"`](/docs/ru/sub-agents#choose-the-subagent-scope)3354* [Субагент использует `isolation: "worktree"`](/docs/ru/sub-agents#choose-the-subagent-scope)
3329* [Рабочий процесс](/docs/ru/workflows#migrate-many-files-in-parallel) запускает агента в собственном worktree3355* [Рабочий процесс](/docs/ru/workflows#migrate-many-files-in-parallel) запускает агента в собственном worktree
3330* Claude Code изолирует [фоновую сессию](/docs/ru/agent-view#how-file-edits-are-isolated) в собственном worktree3356* Claude Code изолирует [фоновую сессию](/docs/ru/agent-view#how-file-edits-are-isolated) в собственном worktree
3331* [`claude remote-control`](/docs/ru/remote-control#start-a-remote-control-session) в режиме `worktree` запускает сессию в собственном worktree3357* [`claude remote-control`](/docs/ru/remote-control#start-a-remote-control-session) в режиме `worktree` запускает сессию в собственном worktree
3332 3358
3333Когда Claude выполняет `git worktree add` через инструмент Bash, а не вызывает `EnterWorktree`, ваш хук WorktreeCreate не запускается. Чтобы проверить или заблокировать эту команду, добавьте хук [`PreToolUse`](#pretooluse) с matcher `Bash`.3359Если Claude выполняет `git worktree add` через инструмент Bash вместо вызова `EnterWorktree`, ваш хук WorktreeCreate не запускается. Чтобы проверить или заблокировать эту команду, добавьте хук [`PreToolUse`](#pretooluse) с matcher `Bash`.
3334 3360
3335По умолчанию Claude Code создаёт изолированную рабочую копию с помощью `git worktree`. Настройка хука WorktreeCreate заменяет это стандартное поведение git, позволяя использовать другую систему контроля версий, например SVN, Perforce или Mercurial.3361По умолчанию Claude Code создаёт изолированную рабочую копию с помощью `git worktree`. Настройка хука WorktreeCreate заменяет это стандартное поведение git, позволяя использовать другую систему контроля версий, например SVN, Perforce или Mercurial.
3336 3362
3337Поскольку хук полностью заменяет стандартное поведение, [`.worktreeinclude`](/docs/ru/worktrees#copy-gitignored-files-into-worktrees) не обрабатывается. Если вам нужно скопировать в новый worktree локальные файлы конфигурации, например `.env`, сделайте это внутри скрипта хука.3363Поскольку хук полностью заменяет стандартное поведение, [`.worktreeinclude`](/docs/ru/worktrees#copy-gitignored-files-into-worktrees) не обрабатывается. Если нужно скопировать локальные файлы конфигурации, такие как `.env`, в новый worktree, делайте это в скрипте хука.
3338 3364
3339Хук должен вернуть путь к каталогу созданного worktree. Claude Code использует этот путь как рабочий каталог изолированной сессии. О том, как каждый тип хука возвращает путь, см. в разделе [Вывод WorktreeCreate](#worktreecreate-output).3365Хук должен вернуть путь к созданному каталогу worktree. Claude Code использует этот путь как рабочий каталог для изолированной сессии. О том, как каждый тип хука возвращает путь, см. [Выходные данные WorktreeCreate](#worktreecreate-output).
3340 3366
3341Claude Code учитывает успешность выполнения хука и возвращённый путь, а `systemMessage` и `continue` отбрасывает.3367Claude Code учитывает успешность хука и возвращённый путь и отбрасывает `systemMessage` и `continue`.
3342 3368
3343Этот пример создаёт рабочую копию SVN и выводит путь, который будет использовать Claude Code. Замените URL репозитория на свой:3369Этот пример создаёт рабочую копию SVN и выводит путь для использования в Claude Code. Замените URL репозитория своим:
3344 3370
3345```json theme={null}3371```json theme={null}
3346{3372{
3359}3385}
3360```3386```
3361 3387
3362Хук считывает `name` worktree из входных данных JSON в stdin, извлекает свежую копию в новый каталог и выводит путь к каталогу. Именно `echo` в последней строке Claude Code считывает как путь к worktree. Перенаправляйте любой другой вывод в stderr, чтобы он не мешал пути.3388Хук считывает `name` worktree из входных данных JSON на stdin, извлекает свежую копию в новый каталог и выводит путь к каталогу. `echo` в последней строке — это то, что Claude Code считывает как путь к worktree. Перенаправляйте любой другой вывод в stderr, чтобы он не мешал пути.
3363 3389
3364<h4 id="worktreecreate-input">3390<h4 id="worktreecreate-input">
3365 Входные данные WorktreeCreate3391 Входные данные WorktreeCreate
3366</h4>3392</h4>
3367 3393
3368Помимо [общих входных полей](#common-input-fields), хуки WorktreeCreate получают поле `name`. Это идентификатор-слаг нового worktree, заданный пользователем или сгенерированный автоматически, например `bold-oak-a3f2`.3394Помимо [общих входных полей](#common-input-fields), хуки WorktreeCreate получают поле `name`. Это slug-идентификатор нового worktree, заданный пользователем или сгенерированный автоматически, например `bold-oak-a3f2`.
3369 3395
3370```json theme={null}3396```json theme={null}
3371{3397{
3378```3404```
3379 3405
3380<h4 id="worktreecreate-output">3406<h4 id="worktreecreate-output">
3381 Вывод WorktreeCreate3407 Выходные данные WorktreeCreate
3382</h4>3408</h4>
3383 3409
3384Хуки WorktreeCreate не используют стандартную модель решений «разрешить/заблокировать». Вместо этого результат определяется успехом или неудачей хука. Хук должен вернуть путь к каталогу созданного worktree:3410Хуки WorktreeCreate не используют стандартную модель решений разрешения/блокировки. Вместо этого результат определяется успехом или неудачей хука. Хук должен вернуть путь к созданному каталогу worktree:
3385 3411
3386* **Командные хуки** (`type: "command"`): выведите путь последней непустой строкой stdout. Claude Code удаляет управляющие последовательности ANSI перед чтением этой строки, поэтому баннеры запуска оболочки, выведенные до вашего `echo`, игнорируются. Перенаправляйте любой другой вывод хука в stderr.3412* **Хуки команд** (`type: "command"`): выведите путь последней непустой строкой stdout. Claude Code удаляет escape-коды ANSI перед чтением этой строки, поэтому баннеры запуска оболочки, выведенные до вашего `echo`, игнорируются. Перенаправляйте любой другой вывод хука в stderr.
3387* **HTTP-хуки** (`type: "http"`): верните `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` в теле ответа.3413* **HTTP-хуки** (`type: "http"`): верните `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` в теле ответа.
3388 3414
3389Если хук завершается с ошибкой или не выдаёт путь, создание worktree завершается ошибкой.3415Если хук завершается неудачей или не выдаёт путь, создание worktree завершается ошибкой.
3390 3416
3391Claude Code разрешает относительный путь относительно каталога, в котором выполнялся хук, сворачивая в нём любые сегменты `.` или `..`. Если полученный путь не является каталогом, в который Claude Code может перейти, сессия выводит ошибку с указанием пути и завершается с кодом выхода 1.3417Claude Code разрешает относительный путь относительно каталога, в котором выполнялся хук, сворачивая в нём любые сегменты `.` или `..`. Если полученный путь не является каталогом, в который Claude Code может войти, сессия выводит ошибку с указанием пути и завершается с кодом 1.
3392 3418
3393Claude Code отклоняет абсолютный путь, содержащий сегменты `.` или `..`, а также любой путь, проходящий через символическую ссылку ниже корня репозитория, поскольку символическая ссылка, закоммиченная в репозиторий, может перенаправить worktree за его пределы. В ошибке указывается отклонённый компонент. Возвращайте нормализованный путь, который не проходит через символическую ссылку внутри репозитория. До v2.1.216 создание worktree следовало пути хука без такой проверки.3419Claude Code отклоняет абсолютный путь, содержащий сегменты `.` или `..`, а также любой путь, проходящий через символическую ссылку ниже корня репозитория, поскольку символическая ссылка, закоммиченная в репозиторий, может перенаправить worktree за его пределы. В ошибке указывается отклонённый компонент. Возвращайте нормализованный путь, который не проходит через символическую ссылку внутри репозитория. До v2.1.216 создание worktree следовало пути хука без этой проверки.
3394 3420
3395<h3 id="worktreeremove">3421<h3 id="worktreeremove">
3396 WorktreeRemove3422 WorktreeRemove
3398 3424
3399Запускается, когда Claude Code очищает worktree, созданный вашим хуком [`WorktreeCreate`](#worktreecreate). Событие срабатывает, когда:3425Запускается, когда Claude Code очищает worktree, созданный вашим хуком [`WorktreeCreate`](#worktreecreate). Событие срабатывает, когда:
3400 3426
3401* Вы выходите из интерактивной [сессии в worktree](/docs/ru/worktrees#start-claude-in-a-worktree) и соглашаетесь удалить worktree, когда Claude Code спрашивает об этом3427* Вы выходите из интерактивной [сессии worktree](/docs/ru/worktrees#start-claude-in-a-worktree) и выбираете удаление worktree в ответ на запрос Claude Code
3402* Вы выходите из интерактивной сессии в worktree, которой не [дали имя](/docs/ru/sessions#name-your-sessions), Claude Code не находит изменённых или неотслеживаемых файлов и удаляет worktree, не спрашивая вас3428* Вы выходите из интерактивной сессии worktree, которой не [дали имя](/docs/ru/sessions#name-your-sessions), Claude Code не находит изменённых или неотслеживаемых файлов и удаляет worktree без запроса
3403* Вы удаляете [фоновую сессию](/docs/ru/agent-view#what-deleting-a-session-removes), которая работает в этом worktree3429* Вы удаляете [фоновую сессию](/docs/ru/agent-view#what-deleting-a-session-removes), работающую в worktree
3404* Вы просите Claude выйти и удалить worktree во время сессии, и Claude удаляет его с помощью инструмента [`ExitWorktree`](/docs/ru/tools-reference)3430* Вы просите Claude выйти и удалить worktree во время сессии, и Claude удаляет его инструментом [`ExitWorktree`](/docs/ru/tools-reference)
3405* Сессия, запущенная [`claude remote-control`](/docs/ru/remote-control#start-a-remote-control-session) в режиме `worktree`, завершается без сбоя, и Claude Code не находит в её worktree изменённых или неотслеживаемых файлов и новых коммитов3431* Сессия, которую [`claude remote-control`](/docs/ru/remote-control#start-a-remote-control-session) запустил в режиме `worktree`, завершается без сбоя, и Claude Code не находит в её worktree изменённых или неотслеживаемых файлов и новых коммитов
3406* Вы останавливаете `claude remote-control`, пока запущенные им в режиме `worktree` сессии ещё работают, и Claude Code не находит в их worktree изменённых или неотслеживаемых файлов и новых коммитов3432* Вы останавливаете `claude remote-control`, пока запущенные им в режиме `worktree` сессии ещё работают, и Claude Code не находит в их worktree изменённых или неотслеживаемых файлов и новых коммитов
3407 3433
3408Когда субагент или агент рабочего процесса завершает работу, Claude Code сохраняет worktree, созданный для него вашим хуком WorktreeCreate, и не запускает ваш хук WorktreeRemove. Удалите эти worktree самостоятельно, когда работа будет завершена.3434Когда субагент или агент рабочего процесса завершает работу, Claude Code сохраняет worktree, созданный для него вашим хуком WorktreeCreate, и не запускает хук WorktreeRemove. Удаляйте такие worktree самостоятельно, когда работа завершена.
3409 3435
3410Claude Code не запрашивает подтверждение перед запуском вашего хука при вызове `ExitWorktree` или очистке `claude remote-control`. `ExitWorktree` отказывается удалять созданный хуком worktree, если в вызове не передан [`discard_changes: true`](/docs/ru/agent-sdk/typescript#exitworktree), поэтому на этом пути ваш хук является последней проверкой.3436Claude Code не запрашивает подтверждение перед запуском хука для вызова `ExitWorktree` или очистки `claude remote-control`. `ExitWorktree` отказывается удалять созданный хуком worktree, если вызов не передаёт [`discard_changes: true`](/docs/ru/agent-sdk/typescript#exitworktree), что делает ваш хук последней проверкой на этом пути.
3411 3437
3412Claude Code ищет изменённые или неотслеживаемые файлы с помощью Git, поэтому не находит их в worktree, который не является Git-checkout и не находится внутри него, даже если в каталоге есть незакоммиченная работа. Проверяйте наличие такой работы в хуке WorktreeRemove, прежде чем он что-либо удалит.3438Claude Code использует git для поиска изменённых или неотслеживаемых файлов, поэтому не находит их в worktree, который не является git-checkout и не находится внутри него, даже если в каталоге есть незакоммиченная работа. Проверяйте наличие такой работы в хуке WorktreeRemove, прежде чем он что-либо удалит.
3413 3439
3414Для worktree на основе git Claude Code выполняет очистку автоматически с помощью `git worktree remove`. Если вы настроили хук WorktreeCreate, добавьте к нему хук WorktreeRemove для управления очисткой:3440Для worktree на основе git Claude Code автоматически выполняет очистку с помощью `git worktree remove`. Если вы настроили хук WorktreeCreate, дополните его хуком WorktreeRemove, чтобы управлять очисткой:
3415 3441
3416* **Нет хука WorktreeRemove**: Claude Code использует git как резервный вариант для удаления при выходе или через `ExitWorktree` и сохраняет worktree, когда очистку выполняет `claude remote-control`:3442* **Нет хука WorktreeRemove**: Claude Code использует git как резервный вариант при удалении на выходе или через `ExitWorktree` и сохраняет worktree при очистке `claude remote-control`:
3417 * **Вы выходите из сессии worktree или Claude вызывает `ExitWorktree`**: Claude Code удаляет путь, возвращённый вашим хуком WorktreeCreate, так же, как это сделала бы `git worktree remove --force`, поэтому worktree, который распознаёт git, удаляется. Worktree, который git не распознаёт, например созданный вашим хуком с помощью системы контроля версий, отличной от git, остаётся на диске.3443 * **Вы выходите из сессии worktree или Claude вызывает `ExitWorktree`**: Claude Code удаляет путь, возвращённый хуком WorktreeCreate, так же, как это сделал бы `git worktree remove --force`, поэтому worktree, распознаваемый git, удаляется. Worktree, который git не распознаёт, например созданный хуком с системой контроля версий, отличной от git, остаётся на диске.
3418 * **`claude remote-control` очищает worktree сессии**: worktree остаётся на диске, а терминал, в котором работает `claude remote-control`, показывает `worktree removal failed, kept: <path>`.3444 * **`claude remote-control` очищает worktree сессии**: worktree остаётся на диске, а терминал, в котором работает `claude remote-control`, показывает `worktree removal failed, kept: <path>`.
3419 * **Вы удаляете фоновую сессию**: см. [Что удаляется при удалении сессии](/docs/ru/agent-view#what-deleting-a-session-removes).3445 * **Вы удаляете фоновую сессию**: см. [Что удаляется при удалении сессии](/docs/ru/agent-view#what-deleting-a-session-removes).
3420* **Хук завершается с кодом 0**: worktree считается удалённым. Claude Code больше ничего не считывает из хука, поэтому убедитесь, что ваш хук удалил каталог.3446* **Хук завершается с кодом 0**: worktree считается удалённым. Claude Code больше ничего не считывает из хука, поэтому убедитесь, что хук удалил каталог.
3421* **Хук завершается с ненулевым кодом**: удаление завершается неудачей, если каталог по пути `worktree_path` после этого всё ещё существует, и worktree остаётся на диске без резервного варианта через Git. Хук, который удалил каталог перед завершением с ненулевым кодом, считается успешно удалившим worktree. О том, как сообщается об ошибке, см. в разделе [Входные данные WorktreeRemove](#worktreeremove-input).3447* **Хук завершается с ненулевым кодом**: удаление завершается неудачей, если каталог по пути `worktree_path` после этого всё ещё существует, и worktree остаётся на диске без резервного варианта через git. Хук, удаливший каталог перед завершением с ненулевым кодом, считается выполнившим удаление. О том, как сообщается о неудаче, см. [Входные данные WorktreeRemove](#worktreeremove-input).
3422 3448
3423Claude Code никогда не удаляет ветку, принадлежащую worktree, созданному хуком, поскольку знает только путь, возвращённый вашим хуком WorktreeCreate. Если ваш хук WorktreeCreate создаёт ветку, удаляйте её в хуке WorktreeRemove.3449Claude Code никогда не удаляет ветку, принадлежащую созданному хуком worktree, потому что знает только путь, возвращённый хуком WorktreeCreate. Если хук WorktreeCreate создаёт ветку, удаляйте её в хуке WorktreeRemove.
3424 3450
3425Claude Code отбрасывает [поля вывода JSON](#json-output) хука WorktreeRemove, такие как `systemMessage` и `continue`.3451Claude Code отбрасывает [поля вывода JSON](#json-output) хука WorktreeRemove, такие как `systemMessage` и `continue`.
3426 3452
3427При удалении фоновой сессии Claude Code проверяет сохранённый путь к worktree перед запуском хука и отклоняет путь, который является символической ссылкой или проходит через неё ниже корня репозитория. На этом пути хук запускается для worktree, в котором ещё есть файлы, только если вы подтверждаете удаление в [представлении агентов](/docs/ru/agent-view#what-deleting-a-session-removes); для такого worktree [`claude rm`](/docs/ru/agent-view#manage-sessions-from-the-shell) вместо этого сохраняет сессию и worktree. До v2.1.216 хук запускался для сохранённого пути без этих проверок.3453При удалении фоновой сессии Claude Code проверяет сохранённый путь worktree перед запуском хука и отклоняет путь, который является символической ссылкой или проходит через неё ниже корня репозитория. На этом пути хук запускается для worktree, всё ещё содержащего файлы, только если вы подтверждаете удаление в [представлении агентов](/docs/ru/agent-view#what-deleting-a-session-removes); для такого worktree [`claude rm`](/docs/ru/agent-view#manage-sessions-from-the-shell) вместо этого сохраняет сессию и worktree. До v2.1.216 хук запускался для сохранённого пути без этих проверок.
3428 3454
3429Claude Code передаёт путь, возвращённый WorktreeCreate, как `worktree_path` во входных данных хука. Этот пример считывает этот путь и удаляет каталог:3455Claude Code передаёт путь, возвращённый WorktreeCreate, как `worktree_path` во входных данных хука. Этот пример считывает этот путь и удаляет каталог:
3430 3456
3461}3487}
3462```3488```
3463 3489
3464Результат определяется кодом выхода хука WorktreeRemove. Когда хук завершается с ненулевым кодом и каталог по пути `worktree_path` после этого всё ещё существует, удаление завершается неудачей:3490Результат определяется кодом выхода хука WorktreeRemove. Если хук завершается с ненулевым кодом, а каталог по пути `worktree_path` после этого всё ещё существует, удаление завершается неудачей:
3465 3491
3466* Worktree остаётся на диске, а команда хука и его stderr попадают в [лог отладки](#debug-hooks).3492* Worktree остаётся на диске, а команда хука и его stderr попадают в [отладочный лог](#debug-hooks).
3467* Если вы удаляли фоновую сессию, сессия тоже остаётся. Сообщение об отказе в [agent view](/docs/ru/agent-view#what-deleting-a-session-removes) сообщает, как завершился хук, например `exited 1`, цитирует начало его stderr и указывает, удалит ли повторное удаление сессии каталог в любом случае.3493* Если вы удаляли фоновую сессию, сессия тоже сохраняется. Сообщение об отказе в [представлении агентов](/docs/ru/agent-view#what-deleting-a-session-removes) сообщает, как завершился хук, например `exited 1`, цитирует начало его stderr и указывает, удалит ли повторное удаление сессии каталог в любом случае.
3468* Если `claude remote-control` очищал worktree сессии, терминал, в котором он работает, показывает `worktree removal failed, kept: <path>`.3494* Если `claude remote-control` очищал worktree сессии, терминал, в котором он работает, показывает `worktree removal failed, kept: <path>`.
3469 3495
3470<h3 id="precompact">3496<h3 id="precompact">
3478| Matcher | Когда срабатывает |3504| Matcher | Когда срабатывает |
3479| :- | :- |3505| :- | :- |
3480| `manual` | `/compact` |3506| `manual` | `/compact` |
3481| `auto` | Автосжатие, когда диалог достигает [окна автосжатия](/docs/ru/model-config#set-the-auto-compact-window) |3507| `auto` | Автосжатие, когда диалог достигает [окна автосжатия](/docs/ru/model-config#set-the-auto-compact-window), и [сжатие при простое](/docs/ru/settings-reference#idlecompaction) |
3482 3508
3483Завершитесь с кодом 2, чтобы заблокировать сжатие. Для ручного `/compact` сообщение из stderr показывается пользователю. Также можно заблокировать сжатие, вернув JSON с `"decision": "block"`.3509Завершитесь с кодом 2, чтобы заблокировать сжатие. Для ручного `/compact` сообщение из stderr показывается пользователю. Также можно заблокировать сжатие, вернув JSON с `"decision": "block"`.
3484 3510
3485Блокировка автоматического сжатия действует по-разному в зависимости от момента срабатывания. Если сжатие было запущено заранее, до достижения лимита контекста, Claude Code пропускает его, и диалог продолжается без сжатия. Если сжатие было запущено для восстановления после ошибки лимита контекста, уже возвращённой API, исходная ошибка отображается, и текущий запрос завершается неудачей.3511Блокировка автоматического сжатия имеет разные последствия в зависимости от момента срабатывания. Если сжатие было запущено заблаговременно, до достижения лимита контекста, Claude Code пропускает его, и диалог продолжается без сжатия. Если сжатие было запущено для восстановления после ошибки лимита контекста, уже возвращённой API, исходная ошибка выводится, и текущий запрос завершается неудачей.
3486 3512
3487Claude Code отбрасывает поля `systemMessage` и `continue` хука PreCompact.3513Claude Code отбрасывает поля `systemMessage` и `continue` хука PreCompact.
3488 3514
3490 Входные данные PreCompact3516 Входные данные PreCompact
3491</h4>3517</h4>
3492 3518
3493Помимо [общих входных полей](#common-input-fields), хуки PreCompact получают `trigger` и `custom_instructions`. Для `manual` поле `custom_instructions` содержит то, что пользователь передаёт в `/compact`, и равно `null`, если он ничего не передаёт. Для `auto` поле `custom_instructions` равно `null`.3519Помимо [общих входных полей](#common-input-fields), хуки PreCompact получают `trigger` и `custom_instructions`. Для `manual` поле `custom_instructions` содержит то, что пользователь передаёт в `/compact`, и равно `null`, если ничего не передано. Для `auto` поле `custom_instructions` равно `null`.
3494 3520
3495```json theme={null}3521```json theme={null}
3496{3522{
3507 PostCompact3533 PostCompact
3508</h3>3534</h3>
3509 3535
3510Запускается после того, как Claude Code завершает операцию сжатия контекста. Используйте это событие, чтобы реагировать на новое сжатое состояние, например чтобы записать сгенерированную сводку в лог или обновить внешнее состояние. Claude Code отбрасывает поля `systemMessage` и `continue` хука PostCompact.3536Запускается после того, как Claude Code завершает операцию сжатия контекста. Используйте это событие, чтобы реагировать на новое сжатое состояние, например чтобы записать в лог сгенерированную сводку или обновить внешнее состояние. Claude Code отбрасывает поля `systemMessage` и `continue` хука PostCompact.
3511 3537
3512Применяются те же значения matcher, что и для `PreCompact`:3538Применяются те же значения matcher, что и для `PreCompact`:
3513 3539
3514| Matcher | Когда срабатывает |3540| Matcher | Когда срабатывает |
3515| :- | :- |3541| :- | :- |
3516| `manual` | После `/compact` |3542| `manual` | После `/compact` |
3517| `auto` | После автосжатия, когда диалог достигает [окна автосжатия](/docs/ru/model-config#set-the-auto-compact-window) |3543| `auto` | После автосжатия, когда диалог достигает [окна автосжатия](/docs/ru/model-config#set-the-auto-compact-window), и после [сжатия при простое](/docs/ru/settings-reference#idlecompaction) |
3518 3544
3519<h4 id="postcompact-input">3545<h4 id="postcompact-input">
3520 Входные данные PostCompact3546 Входные данные PostCompact
3539 PreModelSwitch3565 PreModelSwitch
3540</h3>3566</h3>
3541 3567
3542Запускается до того, как Claude Code применит смену модели, запрошенную вами или клиентом. Используйте его, чтобы заблокировать смену, потребовать подтверждения или показать, во что обойдётся смена, до того как она произойдёт.3568Запускается перед тем, как Claude Code применит переключение модели, запрошенное вами или клиентом. Используйте его, чтобы заблокировать переключение, потребовать подтверждения или показать, во что обойдётся переключение, до того как оно произойдёт.
3543 3569
3544PreModelSwitch требует Claude Code v2.1.251 или новее. Claude Code запускает его для следующих запросов:3570PreModelSwitch требует Claude Code v2.1.251 или новее. Claude Code запускает его для следующих запросов:
3545 3571
3546* `/model <name>` и окно выбора `/model`3572* `/model <name>` и окно выбора `/model`
3547* Окно выбора модели `Option+P` или `Alt+P`3573* Окно выбора модели `Option+P` или `Alt+P`
3548* Настройка Model в `/config`3574* Настройка Model в `/config`
3549* Включение [быстрого режима](/docs/ru/fast-mode), когда это меняет модель сессии3575* Включение [быстрого режима](/docs/ru/fast-mode), если это меняет модель сессии
3550* Запрос `set_model` или смена модели в запросе `apply_flag_settings` от хоста [Agent SDK](/docs/ru/agent-sdk/typescript#query-object) или [Remote Control](/docs/ru/remote-control)3576* Запрос `set_model` или изменение модели в запросе `apply_flag_settings` от хоста [Agent SDK](/docs/ru/agent-sdk/typescript#query-object) или [Remote Control](/docs/ru/remote-control)
3551 3577
3552Claude Code не запускает хуки PreModelSwitch для смен, которые выполняет самостоятельно, например при [автоматическом переключении на резервную модель](/docs/ru/model-config#automatic-model-fallback) или восстановлении модели при возобновлении сессии. Такие изменения доходят только до [PostModelSwitch](#postmodelswitch).3578Claude Code не запускает хуки PreModelSwitch для переключений, которые он выполняет сам, например при [автоматическом переключении на резервную модель](/docs/ru/model-config#automatic-model-fallback) или восстановлении модели при возобновлении сессии. Такие изменения доходят только до [PostModelSwitch](#postmodelswitch).
3553 3579
3554Claude Code сравнивает matcher с каноническим именем модели, на которую переключается сессия, игнорируя суффикс `[1m]`. Псевдоним, например `opus`, идентификатор модели с датой и идентификатор конкретного провайдера, например идентификатор модели Amazon Bedrock, — все соответствуют одному каноническому имени, к которому они разрешаются, поэтому `claude-opus-5` охватывает все варианты написания Opus 5.3580Claude Code сравнивает matcher с каноническим именем модели, на которую переключается сессия, игнорируя суффикс `[1m]`. Псевдоним, например `opus`, идентификатор модели с датой и идентификатор конкретного провайдера, например идентификатор модели Amazon Bedrock, соответствуют одному каноническому имени, в которое они разрешаются, поэтому `claude-opus-5` охватывает все варианты написания Opus 5.
3555 3581
3556Когда Claude Code не может определить каноническое имя целевой модели, например для пользовательского идентификатора модели, который знает только ваш [LLM-шлюз](/docs/ru/llm-gateway), он запускает все хуки PreModelSwitch независимо от matcher. Поэтому блокирующий хук должен проверять `to_model` из своих входных данных, а не полагаться только на matcher.3582Если Claude Code не может определить каноническое имя целевой модели, например для пользовательского идентификатора модели, известного только вашему [LLM-шлюзу](/docs/ru/llm-gateway), он запускает каждый хук PreModelSwitch независимо от matcher. Поэтому блокирующий хук должен проверять `to_model` из входных данных, а не полагаться только на matcher.
3557 3583
3558Записывайте matcher как точное имя, список через `|`, например `claude-opus-4-6|claude-opus-5`, или регулярное выражение, например `.*opus.*`. В этом примере используется matcher с точным именем, а также проверяется `to_model` из входных данных хука, поэтому он отклоняет переключение на Opus 4.6, завершаясь с кодом 2, и пропускает любую другую целевую модель:3584Записывайте matcher как точное имя, список через `|`, например `claude-opus-4-6|claude-opus-5`, или регулярное выражение, например `.*opus.*`. Этот пример использует matcher с точным именем и дополнительно проверяет `to_model` из входных данных хука, поэтому он отклоняет переключение на Opus 4.6, завершаясь с кодом 2, и пропускает любую другую целевую модель:
3559 3585
3560<Tabs>3586<Tabs>
3561 <Tab title="macOS/Linux">3587 <Tab title="macOS/Linux">
3581 </Tab>3607 </Tab>
3582 3608
3583 <Tab title="Windows (PowerShell)">3609 <Tab title="Windows (PowerShell)">
3584 Зарегистрируйте командный хук, который запускает скрипт через PowerShell:3610 Зарегистрируйте хук команды, который запускает скрипт через PowerShell:
3585 3611
3586 ```json theme={null}3612 ```json theme={null}
3587 {3613 {
3608 }3634 }
3609 ```3635 ```
3610 3636
3611 Сохраните этот скрипт в файл `.claude/hooks/block-opus-46.ps1` в вашем проекте:3637 Сохраните этот скрипт в `.claude/hooks/block-opus-46.ps1` в вашем проекте:
3612 3638
3613 ```powershell theme={null}3639 ```powershell theme={null}
3614 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json3640 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json
3621 </Tab>3647 </Tab>
3622</Tabs>3648</Tabs>
3623 3649
3624Чтобы убедиться, что хук работает, выполните `/model claude-opus-4-6` в сессии, использующей другую модель. Claude Code сохранит текущую модель и сообщит, что хук PreModelSwitch заблокировал смену, указав ваше сообщение в качестве причины.3650Чтобы убедиться, что хук работает, выполните `/model claude-opus-4-6` в сессии с другой моделью. Claude Code сохранит текущую модель и сообщит, что хук PreModelSwitch заблокировал переключение, указав ваше сообщение в качестве причины.
3625 3651
3626<h4 id="premodelswitch-input">3652<h4 id="premodelswitch-input">
3627 Входные данные PreModelSwitch3653 Входные данные PreModelSwitch
3628</h4>3654</h4>
3629 3655
3630Помимо [общих входных полей](#common-input-fields), хуки PreModelSwitch получают поля из этой таблицы. Последние пять описывают стоимость повторной отправки диалога новой модели, чтобы хук мог показать эту сумму до смены.3656Помимо [общих входных полей](#common-input-fields), хуки PreModelSwitch получают поля из этой таблицы. Последние пять описывают стоимость повторной отправки диалога новой модели, чтобы хук мог показать эту цифру до переключения.
3631 3657
3632| Поле | Тип | Описание |3658| Поле | Тип | Описание |
3633| :- | :- | :- |3659| :- | :- | :- |
3634| `from_model` | string | Идентификатор модели, с которой происходит смена |3660| `from_model` | string | Идентификатор модели, с которой выполняется переключение |
3635| `to_model` | string | Идентификатор модели, на которую происходит смена. Matcher сравнивается с каноническим именем этой модели |3661| `to_model` | string | Идентификатор модели, на которую выполняется переключение. Matcher сравнивается с каноническим именем этой модели |
3636| `requested_model` | string или `null` | Модель, указанная в запросе: псевдоним, например `opus`, полный идентификатор модели или `null`, если запрос был на модель по умолчанию |3662| `requested_model` | string или `null` | Модель, указанная в запросе: псевдоним, например `opus`, полный идентификатор модели или `null`, если запрашивалась модель по умолчанию |
3637| `source` | string | Откуда пришёл запрос: `"command"` для `/model <name>`, настройки Model в `/config` или включения быстрого режима; `"picker"` для окна выбора модели; `"sdk"` для запроса `set_model` или смены модели в запросе `apply_flag_settings` от хоста Agent SDK или Remote Control |3663| `source` | string | Откуда пришёл запрос: `"command"` для `/model <name>`, настройки Model в `/config` или включения быстрого режима; `"picker"` для окна выбора модели; `"sdk"` для запроса `set_model` или изменения модели в запросе `apply_flag_settings` от хоста Agent SDK или Remote Control |
3638| `context_tokens` | number | Токены, которые следующий запрос повторно отправит в качестве промпта: сумма входных токенов, токенов чтения кэша, создания кэша и выходных токенов последнего ответа в основном диалоге. `0` до первого ответа |3664| `context_tokens` | number | Токены, которые следующий запрос отправит повторно в качестве промпта: сумма входных токенов, токенов чтения кэша, создания кэша и выходных токенов последнего ответа в основном диалоге. `0` до первого ответа |
3639| `prompt_cache_warm` | boolean | Вероятно ли, что кэш промптов текущей модели всё ещё «тёплый», то есть смена приведёт к его потере |3665| `prompt_cache_warm` | boolean | Вероятно ли, что кэш промптов текущей модели ещё «тёплый», то есть переключение приведёт к его потере |
3640| `cache_ttl` | string | [Время жизни кэша промптов](/docs/ru/prompt-caching#cache-lifetime), которое Claude Code запрашивает для этой сессии: `"5m"` или `"1h"` |3666| `cache_ttl` | string | [Время жизни кэша промптов](/docs/ru/prompt-caching#cache-lifetime), которое Claude Code запрашивает для этой сессии: `"5m"` или `"1h"` |
3641| `estimated_cache_write_usd` | number | Оценочная стоимость в долларах США записи `context_tokens` в кэш промптов на `to_model` по тарифу `cache_ttl`, без учёта следующего ответа. Серверу может не понадобиться повторно кэшировать весь контекст, поэтому рассматривайте это значение как оценку |3667| `estimated_cache_write_usd` | number | Оценочная стоимость в долларах США записи `context_tokens` в кэш промптов на `to_model` по тарифу `cache_ttl`, без учёта следующего ответа. Серверу может не потребоваться повторно кэшировать весь контекст, поэтому считайте это оценкой |
3642| `pricing` | string | Как Claude Code рассчитал `estimated_cache_write_usd`: `"configured"` — по собственным тарифам вашей организации, если она их настроила, `"catalog"` — по прейскурантной цене, или `"default"`, когда цена `to_model` неизвестна и Claude Code принял тариф по умолчанию |3668| `pricing` | string | Как Claude Code рассчитал `estimated_cache_write_usd`: `"configured"` — по собственным тарифам вашей организации, если она их настроила, `"catalog"` — по прейскурантной цене, или `"default"` — если цена `to_model` неизвестна и Claude Code использовал тариф по умолчанию |
3643 3669
3644В этом примере показаны входные данные для `/model opus` в сессии, использующей Sonnet 5:3670Этот пример показывает входные данные для `/model opus` в сессии с Sonnet 5:
3645 3671
3646```json theme={null}3672```json theme={null}
3647{3673{
3665 Управление решениями PreModelSwitch3691 Управление решениями PreModelSwitch
3666</h4>3692</h4>
3667 3693
3668Хуки `PreModelSwitch` могут отменить смену, попросить пользователя подтвердить её или позволить ей выполниться. Код выхода 2 или `decision: "block"` верхнего уровня отменяет смену.3694Хуки `PreModelSwitch` могут отменить переключение, попросить пользователя подтвердить его или разрешить его выполнение. Код выхода 2 или `decision: "block"` на верхнем уровне отменяет переключение.
3669 3695
3670Для более тонкого управления возвращайте `permissionDecision` и `permissionDecisionReason` в объекте `hookSpecificOutput`, как для [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` принимает `"allow"`, `"deny"` и `"ask"`. Он не принимает `"defer"`, `updatedInput` или `additionalContext`. В таблице ниже описаны оба поля:3696Для более тонкого управления возвращайте `permissionDecision` и `permissionDecisionReason` в объекте `hookSpecificOutput`, как в [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` принимает `"allow"`, `"deny"` и `"ask"`. Он не принимает `"defer"`, `updatedInput` или `additionalContext`. В таблице ниже описаны оба поля:
3671 3697
3672| Поле | Описание |3698| Поле | Описание |
3673| :- | :- |3699| :- | :- |
3674| `permissionDecision` | `"allow"` выполняет смену и пропускает [подтверждение, которое Claude Code показывает, пока кэш промптов «тёплый»](/docs/ru/prompt-caching#switching-models). `"deny"` отменяет смену. `"ask"` просит пользователя подтвердить её |3700| `permissionDecision` | `"allow"` продолжает и пропускает [подтверждение, которое Claude Code показывает, пока кэш промптов «тёплый»](/docs/ru/prompt-caching#switching-models). `"deny"` отменяет переключение. `"ask"` просит пользователя подтвердить его |
3675| `permissionDecisionReason` | Для `"deny"` показывается пользователю как причина блокировки смены или возвращается как ошибка для запроса `set_model`. Для `"ask"` показывается в запросе подтверждения. Игнорируется для `"allow"` |3701| `permissionDecisionReason` | Для `"deny"` показывается пользователю как причина блокировки переключения или возвращается как ошибка для запроса `set_model`. Для `"ask"` показывается в запросе подтверждения. Игнорируется для `"allow"` |
3676 3702
3677Показать запрос `"ask"` может только `/model` в интерактивной сессии. На всех остальных интерфейсах, включая неинтерактивный режим с флагом `-p`, `/config` и запросы `set_model`, Claude Code рассматривает `"ask"` как отказ.3703Только `/model` в интерактивной сессии может показать запрос `"ask"`. Во всех остальных интерфейсах, включая неинтерактивный режим с флагом `-p`, `/config` и запросы `set_model`, Claude Code рассматривает `"ask"` как отказ.
3678 3704
3679Этот пример просит пользователя подтвердить смену и приводит количество токенов из `context_tokens`:3705Этот пример просит пользователя подтвердить переключение и приводит количество токенов из `context_tokens`:
3680 3706
3681```json theme={null}3707```json theme={null}
3682{3708{
3688}3714}
3689```3715```
3690 3716
3691Когда несколько хуков PreModelSwitch возвращают разные решения, приоритет таков: `deny` > `ask` > `allow`.3717Когда несколько хуков PreModelSwitch возвращают разные решения, приоритет такой: `deny` > `ask` > `allow`.
3692 3718
3693Claude Code показывает пользователю любое `systemMessage`, возвращённое вашим хуком, независимо от решения, поэтому хук, сообщающий о стоимости, может вернуть `{"systemMessage": "..."}` и завершиться с кодом 0.3719Claude Code показывает пользователю любое `systemMessage`, возвращённое хуком, независимо от решения, поэтому хук для отчёта о стоимости может вернуть `{"systemMessage": "..."}` и завершиться с кодом 0.
3694 3720
3695Хук PreModelSwitch, который не ответил до истечения таймаута, блокирует переключение. О том, что делает таймаут для других событий, см. [Таймауты](#timeouts). Таймаут по умолчанию для этого события — 30 секунд. `PreModelSwitch` запускает только хуки `command`, `http` и `mcp_tool`, поэтому значения по умолчанию для `prompt` и `agent` не применяются.3721Хук PreModelSwitch, не ответивший до истечения таймаута, блокирует переключение. О том, что делает таймаут для других событий, см. [Таймауты](#timeouts). Таймаут по умолчанию для этого события — 30 секунд. `PreModelSwitch` запускает только хуки `command`, `http` и `mcp_tool`, поэтому значения по умолчанию для `prompt` и `agent` не применяются.
3696 3722
3697Хук, который завершается с кодом, отличным от 0 или 2, и не выводит JSON-решение, считается неблокирующей ошибкой, как описано в разделе [Другие коды выхода](#other-exit-codes).3723Хук, завершившийся с кодом, отличным от 0 или 2, и не выводящий решения в JSON, считается неблокирующей ошибкой, как описано в разделе [Другие коды выхода](#other-exit-codes).
3698 3724
3699<h3 id="postmodelswitch">3725<h3 id="postmodelswitch">
3700 PostModelSwitch3726 PostModelSwitch
3701</h3>3727</h3>
3702 3728
3703Запускается после смены модели сессии. Используйте его, чтобы давать Claude указания для конкретной модели, не редактируя каждый CLAUDE.md, например инструкцию для всей организации, действующую для определённых моделей.3729Запускается после изменения модели сессии. Используйте его, чтобы дать Claude указания для конкретной модели без редактирования каждого CLAUDE.md, например инструкцию уровня организации, применимую к определённым моделям.
3704 3730
3705PostModelSwitch требует Claude Code v2.1.251 или новее. Он не может блокировать, поскольку модель уже сменилась. Claude Code запускает хуки PostModelSwitch после любого из следующих изменений:3731PostModelSwitch требует Claude Code v2.1.251 или новее. Он не может блокировать, потому что модель уже изменилась. Claude Code запускает хуки PostModelSwitch после любого из следующих изменений:
3706 3732
3707* Смена, запрошенная вами или клиентом3733* Переключение, запрошенное вами или клиентом
3708* [Автоматическое переключение на резервную модель](/docs/ru/model-config#automatic-model-fallback), которое меняет модель сессии3734* [Автоматическое переключение на резервную модель](/docs/ru/model-config#automatic-model-fallback), которое меняет модель сессии
3709* Вход в режим планирования или выход из него при настройке, такой как [`opusplan`](/docs/ru/model-config#opusplan-model-setting)3735* Вход в режим планирования или выход из него при настройке, такой как [`opusplan`](/docs/ru/model-config#opusplan-model-setting)
3710* Восстановление модели Claude Code при возобновлении сессии3736* Восстановление модели Claude Code при возобновлении сессии
3711 3737
3712Claude Code не запускает хуки PostModelSwitch, когда ход обслуживает модель из [цепочки резервных моделей](/docs/ru/model-config#fallback-model-chains), поскольку такая замена длится один ход и не меняет модель сессии.3738Claude Code не запускает хуки PostModelSwitch, когда ход обслуживает модель из [цепочки резервных моделей](/docs/ru/model-config#fallback-model-chains), потому что такая замена длится один ход и не меняет модель сессии.
3713 3739
3714Matcher подчиняется тем же правилам, что и для [PreModelSwitch](#premodelswitch): Claude Code сравнивает его с каноническим именем модели, на которую переключилась сессия.3740Matcher подчиняется тем же правилам, что и в [PreModelSwitch](#premodelswitch): Claude Code сравнивает его с каноническим именем модели, на которую переключилась сессия.
3715 3741
3716Этот пример добавляет указания всякий раз, когда модель сессии меняется на любую модель Opus:3742Этот пример добавляет указания всякий раз, когда модель сессии меняется на любую модель Opus:
3717 3743
3733}3759}
3734```3760```
3735 3761
3736Чтобы убедиться, что хук работает, переключитесь на модель Opus в сессии, использующей другую модель, например выполните `/model opus` в сессии Sonnet, а затем спросите Claude, какие указания у него есть относительно текущей модели.3762Чтобы убедиться, что хук работает, переключитесь на модель Opus в сессии с другой моделью, например выполните `/model opus` в сессии Sonnet, а затем спросите Claude, какие у него есть указания относительно текущей модели.
3737 3763
3738<h4 id="postmodelswitch-input">3764<h4 id="postmodelswitch-input">
3739 Входные данные PostModelSwitch3765 Входные данные PostModelSwitch
3740</h4>3766</h4>
3741 3767
3742Хуки PostModelSwitch получают те же поля, что и [PreModelSwitch](#premodelswitch-input), с `hook_event_name`, равным `"PostModelSwitch"`, и двумя дополнительными значениями `source`: `"auto"` для автоматического переключения на резервную модель или другого изменения, которое Claude Code выполнил самостоятельно, и `"resume"` для модели, восстановленной при возобновлении сессии.3768Хуки PostModelSwitch получают те же поля, что и [PreModelSwitch](#premodelswitch-input), при этом `hook_event_name` равно `"PostModelSwitch"`, и есть ещё два значения `source`: `"auto"` для автоматического переключения на резервную модель или другого изменения, сделанного Claude Code самостоятельно, и `"resume"` для модели, восстановленной при возобновлении сессии.
3743 3769
3744`requested_model` равно `null`, когда `source` равно `"auto"`. Когда `source` равно `"resume"`, это сохранённая настройка модели, которую восстановил Claude Code.3770`requested_model` равно `null`, когда `source` равно `"auto"`. Когда `source` равно `"resume"`, это сохранённая настройка модели, которую восстановил Claude Code.
3745 3771
3747 Управление решениями PostModelSwitch3773 Управление решениями PostModelSwitch
3748</h4>3774</h4>
3749 3775
3750Claude Code берёт [обычный текстовый stdout](#exit-code-0) вашего хука при коде выхода 0 или `additionalContext` из вывода JSON и передаёт его Claude вместе со следующим запросом после смены. Помимо [полей вывода JSON](#json-output), доступных всем хукам, можно вернуть:3776Claude Code берёт [простой текст stdout](#exit-code-0) вашего хука при коде выхода 0 или `additionalContext` из вывода JSON и передаёт его Claude со следующим запросом после переключения. Помимо [полей вывода JSON](#json-output), доступных всем хукам, можно вернуть:
3751 3777
3752| Поле | Описание |3778| Поле | Описание |
3753| :- | :- |3779| :- | :- |
3754| `additionalContext` | Строка, добавляемая в контекст Claude со следующим запросом. См. [Добавление контекста для Claude](#add-context-for-claude) |3780| `additionalContext` | Строка, добавляемая в контекст Claude со следующим запросом. См. [Добавление контекста для Claude](#add-context-for-claude) |
3755 3781
3756Если хук не завершился в течение пяти секунд после отправки следующего промпта, Claude Code отправляет этот запрос без вывода и прикрепляет вывод к следующему запросу. Если модель меняется несколько раз до следующего запроса, Claude Code передаёт только вывод для целевой модели последней смены.3782Если хук не завершился в течение пяти секунд после отправки следующего промпта, Claude Code отправляет этот запрос без вывода и прикрепляет его к следующему за ним запросу. Если модель меняется несколько раз до следующего запроса, Claude Code передаёт только вывод для целевой модели последнего переключения.
3757 3783
3758<h3 id="sessionend">3784<h3 id="sessionend">
3759 SessionEnd3785 SessionEnd
3760</h3>3786</h3>
3761 3787
3762Запускается при завершении сессии Claude Code. Полезен для задач очистки, записи статистики3788Запускается при завершении сессии Claude Code. Полезен для задач очистки, записи
3763сессии в лог или сохранения состояния сессии. Поддерживает matcher для фильтрации по причине выхода.3789статистики сессии в лог или сохранения состояния сессии. Поддерживает matcher для фильтрации по причине выхода.
3764 3790
3765Поле `reason` во входных данных хука указывает, почему сессия завершилась:3791Поле `reason` во входных данных хука указывает, почему сессия завершилась:
3766 3792
3767| Причина | Описание |3793| Причина | Описание |
3768| :- | :- |3794| :- | :- |
3769| `clear` | Сессия очищена командой `/clear` |3795| `clear` | Сессия очищена командой `/clear` |
3770| `resume` | Сессия переключена через интерактивную команду `/resume` |3796| `resume` | Сессия переключена через интерактивную `/resume` |
3771| `logout` | Пользователь вышел из системы |3797| `logout` | Пользователь вышел из системы |
3772| `prompt_input_exit` | Пользователь вышел, когда было видно поле ввода промпта |3798| `prompt_input_exit` | Пользователь вышел, пока было видно поле ввода промпта |
3773| `other` | Другие причины выхода |3799| `other` | Другие причины выхода |
3774| `bypass_permissions_disabled` | Удалено в v2.1.234; Claude Code его не отправляет. Уберите его из своих matcher для `SessionEnd` |3800| `bypass_permissions_disabled` | Удалено в v2.1.234; Claude Code его не отправляет. Уберите его из matcher для `SessionEnd` |
3775 3801
3776<h4 id="sessionend-input">3802<h4 id="sessionend-input">
3777 Входные данные SessionEnd3803 Входные данные SessionEnd
3791 3817
3792Хуки SessionEnd не управляют решениями. Они не могут заблокировать завершение сессии, но могут выполнять задачи очистки. Claude Code отбрасывает их [поля вывода JSON](#json-output), такие как `systemMessage`.3818Хуки SessionEnd не управляют решениями. Они не могут заблокировать завершение сессии, но могут выполнять задачи очистки. Claude Code отбрасывает их [поля вывода JSON](#json-output), такие как `systemMessage`.
3793 3819
3794Таймаут по умолчанию для хуков SessionEnd — 1,5 секунды. Он применяется, когда вы выходите, выполняете `/clear` или переключаете сессии с помощью интерактивной команды `/resume`. Дать хуку больше времени можно двумя способами:3820Таймаут по умолчанию для хуков SessionEnd — 1,5 секунды. Он действует, когда вы выходите, выполняете `/clear` или переключаете сессии через интерактивную `/resume`. Дать хуку больше времени можно двумя способами:
3795 3821
3796* **`timeout` для отдельного хука**: задайте `timeout` в конфигурации этого хука. Общий лимит времени автоматически увеличивается до наибольшего значения `timeout` отдельного хука в ваших файлах настроек, но не более 60 секунд. Если вы увеличиваете лимит таким способом, хук без собственного `timeout` по-прежнему использует значение по умолчанию. Таймауты, заданные для хуков, предоставляемых плагинами, не увеличивают лимит.3822* **`timeout` для отдельного хука**: задайте `timeout` в конфигурации этого хука. Общий лимит времени автоматически увеличивается до наибольшего значения `timeout` отдельного хука в ваших файлах настроек, но не более 60 секунд. Если вы увеличиваете лимит таким образом, хук без собственного `timeout` по-прежнему сохраняет значение по умолчанию. Таймауты, заданные для хуков из плагинов, не увеличивают лимит.
3797* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: задайте эту переменную окружения в миллисекундах, чтобы явно переопределить лимит. Заданное значение также становится таймаутом для каждого хука без собственного `timeout`.3823* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: задайте эту переменную окружения в миллисекундах, чтобы явно переопределить лимит. Заданное значение также становится таймаутом для каждого хука без собственного `timeout`.
3798 3824
3799Этот пример устанавливает лимит в 5 секунд:3825Этот пример устанавливает лимит в 5 секунд:
3802CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude3828CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude
3803```3829```
3804 3830
3805До v2.1.268 `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` увеличивала только общий лимит, а хук без собственного `timeout` всё равно прерывался через 1,5 секунды.3831До v2.1.268 `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` увеличивала только общий лимит, а хук без собственного `timeout` всё равно отменялся через 1,5 секунды.
3806 3832
3807<h3 id="elicitation">3833<h3 id="elicitation">
3808 Elicitation3834 Elicitation
3809</h3>3835</h3>
3810 3836
3811Запускается, когда MCP-сервер запрашивает ввод пользователя в процессе выполнения задачи. По умолчанию Claude Code показывает интерактивное диалоговое окно, в котором пользователь может ответить. Хуки могут перехватить этот запрос и ответить программно, полностью пропустив диалоговое окно.3837Запускается, когда MCP-сервер запрашивает ввод пользователя посреди задачи. По умолчанию Claude Code показывает интерактивное диалоговое окно для ответа пользователя. Хуки могут перехватить этот запрос и ответить программно, полностью пропуская диалоговое окно.
3812 3838
3813Полный пример хука с записью в настройках и скриптом см. в разделе [Ответ на запрос формы из скрипта](#answer-a-form-request-from-a-script).3839Полный хук с записью в настройках и скриптом см. в разделе [Ответ на запрос формы из скрипта](#answer-a-form-request-from-a-script).
3814 3840
3815Поле matcher сопоставляется с именем MCP-сервера.3841Поле matcher сопоставляется с именем MCP-сервера.
3816 3842
3818 Входные данные Elicitation3844 Входные данные Elicitation
3819</h4>3845</h4>
3820 3846
3821Помимо [общих входных полей](#common-input-fields), хуки Elicitation получают поля `mcp_server_name`, `message` и необязательные поля `mode`, `url`, `elicitation_id` и `requested_schema`.3847Помимо [общих входных полей](#common-input-fields), хуки Elicitation получают `mcp_server_name`, `message` и необязательные поля `mode`, `url`, `elicitation_id` и `requested_schema`.
3822 3848
3823Для запроса в режиме формы — самого распространённого случая:3849Для elicitation в режиме формы, наиболее распространённого случая:
3824 3850
3825```json theme={null}3851```json theme={null}
3826{3852{
3840}3866}
3841```3867```
3842 3868
3843Для запроса в режиме URL, используемого для аутентификации через браузер:3869Для elicitation в режиме URL, используемого для аутентификации через браузер:
3844 3870
3845```json theme={null}3871```json theme={null}
3846{3872{
3856```3882```
3857 3883
3858<h4 id="elicitation-output">3884<h4 id="elicitation-output">
3859 Вывод Elicitation3885 Выходные данные Elicitation
3860</h4>3886</h4>
3861 3887
3862Хук Elicitation может ответить на запрос за пользователя, отклонить или отменить его либо оставить его диалоговому окну. Чтобы ответить, отклонить или отменить, завершитесь с кодом 0 и выведите объект `hookSpecificOutput` с `action`. Сервер получает ваш ответ, и диалоговое окно не появляется. Каждая строка этой таблицы показывает, что вернуть для одного исхода и что получает MCP-сервер:3888Хук Elicitation может ответить на запрос вместо пользователя, отклонить или отменить его либо оставить его диалоговому окну. Чтобы ответить, отклонить или отменить, завершитесь с кодом 0 и выведите объект `hookSpecificOutput` с `action`. Сервер получит ваш ответ, и диалоговое окно не появится. Каждая строка этой таблицы показывает, что вернуть для одного исхода и что получит MCP-сервер:
3863 3889
3864| Чтобы | Верните | Сервер получает |3890| Чтобы | Верните | Сервер получит |
3865| :- | :- | :- |3891| :- | :- | :- |
3866| Ответить за пользователя | `"action": "accept"` со значениями полей формы в `content` | `accept` с вашим `content` |3892| Ответить вместо пользователя | `"action": "accept"` со значениями полей формы в `content` | `accept` с вашим `content` |
3867| Отклонить запрос | `"action": "decline"` | `decline` |3893| Отклонить запрос | `"action": "decline"` | `decline` |
3868| Отменить запрос | `"action": "cancel"` | `cancel` |3894| Отменить запрос | `"action": "cancel"` | `cancel` |
3869| Оставить запрос пользователю | Нет вывода, код выхода 0 | Ответ пользователя из [диалогового окна](/docs/ru/mcp#respond-to-mcp-elicitation-requests) |3895| Оставить запрос пользователю | Без вывода, с кодом выхода 0 | Ответ пользователя из [диалогового окна](/docs/ru/mcp#respond-to-mcp-elicitation-requests) |
3870 3896
3871Этот вывод отвечает на запрос в режиме формы, показанный в разделе [Входные данные Elicitation](#elicitation-input). Ключи в `content` — это имена свойств из `requested_schema` этого запроса:3897Этот вывод отвечает на запрос в режиме формы, показанный в разделе [Входные данные Elicitation](#elicitation-input). Ключи в `content` — это имена свойств из `requested_schema` этого запроса:
3872 3898
3893}3919}
3894```3920```
3895 3921
3896В диалоговом окне выбор **Decline** отправляет `decline`, а нажатие `Esc` отправляет `cancel`, поэтому возвращайте то, что вы хотите, чтобы увидел сервер.3922В диалоговом окне выбор **Decline** отправляет `decline`, а нажатие `Esc` отправляет `cancel`, поэтому возвращайте тот вариант, который должен увидеть сервер.
3897 3923
3898Для запроса в режиме URL хук, возвращающий `accept`, пропускает диалоговое окно, поэтому URL так и не открывается.3924Для запроса в режиме URL хук, возвращающий `accept`, пропускает диалоговое окно, поэтому URL так и не открывается.
3899 3925
3900Claude Code отбрасывает `reason`, `systemMessage` и `continue` из вывода JSON хука Elicitation, какое бы `action` вы ни вернули.3926Claude Code отбрасывает `reason`, `systemMessage` и `continue` из вывода JSON хука Elicitation, какой бы `action` вы ни вернули.
3901 3927
3902<h4 id="other-ways-to-decline-an-elicitation">3928<h4 id="other-ways-to-decline-an-elicitation">
3903 Другие способы отклонить запрос elicitation3929 Другие способы отклонить elicitation
3904</h4>3930</h4>
3905 3931
3906Ваш хук также может отклонить запрос следующими способами. Сервер получает тот же `decline`, что и при `"action": "decline"`:3932Хук также может отклонить запрос следующими способами. Сервер получит тот же `decline`, что и для `"action": "decline"`:
3907 3933
3908* **Завершение с кодом 2**: Claude Code игнорирует `hookSpecificOutput`, выведенный тем же хуком3934* **Завершение с кодом 2**: Claude Code игнорирует `hookSpecificOutput`, выведенный тем же хуком
3909* **Вывод `"decision": "block"` верхнего уровня**: блокировка переопределяет `action` в том же выводе3935* **Вывод `"decision": "block"` на верхнем уровне**: блокировка переопределяет `action` в том же выводе
3910 3936
3911Когда одному запросу соответствует несколько хуков, отклонение от одного из них переопределяет `accept` или `cancel` от другого.3937Когда одному запросу соответствует несколько хуков, отклонение от одного из них переопределяет `accept` или `cancel` от другого.
3912 3938
3913Этот скрипт отклоняет запросы в режиме URL и оставляет запросы форм диалоговому окну:3939Этот скрипт отклоняет запросы в режиме URL и оставляет запросы формы диалоговому окну:
3914 3940
3915```bash theme={null}3941```bash theme={null}
3916#!/bin/bash3942#!/bin/bash
3919fi3945fi
3920```3946```
3921 3947
3922Ни пользователь, ни сервер не видят, почему ваш хук отклонил запрос, поскольку Claude Code не показывает ваш stderr или ваш `reason`.3948Ни пользователь, ни сервер не видят, почему хук отклонил запрос, потому что Claude Code не показывает ваш stderr или ваш `reason`.
3923 3949
3924Claude Code игнорировал `decision` верхнего уровня от хуков `Elicitation` и `ElicitationResult` начиная с v2.1.105 и до исправления в v2.1.284.3950Claude Code игнорировал `decision` верхнего уровня от хуков `Elicitation` и `ElicitationResult`, начиная с v2.1.105 и до исправления в v2.1.284.
3925 3951
3926<h4 id="answer-a-form-request-from-a-script">3952<h4 id="answer-a-form-request-from-a-script">
3927 Ответ на запрос формы из скрипта3953 Ответ на запрос формы из скрипта
3928</h4>3954</h4>
3929 3955
3930Этот пример отвечает за пользователя на один повторяющийся вопрос. MCP-сервер с именем `issue-tracker` запрашивает в форме ключ проекта, а хук подставляет `DOCS`. Скрипт принимает запрос, когда `project_key` — единственное поле формы. Для любого другого запроса он ничего не выводит, поэтому появляется диалоговое окно.3956Этот пример отвечает на один повторяющийся вопрос вместо пользователя. MCP-сервер с именем `issue-tracker` запрашивает ключ проекта в форме, и хук подставляет `DOCS`. Скрипт принимает запрос, когда `project_key` — единственное поле формы. Для любого другого запроса он ничего не выводит, поэтому появляется диалоговое окно.
3931 3957
3932<Tabs>3958<Tabs>
3933 <Tab title="macOS/Linux">3959 <Tab title="macOS/Linux">
3934 Зарегистрируйте командный хук для события в файле настроек, указав имя сервера в качестве matcher:3960 Зарегистрируйте хук команды для этого события в файле настроек, указав имя сервера в качестве matcher:
3935 3961
3936 ```json theme={null}3962 ```json theme={null}
3937 {3963 {
3952 }3978 }
3953 ```3979 ```
3954 3980
3955 Сохраните этот скрипт в файл `.claude/hooks/answer-project-key.sh` в вашем проекте и сделайте его исполняемым с помощью `chmod +x`:3981 Сохраните этот скрипт в `.claude/hooks/answer-project-key.sh` в вашем проекте и сделайте его исполняемым с помощью `chmod +x`:
3956 3982
3957 ```bash theme={null}3983 ```bash theme={null}
3958 #!/bin/bash3984 #!/bin/bash
3966 </Tab>3992 </Tab>
3967 3993
3968 <Tab title="Windows (PowerShell)">3994 <Tab title="Windows (PowerShell)">
3969 Зарегистрируйте командный хук, который запускает скрипт через PowerShell, указав имя сервера в качестве matcher:3995 Зарегистрируйте хук команды, который запускает скрипт через PowerShell, указав имя сервера в качестве matcher:
3970 3996
3971 ```json theme={null}3997 ```json theme={null}
3972 {3998 {
3993 }4019 }
3994 ```4020 ```
3995 4021
3996 Сохраните этот скрипт в файл `.claude/hooks/answer-project-key.ps1` в вашем проекте:4022 Сохраните этот скрипт в `.claude/hooks/answer-project-key.ps1` в вашем проекте:
3997 4023
3998 ```powershell theme={null}4024 ```powershell theme={null}
3999 $request = [Console]::In.ReadToEnd() | ConvertFrom-Json4025 $request = [Console]::In.ReadToEnd() | ConvertFrom-Json
4012 </Tab>4038 </Tab>
4013</Tabs>4039</Tabs>
4014 4040
4015Чтобы убедиться, что хук работает, запустите Claude Code командой `claude --debug` и дайте Claude задачу, при которой сервер запросит ключ проекта. Диалоговое окно не появится, а в [логе отладки](#debug-hooks) будет строка, заканчивающаяся на `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`.4041Чтобы убедиться, что хук работает, запустите Claude Code командой `claude --debug` и дайте Claude задачу, при которой сервер запросит ключ проекта. Диалоговое окно не появится, а в [отладочном логе](#debug-hooks) будет строка, заканчивающаяся на `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`.
4016 4042
4017<h3 id="elicitationresult">4043<h3 id="elicitationresult">
4018 ElicitationResult4044 ElicitationResult
4019</h3>4045</h3>
4020 4046
4021Запускается после того, как пользователь ответил на запрос elicitation от MCP. Хуки могут просматривать, изменять или блокировать ответ до его отправки обратно MCP-серверу.4047Запускается после того, как пользователь отвечает на elicitation MCP. Хуки могут просматривать, изменять или блокировать ответ до его отправки обратно MCP-серверу.
4022 4048
4023Когда хук [Elicitation](#elicitation) отвечает на запрос, Claude Code отправляет этот ответ серверу без запуска хуков ElicitationResult.4049Когда хук [Elicitation](#elicitation) отвечает на запрос, Claude Code отправляет этот ответ серверу, не запуская хуки ElicitationResult.
4024 4050
4025Поле matcher сопоставляется с именем MCP-сервера.4051Поле matcher сопоставляется с именем MCP-сервера.
4026 4052
4028 Входные данные ElicitationResult4054 Входные данные ElicitationResult
4029</h4>4055</h4>
4030 4056
4031Помимо [общих входных полей](#common-input-fields), хуки ElicitationResult получают поля `mcp_server_name`, `action` и необязательные поля `mode`, `elicitation_id` и `content`.4057Помимо [общих входных полей](#common-input-fields), хуки ElicitationResult получают `mcp_server_name`, `action` и необязательные поля `mode`, `elicitation_id` и `content`.
4032 4058
4033```json theme={null}4059```json theme={null}
4034{4060{
4044```4070```
4045 4071
4046<h4 id="elicitationresult-output">4072<h4 id="elicitationresult-output">
4047 Вывод ElicitationResult4073 Выходные данные ElicitationResult
4048</h4>4074</h4>
4049 4075
4050Хук ElicitationResult может пропустить ответ пользователя, изменить его значения или заблокировать его. Чтобы изменить или заблокировать ответ, завершитесь с кодом 0 и выведите объект `hookSpecificOutput` с `action`. Каждая строка этой таблицы показывает, что вернуть для одного исхода и что получает MCP-сервер:4076Хук ElicitationResult может пропустить ответ пользователя, изменить его значения или заблокировать его. Чтобы изменить или заблокировать ответ, завершитесь с кодом 0 и выведите объект `hookSpecificOutput` с `action`. Каждая строка этой таблицы показывает, что вернуть для одного исхода и что получит MCP-сервер:
4051 4077
4052| Чтобы | Верните | Сервер получает |4078| Чтобы | Верните | Сервер получит |
4053| :- | :- | :- |4079| :- | :- | :- |
4054| Пропустить ответ | Нет вывода, код выхода 0 | Ответ пользователя без изменений |4080| Пропустить ответ | Без вывода, с кодом выхода 0 | Ответ пользователя без изменений |
4055| Изменить отправленные значения | `"action": "accept"` с новыми значениями в `content` | `accept` с вашим `content` вместо значений пользователя |4081| Изменить отправленные значения | `"action": "accept"` с новыми значениями в `content` | `accept` с вашим `content` вместо значений пользователя |
4056| Заблокировать ответ | `"action": "decline"` | `decline` без значений пользователя |4082| Заблокировать ответ | `"action": "decline"` | `decline` без значений пользователя |
4057| Отменить запрос | `"action": "cancel"` | `cancel` вместе со значениями, отправленными пользователем. Чтобы скрыть их, верните `"decline"` |4083| Отменить запрос | `"action": "cancel"` | `cancel` вместе со значениями, отправленными пользователем. Чтобы не передавать их, верните `"decline"` |
4058 4084
4059Этот вывод изменяет ответ, показанный в разделе [Входные данные ElicitationResult](#elicitationresult-input), так что сервер получает `alice@example.com` там, где пользователь отправил `alice`:4085Этот вывод изменяет ответ, показанный в разделе [Входные данные ElicitationResult](#elicitationresult-input), так что сервер получает `alice@example.com` вместо отправленного пользователем `alice`:
4060 4086
4061```json theme={null}4087```json theme={null}
4062{4088{
4070}4096}
4071```4097```
4072 4098
4073Ваш `content` заменяет весь объект `content` пользователя, поэтому включайте поля, которые вы не меняете. Возвращайте вместе с ним `action`, поскольку Claude Code игнорирует `hookSpecificOutput` без `action`.4099Ваш `content` заменяет весь объект `content` пользователя, поэтому включайте и поля, которые не изменяете. Возвращайте вместе с ним `action`, потому что Claude Code игнорирует `hookSpecificOutput` без `action`.
4074 4100
4075Хуки ElicitationResult также запускаются, когда пользователь отклоняет или отменяет запрос, и ваше `action` заменяет его действие. Прежде чем вернуть `accept`, проверьте, что `action` во входных данных равно `accept`, иначе ваш хук превратит отклонённый запрос в принятый. Этот скрипт вносит то же изменение, когда пользователь принял запрос, сохраняет остальные поля и в противном случае ничего не выводит:4101Хуки ElicitationResult также запускаются, когда пользователь отклоняет или отменяет запрос, и ваш `action` заменяет его действие. Прежде чем возвращать `accept`, проверяйте, что `action` во входных данных равен `accept`, иначе хук превратит отклонённый запрос в принятый. Этот скрипт вносит то же изменение, если пользователь принял запрос, сохраняет остальные поля и в противном случае ничего не выводит:
4076 4102
4077```bash theme={null}4103```bash theme={null}
4078#!/bin/bash4104#!/bin/bash
4094}4120}
4095```4121```
4096 4122
4097Код выхода 2 и `"decision": "block"` верхнего уровня также блокируют ответ. В разделе [Другие способы отклонить запрос elicitation](#other-ways-to-decline-an-elicitation) описано, какой из них действует, когда хук их сочетает, что видит пользователь и какие версии игнорировали `decision`.4123Код выхода 2 и `"decision": "block"` на верхнем уровне также блокируют ответ. В разделе [Другие способы отклонить elicitation](#other-ways-to-decline-an-elicitation) описано, какой из вариантов действует, когда хук их сочетает, что видит пользователь и какие версии игнорировали `decision`.
4098 4124
4099Claude Code отбрасывает `reason`, `systemMessage` и `continue` из вывода JSON хука ElicitationResult, какое бы `action` вы ни вернули.4125Claude Code отбрасывает `reason`, `systemMessage` и `continue` из вывода JSON хука ElicitationResult, какой бы `action` вы ни вернули.
4100 4126
4101<h2 id="prompt-based-hooks">4127<h2 id="prompt-based-hooks">
4102 Prompt-based hooks4128 Prompt-based hooks
4351* **Единственным содержимым stdout**: когда ответ — единственный текст в stdout, он может занимать несколько строк, например отформатированный вывод `jq`. Для ответа на нескольких строках требуется Claude Code v2.1.295 или новее.4377* **Единственным содержимым stdout**: когда ответ — единственный текст в stdout, он может занимать несколько строк, например отформатированный вывод `jq`. Для ответа на нескольких строках требуется Claude Code v2.1.295 или новее.
4352* **На отдельной строке**: асинхронный хук может выводить в stdout другой текст, если ответ целиком умещается на отдельной строке, например при использовании `jq -c`.4378* **На отдельной строке**: асинхронный хук может выводить в stdout другой текст, если ответ целиком умещается на отдельной строке, например при использовании `jq -c`.
4353 4379
4354Claude Code проверяет, что JSON ответ соответствует той же [схеме выходных данных](#json-output), что и синхронные hooks, и отбрасывает любое поле, значение которого имеет неправильный тип, например `systemMessage`, который не является строкой, вместо его доставки. Запустите с `--debug` для просмотра предупреждения, называющего каждое отброшенное поле. До версии v2.1.202 неправильно сформированный JSON выход из асинхронного hook мог привести к сбою сеанса, и сбой повторялся каждый раз при возобновлении сеанса.4380Claude Code проверяет, что JSON-ответ соответствует той же [схеме выходных данных](#json-output), что и у синхронных хуков, и отбрасывает любое поле, значение которого имеет неправильный тип, например `systemMessage`, который не является строкой, вместо его доставки. Запустите с `--debug` для просмотра предупреждения, называющего каждое отброшенное поле.
4355 4381
4356Уведомления о завершении асинхронного hook подавляются по умолчанию. Чтобы их увидеть, включите подробный режим с помощью `Ctrl+O` или запустите Claude Code с `--verbose`.4382Уведомления о завершении асинхронного hook подавляются по умолчанию. Чтобы их увидеть, включите подробный режим с помощью `Ctrl+O` или запустите Claude Code с `--verbose`.
4357 4383