grapha-core 0.3.0

Shared graph types and extraction traits for Grapha
Documentation
# Grapha

[中文文档](docs/README.CN.md)

**Blazingly fast** code intelligence that gives AI agents compiler-grade understanding of your codebase.

Grapha builds a symbol-level dependency graph from source code — not by guessing with regex, but by reading the compiler's own index. For Swift, it taps directly into Xcode's pre-built index store via binary FFI for 100% type-resolved symbols, then enriches with tree-sitter for view structure, docs, and localization. For Rust, it uses tree-sitter with Cargo workspace awareness. The result is a queryable graph with confidence-scored edges, dataflow tracing, impact analysis, and code smell detection — available as both a CLI and an MCP server for AI agent integration.

> **1,991 Swift files — 131K nodes — 784K edges — 8.7 seconds.** Zero-copy binary FFI. Lock-free parallel extraction. No serde on the hot path.

## Why Grapha

| | Grapha |
|---|---|
| **Parsing** | Compiler index store (confidence 1.0) + tree-sitter fallback |
| **Relationship types** | 10 (calls, reads, writes, publishes, subscribes, inherits, implements, contains, type_ref, uses) |
| **Dataflow tracing** | Forward (entry → terminals) + reverse (symbol → entries) |
| **Code quality** | Complexity analysis, smell detection, module coupling metrics |
| **Confidence scores** | Per-edge 0.0–1.0 |
| **Terminal classification** | Auto-detects network, persistence, cache, event, keychain, search |
| **MCP tools** | 11 |
| **Watch mode** | File watcher with debounced incremental re-index |
| **Recall** | Session disambiguation — ambiguous symbols auto-resolve after first use |

## Performance

Benchmarked on a production iOS app (1,991 Swift files, ~300K lines):

| Phase | Time |
|-------|------|
| Extraction (index store + tree-sitter enrichment) | **3.5s** |
| Merge (module-aware cross-file resolution) | 0.3s |
| Classification (entry points + terminals) | 1.7s |
| SQLite persistence (deferred indexing) | 2.0s |
| Search index (BM25 via tantivy) | 1.0s |
| **Total** | **8.7s** |

**Graph:** 131,185 nodes · 783,793 edges · 2,983 entry points · 11,149 terminal operations

**Why it's fast:** zero-copy index store FFI via pointer arithmetic (no serde), lock-free rayon extraction, single shared tree-sitter parse, marker-based enrichment skip, deferred SQLite indexing, USR-scoped edge resolution. Run `grapha index --timing` for a per-phase breakdown.

## Install

```bash
brew tap oops-rs/tap
brew install grapha
```

```bash
cargo install grapha
```

## Quick Start

```bash
# Index a project (incremental by default)
grapha index .

# Search symbols
grapha symbol search "ViewModel" --kind struct --context
grapha symbol search "send" --kind function --module Room --fuzzy

# 360° context — callers, callees, reads, implements
grapha symbol context RoomPage --format tree

# Impact analysis — what breaks if this changes?
grapha symbol impact GiftPanelViewModel --depth 2 --format tree

# Complexity analysis — structural health of a type
grapha symbol complexity RoomPage

# Dataflow: entry point → terminal operations
grapha flow trace RoomPage --format tree

# Reverse: which entry points reach this symbol?
grapha flow trace sendGift --direction reverse

# Code smell detection
grapha repo smells --module Room
grapha repo smells --file Modules/Room/Sources/Room/View/RoomPage+Layout.swift
grapha repo smells --symbol RoomPageCenterContentView

# Module metrics — symbol counts, coupling ratios
grapha repo modules

# MCP server for AI agents (with auto-refresh)
grapha serve --mcp --watch
```

## MCP Server — 11 Tools for AI Agents

```bash
grapha serve --mcp              # JSON-RPC over stdio
grapha serve --mcp --watch      # + auto-refresh on file changes
```

Add to `.mcp.json`:

```json
{
  "mcpServers": {
    "grapha": {
      "command": "grapha",
      "args": ["serve", "--mcp", "--watch", "-p", "."]
    }
  }
}
```

| Tool | What it does |
|------|-------------|
| `search_symbols` | BM25 search with kind/module/role/fuzzy filters |
| `get_symbol_context` | 360° view: callers, callees, reads, implements, contains tree |
| `get_impact` | BFS blast radius at configurable depth |
| `trace` | Forward dataflow to terminals, or reverse to entry points |
| `get_file_symbols` | All declarations in a file, by source position |
| `batch_context` | Context for up to 20 symbols in one call |
| `analyze_complexity` | Structural metrics + severity rating for any type |
| `detect_smells` | Code smell scan scoped to the repo, a module, a file, or a symbol |
| `get_module_summary` | Per-module metrics with cross-module coupling ratio |
| `get_file_map` | File/symbol map organized by module and directory |
| `reload` | Hot-reload graph from disk without restarting the server |

