COMRAD404 / HOWTO

Как настроить pre-commit hooks с AI-проверкой

Пошаговая настройка локального pre-commit hook, который вызывает AI-проверку перед коммитом. Основной путь — через Claude Code CLI, с валидацией конфига и запуском по всем файлам.

Понадобится

Точная оценка не указана в источниках; зависит от готовности pre-commit и выбранного AI backend.
  • Git-репозиторий с уже установленным pre-commit
  • Для основного сценария: Node.js 18+, интернет и Claude Code CLI
  • Для альтернативы OpenAI: OPENAI_API_KEY, доступ из поддерживаемой страны/территории и официальный SDK по текущему quickstart
  • Понимание того, какие типы файлов вы хотите проверять через files или types
  • Готовность отправлять содержимое файлов во внешний AI backend с учётом ваших внутренних правил безопасности

После этой настройки у вас будет локальный pre-commit hook, который запускается перед коммитом и отправляет подходящие файлы на AI-проверку. Воспроизводимый основной путь ниже использует Claude Code CLI; для OpenAI Responses API я отдельно фиксирую рабочий каркас и ограничения.

Результат Локальный hook в .pre-commit-config.yaml, который вызывает внешний AI backend и блокирует коммит, если проверка возвращает неуспешный вердикт.
Время Точная оценка не указана в источниках; зависит от того, установлен ли у вас выбранный backend и готов ли репозиторий.
Сложность Средняя.
Стоимость pre-commit — open source; использование LLM/API оплачивается отдельно по текущим условиям провайдера. API-тарифы OpenAI и подписки ChatGPT — не одно и то же.
Что потребуется Git-репозиторий с уже установленным pre-commit; для основного сценария — Node.js 18+, интернет и Claude Code CLI; для альтернативы OpenAI — OPENAI_API_KEY, доступ из поддерживаемой страны/территории и официальный SDK по текущему quickstart.
Актуальная версия pre-commit v4.6.1 по странице релизов GitHub; проверка источников — на 2026-08-15.

Практический вердикт: если вам нужен быстрый и понятный AI-чек перед коммитом без собственной серверной обвязки, самый короткий воспроизводимый путь из доступных источников — локальный hook + Claude Code CLI. Редакционное ограничение: в предоставленном пакете источников нет полного готового примера с актуальным именем модели для OpenAI, поэтому вариант с Responses API здесь дан как проверенный каркас интеграции, а не как полностью развёрнутый кодовый шаблон.

Какой backend выбрать

Вариант Когда подходит Что важно учесть
Claude Code CLI Когда нужен shell-сценарий, который легко обернуть в локальный hook и получать JSON через --output-format json. Требует Node.js 18+, интернет и доступ из поддерживаемой Anthropic страны; текущие требования по биллингу и доступу нужно сверять в официальной документации.
OpenAI Responses API Когда нужен локальный скрипт с более строгим структурированным ответом через json_schema. Требует OPENAI_API_KEY, сеть и доступ из поддерживаемой страны/территории; для надёжного JSON лучше использовать Structured Outputs, а не старый режим json_object.

