Хуки
Автоматика Claude Code — session-start, session-end, task-completed
Хуки
Хуки — команды, которые Claude Code запускает автоматически при определённых событиях. dev-workflow устанавливает 4 хука при init.
Список хуков
| Event name | Когда | Что делает |
|---|---|---|
| SessionStart | Начало сессии | Загружает vault-контекст, engram-памяти, задачи, workflow (полный или минимальный payload — по source) |
| SessionEnd | Конец сессии | Сохраняет daily log, пишет session-память в engram, финализирует/паузит workflow |
| TaskCompleted | После завершения задачи | Записывает в daily log с названием задачи |
| PostToolUse | После вызова инструмента (Edit/Write/Bash) | Permission-хук: проверяет вызов против allowlist активного агента |
Stdin JSON
Все хуки получают данные от Claude Code через stdin в JSON-формате, не через env variables:
{
"session_id": "abc123",
"cwd": "/path/to/project",
"hook_event_name": "SessionStart",
"source": "startup"
}Каждый хук парсит stdin и извлекает нужные поля:
| Хук | Что читает из stdin |
|---|---|
| SessionStart | cwd, source |
| SessionEnd | cwd |
| TaskCompleted | cwd, task_subject |
| PostToolUse | cwd, tool_name, tool_input, tool_response |
Формат ответа
Хуки возвращают JSON в stdout:
{
"continue": true,
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "vault context injected here"
}
}continue: true— Claude Code продолжает работуhookSpecificOutput.additionalContext— для SessionStart: vault-контекст инжектится в сессию
SessionStart
Самый важный хук. Размер инжектируемого контекста зависит от поля source в stdin — два режима payload:
Полный payload — source: startup, clear, отсутствует или неизвестен (fail-open: незнакомое значение трактуется как полный):
- Имя проекта и текущую ветку
- Содержимое vault (stack, knowledge, gameplan, conventions — с усечением)
- Branch context (если не на main)
- Последнюю сессию из daily log
- Текущую задачу с описанием (если привязана к ветке)
- Активный workflow (если на паузе)
- Релевантные engram-памяти (top-5 по ветке/задаче) + engram health warning
- Активный communication profile
- SPEC drift warning (если SPEC.md изменился после
/vault:from-spec)
Минимальный pointer-блок — source: resume или compact (контекст сессии уже восстановлен самим Claude Code, повторный полный инжект только дублирует токены):
- Имя проекта и текущую ветку
- Указатель текущей задачи (id/статус, без описания)
- Активный workflow (если на паузе)
- Строку-указатель: полный контекст — через
/session:resumeили чтение.dev-vault/
В минимальном режиме хук не делает ни одного engram-обращения (ни search, ни health).
Side effects выполняются безусловно в обоих режимах: GC устаревших engram-trace файлов, авто-создание branch-context файла на новой ветке, синхронизация custom-workflow шимов и сверка .claude/{skills,agents}/ проекта с установленным пакетом dev-workflow: unmodified-файлы тихо обновляются при смене версии, user-modified сохраняются с stderr-уведомлением, удалённые файлы восстанавливаются, hooks-блок settings.json пере-сливается. Отключение авто-синка: DEV_WORKFLOW_AUTO_SYNC=0 (разово) или auto_sync: false в .dev-workflow.lock (постоянно).
SessionEnd
Автоматический auto-save:
- Создаёт/дополняет
.dev-vault/daily/<date>.md - Записывает: проект, ветка, diff stat, uncommitted files
- Пишет session-память в engram (изменённые файлы за сессию)
- Если workflow был running — финализирует (
completed, когда все шаги completed/skipped) или ставит на паузу
TaskCompleted
Срабатывает после завершения задачи через dev-workflow task либо TodoWrite-маркер:
- Извлекает
task_subjectиз stdin JSON - Дописывает запись в
.dev-vault/daily/<date>.mdс названием задачи и ссылкой на коммит, если он есть
PostToolUse
Permission-хук, зарегистрированный с matcher Edit|Write|Bash. Срабатывает после вызова инструмента и может остановить его структурным ответом:
{
"continue": false,
"decision": "block",
"reason": "permission violation: <agent> touched <path> outside allowlist"
}- Включается opt-in флагом
devWorkflow.enforcePermissions: trueв.claude/settings.json(по умолчанию OFF; absent/нечитаемо → OFF). Выключенный флаг → no-op (allow + stderr-warn). - Enforcement действует только для живого прогона:
run.status === "running"И текущий шаг в статусеrunning(per-step liveness — отсекает «зомби»-прогоны, которые conversational-оркестратор не пометилcompleted). - При пустом/битом stdin: fail-closed только если есть живой прогон; иначе allow с громким stderr-предупреждением (никогда не тихий fail-open).
- Активный агент шага резолвится в
run.activeAgent(движком workflow при входе в шаг); хук грузит его allowlist однимparseAgentFileи сопоставляет: Write/Edit → путь (лексический segment-anchored matcher, traversal-safe, пустой allowlist = deny-all); Bash → strict-equality дляshellCommands+ quote/heredoc-aware парсер git-субкоманды дляgitOperations. Нарушение → атомарная записьstatus="failed"+abortReasonиhookBlock. Неразрешённый агент, отказ матчера или крэш при включённом enforcement → fail-closed (block). - PostToolUse срабатывает после инструмента — это detect-and-abort (фиксирует нарушение и останавливает прогон), а не предотвращение записи.
Ручной запуск (для тестирования)
echo '{"cwd":"'"$PWD"'","source":"startup"}' | node /path/to/dist/hooks/session-start.js
echo '{"cwd":"'"$PWD"'"}' | node /path/to/dist/hooks/session-end.js