Хуки
Hooks
Hooks - это автоматические скрипты, которые запускаются в ответ на определённые события во время сессий Claude Code. Они позволяют реализовать автоматизацию, валидацию, управление разрешениями и пользовательские сценарии работы.
Обзор
Hooks - это автоматические действия (shell-команды, HTTP webhooks, промпты к LLM, вызовы MCP-инструментов или обращения к subagent), которые выполняются при возникновении определённых событий в Claude Code. Они принимают на вход JSON и возвращают результаты через exit codes и JSON на выходе.
Ключевые возможности:
- Автоматизация, управляемая событиями
- Ввод/вывод в формате JSON
- Поддержка hook-типов
command,http,mcp_tool,promptиagent - Сопоставление по шаблонам для hooks, привязанных к конкретным инструментам
Конфигурация
Hooks настраиваются в файлах settings со строго заданной структурой:
~/.claude/settings.json- пользовательские настройки (для всех проектов).claude/settings.json- настройки проекта (доступны для совместной работы, попадают в commit).claude/settings.local.json- локальные настройки проекта (не попадают в commit)- Managed policy - настройки на уровне организации
hooks/hooks.jsonв plugin - hooks в области видимости plugin- Frontmatter у Skill/Agent - hooks жизненного цикла компонента
Базовая структура конфигурации
Ключевые поля:
| Field | Description | Example |
|---|---|---|
matcher | Pattern to match tool names (case-sensitive) | "Write", "Edit|Write", "*" |
hooks | Array of hook definitions | [{ "type": "command", ... }] |
type | Hook type: "command" (bash), "prompt" (LLM), "http" (webhook), "mcp_tool" (MCP tool invocation, v2.1.118+), or "agent" (subagent) | "command" |
command | Shell command to execute | "$CLAUDE_PROJECT_DIR/.claude/hooks/format.sh" |
timeout | Optional timeout in seconds. Defaults: 600 for command/http/mcp_tool, 30 for prompt, 60 for agent. | 30 |
once | If true, run the hook only once per session | true |
async | If true, runs in the background without blocking | true |
asyncRewake | If true, runs in the background and wakes Claude on exit code 2. Implies async. | true |
shell | Accepts "bash" or "powershell". Defaults to "bash", or to "powershell" on Windows when Git Bash isn't installed. | "bash" |
statusMessage | Custom spinner message displayed while the hook runs | "Formatting…" |
Примечание: Некоторые события уменьшают timeout по умолчанию.
UserPromptSubmitснижает значение по умолчанию дляcommand,httpиmcp_toolдо 30 секунд, аMessageDisplay- до 10 секунд. Hook-иSessionEndиспользуют общий бюджет в 1,5 секунды; если в ваших настройках задан большийtimeoutдля отдельного hook, Claude Code увеличивает общий бюджет до соответствующего значения, но не более 60 секунд.
Шаблоны matcher
| Pattern | Description | Example |
|---|---|---|
| Exact string | Matches specific tool | "Write" |
| Regex pattern | Matches multiple tools | "Edit|Write" |
| Comma-separated | Matches any listed tool (v2.1.191+) | "Write,Edit" |
| Wildcard | Matches all tools | "*" or "" |
| MCP tools | Server and tool pattern | "mcp__memory__.*" |
Матчеры сопоставляются строго (v2.1.195+). Идентификатор с дефисом (например, имя MCP-инструмента, содержащее дефис) больше не срабатывает случайно как подстрока для другого инструмента. Матчеры со списком через запятую, такие как
"Write,Edit", теперь срабатывают на любом инструменте из списка - в более ранних сборках они молча не срабатывали никогда.
Значения матчера InstructionsLoaded:
| Matcher Value | Description |
|---|---|
session_start | Instructions loaded at session startup |
nested_traversal | Instructions loaded during nested directory traversal |
path_glob_match | Instructions loaded via path glob pattern matching |
Сужение через условия if (пути в аргументах инструмента)
Поле matcher выбирает hook по имени инструмента ("Write", "Edit|Write", "*"). Чтобы фильтровать точнее - по аргументам инструмента, например запускать hook только когда правка затрагивает src/, или блокировать чтение секретных файлов, - добавьте условие if к конкретному обработчику hook. Это не то же самое, что matcher по имени инструмента: matcher определяет, какой инструмент, а if - какой именно вызов.
В if используется синтаксис правил разрешений (ToolName(pattern)), который проверяется одновременно по имени инструмента и его аргументам. Для Read/Edit/Write шаблон пути подчиняется семантике gitignore с теми же якорями, что и в правилах разрешений: голое имя вроде .env совпадает на любой глубине, src/** отсчитывается от текущей директории, /src/** - от корня проекта, ~/... - от домашней директории, а //... - абсолютный путь в файловой системе.
Поле if располагается на уровне обработчика hook - рядом с type и command внутри массива hooks, - а не на уровне matcher:
Примеры допустимых шаблонов if: Edit(src/**) (правки в src/), Read(~/.ssh/**) (чтение любых SSH-ключей), Read(.env) (любой .env в текущем каталоге или ниже по дереву), Bash(git push *) (только подкоманды git push).
Обновление v2.1.214: односегментный шаблон
dir/**в условииifу hook (например,Edit(src/**)) теперь соответствует только<cwd>/dir- а не одноимённому каталогу на любой глубине дерева. Ранееsrc/**также совпадал сfoo/src/**. Если нужно сопоставление на любой глубине, используйте**/dir/**. Важно: это сужение действует только для условийif:у hook и для автоодобрения по allow-правилам - правила разрешений deny/ask по-прежнему сопоставляютdir/**на любой глубине.
Типы hook
Claude Code поддерживает пять типов hook:
Command Hooks
Тип hook по умолчанию. Выполняет shell-команду и обменивается данными через stdin/stdout в формате JSON и коды завершения.
Exec-форма (args)
Добавлено в v2.1.139.
Вместо shell-формы "command": "..." command hook может запускать бинарный файл напрямую через execve(), используя массив args. Парсинг shell при этом не выполняется, поэтому плейсхолдеры путей не требуется экранировать кавычками, а сама конфигурация защищена от уязвимостей типа shell injection.
Эти две формы взаимоисключающие - hook с одновременно заданными command и args отклоняется при загрузке конфигурации. Используйте command, когда нужны конвейеры, перенаправления, цепочки через && или раскрытие шелла; используйте args, когда вызываете один бинарник с аргументами.
HTTP Hooks
> Добавлено в v2.1.63.
Удалённые webhook-эндпоинты, принимающие тот же JSON, что и command hooks. HTTP hooks отправляют POST с JSON на URL и получают JSON в ответ. При включённом sandboxing HTTP hooks маршрутизируются через sandbox. Для подстановки переменных окружения в URL в целях безопасности требуется явно заданный список allowedEnvVars.
Ключевые свойства:
"type": "http"- обозначает, что это HTTP-hook"url"- URL эндпоинта webhook- Маршрутизируется через sandbox, если тот включён
- Требует явного указания списка
allowedEnvVarsдля подстановки любых переменных окружения в URL
Prompt Hooks
Промпты, вычисляемые LLM: содержимое hook - это промпт, который оценивает Claude. Применяются главным образом с событиями Stop и SubagentStop для интеллектуальной проверки завершения задачи.
LLM оценивает prompt и возвращает структурированное решение (подробности см. в Prompt-Based Hooks).
MCP Tool Hooks
Добавлено в v2.1.118.
Тип mcp_tool напрямую вызывает настроенный MCP-инструмент; в конфигурации указываются MCP-сервер и имя инструмента, а не shell-команда или URL. Это удобно, когда логика валидации или реакции уже реализована в одном из настроенных вами MCP-серверов.
Ключевые свойства:
"type": "mcp_tool"- указывает, что это MCP tool hook"server"- имя настроенного MCP-сервера"tool"- имя вызываемого tool на этом сервере
Входные данные hook (имя tool, входные данные tool, контекст сессии) передаются в качестве аргументов MCP tool. О настройке MCP-серверов см. MCP server setup.
Agent Hooks
Верификационные hooks на основе subagent: они запускают отдельный agent для проверки условий или выполнения сложных проверок. В отличие от prompt hooks (одноходовая LLM-оценка), agent hooks могут использовать tools и выполнять многошаговые рассуждения.
Примечание: agent hooks являются экспериментальными и могут измениться.
Ключевые свойства:
"type": "agent"- обозначает, что это agent hook"prompt"- описание задачи для субагента- Агент может использовать инструменты (Read, Grep, Bash и т. д.) для выполнения проверки
- Возвращает структурированное решение, аналогично prompt hooks
События hook
Claude Code поддерживает 33 события hook:
| Event | When Triggered | Matcher Input | Can Block | Common Use |
|---|---|---|---|---|
| SessionStart | Session begins/resumes/clear/compact | startup/resume/clear/compact/fork | No | Environment setup |
| Setup | Initial environment setup (one-time per session) | (none) | No | Provision tooling, install deps |
| InstructionsLoaded | After CLAUDE.md or rules file loaded | (none) | No | Modify/filter instructions |
| UserPromptSubmit | User submits prompt | (none) | Yes | Validate prompts |
| UserPromptExpansion | User prompt is expanded (e.g., @ mentions, slash commands resolved) | (none) | Yes | Transform or inspect expanded prompt |
| PreToolUse | Before tool execution | Tool name | Yes (allow/deny/ask/defer) | Validate, modify inputs |
| PermissionRequest | Permission dialog shown | Tool name | Yes | Auto-approve/deny |
| PermissionDenied | User denies a permission prompt | Tool name | No | Logging, analytics, policy enforcement |
| PostToolUse | After tool succeeds | Tool name | No | Add context, feedback |
| PostToolUseFailure | Tool execution fails | Tool name | No | Error handling, logging |
| PostToolBatch | After a batch of tool uses completes | (none) | No | Aggregate reporting, batched validation |
| Notification | Notification sent | Notification type | No | Custom notifications |
| MessageDisplay | While assistant message text is displayed | (none) | No | Transform or hide displayed message text (v2.1.152) |
| SubagentStart | Subagent spawned | Agent type name | No | Subagent setup |
| SubagentStop | Subagent finishes | Agent type name | Yes | Subagent validation |
| Stop | Claude finishes responding | (none) | Yes | Task completion check |
| StopFailure | API error ends turn | (none) | No | Error recovery, logging |
| TeammateIdle | Agent team teammate idle | (none) | Yes | Teammate coordination |
| TaskCompleted | Task marked complete | (none) | Yes | Post-task actions |
| TaskCreated | Task created via TaskCreate | (none) | No | Task tracking, logging |
| ConfigChange | Config file changes | (none) | Yes (except policy) | React to config updates |
| CwdChanged | Working directory changes | (none) | No | Directory-specific setup |
| DirectoryAdded | New working directory registered mid-session via /add-dir or the SDK register_repo_root control request (v2.1.219) | (none) | No | Set up tooling for a newly added directory |
| FileChanged | Watched file changes | (none) | No | File monitoring, rebuild |
| PreCompact | Before context compaction | manual/auto | No | Pre-compact actions |
| PostCompact | After compaction completes | (none) | No | Post-compact actions |
| PreModelSwitch | Before Claude Code applies a requested model switch | Canonical name of the model being switched to (from to_model) | Yes | Gate or veto model changes |
| PostModelSwitch | After the session's model changes, including changes Claude Code makes itself (such as restoring the model on resume) | Canonical name of the model switched to (from to_model) | No | Log or react to model changes |
| WorktreeCreate | Worktree being created | (none) | Yes (path return) | Worktree initialization |
| WorktreeRemove | Worktree being removed | (none) | No | Worktree cleanup |
| Elicitation | MCP server requests user input | (none) | Yes | Input validation |
| ElicitationResult | User responds to elicitation | (none) | Yes | Response processing |
| SessionEnd | Session terminates | (none) | No | Cleanup, final logging |
PreModelSwitch и PostModelSwitch требуют версии v2.1.251 или новее. Оба получают from_model и to_model; matcher применяется к каноническому имени, полученному из to_model (например, claude-opus-5, .*opus.*). Для них таймаут по умолчанию у command, http и mcp_tool снижен до 30 секунд. |
Для
TaskCreatedиTaskCompletedнужны включённые todo-инструменты (v2.1.233). Эти два события возникают в инструментах отслеживания todo/задач (TaskCreate/Get/Update/List,TodoWrite), которые больше недоступны в Opus 4.8, Sonnet 5, Fable 5, Mythos 5 и более новых моделях. На таких моделях hooks остаются валидной конфигурацией, но просто никогда не срабатывают - ни вывода, ни ошибки вы не получите. УстановитеCLAUDE_CODE_ENABLE_TODO_TOOLS=1, чтобы вернуть эти инструменты, а вместе с ними и события.
Длительность PostToolUse (v2.1.119): входные данные hooks
PostToolUseиPostToolUseFailureтеперь содержатduration_ms- подробности см. в разделе PostToolUse.
PreToolUse
Выполняется после того, как Claude сформировал параметры инструмента, но до его вызова. Используйте для валидации или изменения входных параметров инструмента.
Конфигурация:
Типичные matchers: Task, Bash, Glob, Grep, Read, Edit, Write, WebFetch, WebSearch
Управление выводом:
permissionDecision:"allow","deny","ask"или"defer""allow"пропускает запрос разрешения (кроме инструментов, требующих взаимодействия с пользователем, и connector-инструментов, для которых ваша организация задалаask)"deny"блокирует вызов инструмента"ask"запрашивает подтверждение у пользователя"defer"корректно завершает работу, чтобы инструмент можно было возобновить позже; при этом значенииpermissionDecisionReason,updatedInputиadditionalContextигнорируются- Правила deny и ask всё равно применяются независимо от того, что вернул hook. Если несколько hooks
PreToolUseдают противоречивые решения, приоритет следующий:deny>defer>ask>allow
permissionDecisionReason: обоснование решения. Показывается пользователю (а не Claude) для"allow"и"ask"; показывается Claude для"deny"; игнорируется для"defer"updatedInput: изменённые входные параметры инструмента
PostToolUse
Запускается сразу после завершения работы инструмента. Используйте для проверки, логирования или передачи контекста обратно в Claude.
Конфигурация:
Управление выводом:
- решение
"block"передаёт Claude сообщение с обратной связью additionalContext: контекст, добавляемый для Claude
Дополнительные поля ввода (v2.1.119):
| Field | Type | Description |
|---|---|---|
duration_ms | number | Tool execution time in milliseconds. Excludes time spent in permission prompts and PreToolUse hook execution. Available on both PostToolUse and PostToolUseFailure hooks. |
Восстанавливаемые блокировки (continueOnBlock, v2.1.139)
По умолчанию hook PostToolUse, возвращающий "decision": "block", прерывает текущий ход. Укажите у hook "continueOnBlock": true, чтобы вместо прерывания отказ был передан Claude в виде tool_result - тогда модель сможет прочитать это сообщение и повторить вызов или скорректировать действия.
Используйте это, когда reason у hook - это то, на что Claude может отреагировать (например, «этот файл доступен только для чтения; запишите в другое место»); не указывайте, если блокировка должна полностью прервать ход.
UserPromptSubmit
Запускается, когда пользователь отправляет prompt, до того как Claude приступит к его обработке.
Конфигурация:
Управление выводом:
decision:"block"- заблокировать обработкуreason: пояснение причины блокировкиadditionalContext: контекст, добавляемый в prompt
Stop и SubagentStop
Срабатывают, когда Claude завершает ответ (Stop) или когда завершает работу субагент (SubagentStop). Поддерживают оценку на основе prompt для интеллектуальной проверки завершённости задачи.
Дополнительное входное поле: hook'и Stop и SubagentStop получают в JSON-входе поле last_assistant_message с последним сообщением от Claude или субагента перед остановкой. Это удобно для оценки завершённости задачи.
Конфигурация:
Защита от последовательных блокировок (v2.1.143): если
Stophook возвращает"decision": "block"(или устанавливаетcontinue: false) 8 раз подряд в рамках одного хода, Claude Code прерывает цикл и завершает сессию с предупреждением. Порог можно переопределить переменной окруженияCLAUDE_CODE_STOP_HOOK_BLOCK_CAP=<integer>(значение0полностью отключает ограничение). Это защищает от бесконечного зацикливания сессии из-за некорректно работающего Stop hook.
Новое поле возврата (v2.1.163): hook Stop или SubagentStop может вернуть hookSpecificOutput.additionalContext, чтобы передать Claude обратную связь и продолжить ход, не показывая пометку об ошибке. Раньше повлиять на модель из Stop hook было неудобно; теперь hook может аккуратно подмешивать контекст, минуя поведение с пометкой об ошибке, свойственное прежним способам передачи обратной связи (например, "decision": "block").
SubagentStart
Срабатывает при запуске subagent. На вход matcher подаётся имя типа агента, что позволяет hooks нацеливаться на конкретные типы subagent.
Конфигурация:
SessionStart
Запускается при старте или возобновлении сессии. Позволяет сохранять переменные окружения.
Matchers: startup, resume, clear, compact, fork
Обновление в v2.1.214: форкнутая сессия теперь возвращает source
"fork"- ранее возвращалось"resume".
Особенность: используйте CLAUDE_ENV_FILE для сохранения переменных окружения (также доступно в hooks CwdChanged и FileChanged):
Вывод на уровне сессии (v2.1.152): hook SessionStart может возвращать JSON для повторного сканирования skills и установки заголовка сессии:
Параметр верхнего уровня reloadSkills: true запускает повторное сканирование skills в текущей сессии (аналогично команде /reload-skills), благодаря чему skills, только что установленные hook'ом, сразу становятся доступными. Поле hookSpecificOutput.sessionTitle задаёт отображаемое название сессии при её запуске и возобновлении.
SessionEnd
Выполняется при завершении сессии для очистки или финального логирования. Не может предотвратить завершение.
Значения поля Reason:
clear- пользователь очистил сессиюlogout- пользователь вышел из аккаунтаprompt_input_exit- пользователь вышел из строки вводаother- иная причина
Конфигурация:
Событие Notification
Обновлённые matchers для событий уведомлений:
permission_prompt- уведомление о запросе разрешенияidle_prompt- уведомление о простоеauth_success- успешная аутентификацияelicitation_dialog- диалог, показанный пользователюagent_needs_input- фоновому агенту требуется ввод (v2.1.198)agent_completed- фоновый агент завершил работу (v2.1.198)
PreModelSwitch
Срабатывает перед тем, как Claude Code применит запрошенную смену модели - например, при выполнении /model или когда какой-либо компонент запрашивает другую модель. Требуется v2.1.251 или новее.
Matchers: каноническое имя модели, на которую выполняется переключение, берётся из to_model. Можно сопоставлять конкретную модель (claude-opus-5) или целое семейство через regex (.*opus.*).
Входные поля: помимо общих полей, hook получает from_model (модель, использовавшаяся до переключения) и to_model (запрошенная модель).
Может блокировать: да. Код выхода 2 отменяет переключение и выводит stderr как ошибку, так что сессия продолжает работу с текущей моделью. Используйте это для контроля или запрета смены модели - например, чтобы в проекте, чувствительном к расходам, нельзя было переключиться на самую дорогую модель.
Timeout: это событие уменьшает timeout по умолчанию для command, http и mcp_tool до 30 секунд.
Конфигурация:
PostModelSwitch
Срабатывает после смены модели в сессии. Также вызывается при изменениях, которые Claude Code инициирует сам, - например, при восстановлении ранее выбранной модели во время возобновления сессии, - а не только при переключениях, запрошенных вами. Требуется версия v2.1.251 или новее.
Matchers: те же, что и у PreModelSwitch, - каноническое имя, полученное из to_model.
Входные поля: from_model и to_model, а также общие поля.
Может блокировать: нет. Переключение уже произошло; hook может только наблюдать и реагировать.
Тайм-аут: это событие уменьшает тайм-аут по умолчанию для command, http и mcp_tool до 30 секунд.
Конфигурация:
Hooks на уровне компонента
Hooks можно привязать к конкретным компонентам (skills, agents, commands) через их frontmatter:
В SKILL.md, agent.md или command.md:
Поддерживаемые события для hooks компонентов: PreToolUse, PostToolUse, Stop
Это позволяет определять hooks непосредственно в том компоненте, который их использует, благодаря чему связанный код хранится вместе.
Hooks во frontmatter субагента
Если hook Stop определён во frontmatter субагента, он автоматически преобразуется в hook SubagentStop, привязанный к этому субагенту. Таким образом, stop hook срабатывает только по завершении именно этого субагента, а не при остановке основной сессии.
Требуется доверие к workspace (v2.1.218): hooks во frontmatter проектного subagent теперь требуют подтверждённого доверия к workspace для папки, из которой был загружен файл агента, - иначе они не будут запущены. До версии v2.1.218 эти hooks могли выполняться из папок, которым вы не выдавали доверие. Список scopes, на которые это требование не распространяется, см. в документации по subagents.
Событие PermissionRequest
Обрабатывает запросы разрешений с пользовательским форматом вывода:
Входные и выходные данные hook
JSON на входе (через stdin)
Все hook получают на вход JSON через stdin:
Общие поля:
| Field | Description |
|---|---|
session_id | Unique session identifier |
transcript_path | Path to the conversation transcript file |
cwd | Current working directory |
prompt_id | UUID of the prompt being processed; correlates with the OpenTelemetry prompt.id attribute (v2.1.196) |
hook_event_name | Name of the event that triggered the hook |
agent_id | Identifier of the agent running this hook |
agent_type | Type of agent ("main", subagent type name, etc.) |
worktree | Path to the git worktree, if the agent is running in one |
effort.level | (v2.1.133+) Active effort level: low, medium, high, xhigh, or max |
Коды возврата
| Exit Code | Meaning | Behavior |
|---|---|---|
| 0 | Success | Continue, parse JSON stdout |
| 2 | Blocking error | Block operation, stderr shown as error |
| Other | Non-blocking error | Continue, stderr shown in verbose mode |
JSON-вывод (stdout, exit code 0)
Область действия (v2.1.121+):
hookSpecificOutput.updatedToolOutputтеперь учитывается для всех инструментов, а не только для MCP. HookPostToolUseнаBash,Edit,Readи т. п. может переписать вывод инструмента до того, как его увидит Claude - это удобно для скрытия секретов, нормализации diff-ов или фильтрации шумного вывода команд. Пример (удаление ANSI-кодов цвета из выводаBash):
retry(PermissionDenied): используйте в JSONhookSpecificOutput.retry: true, чтобы сообщить модели, что она может повторить отклонённый вызов инструмента.
Устаревшая форма decision для
PreToolUse: дляPreToolUseполя верхнего уровняdecisionиreasonустарели - вместо них используйтеhookSpecificOutput.permissionDecision(allow/deny/ask/defer) иpermissionDecisionReason. Приоритет решений:deny>defer>ask>allow. Учтите также, чтоsuppressOutputпринимается, но не даёт никакого эффекта.
terminalSequence (v2.1.141)
Hook-и могут выводить сырые escape-последовательности OSC (operating system command), задавая поле terminalSequence в JSON-выводе. Когда hook завершает работу, host пишет эту последовательность в свой управляющий терминал - это удобно для desktop-уведомлений, обновления заголовка окна и звуковых сигналов терминала, причём без необходимости иметь собственный TTY.
| Field | Type | Description |
|---|---|---|
terminalSequence | string | Raw escape sequence (typically OSC 9 / OSC 0 / OSC 777). Written to the host terminal verbatim. |
| Пример - отправить desktop-уведомление через OSC 9 по завершении длительной задачи: |
Настройте это на hook Stop, чтобы уведомление срабатывало, когда Claude завершает ход. Поддержка escape-последовательностей зависит от терминала; Kitty/iTerm2/Windows Terminal поддерживают OSC 9.
Переменные окружения
| Variable | Availability | Description |
|---|---|---|
CLAUDE_PROJECT_DIR | All hooks | Absolute path to project root |
CLAUDE_ENV_FILE | SessionStart, CwdChanged, FileChanged | File path for persisting env vars |
CLAUDE_CODE_REMOTE | All hooks | "true" if running in remote environments |
${CLAUDE_PLUGIN_ROOT} | Plugin hooks | Path to plugin directory |
${CLAUDE_PLUGIN_DATA} | Plugin hooks | Path to plugin data directory |
CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS | SessionEnd hooks | Configurable timeout in milliseconds for SessionEnd hooks (overrides default) |
CLAUDE_CODE_SESSION_ID | Bash tool subprocesses (v2.1.132+) | Session UUID; matches the session_id field in hook input JSON. Use to correlate bash logs with hook telemetry. |
CLAUDE_EFFORT | Bash tool subprocesses (v2.1.133+) | Active effort level (low/medium/high/xhigh/max); matches effort.level in hook input JSON. |
CLAUDE_CODE_STOP_HOOK_BLOCK_CAP | Process-wide (v2.1.143+) | Max consecutive Stop-hook blocks before the session ends with a warning (default 8). Set to 0 to disable the cap. |
Hooks на основе промптов
Для событий Stop и SubagentStop можно использовать оценку с помощью LLM:
Схема ответа LLM:
Примеры
Пример 1: Валидатор Bash-команд (PreToolUse)
Файл: .claude/hooks/validate-bash.py
Текущая дата: среда, 2 сентября 2026 г.
<query>Конфигурация: </query>
Пример 2: Сканер безопасности (PostToolUse)
Файл: .claude/hooks/security-scan.py
Пример 3: Автоформатирование кода (PostToolUse)
Файл: .claude/hooks/format-code.sh
Пример 4: Валидатор промптов (UserPromptSubmit)
Файл: .claude/hooks/validate-prompt.py
Пример 5: интеллектуальный Stop hook (на основе prompt)
Пример 6: трекер использования контекста (парные hooks)
Отслеживайте расход токенов на каждый запрос, используя связку hooks UserPromptSubmit (перед отправкой сообщения) и Stop (после получения ответа).
Файл: .claude/hooks/context-tracker.py
Текущая дата: среда, 2 сентября 2026 г.
<query>Конфигурация: </query>
Как это работает:
UserPromptSubmitсрабатывает до обработки вашего промпта - сохраняет текущее количество токеновStopсрабатывает после ответа Claude - вычисляет разницу и выводит информацию об использовании- Каждая сессия изолирована благодаря
session_idв имени временного файла
Методы подсчёта токенов:
| Method | Accuracy | Dependencies | Speed |
|---|---|---|---|
| Character estimation | ~80-90% | None | <1ms |
| tiktoken (p50k_base) | ~90-95% | pip install tiktoken | <10ms |
Примечание: Anthropic не выпускала официальный офлайн-токенизатор. Оба метода дают лишь приближённую оценку. В транскрипт входят промпты пользователя, ответы Claude и вывод инструментов, но НЕ системные промпты и не внутренний контекст.
Пример 7: предустановка разрешений для auto-mode (одноразовый скрипт настройки)
Одноразовый скрипт настройки, который добавляет в ~/.claude/settings.json около 67 безопасных правил разрешений, соответствующих базовому набору auto-mode в Claude Code, - без каких-либо hook и без запоминания будущих решений. Запустите один раз; повторный запуск безопасен (уже добавленные правила пропускаются).
Файл: 09-advanced-features/setup-auto-mode-permissions.py
Что добавляется:
| Category | Examples |
|---|---|
| Built-in tools | Read(*), Edit(*), Write(*), Glob(*), Grep(*), Agent(*), WebSearch(*) |
| Git read | Bash(git status:*), Bash(git log:*), Bash(git diff:*) |
| Git write (local) | Bash(git add:*), Bash(git commit:*), Bash(git checkout:*) |
| Package managers | Bash(npm install:*), Bash(pip install:*), Bash(cargo build:*) |
| Build & test | Bash(make:*), Bash(pytest:*), Bash(go test:*) |
| Common shell | Bash(ls:*), Bash(cat:*), Bash(find:*), Bash(cp:*), Bash(mv:*) |
| GitHub CLI | Bash(gh pr view:*), Bash(gh pr create:*), Bash(gh issue list:*) |
| Что намеренно исключено (никогда не добавляется этим скриптом): |
rm -rf,sudo, force push,git reset --hardDROP TABLE,kubectl delete,terraform destroynpm publish,curl | bash, деплой в production
Пример 8: Логирование прогресса обучения (SessionEnd)
Записывайте, какие модули вы изучили, в конце каждой сессии Claude Code. Прогресс сохраняется
в ~/.claude-howto-progress.json - вне репозитория, поэтому он переживает git pull без
перезаписи.
Почему SessionEnd, а не Stop?
Stop срабатывает после каждого ответа Claude. SessionEnd срабатывает один раз - при
завершении сессии, что как раз и нужно для дневниковой записи в конце сессии.
Почему /dev/tty для ввода?
Hook-скрипты получают JSON-payload hook через stdin, поэтому интерактивный read должен обращаться
напрямую к /dev/tty, чтобы достучаться до терминала.
Файл: 06-hooks/session-end.sh
Установка - скопируйте скрипт в каталог hook'ов проекта, чтобы путь, указанный в settings.json, корректно разрешался:
Конфигурация (в .claude/settings.json):
Вывод - ~/.claude-howto-progress.json:
Продемонстрированные ключевые паттерны:
| Pattern | Why it matters |
|---|---|
SessionEnd event | Fires once on exit - not after every response like Stop |
read -r INPUT </dev/tty | Hooks own stdin (JSON payload); use /dev/tty for user input |
$CLAUDE_PROJECT_DIR | Portable path - never hardcode /Users/yourname/... |
| Guard clause at top | Prevents the hook running in unrelated projects if installed globally |
| Store outside the repo | ~/ path survives git pull without overwriting your data |
| Дополнение: визуальный трекер прогресса |
Полноценный интерфейс с чекбоксами, охватывающий все 10 модулей, доступен во встроенном трекере - откройте его в браузере:
Прогресс хранится в браузерном localStorage (на диск в репозитории ничего не пишется).
Кнопка Export сохраняет снимок в формате JSON, а Import - восстанавливает его.
Hooks плагинов
Плагины могут содержать hooks в файле hooks/hooks.json:
Файл: plugins/hooks/hooks.json
Переменные окружения в hooks плагинов:
${CLAUDE_PLUGIN_ROOT}- путь к директории плагина${CLAUDE_PLUGIN_DATA}- путь к директории данных плагина
Это позволяет плагинам подключать собственные hooks для валидации и автоматизации.
Hooks для MCP-инструментов
MCP-инструменты соответствуют шаблону mcp__<server>__<tool>:
Вопросы безопасности
Отказ от ответственности
ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК: hooks выполняют произвольные shell-команды. Вся ответственность лежит на вас:
- за команды, которые вы настраиваете;
- за права доступа к файлам и их изменения;
- за возможную потерю данных или повреждение системы;
- за тестирование hooks в безопасном окружении до использования в production.
Замечания по безопасности
- Требуется доверие к рабочему пространству: команды, выводимые hooks
statusLineиfileSuggestion, теперь применяются только после подтверждения доверия к рабочему пространству. - Размер терминала для status-line (v2.1.153): скриптам команд строки состояния теперь передаются переменные окружения
COLUMNSиLINES, что позволяет адаптировать вывод под ширину/высоту терминала (например,[ "$COLUMNS" -lt 80 ] && short_output). - HTTP hooks и переменные окружения: для подстановки переменных окружения в URL HTTP hooks требуют явно заданного списка
allowedEnvVars. Это защищает от случайной утечки чувствительных переменных окружения на удалённые endpoints. - Иерархия управляемых настроек: параметр
disableAllHooksтеперь подчиняется иерархии управляемых настроек - это значит, что настройки уровня организации могут принудительно отключать hooks, и отдельный пользователь не сможет это переопределить. - Автоодобрение PowerShell (v2.1.119): команды инструмента PowerShell теперь можно автоматически одобрять в permission mode - так же, как Bash. Это уравнивает возможности для пользователей Windows, использующих Claude Code с shell-инструментами на базе PowerShell.
- Закрыта лазейка с автоодобрением голых env-var в Bash (v2.1.145): до версии 2.1.145 Bash-команда вида
FOO=bar somecommand(присваивание переменной перед командой, отсутствующей в allowlist) могла быть автоматически одобрена, если в allowlist находилось лишь самоFOO=bar. В v2.1.145 эта лазейка закрыта - теперь такие команды вызывают запрос разрешения. Скрипты, полагавшиеся на неявное разрешение, начнут запрашивать подтверждение; чтобы вернуть автоодобрение, явно добавьте permission ruleBash(...), покрывающее команду целиком, а не только присваивание переменной.
Рекомендации
| Do | Don't |
|---|---|
| Validate and sanitize all inputs | Trust input data blindly |
Quote shell variables: "$VAR" | Use unquoted: $VAR |
Block path traversal (..) | Allow arbitrary paths |
Use absolute paths with $CLAUDE_PROJECT_DIR | Hardcode paths |
Skip sensitive files (.env, .git/, keys) | Process all files |
| Test hooks in isolation first | Deploy untested hooks |
Use explicit allowedEnvVars for HTTP hooks | Expose all env vars to webhooks |
Отладка
Включение режима отладки
Запустите Claude с флагом debug, чтобы получить подробные логи hook:
Подробный режим
Нажмите Ctrl+O в Claude Code, чтобы включить подробный режим и наблюдать за ходом выполнения hooks.
Тестирование hooks по отдельности
Полный пример конфигурации
Детали выполнения hook
| Aspect | Behavior |
|---|---|
| Timeout | 600 seconds default for command/http/mcp_tool (30 for prompt, 60 for agent); configurable per hook |
| Parallelization | All matching hooks run in parallel |
| Deduplication | Identical hook commands deduplicated |
| Environment | Runs in current directory with Claude Code's environment |
Устранение неполадок
Hook не выполняется
- Убедитесь, что синтаксис JSON-конфигурации корректен
- Проверьте, что паттерн matcher совпадает с именем инструмента
- Убедитесь, что скрипт существует и является исполняемым:
chmod +x script.sh - Запустите
claude --debug, чтобы увидеть логи выполнения hook - Убедитесь, что hook читает JSON из stdin (а не из аргументов командной строки)
Hook неожиданно блокирует выполнение
- Протестируйте hook на тестовом JSON:
echo '{"tool_name": "Write", ...}' | ./hook.py - Проверьте код выхода: 0 - разрешить, 2 - заблокировать
- Проверьте вывод в stderr (отображается при коде выхода 2)
Ошибки парсинга JSON
- Всегда читайте из stdin, а не из аргументов командной строки
- Используйте полноценный парсер JSON (а не манипуляции со строками)
- Корректно обрабатывайте отсутствующие поля
Установка
Шаг 1. Создайте директорию для hooks
Шаг 2. Скопируйте примеры hooks
Шаг 3: Настройка в settings
Отредактируйте ~/.claude/settings.json или .claude/settings.json, добавив конфигурацию hook, показанную выше.
Связанные концепции
- Checkpoints и Rewind - сохранение и восстановление состояния диалога
- Slash Commands - создание собственных slash commands
- Skills - переиспользуемые автономные возможности
- Subagents - делегирование выполнения задач
- Plugins - упакованные расширения
- Продвинутые возможности - знакомство с расширенными возможностями Claude Code
Дополнительные материалы
- Официальная документация по hooks - полный справочник по hooks
- CLI Reference - документация по интерфейсу командной строки
- Руководство по Memory - настройка постоянного контекста
Последнее обновление: 2 сентября 2026 г. Версия Claude Code: 2.1.257 Источники:
- https://code.claude.com/docs/en/hooks
- https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md
- https://code.claude.com/docs/en/sub-agents Совместимые модели: Claude Fable 5, Claude Opus 5, Claude Sonnet 5, Claude Sonnet 4.6, Claude Opus 4.8, Claude Haiku 4.5