Хуки выполняют shell-команды в фиксированных точках сессии: после записи файла, перед запуском инструмента, по завершении хода. Это единственная часть конфигурации, которая выполняет код, не спрашивая каждый раз, — потому и стоит выловить её беззвучные сбои. Матчер с несуществующим именем инструмента не срабатывает никогда и никогда не жалуется. Команда, тянущаяся за аргументом, получает пустую строку: событие приходит как JSON на стандартный ввод, а не аргументами. И только часть событий действительно способна остановить то, что вот-вот произойдёт. Конструктор покрывает все три случая и говорит, какие события прерывают, а какие лишь наблюдают.
Возможности
Каждое событие перечислено вместе с тем, на что оно срабатывает
Матчеры сверяются с настоящими именами, регистр учитывается
Предупреждает о матчере на событии, у которого нет инструмента
Предупреждает, когда команда тянется за аргументами, которых не получит
Говорит, какие события могут прервать действие и как
Частые шаблоны матчеров одним щелчком
Несколько хуков правильно сгруппированы по событию и матчеру
Отмечает разрушительную команду до того, как она запустится без присмотра
Как использовать Конструктор хуков
Выберите событие, в которое хотите вмешаться
Добавьте матчер, если событие привязано к инструменту
Напишите команду, читающую полезную нагрузку со стандартного ввода
Прочтите предупреждения и внесите вывод в settings.json
Пример
Ввод
prettier --write "$1"
Результат
Warning: $1 will be empty — a hook is not given arguments
Событие приходит по конвейеру как JSON; читайте его через jq.
Частые ошибки и устранение неполадок
Хук никогда не запускается. — Обычно дело в матчере. Имена инструментов с заглавной буквы и чувствительны к регистру — Write, а не write, — а несуществующее имя беззвучно ни с чем не совпадает.
Команда работает, но не получает ввода. — Ввод хука приходит как JSON на стандартный ввод. Читайте его, например, через jq -r '.tool_input.file_path', а не ждите аргумент.
Мой хук не может остановить вызов инструмента. — Это умеют лишь некоторые события и только через выход со статусом 2. Всё прочее трактуется как «продолжай», а события вроде PostToolUse и так срабатывают постфактум.
Сессия зависает на моём хуке. — Задайте тайм-аут. Хук, ждущий чего-то — сетевого вызова, блокировки, — держит всю сессию.
Часто задаваемые вопросы
Какое событие взять для форматтера?
PostToolUse с матчером на пишущие инструменты, чтобы он запускался, когда файл уже существует. Форматировать до записи нечего.
Как хук получает событие?
Как JSON на стандартный ввод: имя инструмента, его вход и окружающий контекст. Ничего не передаётся аргументами командной строки, поэтому команда, написанная вокруг $1, не получает ничего.
Может ли хук помешать инструменту запуститься?
До запуска — да: выход со статусом 2 прерывает. Какие события это позволяют, показывается при выборе, потому что попытка прервать из события, срабатывающего после, — ошибка одновременно частая и сбивающая с толку.
Хуки запускаются без вопроса?
Да — в этом их смысл и причина внимательно читать любой хук перед добавлением. Хук, удаляющий файлы, здесь отмечается, но общее правило: всё в этом файле работает без присмотра.
Можно ли несколько хуков на одно событие?
Да. Хуки с одинаковым событием и матчером группируются в выводе — именно эту форму ждёт файл конфигурации.
Связанные инструменты
Тестер правил доступа — Проверьте правила «разрешить», «спросить» и «запретить» на командах.