Hooks у Claude Code: автоматизація без втручання моделі » IT-FORMAT
» » » Hooks у Claude Code: автоматизація без втручання моделі
ВИП. №185· травень 2026· НІЖИН

Новий формат бізнесу — у цифрі, у вашій щоденній роботі.

Автоматизація обліку, власні розробки на BAS/1С, IP-телефонія та відеоспостереження. Пишемо про те, що робимо — і робимо те, про що пишемо.

Hooks у Claude Code: автоматизація без втручання моделі

IT-Wiki / Claude Code: команди і автоматизація 14 травня 2026 Переглядів: 8 Автор: Claudia
Hooks у Claude Code
Editorial composition · гачки і стрілки потоку
Перед стартом

Один з трьох файлів settings.json доступний для редагування: ~/.claude/settings.json (user), <repo>/.claude/settings.json (project), .claude/settings.local.json (local, у gitignore). Базове знання shell на цільовій ОС. Корисно мати jq — деякі hooks повертають JSON.

Що таке hook у двох реченнях

Hook — це shell-команда у settings.json, яку CC запускає на одній із подій життєвого циклу. Команда виконується процесом-нащадком shell'а; її stdout/stderr/exit code впливають на CC (можна заблокувати tool-виклик, можна повернути дані моделі, можна нічого не повертати — тоді hook просто «зробив свою справу»).

Це принципово відрізняється від tool-ів: tool — це функція, яку викликає модель; hook — функція, яку викликає система навколо моделі.

6 типів подій

ТипКоли запускаєтьсяМоже заблокувати?
PreToolUseПеред викликом tool-аТак (exit 2)
PostToolUseПісля виклику tool-аНі (вже виконалось)
SessionStartСтарт сесіїНі
StopКінець відповіді моделі (end-of-turn)Ні
NotificationКоли CC хоче повідомити користувача (наприклад, чекає підтвердження)Ні
UserPromptSubmitПеред обробкою кожного промта користувачаТак (заблокує промт)

Структура hook у settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "ruff format "${tool_input.file_path}""
      }
    ]
  }
}

Розбір:

  • "PostToolUse" — тип події.
  • "matcher" — regex по імені tool-а. "Edit" ловить тільки виклики Edit, "Bash" — тільки Bash, ".*" — всі. Можна "Edit|Write".
  • "command" — сама shell-команда. Має доступ до плейсхолдерів ${tool_input.<поле>} — параметрів, з якими викликано tool.

Реальні рецепти

1. Auto-format Python після Edit

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "command": "case "${tool_input.file_path}" in *.py) ruff format "${tool_input.file_path}";; esac"
    }]
  }
}

Після кожного Edit/Write по .py-файлу — запускається ruff format. CC бачить уже відформатований код у наступному Read. Це знімає 80% перепалок «модель пише з 2-tab, а проект на 4-space».

2. Audit-лог Bash-команд

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "command": "echo "$(date -Iseconds) ${tool_input.command}" >> ~/.claude/bash-audit.log"
    }]
  }
}

Кожна Bash-команда, яку CC хоче виконати, записується в audit-log до виконання. Корисно для:

  • Compliance (можна показати команді безпеки, що саме виконує агент).
  • Debugging — згадати «що ж він тоді зробив».
  • Постфактумного reviewing — підозрілий patern (наприклад, виконав 50 однакових команд) видно у логу.

3. Push-сповіщення у Telegram на завершення сесії

{
  "hooks": {
    "Stop": [{
      "command": "curl -s 'https://api.telegram.org/bot$TOKEN/sendMessage' -d 'chat_id=$CHAT_ID' -d 'text=CC session done'"
    }]
  }
}

На Stop (кінець відповіді моделі) — пуш у Telegram. Корисно для cron-запусків («Recurring jobs») — отримуєш сповіщення, що нічна задача завершилась успішно (або, якщо exit-code-aware, що впала).

4. Заборона rm -rf без явного підтвердження

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "command": "case "${tool_input.command}" in *'rm -rf'*) echo 'BLOCKED: rm -rf needs manual confirmation' >&2; exit 2;; esac"
    }]
  }
}

Якщо CC спробує виконати команду з rm -rf — hook повертає exit 2 і CC отримує stderr як reason для блокування. Модель бачить блок, шукає альтернативу.

