Руководство по интеграции Claude Code и Git

Руководство по подключению конвейера CPG-анализа CodeGraph к хукам Claude Code и рабочим процессам Git.

Содержание

Обзор

CodeGraph интегрируется с Claude Code через пять скриптов-хуков, которые внедряют данные CPG-анализа в диалог на разных этапах жизненного цикла. В сочетании с git-хуками GoCPG, поддерживающими базу данных CPG в актуальном состоянии, это создаёт непрерывный цикл обратной связи:

  1. Начало сессии – Claude получает контекст проекта и статистику CPG
  2. Пользователь задаёт вопрос – упомянутые сущности кода разрешаются через CPG
  3. Claude редактирует файл – методы с высокой сложностью в этом файле вызывают предупреждения
  4. Claude коммитит код – коммит анализируется на метрики качества, зону поражения и влияние до/после
  5. Claude завершает ответ – файлы, упомянутые в ответе, проверяются на проблемы качества

Все хуки обмениваются данными через JSON на stdin/stdout и возвращают {"additionalContext": "..."} для внедрения markdown-контекста в диалог, или {} для молчания.

Архитектура

Система хуков

Хуки Claude Code настраиваются в .claude/settings.json. Каждый хук срабатывает на определённое событие жизненного цикла и получает JSON на stdin.

Жизненный цикл Claude Code
    |
    +-- SessionStart ---------> session_context.py -----> Имя проекта, язык, статистика CPG
    |
    +-- UserPromptSubmit -----> enrich_prompt.py -------> CPG-поиск упомянутых сущностей
    |
    +-- PreToolUse (Edit) ----> pre_tool_use.py --------> Предупреждения о сложности перед редактированием
    |
    +-- PostToolUse (Bash) ---> commit_analysis.py -----> Качество коммита + зона поражения + дельта
    |
    +-- PostToolUse (Bash) ---> cli_error_monitor.py ---> Обнаружение паттернов ошибок CLI
    |
    +-- Stop -----------------> post_analysis.py -------> Проверка качества файлов в ответе

Поток данных

Все хуки запрашивают базу данных CPG одним из двух способов:

  1. Подпроцесс GoCPG (gocpg.exe query --sql "...") – используется большинством хуков через _utils.run_gocpg_query(). Не требует Python-зависимости от DuckDB.

  2. Прямое подключение DuckDB (import duckdb; con.execute(...)) – используется commit_analysis.py для полного конвейера анализа (CommitAnalyzer, CPGFreshnessChecker). При неудаче импорта DuckDB переключается на подпроцесс.

Скрипт хука
    |
    +-- _utils.get_active_project()  --> config.yaml --> db_path
    |
    +-- _utils.run_gocpg_query(sql, db_path)  --> gocpg.exe query --> stdout
    |   ИЛИ
    +-- duckdb.connect(db_path)  --> прямой SQL
    |
    +-- safe_json_output(markdown)  --> {"additionalContext": "..."} --> Claude Code

Общие утилиты

Все хуки импортируют из .claude/hooks/_utils.py:

Функция Назначение
get_active_project() Читает config.yaml, возвращает словарь активного проекта (name, db_path, language, domain)
run_gocpg_query(sql, db_path) Выполняет SQL через подпроцесс gocpg.exe query
run_cli_query(query) Выполняет запрос на естественном языке через python -m src.cli query
extract_entities(text) Извлекает CamelCase-имена, snake_case-идентификаторы и пути к файлам из текста
safe_json_output(context) Пишет {"additionalContext": context} или {} в stdout
read_stdin_json() Парсит JSON из stdin
get_active_project_auto(cwd) Автоопределение проекта по CWD с фолбэком на get_active_project()
load_parse_scope(db_path) Загрузка scope парсинга из таблицы cpg_parse_scope в DuckDB
is_partial_scope(scope) Проверка, имеет ли scope исключения или выборочный режим импорта
tests_in_scope(scope) Проверка, включены ли тесты в scope парсинга

Константы: PROJECT_ROOT (два уровня вверх от директории хуков), GOCPG_BINARY (gocpg/gocpg.exe), CONFIG_PATH (config.yaml).

