Руководство по интеграции Claude Code и Git¶
Руководство по подключению конвейера CPG-анализа CodeGraph к хукам Claude Code и рабочим процессам Git.
Содержание¶
- Обзор
- Архитектура
- Система хуков
- Поток данных
- Общие утилиты
- Справочник по хукам
- SessionStart: контекст проекта
- UserPromptSubmit: обогащение сущностями
- PreToolUse: шлюз сложности
- PostToolUse: анализ коммита
- Stop: пост-анализ
- Интеграция с Git
- Git-хуки GoCPG
- Актуальность CPG и автоматические обновления
- Конфигурация
- Настройки Claude Code
- Конфигурация проекта
- Установка
- Устранение неполадок
Обзор¶
CodeGraph интегрируется с Claude Code через пять скриптов-хуков, которые внедряют данные CPG-анализа в диалог на разных этапах жизненного цикла. В сочетании с git-хуками GoCPG, поддерживающими базу данных CPG в актуальном состоянии, это создаёт непрерывный цикл обратной связи:
- Начало сессии – Claude получает контекст проекта и статистику CPG
- Пользователь задаёт вопрос – упомянутые сущности кода разрешаются через CPG
- Claude редактирует файл – методы с высокой сложностью в этом файле вызывают предупреждения
- Claude коммитит код – коммит анализируется на метрики качества, зону поражения и влияние до/после
- 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 одним из двух способов:
-
Подпроцесс GoCPG (
gocpg.exe query --sql "...") – используется большинством хуков через_utils.run_gocpg_query(). Не требует Python-зависимости от DuckDB. -
Прямое подключение 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
Время ожидания: 8с
Срабатывает: Перед любым вызовом инструмента 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
Самый сложный хук. Запускает многофазный конвейер анализа:
- Проверка актуальности CPG (2с) – сравнивает
cpg_git_state.commit_hashсgit rev-parse HEAD - Захват метрик до обновления (~1с) – снимок текущих метрик для изменённых файлов (для дельта-отчёта)
- Обновление CPG с полным перепарсингом (40с) – запускает
gocpg update --forceдля точных метрик - Анализ качества + зона поражения (16с) – запросы
nodes_methodдля CC, исходящей связности, TODO/FIXME, устаревшего кода; запросыcall_containmentдля вызывающих изменённых методов - Вычисление дельты – сравнение метрик до и после обновления
Вывод включает влияние до/после, предупреждения о качестве и зону поражения:
## 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 HEADcommits_behind()– считает, на сколько коммитов CPG отстаёт от HEADensure_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.
Ручная установка¶
-
Убедитесь, что бинарник GoCPG существует по пути
gocpg/gocpg.exe(или установите переменную окруженияGOCPG_PATH) -
Убедитесь, что база данных CPG существует – импортируйте проект при необходимости:
bash python -m src.cli import . --language python -
Установите git-хуки GoCPG:
bash gocpg/gocpg.exe hooks install --repo=. --db=data/projects/codegraph.duckdb -
Скопируйте
.claude/settings.jsonс конфигурацией хуков (см. Настройки Claude Code выше) -
Проверьте через
/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