Architecture
Revet is a Cargo workspace with three crates:
| Crate | Purpose |
|---|---|
crates/core (revet-core) | All analysis logic: parsers, graph, analyzers, diff, config, cache |
crates/cli (revet-cli) | CLI commands and output formatters |
crates/node-binding (revet-node) | NAPI-RS Node.js bindings — functional basic API |
Three-layer pipeline
Files
│
▼
Layer 1: Code Graph (tree-sitter AST → petgraph DiGraph)
│ parser/mod.rs parallel parse-then-merge
│ graph/mod.rs CodeGraph + NodeId + EdgeKind
│ cache.rs per-file msgpack cache (incremental)
│
▼
Layer 2: Domain Analyzers (regex line-by-line scanning)
│ analyzer/mod.rs AnalyzerDispatcher + rayon parallel
│ analyzer/*.rs one file per domain
│
▼
Layer 3: LLM Reasoning (--ai flag, opt-in)
│ cli/src/ai/mod.rs per-finding LLM call with ±4-line snippet
│ cli/src/ai/client.rs Anthropic / OpenAI / Ollama backends
│
▼
Finding pipeline
│ suppress.rs revet-ignore inline comments
│ baseline.rs baseline suppression
│ diff/ diff-line filtering
│
▼
Output formatters (cli/src/output/)
Layer 1 — Code Graph
ParserDispatcherroutes files to language parsers by extension- Each parser implements
LanguageParserand produces a localCodeGraph - Phase 1: parallel tree-sitter parse (rayon) → per-file
(CodeGraph, ParseState) - Phase 2: sequential merge via
CodeGraph::merge()with NodeId remapping - Phase 3:
CrossFileResolveraddsImportsandCallsedges across files - Cache:
FileGraphCachestores per-file fragments under.revet-cache/files/<hash>.msgpack
Layer 2 — Domain Analyzers
- Each analyzer implements
Analyzer(file-based) orGraphAnalyzer(graph-based) - File analyzers run fully in parallel via rayon
- Graph analyzers run after the full graph is built
- Finding IDs are renumbered sequentially per prefix after collection
Key data structures
// A finding from any analyzer
struct Finding {
id: String, // e.g. "SEC-001"
severity: Severity, // Error | Warning | Info
file: PathBuf,
line: usize,
message: String,
suggestion: Option<String>,
fix_kind: Option<FixKind>,
affected_dependents: usize,
}
// The code graph
struct CodeGraph {
graph: DiGraph<Node, Edge>, // petgraph
node_index: HashMap<String, NodeId>, // fast lookup
root_path: PathBuf,
}
Adding an analyzer
- Create
crates/core/src/analyzer/<name>.rsimplementingAnalyzer - Register in
AnalyzerDispatcher::new()inanalyzer/mod.rs - Add toggle field to
ModulesConfiginconfig.rs - Add tests in
crates/core/tests/test_<name>_analyzer.rs
Node.js bindings (crates/node-binding)
The revet-node crate exposes an async JavaScript / TypeScript API via NAPI-RS. Published as @revet/core.
Functions: analyzeRepository, analyzeFiles, analyzeGraph, suppress, getVersion, watchRepo.
See the Node.js API reference for full documentation including the streaming watch API.
Adding a language parser
- Create
crates/core/src/parser/<lang>.rsimplementingLanguageParser - Register in
ParserDispatcher::new()inparser/mod.rs - Add the tree-sitter grammar crate to
Cargo.toml - Add tests in
crates/core/tests/test_<lang>_parser.rs