Дополнительные модули:

Модуль Назначение
_feedback.py Датаклассы ReviewFeedback и ReviewFinding для структурированных markdown-отчётов
_metrics.py JSONL-логирование производительности через контекстный менеджер timed_hook()
_session_cache.py Файловый кеш контекста проекта (избегает повторного чтения config.yaml)
_project_detector.py Автоопределение проекта по CWD и git remote

Справочник по хукам

SessionStart: контекст проекта

Файл: .claude/hooks/session_context.py Время ожидания: 10с Срабатывает: Один раз при начале сессии Claude Code

Читает активный проект из config.yaml и запускает gocpg stats для получения размера CPG. Выводит:

## Project Context
Active project: codegraph (python)
Domain: python_generic

### CPG Statistics
- Methods: 52341
- Calls: 111234
- Files: 1847
- Total nodes: 312000
- Total edges: 890000

Это даёт Claude немедленное понимание масштаба проекта и доступных данных CPG.

UserPromptSubmit: обогащение сущностями

Файл: .claude/hooks/enrich_prompt.py Время ожидания: 15с Срабатывает: На каждое сообщение пользователя

Извлекает сущности кода из сообщения пользователя (CamelCase-имена классов, snake_case-имена функций, пути к файлам) и ищет их в CPG. Возвращает расположение и данные о сложности для до 3 сущностей.

## CodeGraph CPG Context

### CommitAnalyzer
  - `analyze_commit` at `src/dogfooding/commit_analyzer.py:298` (complexity: 12)
  - `_deduplicate_methods` at `src/dogfooding/commit_analyzer.py:115` (complexity: 3)

### cpg_freshness
  - `is_fresh` at `src/dogfooding/cpg_freshness.py:64` (complexity: 2)
  - `ensure_fresh` at `src/dogfooding/cpg_freshness.py:98` (complexity: 5)

Это помогает Claude находить сущности кода без ручного поиска по файлам.

Определение интерфейсной экспозиции (M1)

Для каждой найденной сущности хук дополнительно проверяет, из каких интерфейсных слоёв она вызывается:

### CommitAnalyzer
  - `analyze_commit` at `src/dogfooding/commit_analyzer.py:298` (complexity: 12)
  **Exposed via:** CLI, MCP, REST API

Функция lookup_interface_exposure() ищет вызовы сущности из 4 интерфейсных слоёв (CLI, REST API, MCP, ACP) через таблицу nodes_call в CPG. Это позволяет Claude оценить потенциальное влияние изменений на внешние интерфейсы.

PreToolUse: шлюз сложности

Файл: .claude/hooks/pre_tool_use.py Время ожидания:Срабатывает: Перед любым вызовом инструмента Edit или Write

Проверяет целевой файл на методы с CC > 15, высокой исходящей связностью (> 30), маркерами TODO/FIXME или устаревшим кодом. Предупреждает Claude перед модификацией сложного кода:

## File Quality Warning
- `classify` (CC: 17, fan_out: 39) -- high complexity, review carefully
- `_score_domain` (CC: 16, has TODO/FIXME)

Не-исходные файлы (.md, .json, .yaml и т.д.) молча пропускаются.

Проверка полноты регистрации (CR2)

При редактировании файлов в директориях scenarios/, services/, analysis/, security/ хук дополнительно проверяет, все ли публичные функции файла зарегистрированы в интерфейсных слоях:

## Registration Warning
**Registration check:** `analyze_security`, `scan_endpoints` not called from any interface layer (CLI/API/MCP/ACP)

Функция check_registration_completeness() извлекает публичные функции (не начинающиеся с _ или test_) из целевого файла через CPG, затем проверяет, вызываются ли они из любого интерфейсного слоя. Если часть функций зарегистрирована, а часть нет – выдаётся предупреждение.

Файлы в самих интерфейсных слоях (src/cli/, src/api/routers/, src/mcp/tools/, src/acp/) пропускаются.

PostToolUse: анализ коммита

Файл: .claude/hooks/commit_analysis.py Время ожидания: 60с Срабатывает: После любого вызова инструмента Bash, содержащего git commit