Пошаговая настройка

  1. Подготовьте AI backend и проверьте, что он запускается локально.

    Для полностью воспроизводимого сценария используйте Claude Code CLI. По официальной документации для него нужны Node.js 18+, интернет и доступ из поддерживаемой Anthropic страны.

    npm install -g @anthropic-ai/claude-code
    claude doctor

    Ожидаемый результат: claude doctor завершается без блокирующей ошибки. Если вы уже стандартизировали OpenAI, этот шаг можно заменить на подготовку локального скрипта для Responses API, но готовый end-to-end пример с актуальным именем модели в данном пакете источников не зафиксирован.

  2. Создайте файл .pre-commit-config.yaml в корне репозитория.

    Для repository-local hooks официальная документация pre-commit использует repo: local. В hook должны быть заданы как минимум id, name, language, entry и выбор файлов через files или types. Актуальная форма языка в документации — language: unsupported; system отмечен как старый alias.

    repos:
      - repo: local
        hooks:
          - id: ai-review
            name: AI review via Claude Code
            language: unsupported
            entry: bash scripts/ai-review.sh
            files: .(py|js|ts|tsx|md)$
            pass_filenames: true
            require_serial: true

    Здесь pass_filenames: true оставляет стандартную передачу имён файлов в скрипт, а require_serial: true принудительно запускает hook последовательно. Это полезно для AI-проверки, потому что по умолчанию require_serial равно false.

    Ожидаемый результат: в репозитории есть валидный YAML-конфиг с одним локальным hook.

  3. Создайте обёртку scripts/ai-review.sh, которую будет вызывать pre-commit.

    Ниже — минимальный shell-сценарий: он получает имена файлов от pre-commit, для каждого файла вызывает Claude Code в print mode с JSON-ответом и завершает hook ошибкой, если модель вернула fail.

    #!/usr/bin/env bash
    set -euo pipefail
    
    if [ "$#" -eq 0 ]; then
      exit 0
    fi
    
    claude doctor >/dev/null
    
    for file in "$@"; do
      if [ ! -f "$file" ]; then
        continue
      fi
    
      prompt="$(printf 'Review the file below. Return JSON only with keys "verdict" ("pass" or "fail") and "issues" (array of strings).nnPath: %snn%sn' "$file" "$(cat "$file")")"
      output="$(claude -p "$prompt" --output-format json)"
    
      echo "$output" | grep -q '"verdict"' || {
        echo "Unexpected Claude Code output for $file"
        echo "$output"
        exit 1
      }
    
      if echo "$output" | grep -Eq '"verdict"[[:space:]]*:[[:space:]]*"fail"'; then
        echo "AI review failed for $file"
        echo "$output"
        exit 1
      fi
    done

    Ожидаемый результат: в папке scripts появился локальный wrapper-скрипт, а логика hook теперь вынесена из YAML в отдельный файл.

  4. Проверьте синтаксис конфига командой pre-commit validate-config.

    Это официальный способ быстро проверить, что YAML-конфиг читается корректно и содержит допустимые поля.

    pre-commit validate-config

    Ожидаемый результат: команда завершается без ошибки. Если проверка падает, сначала исправьте конфиг, а уже потом устанавливайте hooks.

  5. Установите hooks в репозиторий командой pre-commit install --install-hooks.

    Согласно документации, это штатный путь для установки hook-окружений и привязки pre-commit к вашему репозиторию.

    pre-commit install --install-hooks

    Ожидаемый результат: hook установлен, и следующий обычный коммит будет запускать вашу AI-проверку автоматически.

  6. Прогоните hook по всему репозиторию до первого реального коммита.

    Для первичной проверки используйте официальный способ — запуск по всем файлам. Так вы сразу увидите, что wrapper вызывается, а фильтр files работает так, как вы ожидали.

    pre-commit run --all-files

    Ожидаемый результат: hook обходит все подходящие файлы. Если AI возвращает pass, команда завершается успешно; если возвращает fail, запуск завершится ошибкой и покажет JSON-ответ для проблемного файла.

Альтернатива: тот же hook, но с OpenAI Responses API

Если вы хотите не CLI, а локальный скрипт с API-вызовом, общая схема не меняется: pre-commit по-прежнему запускает repository-local hook, а в entry вы подставляете свой локальный скрипт. По текущему quickstart OpenAI нужно:

  • экспортировать OPENAI_API_KEY;
  • установить официальный SDK;
  • вызывать client.responses.create(...);
  • забирать текст результата из response.output_text;
  • для надёжного структурированного JSON использовать response_format: { type: 'json_schema' }, а не старый режим json_object.

Ограничение: в предоставленных источниках нет полного, проверяемого здесь примера локального hook-скрипта с актуальным именем модели и готовой схемой JSON, поэтому для OpenAI безопаснее повторить тот же паттерн обёртки, но сверить точный запрос с текущей официальной документацией перед внедрением в командный стандарт.

Как проверить, что всё работает

  1. Проверьте конфиг: запустите pre-commit validate-config. Успех без ошибок означает, что YAML распознан корректно.
  2. Проверьте установку hooks: выполните pre-commit install --install-hooks. После этого hook должен запускаться на обычном коммите автоматически.
  3. Проверьте полный прогон: выполните pre-commit run --all-files. Это официальный тестовый путь для всего репозитория.
  4. Проверьте блокировку: измените любой файл, попадающий под ваш шаблон files, и убедитесь, что при следующем запуске hook обращается к backend и прерывает процесс, если получает "verdict": "fail".

Если вам нужен следующий уровень контроля над политиками ответа модели, после базовой интеграции полезно отдельно настроить guardrails для AI-приложения.

Частые ошибки и исправления

  • Ошибка: pre-commit validate-config не проходит.
    Решение: проверьте, что у hook есть repo: local, а в определении заданы id, name, language, entry и выбор файлов через files или types. Для текущей документации используйте language: unsupported.
  • Ошибка: ваш скрипт ожидает имена файлов, но получает пустой список или не те аргументы.
    Решение: помните, что pass_filenames по умолчанию равно true. Если вы вручную отключали передачу имён файлов, адаптируйте скрипт, чтобы он не полагался на $@.
  • Ошибка: hook делает несколько AI-вызовов одновременно и ведёт себя нестабильно.
    Решение: задайте require_serial: true. По умолчанию это поле равно false, поэтому без явной настройки hook может запускаться не так, как вы ожидаете для внешнего AI backend.
  • Ошибка: команда claude не запускается или claude doctor сообщает о проблемах.
    Решение: проверьте требования Anthropic: Node.js 18+, интернет и доступ из поддерживаемой страны. Затем повторно выполните claude doctor.
  • Ошибка: OpenAI-скрипт не проходит аутентификацию или доступ к API не работает.
    Решение: проверьте наличие OPENAI_API_KEY и убедитесь, что доступ идёт из поддерживаемой OpenAI страны/территории. По справке OpenAI доступ из неподдерживаемой локации может привести к блокировке или приостановке аккаунта.

