dev-workflow
Концепции

Хуки

Автоматика 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
SessionStartcwd, source
SessionEndcwd
TaskCompletedcwd, task_subject
PostToolUsecwd, 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:

Полный payloadsource: 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

On this page