Самый сложный хук. Запускает многофазный конвейер анализа:

  1. Проверка актуальности CPG (2с) – сравнивает cpg_git_state.commit_hash с git rev-parse HEAD
  2. Захват метрик до обновления (~1с) – снимок текущих метрик для изменённых файлов (для дельта-отчёта)
  3. Обновление CPG (40с) – запускает gocpg update; устойчивую post-commit трассировку выполняет отделённый GoCPG worker
  4. Анализ качества + зона поражения (16с) – запросы nodes_method для CC, исходящей связности, TODO/FIXME, устаревшего кода; запросы call_containment для вызывающих изменённых методов
  5. Вычисление дельты – сравнение метрик до и после обновления

Вывод включает влияние до/после, предупреждения о качестве и зону поражения:

## Commit Analysis Report
**Summary:** 3 files, 45 methods, 2 high-CC, 1 TODO/FIXME, 128 affected callers
**CPG status:** fresh

**Impact of changes:**
- `_get_fallback_domain`: CC 29->8 (-21), FanOut 18->5 (-13)

**High complexity methods:**
- `classify` (CC: 17)

**Blast radius:** 128 callers affected
- `classify` called by: `run_intent_classifier`, `IntentBenchmark._evaluate_single` +126 more

Хук срабатывает только для команд git commit. Другие Bash-команды (ls, git status и т.д.) возвращают пустой {}.

Запасной путь: Если импорт DuckDB не удаётся, переключается на анализ через подпроцесс (проще, без зоны поражения и дельта-отчёта).

Дополнительные фазы анализа (Code Review v3)

Помимо базового конвейера, хук выполняет расширенный анализ:

Обнаружение влияния на интерфейсы (CR1). Если изменённые файлы находятся в интерфейсных слоях (CLI, REST API, MCP, ACP), хук сообщает, какие слои затронуты и сколько методов в них изменилось:

**Interface Impact:**
- CLI: 3 methods affected in `src/cli/audit_commands.py`
- MCP: 1 method affected in `src/mcp/tools/search.py`

Межмодульные зависимости (CR3). Хук анализирует, какие смежные интерфейсные слои могут потребовать обновления при изменении одного из них.

Зона поражения Go CPG (L1). Если настроена база данных Go CPG (go_db_path), хук запрашивает call_containment в обеих базах для объединённого blast radius по Python + Go коду.

Дельта покрытия историй (L4). Если обнаружено влияние на интерфейсные слои, хук проверяет, не появились ли пробелы в покрытии пользовательских историй – например, функция удалена из CLI, но осталась в API.

PostToolUse: мониторинг ошибок CLI

Файл: .claude/hooks/cli_error_monitor.py Время ожидания:Срабатывает: После любого вызова инструмента Bash

Отслеживает вывод CLI-команд на распространённые паттерны ошибок и предоставляет диагностику с рекомендациями:

  • База данных не найдена / DatabaseNotConfiguredError
  • Ошибки импорта DuckDB
  • Python ImportError / ModuleNotFoundError
  • Необработанные трейсбеки
  • Сообщения RuntimeWarning
  • Бинарник GoCPG не найден

При обнаружении паттерна ошибки хук возвращает контекстное сообщение с типом ошибки и предложенным решением.

Stop: пост-анализ

Файл: .claude/hooks/post_analysis.py Время ожидания: 10с Срабатывает: Когда Claude завершает ответ (кроме завершений по ошибке)

Сканирует текст ответа Claude на наличие путей к исходным файлам (src/..., pkg/... и т.д.) и проверяет каждый файл на проблемы качества через CPG:

  • Маркеры TODO/FIXME
  • Отладочный код
  • Пики сложности (методы с CC значительно выше среднего по файлу)
  • Точки высокой исходящей связности (fan_out > 30)
  • Устаревшие методы
## Post-Analysis
- `src/workflow/copilot.py`: complexity spikes: `classify` (CC:17), fan-out hotspots: `classify` (fan_out:39)
- `src/dogfooding/commit_analyzer.py`: 2 methods with TODO/FIXME markers

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

