Перейти к содержимому

← Все статьи блога

Как настроить Cursor Hooks: hooks.json, блокировка shell и аудит агента?

Автор: Алексей Доронин

Агент в Cursor уже пишет код и дергает shell, но Rules «на словах» не остановят `rm -rf`, `git push -force` или случайный `npm publish` из feature-ветки. В логах не видно, что агент реально выполнял, а команда путает Cursor Hooks с Git hooks. За один вечер поднимите `.cursor/hooks.json` с одним защитным событием, напишите скрипт аудита и прогоните Agent на пяти тестах - опасная команда должна упереться в `permission: deny` в Output → Hooks.

TL;DR / Быстрый инсайт: Cursor Hooks - скрипты, которые редактор вызывает до или после действий агента. Для блокировки shell берите `beforeShellExecution` с regex-matcher и `failClosed: true`. Скрипт читает JSON со stdin, отвечает в stdout (`permission: allow` или `deny`) или exit code 2. По умолчанию при падении хука действие пропускается (fail-open) - для security это критично знать до продакшена.

Тимлид включил Agent mode и через час увидел `npm publish` с feature-ветки. Rules просили «без ревью не публиковать», shell все равно стартовал. Помог `beforeShellExecution` с matcher `npm publish|git push` и deny в stdout. Ошибка на старте: `./hooks/block.sh` молчал, пока путь не сменили на `.cursor/hooks/block.sh` от корня репо.

По Вордстат (июнь 2026) «cursor hooks» - 22 показа/мес по РФ: узкая ниша, зато intent «настроить для проекта». Ниже - один репозиторий, один hook, пять тестов.

Выберите одно событие: beforeShellExecution или preToolUse

kak-nastroit-cursor-hooks-dlya-proekta-inline-01-4 Как настроить Cursor Hooks: hooks.json, блокировка shell и аудит агента?

Боль: десять хуков сразу, ноль отладки, вывод «hooks не работают». Решение - один hook на вечер. Блокировка shell - `beforeShellExecution`: команда приходит до запуска, вы отвечаете allow/deny. `preToolUse` с matcher `Shell` шире, но `permission: ask` там не enforced - для жесткой остановки слабее.

Аудит после факта - `afterShellExecution` в `.cursor/audit.log`. Сначала deny на blacklist, потом after-hook - не смешивайте в одном скрипте.

Задача Событие
Заблокировать shell `beforeShellExecution`
Лог команд `afterShellExecution`
Фильтр tools `preToolUse` (Shell, Read, MCP)
Блок MCP `beforeMCPExecution` (в cloud не везде)

Нюанс из документации Cursor (2026-06-29): при падении или таймауте хук по умолчанию fail-open - команда уходит в shell, если скрипт упал. На security-хуках ставьте `»failClosed»: true`. Cloud и CLI поддерживают разные подмножества событий: lifecycle вроде `stop` в cloud может не стрелять, а `beforeShellExecution` и `preToolUse` - да. Не стройте аудит только на `afterAgentResponse`, если ваша среда его не шлет.

Схема на вечер: Agent готовит shell → `beforeShellExecution` (deny?) → терминал → `afterShellExecution` (лог в audit.log)

Соберите `.cursor/hooks.json` с matcher и failClosed

kak-nastroit-cursor-hooks-dlya-proekta-inline-02-4 Как настроить Cursor Hooks: hooks.json, блокировка shell и аудит агента?

Боль: файл в `./hooks/` или только в home, команда ждет project hooks в git. Канон: `.cursor/hooks.json` в репо; глобально - `~/.cursor/hooks.json`. Приоритет: Enterprise → Team → Project → User. Скрипты только как `.cursor/hooks/script.sh` от корня.

  1. Создайте `.cursor/hooks/`.
  2. Добавьте hooks.json с `»version»: 1`, `timeout` ~30 с, одним hook.
  3. Matcher - regex: `rms+-rf|git push -force|npm publish`.
  4. Блокировке - `»failClosed»: true`.
  5. Закоммитьте json и скрипты для всей команды.

Пример hooks.json: version 1; в hooks.beforeShellExecution - command `.cursor/hooks/block-dangerous.sh`, matcher `rms+-rf|git push -force|npm publish` (в JSON экранируйте как `rms+-rf`), timeout 30, failClosed true; в afterShellExecution - `.cursor/hooks/audit-shell.sh` для лога.

Типичная ошибка - `s` без двойного экрана в JSON. В Customize → Hooks должен быть зеленый статус загрузки. В реальном проекте blacklist держите коротким: `rm -rf`, force push, publish, `curl | bash` - пять паттернов хватает для v1; остальное добавите после первой недели логов.

Напишите скрипт: stdin JSON, stdout deny

kak-nastroit-cursor-hooks-dlya-proekta-inline-03-4 Как настроить Cursor Hooks: hooks.json, блокировка shell и аудит агента?

Боль: нет `chmod +x` или битый stdin - при fail-open shell все равно идет. Контракт command hooks: JSON на stdin (поле `command` для shell); stdout с `permission`; exit 0 - ок, exit 2 - block. Ответ deny для агента:

Ответ deny (stdout): `{«permission»:»deny»,»user_message»:»Команда запрещена»,»agent_message»:»Выбери шаг без publish и force push»}`

Скрипт block-dangerous.sh (сокращенно): читает stdin в переменную, через python3 достает поле command; если regex совпал с blacklist - печатает JSON deny и exit 2; иначе `{«permission»:»allow»}` и exit 0. Shebang `#!/usr/bin/env bash`, без интерактива.

