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

Руководство по интеграции 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 -----> Качество коммита + зона поражения + дельта
    |
    +-- 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

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

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

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() ищет вызовы сущности из 5 интерфейсных слоёв (CLI, REST API, TUI, 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/TUI/MCP/ACP)

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

Файлы в самих интерфейсных слоях (src/cli/, src/api/routers/, src/tui/commands/, 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 --force для точных метрик
  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, TUI, 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.

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 дополнительно проверяет:

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

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

Git-хуки GoCPG

GoCPG может установить git-хук post-commit, который запускает инкрементальное обновление CPG после каждого коммита:

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

Это создаёт .git/hooks/post-commit, который запускает gocpg update в фоне. CPG остаётся синхронизированным с кодом без ручного вмешательства.

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

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(force=True) – запускает gocpg update --force если CPG устарел

Флаг --force критически важен: инкрементальные обновления (gocpg update без --force) пропускают MethodMetricsPass, оставляя cyclomatic_complexity, fan_in и fan_out равными 0 для новых/изменённых методов. Полный перепарсинг запускает весь конвейер включая вычисление метрик.

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

Коммит из терминала              Коммит через Claude Code
    |                                |
    v                                v
git post-commit хук              Хук PostToolUse срабатывает
    |                                |
    v                                +-- Проверка актуальности CPG
gocpg update (инкрементальный)  |   +-- Захват метрик до обновления
    |                                +-- gocpg update --force (полный перепарсинг)
    v                                +-- Анализ качества + зона поражения
CPG обновлён (CC=0 для новых)    +-- Дельта-отчёт (до->после)
                                     |
                                     v
                                 Отчёт внедряется в диалог

Когда оба хука активны, git-хук post-commit может работать параллельно с хуком Claude Code PostToolUse. Хук Claude Code обрабатывает это корректно – если файл DuckDB заблокирован другим процессом gocpg.exe, ошибка перехватывается и происходит переключение на запросы через подпроцесс или выдача частичного результата.

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

Настройки 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
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/post_analysis.py",
        "timeout": 10000
      }]
    }]
  }
}

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

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

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

Хуки читают активный проект из 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() для чтения этой конфигурации.

Установка

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

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