Пост-анализ тестов и регистрации (L2)

Хук Stop дополнительно проверяет:

  • Отсутствие тестов: если изменённые файлы содержат публичные функции без соответствующих тестов
  • Незарегистрированные интерфейсы: если новые функции не вызываются из интерфейсных слоёв

CLI-команда ревью

Помимо хуков, CodeGraph предоставляет самостоятельную CLI-команду для проверки кода:

# Проверка изменений относительно базового рефа
python -m src.cli review --base-ref HEAD~3

# Проверка проиндексированных изменений
python -m src.cli review --staged

# Проверка конкретных файлов
python -m src.cli review --files src/api/main.py src/auth.py

# Форматы вывода
python -m src.cli review --format json --output-file report.json
python -m src.cli review --format sarif --output-file report.sarif
python -m src.cli review --base-ref HEAD~5 --sarif-file out.sarif

# Без анализа безопасности
python -m src.cli review --no-security

CLI-команда использует ReviewPipeline (src/review/pipeline.py), который оркестрирует: 1. Определение проекта и проверку статуса CPG 2. Загрузку scope парсинга для scope-aware фильтрации 3. Анализ качества (мёртвый код, высокая сложность, большие методы) 4. Анализ безопасности через SecurityPRReview (опционально) 5. Scope-aware агрегацию через ReviewAggregator 6. Вывод в формате markdown, JSON или SARIF 2.1.0

Коды возврата: 0 = чисто или только medium/low, 1 = обнаружены critical или high.

Scope-aware фильтрация

Когда CPG построен с исключениями (например, только бэкенд без тестов/фронтенда), конвейер применяет фильтрацию с учётом scope:

Тип находки Условие Действие
dead_code Scope ограничен Понизить до info, пометить scope_limited
missing_test include_tests=false Полностью подавить
blast_radius Scope ограничен Понизить до info, пометить scope_limited
complexity Не затронут (метрика per-method)
security Не затронут (реальная уязвимость)

При ограниченном scope в начало отчёта добавляется блок-дисклеймер.

Метрики и мониторинг

Все хуки логируют метрики выполнения в data/hook_metrics.jsonl:

{"timestamp": "2026-03-06T12:00:00Z", "hook": "commit_analysis", "duration_ms": 1234.5, "findings": 3, "project": "codegraph", "status": "ok"}

Просмотр статистики через CLI:

python -m src.cli dogfood hooks-status
python -m src.cli dogfood hooks-status --last 50
python -m src.cli dogfood hooks-status --hook commit_analysis

Панель показывает агрегаты по хукам: количество запусков, ok/error/warning, процент ошибок, среднее и максимальное время выполнения, общее количество находок.

Устойчивость к сбоям

Все хуки следуют принципу fail-open: - Отсутствует бинарник gocpg: CPG-запросы пропускаются, выводится пустой контекст - Повреждённая или отсутствующая БД: анализ пропускается, предупреждение в метрики - Таймаут: частичные результаты возвращаются в пределах бюджета - Ошибки импорта: переключение на subprocess-путь (commit_analysis) - Любое необработанное исключение: перехватывается на верхнем уровне, пустой JSON

Интеграция с Git

Git-хуки GoCPG

GoCPG может установить git-хуки, которые запускают инкрементальное обновление CPG после каждого коммита. С флагом --review-trace хук post-commit дополнительно сохраняет полную трассировку ревью:

gocpg/gocpg.exe hooks install --repo=. --db=data/projects/codegraph.duckdb --review-trace

Это создаёт .git/hooks/post-commit, который запускает отделённый worker. Worker выполняет gocpg update, проверяет, что DuckDB можно немедленно переоткрыть после обновления, и сохраняет артефакты ревью в data/reviews/.

Артефакты по каждому коммиту:

  • <sha>.log — живой лог worker с heartbeat-сообщениями
  • <sha>.status.json — текущая фаза и снимок прогресса
  • <sha>.meta.json — финальный статус, включая gocpg_update_ok и db_unlocked_after_update
  • <sha>.json / <sha>.md — результат ревью

Посмотреть трассировку из терминала:

