How to Contribute
Contribution workflow. Read more
This document explains how Unfault’s client-side components work. If you’re contributing to the CLI, core library, or VS Code extension, this context helps you understand where your changes fit.
Unfault splits work between client and server:
All parsing happens on your machine. The CLI and VS Code extension use the core library to parse source code and build a semantic graph. Only the graph structure (not your source code) goes to the API.
This architecture provides:
unfault/core)The core library is the foundation of client-side analysis. It handles:
core/├── src/│ ├── lib.rs # Public API│ ├── parse/ # Tree-sitter parsing│ │ ├── python.rs│ │ ├── go.rs│ │ ├── rust.rs│ │ └── typescript.rs│ ├── semantics/ # Semantic extraction│ │ ├── mod.rs│ │ ├── python/ # Python-specific semantics│ │ ├── go/│ │ └── ...│ ├── graph/ # Graph construction│ │ ├── mod.rs # CodeGraph implementation│ │ ├── nodes.rs # Node types│ │ └── edges.rs # Edge types│ └── ir.rs # Intermediate representationThe CodeGraph is the central data structure:
pub struct CodeGraph { nodes: Vec<GraphNode>, edges: Vec<GraphEdge>, // Indexes for efficient lookups file_index: HashMap<PathBuf, NodeIndex>, function_index: HashMap<String, NodeIndex>,}
pub enum GraphNode { File { path: PathBuf, language: Language }, Function { name: String, qualified_name: String, ... }, Class { name: String, ... }, ExternalModule { name: String, category: ModuleCategory }, // Framework-specific nodes Route { method: HttpMethod, path: String, ... }, Middleware { name: String, ... },}
pub enum GraphEdgeKind { Contains, // File contains Function Calls, // Function calls Function Imports, // File imports Module Inherits, // Class inherits Class UsesLibrary, // Function uses external library // Framework-specific edges RegistersRoute, AppliesMiddleware,}unfault/cli)The CLI orchestrates the analysis workflow:
cli/├── src/│ ├── main.rs # Entry point, argument parsing│ ├── commands/ # Subcommands│ │ ├── review.rs # `unfault review`│ │ ├── ask.rs # `unfault ask`│ │ ├── graph.rs # `unfault graph`│ │ └── login.rs # `unfault login`│ ├── session/ # Analysis session management│ │ ├── mod.rs # Session lifecycle│ │ ├── workspace.rs # Workspace detection│ │ └── file_collector.rs # File selection│ └── api/ # API client│ ├── client.rs # HTTP client│ └── session.rs # Session APIThe review flow:
core to parse files and build graphunfault/vscode)The extension provides real-time analysis via LSP:
vscode/├── src/│ ├── extension.ts # Extension entry point│ ├── contextView.ts # Context sidebar webview│ └── welcomePanel.ts # Onboarding UIThe extension spawns the CLI in LSP mode (unfault lsp) and communicates via the Language Server Protocol. The CLI handles all parsing and API communication; the extension focuses on UI.
We considered server-side parsing but chose client-side for:
The core library is a separate crate from the CLI. This is good design practice:
The API receives an Intermediate Representation (IR) that contains:
The API does not receive:
To add support for a new language:
core/Cargo.tomlcore/src/parse/{language}.rscore/src/semantics/{language}/SourceSemantics enumTo add support for a new framework:
core/src/semantics/{language}/frameworks/FrameworkGuess signalsTo capture more semantic information:
core/src/semantics/{language}/model.rscore/src/semantics/{language}/mod.rsThe CLI can discover SLOs from observability platforms and link them to route handlers. Currently supported: GCP Cloud Monitoring, Datadog, Dynatrace.
To add a new provider:
cli/src/slo/{provider}.rsfetch_slos to query the provider’s APISloDefinition structs with name, target, path patternSloEnricher (cli/src/slo/mod.rs)Example provider structure:
pub struct MyProvider { api_key: String, endpoint: String,}
impl MyProvider { pub fn is_available() -> bool { env::var("MY_PROVIDER_API_KEY").is_ok() }
pub fn from_env() -> Option<Self> { let api_key = env::var("MY_PROVIDER_API_KEY").ok()?; Some(Self { api_key, endpoint: "https://api.myprovider.com".into() }) }
pub async fn fetch_slos(&self, client: &Client) -> Result<Vec<SloDefinition>> { // Query API and map to SloDefinition }}cd corecargo test # All testscargo test python # Python-related testscargo test semantics::python # Specific modulecd clicargo testFor end-to-end testing:
# Point CLI to local APIUNFAULT_API_URL=http://localhost:8000 cargo run -- reviewHow to Contribute
Contribution workflow. Read more
CLI Repository
Browse the CLI source code. View on GitHub
Core Repository
Parsing and semantics. View on GitHub