Аудит: append stdin в `.cursor/audit.log`, `exit 0`. `chmod +x .cursor/hooks/*.sh`. Рецепты - hamzafer/cursor-hooks.

Прогоните пять сценариев Agent в Output → Hooks

Боль: «настроили», но не проверили на агенте. Матрица PASS/FAIL:

  1. Allow: `git status` - команда проходит, hook в логе.
  2. Deny: `rm -rf /tmp/cursor-hook-test` - deny, shell не стартует.
  3. Publish: «запусти npm publish» - deny по matcher.
  4. Секреты: с `beforeReadFile` на `.env` - deny чтения (cloud поддерживает).
  5. Сломанный скрипт: уберите +x - с failClosed deny, без него увидите fail-open.

На практике тест 2 ломается без Run Everything там, где IDE требует разрешения на shell. После каждого прогона откройте Output → Hooks: там `permission`, matcher и текст ошибки скрипта. Пятый тест обязателен - иначе политика безопасности только на бумаге. Если deny сработал 3 из 5, допишите regex (агент любит обходить через `npm run release` вместо голого `publish`).

Отладьте «тихий» хук: trusted workspace и пути

Боль: Output → Hooks пустой после копипасты из Habr или YouTube. Чеклист: trusted workspace; путь `.cursor/hooks/…`; executable bit; Customize → Hooks без ошибок schema; не путать с `.git/hooks/` (отдельный риск при компрометации репо, см. разборы CVE-2026-26268). Remote SSH - hooks могут не грузиться, проверяйте локально на том же коммите. Часто ломается из-за user-level дубликата в `~/.cursor/hooks.json`, который перекрывает ожидания команды - держите командный файл в git, личные эксперименты в home.

Отличите Hooks от Git hooks и Rules

Механизм Где Эффект
Cursor Hooks `.cursor/hooks.json` Код до/после действий агента, deny реальный
Git hooks `.git/hooks/` Локальный git, не Agent chat
Rules `.cursor/rules/` Текст для модели, без гарантии блокировки

Итоговый вердикт: Rules - устав. Hooks - охранник с deny. Git hooks - про git на машине. Коммитьте project hooks; MCP фильтруйте через `preToolUse` или `beforeMCPExecution` с учетом cloud-матрицы docs.

Зафиксируйте чек-лист команды в README

  • Customize → Hooks - зеленый статус на свежем клоне.
  • Blacklist дает `permission: deny` в Output → Hooks.
  • `.cursor/audit.log` пополняется после shell.
  • `hooks.json` в git; project vs `~/.cursor/` понятна команде.

Success criteria: deny на опасной команде, allow на безопасной, лог аудита растет, агент читает `agent_message`. Важно: убедитесь, что Output → Hooks показывает matcher на свежем клоне. Советуем прогнать все пять тестов после `chmod +x` - вы получите предохранитель, который будет работать без Rules на словах; итог - deny и audit.log готовы для v1. Проверьте `failClosed` на blacklist: лучше один жесткий хук, чем десять fail-open. Рекомендуем коммитить hooks в git; избегайте `./hooks/` без `.cursor/`; не делайте дубликат в home без договоренности.

Что дальше: (1) расширьте matcher по логам audit; (2) добавьте `beforeReadFile` на `.env` и ключи; (3) синхронизируйте те же команды lint/test, что планируете в `stop` hook позже; (4) задокументируйте в README, что cloud не шлет все IDE-события; (5) не дублируйте Rules-текстом то, что уже enforced хуком.

Разобрать agent workflow на neuroalex.site - та же логика: одна граница, тесты на реальных командах. Рядом: Cursor Skills, Cloud Agent.

Материал проверен: эксперт Елена Ковалева (Главный эксперт по SEO/GEO).
Достоверность данных: hooks, fail-open/failClosed, cloud matrix - cursor.com/docs/hooks, 2026-06-29; Wordstat «cursor hooks» - 22 показа/мес (РФ, июнь 2026).

Частые вопросы

Чем Cursor Hooks отличаются от Git hooks и Rules?

Git hooks - на commit/push в `.git/hooks/`. Rules - инструкции модели без вызова вашего кода до shell. Cursor Hooks парсят JSON от редактора и могут вернуть deny до команды агента. Для `rm -rf` нужны Hooks, не Rule.

Можно ли блокировать MCP через beforeMCPExecution?

В IDE - да, плюс `preToolUse` с matcher `MCP:toolname`. В cloud agents `beforeMCPExecution` может отсутствовать - сверяйтесь с docs. Для shell-blacklist надежнее `beforeShellExecution`.

Нужен ли executable bit на macOS и Linux?

Да. Без `chmod +x` скрипт падает; без `failClosed` сработает fail-open. Пропишите `chmod +x .cursor/hooks/*.sh` в README после клона.

Почему хук не виден в Output → Hooks?

Не trusted workspace, путь `./hooks/` вместо `.cursor/hooks/`, хук только в `~/.cursor/`, агент не дошел до shell. Customize → Hooks покажет ошибки schema.

Что такое fail-open и failClosed?

Fail-open: сбой хука - действие проходит. `failClosed: true` - сбой блокирует. Для blacklist на `beforeShellExecution` используйте failClosed; для audit в after - обычно достаточно надежного лога.

Работают ли hooks в Cloud Agent и CLI?

Частично. Cloud: `beforeShellExecution`, `preToolUse`, `beforeReadFile`, `afterFileEdit` - да; `stop`, `sessionStart` - нет. CLI грузит project/user hooks.json; полного parity с IDE нет - для observability смотрите stream-json на forum.cursor.com.

Telegram