python scripts/review_trace_status.py <commit-sha>
python scripts/review_trace_status.py <commit-sha> --watch

Проверка статуса хуков:

gocpg/gocpg.exe hooks status --repo=.

Удаление хуков:

gocpg/gocpg.exe hooks uninstall --repo=.

Актуальность CPG и автоматические обновления

CPGFreshnessChecker (src/dogfooding/cpg_freshness.py) управляет синхронизацией CPG:

  • is_fresh() – сравнивает cpg_git_state.commit_hash (в DuckDB) с git rev-parse HEAD
  • commits_behind() – считает, на сколько коммитов CPG отстаёт от HEAD
  • ensure_fresh() – запускает gocpg update, если CPG устарел

Для устойчивого post-commit feedback worker с трассировкой не зависит от src.cli review. Он вызывает ReviewPipeline напрямую по изменённым файлам, что изолирует ревью от посторонних ошибок импорта в CLI и удерживает время выполнения в пределах фактической области коммита.

Взаимодействие git-хуков и хуков Claude Code:

Коммит из терминала              Коммит через Claude Code
    |                                |
    v                                v
git post-commit хук              Хук PostToolUse срабатывает
    |                                |
    v                                +-- Проверка актуальности CPG
Отделённый review worker         |   +-- Best-effort update через API/webhook
    |                            |   +-- Диагностика для диалога
    +-- gocpg update             |
    +-- Проверка разблокировки DuckDB
    +-- ReviewPipeline(files=changed)
    +-- data/reviews/<sha>.*     |
    v                            v
Устойчивый локальный trace       Отчёт внедряется в диалог

Когда оба хука активны, git post-commit trace даёт устойчивый цифровой след, а хук Claude Code остаётся conversational/best-effort механизмом. Worker с трассировкой фиксирует, освободилась ли БД сразу после обновления, поэтому проблемы с lock видны в data/reviews/<sha>.meta.json.

Конфигурация

Настройки Claude Code

Конфигурация хуков находится в .claude/settings.json:

{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/session_context.py",
        "timeout": 10000
      }]
    }],
    "UserPromptSubmit": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/enrich_prompt.py",
        "timeout": 15000
      }]
    }],
    "PreToolUse": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/pre_tool_use.py",
        "timeout": 8000
      }]
    }],
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/commit_analysis.py",
        "timeout": 60000
      }, {
        "type": "command",
        "command": "python .claude/hooks/cli_error_monitor.py",
        "timeout": 5000
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/post_analysis.py",
        "timeout": 10000
      }]
    }]
  }
}

Формат matcher: Поле matcher – это строка с регулярным выражением, а не объект. Используйте "" для соответствия всем событиям или "Bash" для соответствия только инструменту Bash. Формат объекта ({"tools": ["Bash"]}) больше не поддерживается.

Время ожидания: В миллисекундах. Если хук превышает время ожидания, Claude Code завершает процесс и продолжает без его вывода.

Примечание: Реальный .claude/settings.json может использовать абсолютные пути (например, python D:/work/codegraph/.claude/hooks/session_context.py). Выше показаны относительные пути для переносимости.

Конфигурация проекта

Хуки читают активный проект из config.yaml:

projects:
  active: codegraph
  registry:
    codegraph:
      db_path: data/projects/codegraph.duckdb
      source_path: .
      language: python
      domain: python_generic

db_path определяется относительно корня проекта. Все хуки используют _utils.get_active_project() для чтения этой конфигурации.

Конвейер ревью

Конфигурация конвейера ревью в config.yaml:

review_pipeline:
  # Определение проекта
  auto_detect_project: true           # Автоопределение проекта по CWD
  detect_by_source_path: true         # Сопоставление CWD с source_path в реестре
  freshness_check_on_session: true    # Проверка актуальности CPG при SessionStart
  auto_reparse: prompt                # Автоперепарсинг: "prompt", "always", "never"
  max_reparse_timeout_seconds: 60     # Таймаут перепарсинга CPG
  stale_threshold_commits: 0          # Порог отставания в коммитах (0 = любое отставание)
  max_findings_in_summary: 10         # Макс. находок в сводке
  # Учёт scope
  scope_aware_filtering: true
  suppress_tests_outside_scope: true
  demote_dead_code_partial_scope: true
  show_scope_disclaimer: true
  # Метрики и устойчивость
  metrics_enabled: true
  metrics_file: data/hook_metrics.jsonl
  fail_open: true

