Static architecture analysis for local backend codebases. Deterministic, local-only, no external APIs.
archsentinal/
├── core/ # Rust analysis engine (no CLI deps in lib)
│ ├── src/
│ │ ├── lib.rs # analyze(), scan(), AnalysisResult, ScanResult
│ │ ├── main.rs # CLI (clap): scan subcommand, --json, --config
│ │ ├── config.rs # ScanConfig (skip_dirs, entry_points, layers, etc.)
│ │ ├── file_config.rs # .archsentinal.toml load + merge
│ │ ├── scanner.rs # File scanner
│ │ ├── extract.rs # Dependency extraction (Rust/syn, JS/TS/Python/Go regex)
│ │ ├── graph.rs # DependencyGraph (petgraph)
│ │ ├── tarjan.rs # SCC / cycle detection
│ │ ├── dead.rs # Dead file detection (entry points, test/config exclusions)
│ │ └── god.rs # God file detection (LOC threshold)
│ └── Cargo.toml
├── app/ # Tauri desktop wrapper (Phase 2+)
│ ├── src/
│ ├── capabilities/
│ ├── tauri.conf.json
│ └── Cargo.toml
├── ui/
│ ├── index.html
│ └── main.js
├── Cargo.toml
├── archsentinal.example.toml # Example .archsentinal.toml
└── README.md
# Human-readable output (default)
archsentinal scan <path>
# JSON output
archsentinal scan <path> --json
# Use a specific config file
archsentinal scan <path> --config .archsentinal.tomlIf .archsentinal.toml exists in the project root, it is loaded and merged with defaults (skip directories, LOC threshold, entry points, layers, ignore test/config files). Malformed config prints a warning and falls back to defaults.
See archsentinal.example.toml. Summary of options:
- skip_dirs — Directories to skip when scanning
- god_file_loc_threshold — LOC above which a file is reported as a "god file" (default 500)
- entry_points — Basenames excluded from dead file list (e.g. main.rs, index.ts)
- ignore_test_files — Do not report test files as dead (default true):
*.test.*,*.spec.*,tests/,__tests__/ - ignore_config_files — Do not report config files as dead (default true); config_file_patterns lists globs (e.g. vite.config.*)
- [layers] — Optional layer name → path prefixes (e.g.
controllers = ["src/controllers"])
{
"root_path": "/path/to/project",
"total_files": 42,
"total_edges": 58,
"cycles": [["/a.rs", "/b.rs"]],
"dead_files": ["/unused.rs"],
"god_files": [
{ "file": "/large.py", "loc": 600, "out_degree": 5, "in_degree": 2 }
],
"dependency_density": 0.032,
"average_out_degree": 1.38,
"sample_edges": [["/main.py", "/foo.py"]]
}- walkdir — Recursive file scan
- petgraph — Dependency graph
- syn / quote — Rust AST (use/mod)
- regex — JS/TS/Python/Go import extraction
- serde / serde_json — AnalysisResult JSON
- toml — .archsentinal.toml parsing
- clap — CLI (scan subcommand, --json, --config)
- anyhow / thiserror — Errors
Prerequisites: Rust toolchain (cargo or rustup).
cd archsentinal
./cargo.sh build -p archsentinal-core --release
./cargo.sh run -p archsentinal-core -- scan ./path/to/codebase
./cargo.sh run -p archsentinal-core -- scan ./path/to/codebase --jsonOr with system cargo:
cargo build -p archsentinal-core --release
./target/release/archsentinal scan ./path/to/codebase
./target/release/archsentinal scan ./path/to/codebase --jsonDesktop app (Phase 2+): cargo tauri dev -p archsentinal-app
- CLI —
archsentinal scan <path>,--json,--config <file> - AnalysisResult — total_files, total_edges, cycles, dead_files, god_files, dependency_density, average_out_degree (serde)
- God file detection — LOC ≥ threshold; report path, LOC, out_degree, in_degree
- .archsentinal.toml — skip_dirs, god_file_loc_threshold, entry_points, layers, ignore_test_files, ignore_config_files
- Dead file logic — Configurable entry points; exclude test files (e.g. .test., tests/) and config files by pattern
- Unit tests — cycle, dead file, god file, config loading
- Separation — Engine returns pure data; CLI handles parsing and printing only
Intended to be deployed at sarweshsoman.in/archsentinal (web build) with desktop distribution separately.