Hooks
Хуки позволяют запускать произвольные shell-команды в определённых точках жизненного цикла Kodik: перед и после вызова инструмента, при запуске сессии, при компактировании и в других ситуациях. С помощью хуков можно блокировать нежелательные действия, вести аудит-лог, автоматически модифицировать входные данные инструментов и многое другое.
Где определяются хуки
Заголовок раздела «Где определяются хуки»Хуки могут поступать из трёх источников, которые загружаются одновременно:
| Источник | Расположение файла |
|---|---|
| Проект | .kodik/hooks/hooks.json (или .kodik/hooks/hooks.toml) в корне рабочей директории |
| Пользователь | ~/Documents/Kodik/Hooks/hooks.json (или hooks.toml) |
| Плагин | hooks/hooks.json внутри директории установленного плагина |
Проектные хуки применяются только к доверенным рабочим директориям. При первом обнаружении файла хуков Kodik предложит подтвердить доверие к проекту.
Быстро создать хук можно с помощью команды /create-hook.
Поддерживаемые события
Заголовок раздела «Поддерживаемые события»| Событие | Когда срабатывает | Матчер |
|---|---|---|
PreToolUse | Перед выполнением любого инструмента | Regex по имени инструмента |
PostToolUse | После выполнения инструмента | Regex по имени инструмента |
PermissionRequest | При запросе разрешения на использование инструмента | Regex по имени инструмента |
SubagentStart | При запуске субагента | Regex по типу агента |
SubagentStop | При остановке субагента | Regex по типу агента |
SessionStart | При старте или возобновлении сессии | Regex по источнику (startup или resume) |
PreCompact | Перед компактированием контекста | Regex по триггеру (manual или auto) |
PostCompact | После компактирования контекста | Regex по триггеру (manual или auto) |
UserPromptSubmit | При отправке пользователем сообщения | Матчер не применяется |
Stop | При остановке агента | Матчер не применяется |
Поле matcher — это строка регулярного выражения, которая проверяется против дискриминатора события:
- События с инструментами (
PreToolUse,PostToolUse,PermissionRequest): проверяется имя инструмента. - События субагентов (
SubagentStart,SubagentStop): проверяется тип агента. SessionStart: проверяется источник —startupилиresume.PreCompact/PostCompact: проверяется триггер —manualилиauto.UserPromptSubmit,Stop: матчер игнорируется, хук срабатывает всегда.
Матчер привязывается к началу и концу значения — например, Bash соответствует только инструменту с именем Bash. Чтобы сопоставить несколько инструментов, используйте синтаксис Edit|Write или .*.
Формат файла хуков
Заголовок раздела «Формат файла хуков»{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "python3 audit_tool.py", "timeout": 10 } ] } ], "SessionStart": [ { "hooks": [ { "type": "command", "command": "echo session started >> ~/kodik-sessions.log" } ] } ] }}Каждая запись в массиве события содержит:
matcher— необязательная regex-строка (отсутствие означает «всегда совпадает»).hooks— массив обработчиков. Сейчас поддерживается только типcommand.command— shell-команда, которую нужно выполнить.timeout— таймаут в секундах (по умолчанию 30, диапазон 1–300).
Входные данные хука
Заголовок раздела «Входные данные хука»Хук получает на stdin JSON-объект с информацией о событии:
{ "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "ls -la" }, "context": { ... }}Результат выполнения хука
Заголовок раздела «Результат выполнения хука»Хук сигнализирует об исходе через код возврата и/или stdout:
| Код возврата | Значение |
|---|---|
0 | Продолжить выполнение |
2 | Заблокировать действие; содержимое stderr становится причиной блокировки |
Кроме того, хук может вернуть структурированный JSON в последней непустой строке stdout. Поддерживаемые поля:
| Поле | Тип | Описание |
|---|---|---|
decision | "block" | "approve" | Явно заблокировать или разрешить действие |
reason | string | Причина решения, показывается пользователю |
modified_input | object | Изменённые входные данные инструмента (только для PreToolUse) |
modified_prompt | string | Изменённый текст промпта (только для UserPromptSubmit) |
additional_context | string | Дополнительный контекст, передаваемый агенту |
Пример блокировки с причиной:
{ "decision": "block", "reason": "Изменения в продакшн-ветке запрещены без код-ревью."}Переменные окружения
Заголовок раздела «Переменные окружения»Kodik передаёт в хук переменные окружения в зависимости от источника хука:
- Проектный хук:
KODIK_PROJECT_ROOT— путь к корню проекта. - Пользовательский хук:
KODIK_HOOKS_ROOT— путь к директории пользовательских хуков. - Хук плагина:
KODIK_PLUGIN_ROOTиKODIK_PLUGIN_ID.
Создание хука с помощью /create-hook
Заголовок раздела «Создание хука с помощью /create-hook»Напечатайте /create-hook в чате и опишите, что должен делать хук. Kodik сгенерирует и сохранит файл хуков в .kodik/hooks/hooks.json вашего проекта (или в глобальную директорию, если вы явно укажете). После создания хука перезагрузите окно IDE или начните новую задачу, чтобы изменения вступили в силу.