Files
code-review-graph/docs/architecture.md
T
dev 307d2fd471 feat: add project-review workflow (whole-project / single-feature review)
Adds the project-review workflow for code review independent of the git
diff. The scope is parsed from the user instruction: 全面/整个项目 ->
whole-project (score every source file), otherwise feature + target
keyword (locate the code with semantic search + graph queries).

- scoring_tools.py: score_review_func gains all_files=True to score every
  source file in the graph via store.get_all_files()
- main.py: score_review_tool gains all_files param; registers the
  project_review MCP prompt (prompts 6->7)
- prompts.py: project_review_prompt(scope, target) with whole-project and
  feature branches (fixed a precedence bug that truncated the feature text)
- skills.py + skills/project-review/: new read-only project-review skill
  with shared checklists
- .opencode/command/code-review-graph-project-review.md: slash command
- tests: test_project_review.py (prompt rendering), TestProjectReviewPrompt,
  skill count assertions 5->6, all_files wiring checks
- docs: prompts (6->7) + project-review entries across COMMANDS, CLAUDE,
  README (+localized), INDEX, architecture, LLM-OPTIMIZED-REFERENCE,
  CHANGELOG
2026-08-06 13:56:54 +08:00

129 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Architecture
## System Overview
`code-review-graph` is a local-first code intelligence graph exposed through a CLI and MCP server. It maintains a persistent, incrementally updated knowledge graph of a codebase so AI coding tools can review changes with structural context instead of reading broad file dumps. Claude Code is supported, but it is one client among several.
## Component Diagram
```
┌──────────────────────────────────────────────────────────────┐
│ AI coding clients / CLI │
│ │
│ MCP clients Hooks / watch mode │
│ ├── Codex └── incremental update │
│ ├── Claude Code, CodeBuddy Code │
│ ├── Cursor, Windsurf, Zed, Continue │
│ └── Gemini CLI, Qwen, Qoder, Copilot, OpenCode │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────────────────────────┐ │
│ │ MCP Server (stdio or localhost HTTP) │ │
│ │ │ │
│ │ 31 MCP Tools + 7 MCP Prompts │ │
│ │ ├── Core: build, impact, query, review, │ │
│ │ │ search, traverse, embed, stats, docs │ │
│ │ ├── Flows: list, get, affected │ │
│ │ ├── Communities: list, get, architecture │ │
│ │ ├── Analysis: detect_changes, refactor, │ │
│ │ │ apply_refactor, hotspots, gaps │ │
│ │ ├── Scoring: score_review, dedupe_ │ │
│ │ │ findings, generate_report │ │
│ │ ├── Wiki: generate, get_page │ │
│ │ └── Multi-repo: list_repos, cross_search │ │
│ └────────────────┬───────────────────────────┘ │
└───────────────────┼──────────────────────────────────────────┘
┌───────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────────┐
│ Parser │ │ Graph │ │ Incremental │
│ │ │ Store │ │ Engine │
└────┬────┘ └────┬────┘ └──────┬──────┘
│ │ │
▼ ▼ ▼
Tree-sitter SQLite DB git/svn diff
grammars (.code-review- subprocess
graph/
graph.db)
Scoring module (code_review_graph/scoring.py) sits on top of the
GraphStore and reads changed files + git history to compute the
objective review metrics consumed by the unified-review skill and the
score_review / dedupe_findings / generate_report MCP tools.
```
## Data Flow
### Full Build
1. `collect_all_files()` gathers tracked files (`git ls-files`) and applies `.code-review-graphignore` (gitignored files are skipped automatically when git is available)
2. For each file, `CodeParser.parse_file()` uses Tree-sitter to extract AST
3. AST walker identifies structural nodes (classes, functions, imports) and edges (calls, inheritance)
4. `GraphStore.store_file_nodes_edges()` persists to SQLite with file hash for change detection
5. Metadata updated with timestamp
### Incremental Update
1. `get_changed_files()` uses VCS metadata to identify changed files (git diff by default, with SVN support in the incremental layer)
2. `find_dependents()` queries the graph for files importing the changed files
3. Changed + dependent files are re-parsed (others skipped via hash comparison)
4. Only affected rows in SQLite are updated
### Review Context Generation
1. Changed files identified (git diff or explicit list)
2. `get_impact_radius()` walks outward from the changed nodes, relaxing a weighted
best-path score per node (per-edge-kind weight × depth decay) rather than a plain BFS
3. Source snippets extracted for changed areas only
4. Review guidance generated (test coverage gaps, wide blast radius warnings)
5. Assembled into a structured, token-efficient context for MCP clients and the CLI
6. Where a cheap baseline can be estimated, compact `context_savings` metadata is attached as an estimate rather than an exact tokenisation
## Storage
### SQLite Schema
- **nodes** table: id, kind, name, qualified_name, file_path, line_start/end, language, community_id, etc.
- **edges** table: id, kind, source_qualified, target_qualified, file_path, line
- **metadata** table: key-value pairs (last_updated, build_type, schema_version)
- **flows** table: id, name, entry_point_id, depth, node_count, file_count, criticality, path_json
- **flow_memberships** table: flow_id, node_id, position
- **communities** table: id, name, level, parent_id, cohesion, size, dominant_language, description
- **nodes_fts** (FTS5 virtual table): full-text search on name, qualified_name, file_path, signature
- **community_summaries**, **flow_snapshots**, **risk_index** tables: compact precomputed summaries for token-efficient queries
- **embeddings** table (separate DB): qualified_name, vector, text_hash, provider
Indexes on qualified_name, file_path, edge source/target, criticality, community_id, and cohesion for fast lookups.
WAL mode enabled for concurrent read access during updates.
### Qualified Names
Nodes are uniquely identified by qualified names:
- Files: absolute path (e.g., `/repo/src/auth.py`)
- Functions: `file_path::function_name` (e.g., `/repo/src/auth.py::authenticate`)
- Methods: `file_path::ClassName.method_name` (e.g., `/repo/src/auth.py::AuthService.login`)
## Parsing Strategy
Tree-sitter provides language-agnostic AST access. The parser:
1. Walks the AST recursively
2. Pattern-matches on node types (language-specific mappings in `_CLASS_TYPES`, `_FUNCTION_TYPES`, etc.)
3. Extracts names, parameters, return types, base classes
4. Identifies calls within function bodies
5. Resolves imports to module paths
This approach is more robust than tree-sitter queries across grammar versions.
## Visualization
The `visualization.py` module generates an interactive D3.js force-directed graph as a self-contained HTML file. It reads all nodes and edges from the SQLite graph store and renders them in the browser, allowing developers to visually explore code relationships, filter by node kind, and inspect dependencies.
## Impact Analysis Algorithm
BFS from seed nodes (changed files' contents):
1. Seed = all qualified names in changed files
2. For each node in frontier:
- Follow forward edges (what this node affects)
- Follow reverse edges (what depends on this node)
3. Expand up to `max_depth` hops (default: 2)
4. Collect all reached nodes as "impacted"
This captures both downstream effects (things that call changed code) and upstream context (things that the changed code depends on).