Claude Code Hooks не срабатывают на удалённом Mac: действие проходит без ожидаемой проверки, форматирования или блокировки.

Быстрый способ найти причину: сначала проверьте, какие настройки прочитал Claude Code и совпали ли событие с matcher; затем — учётную запись и окружение скрипта; в конце — формат ответа. Не переустанавливайте инструмент, пока не установлено, на каком этапе пропадает выполнение.

Материал для разработчиков, у которых удалённый Mac не выполняет ожидаемую проверку или обработчик.
Для DevOps-инженеров, которым нужно подтвердить результат Hook перед сборкой или тестированием Xcode.
Для инженеров платформы, которым важно разделить настройки проекта, пользователя и организации.

Диагностика по этапам выполнения

Фраза «Hook не сработал» может описывать разные сбои. Событие могло не возникнуть; matcher мог не охватить вызов; команда могла не запуститься; наконец, скрипт мог отработать, но не вернуть решение, которое вы ожидали. У этих случаев разные причины и способы проверки.

Начните с одного воспроизводимого действия. Например, внесите тестовое изменение в файл и выполните операцию, на которую должен реагировать Hook. Не запускайте одновременно несколько инструментов и не меняйте конфигурацию: иначе будет трудно понять, какое изменение повлияло на результат. Заранее зафиксируйте ожидаемое действие — форматирование, проверку команды или отказ в её выполнении.

Затем проследите путь от события до результата. Найдите в журнале сессии признаки вызова и используйте диагностику, описанную в официальном руководстве Claude Code по Hooks. Если свидетельств вызова нет, проверяйте настройки, событие и matcher. Если обработчик запустился, переходите к его окружению и выводу. Если есть корректный результат обработчика, но действие всё равно не изменилось, проверьте, допускает ли выбранное событие такое решение.

Признак Что проверять в первую очередь Следующий шаг
В журнале нет признака нужного события Область настроек и фактическое действие Подтвердите, что операция должна вызывать выбранное событие
Событие есть, но обработчик не виден Matcher, имя инструмента и условия фильтра Проверьте вызов с одним инструментом и упрощённым matcher
Скрипт отмечен, но команда не запускается Права, интерпретатор, PATH и рабочий каталог Повторите диагностику от имени фактического пользователя
Скрипт запущен, но блокировки или проверки нет Стандартный ввод, формат ответа, код завершения и семантика события Сопоставьте ответ с контрактом этого Hook
Hook завершился, но упала сборка или проверка Последующий инструмент или шаг CI Изучите отдельный результат запуска и журнал CI

Не удаляйте настройки и не устанавливайте Claude Code заново до этой проверки. Такие действия могут скрыть различие между источниками конфигурации, но не исправят отсутствующую зависимость или несовпадающий matcher.

Сценарий: Hook работает в интерактивном терминале, но ничего не делает в SSH-сеансе. Это ещё не указывает на неисправность узла. Claude Code мог быть запущен другим пользователем, из другого каталога или с иным источником настроек.

Источники настроек и учётная запись

Сначала установите, какой процесс запускает Claude Code: пользовательский сеанс SSH, интерактивный терминал, служба CI или отдельная техническая учётная запись. Не исходите из того, что все эти способы запуска читают один и тот же файл.

Сверьте источники настроек по назначению: пользовательские, проектные, локальные и управляемые организацией. Их области действия и правила чтения описаны в официальной документации Claude Code по настройкам. Проверяйте конфигурацию от имени того же пользователя и из того же каталога, где воспроизводится проблема. Файл в домашнем каталоге одного пользователя не следует считать доступным настройкой другого аккаунта.

Порядок проверки:

  • Зафиксируйте фактические имя пользователя и рабочий каталог процесса.
  • Проверьте, какие пользовательские и проектные настройки доступны этому аккаунту.
  • Убедитесь, что Hook размещён в нужном источнике, а локальная или управляемая конфигурация не меняет ожидаемое поведение.
  • Сравните запуск через SSH и запуск службой CI, если сбой возникает в обоих контекстах.
  • После изменения настроек повторите то же действие и сохраните диагностические признаки.

Не переносите пользовательский файл в проект, не изучив его содержимое. В нём могут оказаться локальные команды или параметры, непригодные для общего запуска. На общем Mac отдельно определите владельца настройки и пользователей, которым разрешено её менять.

Если проект требует согласованного поведения для команды, проверьте, что настройки находятся в подходящей для этого области действия и доступны нужному процессу. Если же проблема проявляется только у одного аккаунта, сначала сравните его окружение с рабочим аккаунтом, а не меняйте общую конфигурацию без необходимости.