**Recall:** The MCP server remembers symbol resolutions within a session. If `helper` is ambiguous the first time, after you disambiguate with `File.swift::helper`, future bare `helper` queries resolve automatically.

## Commands

### Symbols

```bash
grapha symbol search "query" [--kind K] [--module M] [--fuzzy] [--context]
grapha symbol context <symbol> [--format tree]
grapha symbol impact <symbol> [--depth N] [--format tree]
grapha symbol complexity <symbol>          # property/method/dependency counts, severity
grapha symbol file <path>                  # list declarations in a file
```

### Dataflow

```bash
grapha flow trace <symbol> [--direction forward|reverse] [--depth N]
grapha flow graph <symbol> [--depth N]     # semantic effect graph
grapha flow entries                        # list auto-detected entry points
```

### Repository

```bash
grapha repo smells [--module M | --file PATH | --symbol QUERY]
grapha repo modules                        # per-module metrics
grapha repo map [--module M]               # file/symbol overview
grapha repo changes [scope]                # git diff → affected symbols
```

### Indexing & Serving

```bash
grapha index . [--full-rebuild] [--timing]
grapha analyze <path> [--compact] [--filter fn,struct]
grapha serve [--mcp] [--watch] [--port N]
```

### Localization & Assets

```bash
grapha l10n symbol <symbol>                # resolve l10n records from SwiftUI subtree
grapha l10n usages <key> [--table T]       # find usage sites for a localization key
grapha asset list [--unused]               # image assets from xcassets catalogs
grapha asset usages <name>                 # find Image()/UIImage() references
```

### Concepts

```bash
grapha concept search "送礼横幅"             # business concept → candidate code scopes
grapha concept show "送礼横幅"               # inspect stored aliases and bindings
grapha concept bind "送礼横幅" --symbol GiftBannerPage
grapha concept alias "送礼横幅" --add "礼物 banner"
grapha concept prune                       # drop bindings to missing symbols
```

## Configuration

Optional `grapha.toml` at project root:

```toml
[swift]
index_store = true                         # false → tree-sitter only

[output]
default_fields = ["file", "module"]

[[external]]
name = "FrameUI"
path = "/path/to/local/frameui"            # include in cross-repo analysis

[[classifiers]]
pattern = "FirebaseFirestore.*setData"
terminal = "persistence"
direction = "write"
operation = "set"
```

## Architecture

```
grapha-core/     Shared types (Node, Edge, Graph, ExtractionResult)
grapha-swift/    Swift: index store → SwiftSyntax → tree-sitter waterfall
grapha/          CLI, Rust extractor, query engines, MCP server, web UI
nodus/           Agent tooling package (skills, rules, commands)
```

### Extraction Waterfall (Swift)

```
Xcode Index Store (binary FFI)      → compiler-resolved USRs, confidence 1.0
  ↓ fallback
SwiftSyntax (JSON FFI)              → accurate parse, no type resolution, confidence 0.9
  ↓ fallback
tree-sitter-swift (bundled)         → fast, limited accuracy, confidence 0.6–0.8
```

After index store extraction, tree-sitter enriches doc comments, SwiftUI view hierarchy, and localization metadata in a single shared parse.

### Graph Model

**14 node kinds:** function, struct, enum, trait, protocol, extension, property, field, variant, constant, type_alias, impl, module, view, branch

**10 edge kinds:** calls, implements, inherits, contains, type_ref, uses, reads, writes, publishes, subscribes

**Dataflow annotations:** direction (read/write/pure), operation (fetch/save/publish), condition, async_boundary, provenance (source file + span)

**Node roles:** entry_point (SwiftUI View, @Observable, fn main, #[test]) · terminal (network, persistence, cache, event, keychain, search)

### Nodus Package

```bash
nodus add wenext/grapha --adapter claude
```

Installs skills, rules, and slash commands (`/index`, `/search`, `/impact`, `/complexity`, `/smells`) for grapha-aware AI workflows.

## Supported Languages

| Language | Extraction | Type Resolution |
|----------|-----------|----------------|
| **Swift** | Index store + tree-sitter | Compiler-grade (USR) |
| **Rust** | tree-sitter | Name-based |

The per-language crate architecture supports adding new languages with the same waterfall pattern: compiler index → syntax parser → tree-sitter fallback.

## Development

```bash
cargo build                    # Build all workspace crates
cargo test                     # Run all tests (~200)
cargo clippy && cargo fmt      # Lint + format
```

## License

MIT