Це не замінює permissions (спиця «Permissions і settings.json» циклу), а доповнює — permissions працює на рівні patterns, hook може мати багатшу логіку.

5. Перевірка комітів на secrets

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "command": "case "${tool_input.command}" in *'git commit'*) git diff --cached | grep -E 'API_KEY|SECRET|TOKEN' && { echo 'BLOCKED: possible secret in commit' >&2; exit 2; };; esac; exit 0"
    }]
  }
}

Перед git commit сканує staged-diff на регекс API_KEY|SECRET|TOKEN. Якщо знайдено — блокує. Не замінює gitleaks/trufflehog (ті точніше), але fail-fast захист.

6. SessionStart-банер «де ти зараз»

{
  "hooks": {
    "SessionStart": [{
      "command": "echo '== Branch:' $(git branch --show-current 2>/dev/null) '== Status:' $(git status --porcelain 2>/dev/null | wc -l) 'changes'"
    }]
  }
}

На старті сесії — короткий стан репо у консолі. Економить запит «де ми зараз». Особливо корисно, якщо часто перемикаєш гілки і повертаєшся через /resume.

Підводні камені

Що ламається або робить hooks небезпечними

Format виходу критичний. Hook може повертати:

  • Просто exit code (0 — OK; 2 — блокувати tool/prompt, stderr передається моделі як reason).
  • JSON на stdout (для подачі повідомлень моделі або зміни параметрів).
  • Інші exit codes — трактуються як помилка hook'а, але не блокують tool автоматично.

Якщо твій hook пише в stdout щось не-JSON і виходить з кодом 0 — CC проігнорує вихід. Якщо повертаєш JSON — він має бути валідний, інакше hook fail.

Hook довше 5 секунд блокує сесію. Користувач сидить і чекає, поки CC чекає на hook. Не роби в hook мережевих викликів (curl на API), повільних linter'ів, scan-ів. Якщо це обов'язково — запускай у фоні через & або у бічному процесі.

Hook працює у shell ОС, з повними правами CC-користувача. Це не пісочниця: rm, chmod, мережа — все доступне. Це diff від tool permissions у самому CC. Тому: не клади у hook script-и з зовнішніми залежностями, не довіряй ${tool_input.*} сліпо (екрануй).

Регекс у matcher — точкова річ. "Edit" матчить тільки точну назву tool-а. "Edit|Write" — обидва. "^E" — все, що починається з E (Edit, ExitPlanMode тощо). Тестуй регулярки на реальних tool-іменах.

JSON у settings.json — JSON. Trailing commas, comments — все це не валідне. CC при невалідному settings.json може просто проігнорувати hooks і не сказати про це у вікно сесії. Перевір jq . ~/.claude/settings.json перед перезапуском.

Project-level hooks vs user-level. Project hooks застосовуються тільки у тому репо; user-level — глобально. Якщо переплутав місця — побачиш, що hook не спрацював, хоча в JSON він є.

Як налагоджувати hook

  1. Перевір синтаксис JSON: jq . ~/.claude/settings.json.
  2. Подивись список активних hooks: slash /hooks.
  3. Додай у hook tee -a ~/.claude/hooks-debug.log, щоб бачити, чи спрацював.
  4. Запусти tool, який має тригерити hook. Подивись у лог. Якщо порожньо — matcher неправильний.
  5. Якщо лог є, але hook не блокує (а має) — перевір exit code (повинно бути exit 2).

Cross-refs

Чек: чи безпечний мій hook
  • JSON-синтаксис валідний (jq не падає).
  • Hook виконується за < 1 секунду (інакше блокуєш UX).
  • Жодних мережевих викликів у тілі (виключити з PreToolUse/PostToolUse).
  • Якщо блокує — повертає exit 2 з reason у stderr.
  • Параметри з ${tool_input.*} екрановано (double-quotes, case-statement, не пряма interpolation у пайп).
  • Hook логує себе, щоб дебажити коли «не спрацював».
  • Hook не виконує деструктивних дій (delete, kill) без явного фільтра matcher.
Актуальність

Формат hooks у settings.json для CC станом на травень 2026. Anthropic може додати нові типи подій або змінити схему JSON — перевіряти у release notes. Швидкий тест — /hooks у своїй сесії.

Опубліковано: Вчора, 18:52 · Автор: Claudia
Теги
Вхід
Опитування

Якою програмою обліку ви користуєтесь?