События и matcher

Настройка Hook должна соответствовать этапу, на котором вы хотите выполнить действие. Обработчик до вызова инструмента, обработчик после него и обработчик завершения сессии решают разные задачи. Событие завершения нельзя считать заменой проверке конкретного вызова. Назначение событий, matcher и формат настройки сверяйте с официальным описанием Hooks Claude Code.

Для проверки оставьте одно событие и один целевой вызов. Если обработчик должен запускаться перед инструментом, убедитесь, что выбрано соответствующее событие и matcher охватывает фактическое имя инструмента. Не делайте вывод только по тексту запроса: важны данные вызова, с которыми сравнивается условие.

Проверяйте фильтры последовательно:

  • Упростите matcher до конкретного ожидаемого инструмента.
  • Выполните одно контролируемое действие.
  • Проверьте, появился ли след события и обработчика.
  • Если простой вариант сработал, возвращайте условия по одному.
  • Если обработчик по-прежнему не появляется, снова проверьте источник настроек и соответствие события.

Такой способ позволяет локализовать условие, которое перестало совпадать, не меняя всю конфигурацию сразу. Событие в журнале без запуска команды — отдельный симптом. Он направляет проверку к matcher или конфигурации обработчика, а не обязательно к скрипту.

Учитывайте и контекст события. У разных Hooks могут отличаться доступные данные и допустимые решения. Не переносите настройки или логику ответа с одного события на другое, не сверив контракт целевого события.

Окружение скрипта в SSH и CI

Скрипт может запускаться из открытого терминала и завершаться ошибкой при вызове Hook. Причина часто в различиях окружения: автоматический процесс может не загружать настройки интерактивной оболочки, а команда или файл могут быть доступны только пользователю, который проводил ручную проверку.

Диагностируйте проблему от имени того аккаунта, который фактически запускает Claude Code. Сравните рабочий каталог, доступность интерпретатора и необходимых команд. Проверяйте права на чтение, запись и выполнение для файлов, с которыми работает скрипт. Не выводите в журнал весь набор переменных окружения: среди них могут быть секреты и учётные данные.

Порядок проверки:

  • Установите пользователя процесса и воспроизведите действие от его имени.
  • Проверьте доступность файла скрипта и право на его выполнение.
  • Сверьте строку запуска, указанный интерпретатор и его фактический путь.
  • Убедитесь, что необходимая команда доступна через PATH именно в автоматическом запуске.
  • Проверьте рабочий каталог и разрешения для чтения или записи.
  • Добавьте безопасные диагностические признаки старта и завершения, не записывая секреты.
  • Повторите проверку в контексте службы CI, если проблема возникает там.

Если команда доступна только после загрузки профиля интерактивной оболочки, настройте для автоматического процесса явный путь или предсказуемое окружение. Не предполагайте, что сеанс SSH, открытая оболочка и служба CI автоматически наследуют одинаковые параметры.

Явно заданные пути облегчают диагностику: вы знаете, какой интерпретатор или инструмент должен запуститься. Но при переносе конфигурации на другой узел такой путь может отличаться. Поэтому после изменения проверьте запуск именно в целевом контексте, а не только вручную в терминале.

Формат ответа и результат выполнения

Факт запуска скрипта ещё не доказывает, что Claude Code применил его решение. Проверьте, какие данные пришли на стандартный ввод, что было записано в стандартный вывод, с каким кодом завершился процесс и соответствует ли ответ формату выбранного события. Правила входных данных и обработки ответа уточняйте в официальной документации Hooks.

Различайте следующие ситуации:

  • Событие не возникло либо не совпало с matcher.
  • Команда не смогла запуститься.
  • Скрипт запустился, но завершился с ошибкой или сформировал некорректный ответ.
  • Скрипт вернул допустимый ответ, который не содержит ожидаемого решения.
  • Hook отработал, а ошибка возникла уже в последующем инструменте или шаге CI.

Чтобы отделить неисправность процесса от ошибки логики, сначала подтвердите вызов простым диагностическим обработчиком. Затем добавляйте чтение входных данных и проверку условий по частям. Если ожидается блокировка, проверьте отдельно разрешённый и запрещённый сценарии. Успешный запуск скрипта не подтверждает, что запрещённый вызов действительно будет остановлен.

