Хуки
Hooks
Hooks - это автоматические сценарии, которые выполняются в ответ на определённые события во время сеансов Claude Code. Они позволяют реализовать автоматизацию, валидацию, управление разрешениями и настраиваемые рабочие процессы.
Обзор
Hooks - это автоматические действия (shell-команды, HTTP-webhooks, LLM-промпты, вызовы MCP-инструментов или запуск subagent'ов), которые срабатывают автоматически при определённых событиях в Claude Code. Они принимают входные данные в формате JSON и возвращают результаты через коды завершения и JSON-вывод.
Ключевые возможности:
- Автоматизация, управляемая событиями
- Ввод/вывод в формате JSON
- Поддержка типов hooks:
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плагина - hooks в области плагина- 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 (default 60) | 30 |
once | If true, run the hook only once per session | true |
Шаблоны 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-команду и обменивается данными через JSON по stdin/stdout, а также через коды возврата.
Exec-форма (args)
Добавлено в v2.1.139.
Вместо shell-формы "command": "..." command hook может запускать бинарник напрямую через execve(), передавая массив args. Shell-парсинг при этом не выполняется, поэтому подстановки путей никогда не требуют экранирования кавычками, а конфигурация защищена от ошибок, связанных с shell-инъекциями.
Эти две формы взаимоисключающие - hook, в котором одновременно заданы command и args, отклоняется при загрузке конфигурации. Используйте command, когда нужны конвейеры, перенаправления, объединение команд через && или подстановки shell; используйте args, когда вызываете один бинарник с аргументами.
HTTP Hooks
> Добавлено в v2.1.63.
Удалённые webhook-эндпоинты, которые получают тот же JSON на вход, что и command hooks. HTTP hooks отправляют JSON методом POST на указанный URL и получают JSON-ответ. Когда sandboxing включён, запросы HTTP hooks маршрутизируются через sandbox. Для интерполяции переменных окружения в URL необходимо в целях безопасности явно задать список allowedEnvVars.
Ключевые свойства:
"type": "http"- обозначает hook как HTTP"url"- URL endpoint webhook'а- Маршрутизируется через sandbox, если 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"- определяет этот hook как вызов MCP-инструмента"server"- имя настроенного MCP-сервера"tool"- имя вызываемого инструмента на этом сервере
Входные данные hook (имя инструмента, его входные параметры, контекст сессии) передаются как аргументы MCP-инструмента. О настройке MCP-серверов см. MCP server setup.
Agent Hooks
Проверочные hooks на основе субагентов: для оценки условий или выполнения сложных проверок запускается отдельный агент. В отличие от prompt hooks (одношаговая оценка через LLM), agent hooks могут использовать инструменты и выполнять многошаговые рассуждения.
Ключевые свойства:
"type": "agent"- обозначает, что это agent hook"prompt"- описание задачи для субагента- Агент может использовать инструменты (Read, Grep, Bash и т. д.) для выполнения проверки
- Возвращает структурированное решение, аналогичное prompt hooks
События hook
Claude Code поддерживает 31 событие 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) | 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 |
| 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 |
Длительность в PostToolUse (v2.1.119): входные данные hook'ов
PostToolUseиPostToolUseFailureтеперь включаютduration_ms- подробнее см. в разделе PostToolUse.
PreToolUse
Запускается после того, как Claude сформировал параметры инструмента, но до их обработки. Используйте этот hook для валидации или изменения входных параметров инструмента.
Конфигурация:
Часто используемые матчеры: Task, Bash, Glob, Grep, Read, Edit, Write, WebFetch, WebSearch
Управление выводом:
permissionDecision:"allow","deny","ask"или"defer""allow"пропускает запрос разрешения (кроме инструментов, требующих взаимодействия с пользователем, и инструментов-коннекторов, для которых ваша организация установила значениеask)"deny"блокирует вызов инструмента"ask"запрашивает подтверждение у пользователя"defer"корректно завершает работу, чтобы инструмент можно было возобновить позже; при этом значении поляpermissionDecisionReason,updatedInputиadditionalContextигнорируются- Правила
denyиaskвсё равно применяются независимо от того, что вернул hook. Если несколько hook-овPreToolUseдают противоречивые решения, приоритет следующий:deny>defer>ask>allow
permissionDecisionReason: обоснование решения. Для"allow"и"ask"показывается пользователю (но не Claude); для"deny"показывается Claude; для"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): Если Stop hook возвращает "decision": "block" (или устанавливает continue: false) 8 раз подряд в рамках одного хода, Claude Code принудительно прерывает цикл и завершает сессию с предупреждением. Порог можно переопределить через переменную окружения CLAUDE_CODE_STOP_HOOK_BLOCK_CAP=<integer> (значение 0 полностью отключает лимит). Это защищает от ситуации, когда сбойный Stop hook бесконечно зацикливает сессию.
Поле возврата (v2.1.163): Stop или SubagentStop hook может вернуть hookSpecificOutput.additionalContext, чтобы передать Claude обратную связь и продолжить ход, не показывая метку ошибки. Раньше повлиять на модель из Stop hook было неудобно; теперь hook может аккуратно внедрить контекст, избегая появления метки ошибки, характерной для прежних способов передачи обратной связи (например, "decision": "block").
SubagentStart
Срабатывает в момент запуска субагента. В matcher передаётся имя типа агента, что позволяет применять hooks к конкретным типам субагентов.
Конфигурация:
SessionStart
Запускается при старте или возобновлении сессии. Может сохранять переменные окружения.
Matchers: startup, resume, clear, compact, fork
Обновление v2.1.214: форкнутая сессия теперь возвращает источник
"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- иная причина
Конфигурация:
Событие уведомления
Обновлённые matchers для событий уведомлений:
permission_prompt- уведомление с запросом разрешенияidle_prompt- уведомление о простоеauth_success- успешная аутентификацияelicitation_dialog- диалог, отображаемый пользователюagent_needs_input- фоновому agent требуется ввод (v2.1.198)agent_completed- фоновый agent завершил работу (v2.1.198)
Hooks на уровне компонента
Hooks можно привязывать к конкретным компонентам (skills, agents, commands) через их frontmatter:
В SKILL.md, agent.md или command.md:
Поддерживаемые события для hooks в компонентах: PreToolUse, PostToolUse, Stop
Это позволяет определять hooks прямо в том компоненте, который их использует, благодаря чему связанный код хранится вместе.
Hooks во frontmatter субагента
Если во frontmatter субагента задан hook Stop, он автоматически преобразуется в hook SubagentStop, привязанный к этому субагенту. Это гарантирует, что stop hook срабатывает именно при завершении данного субагента, а не при остановке основной сессии.
Требуется доверие к рабочей области (v2.1.218): hooks во frontmatter project-субагента теперь требуют подтверждения доверия к рабочей области для папки, из которой был загружен файл агента, - иначе они не запустятся. До версии v2.1.218 такие hooks могли выполняться из папок, которым вы не давали доверие. О том, для каких scopes сделано исключение, см. документацию по субагентам.
Событие PermissionRequest
Обрабатывает запросы разрешений с пользовательским форматом вывода:
Входные и выходные данные hook
JSON на входе (через stdin)
Все hooks получают 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, код возврата 0)
Область применения (v2.1.121+):
hookSpecificOutput.updatedToolOutputтеперь учитывается для всех инструментов, а не только для MCP-инструментов. HookPostToolUse, навешенный наBash,Edit,Readи т. д., может переписать вывод инструмента до того, как его увидит Claude, - это удобно для маскирования секретов, нормализации diff-ов или отсеивания шумного вывода команд. Пример (удаление ANSI-кодов цвета из выводаBash):
terminalSequence (v2.1.141)
Hook-и могут выдавать сырые OSC-последовательности (operating system command) - для этого в JSON-выводе задаётся поле terminalSequence. Когда hook возвращает результат, хост записывает эту последовательность в свой управляющий терминал. Это удобно для десктопных уведомлений, обновления заголовка окна и подачи звукового сигнала терминала (bell) - без необходимости держать собственный 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:
Текущая дата: вторник, 4 августа 2026 г.
<query>Схема ответа LLM: </query>
Примеры
Пример 1: Валидатор Bash-команд (PreToolUse)
Файл: .claude/hooks/validate-bash.py
Текущая дата: вторник, 4 августа 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 (на основе промпта)
Пример 6: Трекер использования контекста (пары hook'ов)
Отслеживайте расход токенов на каждый запрос с помощью связки hook'ов UserPromptSubmit (перед сообщением) и Stop (после ответа).
Файл: .claude/hooks/context-tracker.py
Текущая дата: вторник, 4 августа 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 хука через 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>:
Вопросы безопасности
Отказ от ответственности
ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК: hook’и выполняют произвольные shell-команды. Вы несёте полную ответственность за:
- команды, которые вы настраиваете;
- права доступа к файлам и их изменения;
- возможную потерю данных или повреждение системы;
- тестирование hook’ов в безопасных окружениях перед использованием в production.
Замечания по безопасности
- Требуется доверие к рабочей области: команды, выводимые hook’ами
statusLineиfileSuggestion, теперь вступают в силу только после подтверждения доверия к рабочей области. - Размер терминала для status-line (v2.1.153): скрипты команд status-line теперь получают переменные окружения
COLUMNSиLINES, что позволяет адаптировать вывод под ширину/высоту терминала (например,[ "$COLUMNS" -lt 80 ] && short_output). - HTTP-hook’и и переменные окружения: для интерполяции переменных окружения в URL HTTP-hook’и требуют явного указания списка
allowedEnvVars. Это предотвращает случайную утечку чувствительных переменных окружения на удалённые endpoint’ы. - Иерархия управляемых настроек: параметр
disableAllHooksтеперь учитывает иерархию управляемых настроек - это значит, что настройки уровня организации могут принудительно отключать hook’и без возможности переопределения со стороны отдельных пользователей. - Автоодобрение PowerShell (v2.1.119): команды инструмента PowerShell теперь могут автоматически одобряться в режиме разрешений - аналогично Bash. Это уравнивает возможности для пользователей Windows, работающих в Claude Code с shell-инструментами на базе PowerShell.
- Закрыта лазейка с автоодобрением «голых» env-var в Bash (v2.1.145): до версии v2.1.145 Bash-команда вида
FOO=bar somecommand(встроенное присваивание переменной вместе с командой, отсутствующей в allowlist) могла быть автоматически одобрена, если в allowlist находилось только самоFOO=bar. В v2.1.145 эта лазейка закрыта - такие команды теперь вызывают запрос разрешения. Скрипты, полагавшиеся на неявное разрешение, начнут запрашивать подтверждение; чтобы вернуть автоодобрение, явно добавьте правило разрешенияBash(...), охватывающее команду целиком, а не только присваивание переменной.
Лучшие практики
| 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 с флагом отладки, чтобы получить подробные логи hook'ов:
Подробный режим
Нажмите Ctrl+O в Claude Code, чтобы включить подробный режим и отслеживать ход выполнения hook'ов.
Тестирование hook'ов по отдельности
Полный пример конфигурации
Детали выполнения hook
| Aspect | Behavior |
|---|---|
| Timeout | 60 seconds default, configurable per command |
| 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 - Проверьте exit code: 0 - разрешить, 2 - заблокировать
- Проверьте вывод в stderr (отображается при exit code 2)
Ошибки парсинга JSON
- Всегда читайте из stdin, а не из аргументов командной строки
- Используйте полноценный парсер JSON (а не манипуляции со строками)
- Корректно обрабатывайте отсутствующие поля
Установка
Шаг 1. Создайте директорию для hooks
Шаг 2: Скопируйте примеры hooks
Шаг 3: Настройка в settings
Отредактируйте ~/.claude/settings.json или .claude/settings.json, добавив конфигурацию hook, показанную выше.
Связанные концепции
- Checkpoints и Rewind - сохранение и восстановление состояния диалога
- Slash-команды - создание пользовательских slash-команд
- Skills - переиспользуемые автономные возможности
- Subagents - делегированное выполнение задач
- Plugins - упакованные комплекты расширений
- Продвинутые возможности - знакомство с продвинутыми возможностями Claude Code
Дополнительные материалы
- Официальная документация по hooks - полный справочник по hooks
- Справочник по CLI - документация по интерфейсу командной строки
- Руководство по memory - настройка постоянного контекста
Последнее обновление: 4 августа 2026 г. Версия Claude Code: 2.1.220 Источники:
- 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