Skip to main content

argus_repomap/
lib.rs

1//! Repository structure mapping via tree-sitter and PageRank ranking.
2//!
3//! Generates a compressed, ranked map of codebase symbols (classes, functions,
4//! signatures) optimized for LLM token efficiency. Uses tree-sitter for AST
5//! parsing, petgraph for PageRank, and the `ignore` crate for file walking.
6
7pub mod budget;
8pub mod graph;
9pub mod output;
10pub mod parser;
11pub mod walker;
12
13use std::path::{Path, PathBuf};
14
15use argus_core::{ArgusError, OutputFormat};
16
17/// Generate a ranked map of the codebase at `root`.
18///
19/// Walks the repository, parses source files, builds a symbol graph, runs
20/// PageRank, fits to the token budget, and formats the output.
21///
22/// # Errors
23///
24/// Returns [`ArgusError`] if file walking or parsing fails.
25///
26/// # Examples
27///
28/// ```no_run
29/// use std::path::Path;
30/// use argus_core::OutputFormat;
31/// use argus_repomap::generate_map;
32///
33/// let map = generate_map(Path::new("."), 1024, &[], OutputFormat::Text).unwrap();
34/// println!("{map}");
35/// ```
36pub fn generate_map(
37    root: &Path,
38    max_tokens: usize,
39    focus_files: &[PathBuf],
40    format: OutputFormat,
41) -> Result<String, ArgusError> {
42    let files = walker::walk_repo(root)?;
43
44    let mut all_symbols = Vec::new();
45    let mut all_references = Vec::new();
46
47    for file in &files {
48        let symbols = parser::extract_symbols(file)?;
49        let references = parser::extract_references(file)?;
50        all_symbols.extend(symbols);
51        all_references.extend(references);
52    }
53
54    let mut symbol_graph = graph::SymbolGraph::build(all_symbols, all_references);
55    symbol_graph.compute_pagerank();
56
57    let ranked = if focus_files.is_empty() {
58        symbol_graph.ranked_symbols()
59    } else {
60        symbol_graph.ranked_symbols_for_files(focus_files)
61    };
62
63    let selected = budget::fit_to_budget(&ranked, max_tokens);
64
65    match format {
66        OutputFormat::Text => Ok(output::format_tree(&selected)),
67        OutputFormat::Json => output::format_json(&selected),
68        OutputFormat::Markdown => Ok(output::format_markdown(&selected)),
69        OutputFormat::Sarif => Err(ArgusError::Config(
70            "SARIF output is only supported for the review subcommand.".into(),
71        )),
72    }
73}