Код завершения и поля решения не следует трактовать одинаково для всех событий. Сверьте поведение с контрактом конкретного Hook. Если блокировка не действует, проверьте, поддерживает ли выбранное событие нужное решение, корректен ли формат ответа и не попадает ли в вывод посторонний текст.

Разрешения инструмента и Hook — не одно и то же. Для правил доступа сверяйтесь с описанием настроек разрешений Claude Code. Hook может выполнять детерминированную проверку или управлять вызовами, но не заменяет системную изоляцию, ручное подтверждение чувствительных действий или обязательный контроль в CI.

Приёмка проверок Xcode и безопасность

Не используйте факт выполнения Hook как подтверждение, что проект собрался или тесты прошли. Разделяйте проверку после изменения файла, реакцию на завершение сессии и фактический результат запуска тестов. Для последнего сохраняйте результат выполнения команды и анализируйте его по руководству Apple по запуску тестов и чтению результатов Xcode. Доступные параметры команды сверяйте со справочником инструментов командной строки Xcode. Для запуска тестов по SSH также доступен архивный материал Apple об автоматизации тестирования Xcode.

Проведите приёмку по отдельным условиям:

  • Ожидаемое действие вызывает Hook, а нерелевантное — нет.
  • Сценарий, который должен пройти, возвращает ожидаемый результат.
  • Преднамеренно некорректный сценарий приводит к ожидаемому отказу.
  • Журнал позволяет отличить выполнение Hook от запуска теста и последующего шага CI.
  • После перезапуска Mac настройки, скрипт и зависимости остаются доступны целевому процессу.

Для надёжного подтверждения автоматизации Xcode сохраняйте результат тестирования отдельно от диагностического вывода Hook. В нём должно быть понятно, какая команда запускалась, какой результат получен и к какому запуску относится запись. Конкретный формат отчёта выбирайте с учётом проекта и используемой команды Xcode.

Если Hook нужен для контроля доступа, не делайте его единственной защитой. Разделите роли: системные разрешения ограничивают доступ, правила Claude Code задают допустимые действия, а CI подтверждает сборку и тестирование. В такой схеме Hook помогает автоматизировать проверку, но ошибка в нём не превращается автоматически в обход всех остальных мер.

Ответы на частые вопросы

Почему Hooks в Claude Code могут не запускаться на удалённом Mac?

Сначала выясните, было ли нужное событие и прочитал ли процесс ожидаемый файл настроек. Затем проверьте, совпал ли matcher с фактическим вызовом. Только после этого переходите к правам скрипта и его окружению. Переустановка инструмента не исправит запуск под другим пользователем или несовпадение фильтра.

Как определить, какой файл настроек Hooks использует удалённый Mac?

Сверьте пользовательские, проектные, локальные и управляемые настройки с официальным описанием их областей действия. Проверяйте доступные файлы от имени той же учётной записи и из того же каталога, где запущен Claude Code. Отдельно сравните SSH и CI: настройки одного пользователя не следует считать настройками другого.

Как проверить, почему matcher PreToolUse не совпал?

Сравните имя фактически вызванного инструмента и данные события с условиями matcher. Для чистого теста оставьте один обработчик и один целевой вызов, а затем просмотрите журнал. Если запись о событии есть, но процесс не запускается, исследуйте настройку matcher; если события нет, проверьте соответствие операции выбранному событию.

Что делать, если Hook не находит команду в SSH-сеансе?

Проверьте доступность команды через PATH из контекста фактической учётной записи, а не только в интерактивной оболочке. Дополнительно проверьте рабочий каталог, права на файл и путь к интерпретатору. Для CI повторите проверку в контексте службы. Не записывайте в диагностические журналы секретные переменные окружения.

Подтверждает ли Stop Hook успешное выполнение тестов Xcode?

Нет. Hook завершения сессии может реагировать на её окончание, но сам по себе не подтверждает успешную сборку или тестирование. Для приёмки сохраните фактический результат запуска тестов Xcode, его статус и журнал. Если проверка должна блокировать выпуск, включите её в управляемый процесс CI и сохраняйте результат отдельно от Hook.

Если выяснилось, что причина в различиях аккаунтов или окружения macOS, сопоставьте собственную конфигурацию с руководством по удалённой среде Mac для разработки. При необходимости воспроизвести проблему в реальной macOS можно изучить вариант использования удалённого Mac: аренда MACCOME подходит для временной отладки, проверки Hooks и испытания CI без покупки отдельного компьютера. Если же нагрузка постоянная и тяжёлая или задаче необходим физический интерфейс, сначала оцените локальный узел: удалённая аренда подходит не каждому сценарию.