Безопасность и ограничения

  • Код уходит во внешний сервис. Любой AI hook такого типа передаёт содержимое файлов внешнему backend. Для приватных репозиториев сначала согласуйте это с вашей внутренней политикой безопасности.
  • OpenAI хранит состояние приложения по умолчанию 30 дней для Responses API. Источник указывает 30-дневный период retention по умолчанию, а также при store=true. Если вы выбираете OpenAI backend, учитывайте это отдельно.
  • Есть региональные ограничения. И OpenAI, и Claude Code зависят от доступа из поддерживаемых стран/территорий. Точные списки и условия меняются, поэтому перед командным внедрением их нужно перепроверять в актуальной официальной документации.
  • pre-commit не даёт вам модель сам по себе. Он только оркестрирует запуск hooks. AI backend, авторизация, сеть, биллинг и локальные зависимости вы поддерживаете отдельно.
  • Для language: unsupported нет изолированного окружения от pre-commit. Это удобно для обёрток над внешним CLI, но означает, что состояние локальной машины влияет на воспроизводимость.
  • Стоимость нельзя зафиксировать в статье. Токены, планы и требования к доступу меняются. Проверяйте официальные страницы провайдеров перед закупкой лимитов или внедрением в CI.

Практическое ограничение этого подхода: такой hook полезен как ранний фильтр перед коммитом, но редакционно я не рекомендую считать его финальной проверкой качества или безопасности без отдельного тестирования и review-процесса.

Что делать дальше

Источники

Вопросы и ответы

  • Можно ли сделать такую проверку без облачного AI backend?
    Да, pre-commit сам по себе не требует облака, но конкретно эта инструкция описывает схему, где локальный hook вызывает внешний AI backend. Сам pre-commit модель не предоставляет.
  • Что выбрать для первого запуска: Claude Code CLI или OpenAI Responses API?
    Если вам нужен самый короткий воспроизводимый путь из текущих источников, выбирайте Claude Code CLI. Если вам нужен строгий структурированный JSON в локальном скрипте, смотрите в сторону OpenAI Responses API с json_schema.
  • Обязательно ли использовать pass_filenames?
    Нет. Это поведение настраивается, а по умолчанию pass_filenames равно true. Если вы хотите, чтобы скрипт сам собирал diff или список файлов, можно строить логику без передачи аргументов.
  • Почему в конфиге стоит language: unsupported, а не system?
    Потому что текущая документация pre-commit отмечает unsupported как актуальную форму, а system — как старый alias.
  • Сколько это стоит?
    Сам pre-commit — open source. Стоимость появляется на стороне AI backend: у OpenAI это отдельные API-тарифы, не равные подписке ChatGPT; у Anthropic текущие условия доступа и биллинга нужно проверять по официальной документации.

Шаги

HOW-TO
  1. Подготовить backend AI

    | Для воспроизводимого пути установите Claude Code CLI через npm и проверьте окружение командой claude doctor.

  2. Создать .pre-commit-config.yaml

    | Добавьте repository-local hook с repo: local, language: unsupported, entry на локальный wrapper-скрипт, фильтр files и require_serial: true.

  3. Написать wrapper-скрипт

    | Создайте scripts/ai-review.sh, который принимает имена файлов от pre-commit, вызывает Claude Code в print mode с JSON-выводом и завершает процесс ошибкой при fail.

  4. Провалидировать конфиг

    | Запустите pre-commit validate-config и исправьте YAML до чистого завершения без ошибок.

  5. Установить hooks

    | Выполните pre-commit install --install-hooks, чтобы привязать pre-commit к репозиторию и подготовить hook-окружения.

  6. Проверить весь репозиторий

    | Запустите pre-commit run --all-files и убедитесь, что hook отрабатывает на нужных файлах и блокирует процесс при fail-вердикте AI.

Источники

SOURCES

Вопросы и ответы

FAQ
Можно ли сделать такую проверку без облачного AI backend?

Да, pre-commit сам по себе не требует облака, но в этой инструкции локальный hook вызывает внешний AI backend. Сам pre-commit модель не предоставляет.

Что выбрать для первого запуска: Claude Code CLI или OpenAI Responses API?

Для самого короткого воспроизводимого пути из текущих источников удобнее Claude Code CLI. Если вам нужен строгий структурированный JSON в локальном скрипте, используйте OpenAI Responses API с response_format: { type: 'json_schema' }.

Обязательно ли использовать pass_filenames?

Нет. Это поведение настраивается, а по умолчанию pass_filenames равно true. Если вы меняете это значение, скрипт нужно адаптировать под вашу схему передачи файлов.

Почему в конфиге стоит language: unsupported, а не system?

Потому что текущая документация pre-commit отмечает unsupported как актуальную форму, а system — как старый alias.

Сколько это стоит?

Сам pre-commit — open source. Затраты появляются на стороне AI backend: у OpenAI это отдельные API-тарифы, не равные подписке ChatGPT; у Anthropic текущие условия доступа и биллинга нужно проверять по официальной документации.

Читайте также

LINKS