Самоанализ

Секция dogfooding настраивает пороги анализа коммитов:

dogfooding:
  enabled: true
  auto_update_cpg: true
  cc_threshold: 10          # Порог CC для предупреждений в анализе коммита
  fan_out_threshold: 30     # Порог исходящей связности
  max_files_per_commit: 15  # Макс. файлов для анализа в коммите

Примечание: cc_threshold в секции dogfooding (10) отличается от CC_THRESHOLD в pre_tool_use.py (15). Хук анализа коммита использует значение из конфигурации; хук pre-tool-use использует встроенную константу.

Установка

Установка одной командой

python -m src.cli.import_commands dogfood setup --repo . --db data/projects/codegraph.duckdb

Это устанавливает git-хуки GoCPG и проверяет конфигурацию хуков Claude Code.

Ручная установка

  1. Убедитесь, что бинарник GoCPG существует по пути gocpg/gocpg.exe (или установите переменную окружения GOCPG_PATH)

  2. Убедитесь, что база данных CPG существует – импортируйте проект при необходимости: bash python -m src.cli import . --language python

  3. Установите git-хуки GoCPG: bash gocpg/gocpg.exe hooks install --repo=. --db=data/projects/codegraph.duckdb

  4. Скопируйте .claude/settings.json с конфигурацией хуков (см. Настройки Claude Code выше)

  5. Проверьте через /doctor в Claude Code – не должно быть ошибок настроек

Проверка

# Проверка статуса конвейера самоанализа
python -m src.cli.import_commands dogfood status

# Проверка хуков GoCPG
gocpg/gocpg.exe hooks status --repo=.

# Ручной тест commit_analysis.py
echo '{"tool":"Bash","tool_input":{"command":"git commit -m \"test\""},"tool_result":"ok"}' | python .claude/hooks/commit_analysis.py

Устранение неполадок

Хук возвращает пустой {} на все события: - Проверьте, что в config.yaml есть активный проект с валидным db_path - Убедитесь, что файл DuckDB существует по настроенному пути - Убедитесь, что gocpg/gocpg.exe существует и является исполняемым

Обогащение сущностями ничего не находит: - CPG может не содержать запрашиваемую сущность. Запустите gocpg query --sql "SELECT COUNT(*) FROM nodes_method" для проверки наполненности CPG - Извлечение сущностей распознаёт только CamelCase-имена (> 3 символов), snake_case-имена (> 5 символов) и пути к исходным файлам

Шлюз сложности никогда не срабатывает: - Срабатывает только для инструментов Edit и Write, не для Bash - Проверяет только исходные файлы (.py, .go, .ts и т.д.) - Порог CC > 15 – меньшие значения не сообщаются

Анализ коммита показывает устаревшие метрики (CC=0): - Хук использует флаг --force по умолчанию. Если метрики показывают 0, полный перепарсинг мог превысить время ожидания (бюджет 40с) - Проверьте, не работает ли другой процесс gocpg.exe, удерживающий блокировку DuckDB - Попробуйте ручное обновление: gocpg/gocpg.exe update --force --input=. --output=<db>

Дельта-отчёт не появляется: - Дельта-отчёт появляется только когда CPG был устаревшим до обновления - Если git-хуки GoCPG или gocpg watch уже обновили CPG, метрики до обновления для сравнения отсутствуют

Ошибка блокировки DuckDB: - Другой процесс gocpg.exe удерживает файл. Хук обрабатывает это корректно, переключаясь на запросы через подпроцесс - В рабочей среде это редкость, поскольку хук срабатывает после завершения Bash-команды

/doctor показывает ошибки настроек: - Убедитесь, что все поля matcher являются строками ("" или "Bash"), а не объектами - Проверьте синтаксис JSON в .claude/settings.json