Skip to main content

repo_mapper/
config.rs

1//! Configuration types (SPEC §14).
2
3use std::collections::HashSet;
4use std::path::PathBuf;
5
6pub use crate::cache::map_cache::RefreshMode;
7
8/// Configuration for RepoMap (SPEC §14).
9#[derive(Debug, Clone)]
10pub struct RepoMapConfig {
11    /// Maximum tokens in repo map output (default: 1024)
12    pub map_tokens: usize,
13    /// Repository root directory (default: cwd)
14    pub root: PathBuf,
15    /// Prefix prepended to map output
16    pub repo_content_prefix: Option<String>,
17    /// Emit diagnostic output
18    pub verbose: bool,
19    /// LLM context window size
20    pub max_context_window: Option<usize>,
21    /// Multiplier for no-chat mode (default: 8)
22    pub map_mul_no_files: usize,
23    /// Map cache refresh mode (default: Auto)
24    pub refresh: RefreshMode,
25    /// Force cache recomputation
26    pub force_refresh: bool,
27    /// Exclude files with PageRank ≤ 0.0001
28    pub exclude_unranked: bool,
29    /// Self-edge weight (default: 0.1)
30    pub self_edge_weight: f64,
31    /// Maximum line length (default: 100)
32    pub max_line_length: usize,
33    /// PageRank damping factor (default: 0.85)
34    pub pagerank_damping: f64,
35    /// PageRank convergence tolerance (default: 1e-6)
36    pub pagerank_tol: f64,
37    /// PageRank maximum iterations (default: 100)
38    pub pagerank_max_iter: usize,
39    /// Anchor files: always included in map, used as RWR restart seeds (SPEC §7.1a)
40    pub anchor_fnames: Vec<PathBuf>,
41    /// Anchor identifiers: defining files used as RWR restart seeds (SPEC §7.1a)
42    pub anchor_idents: HashSet<String>,
43    /// Scoped anchors: file + ident pairs (-a file.py:my_fn). File becomes the RWR seed;
44    /// ident gets edge-weight boost as if passed to -i (SPEC §7.1a)
45    pub anchor_scoped: Vec<(PathBuf, String)>,
46    /// Personalization weight multiplier for anchor files (SPEC §7.1, default: 10.0)
47    pub anchor_weight_multiplier: f64,
48}
49
50impl Default for RepoMapConfig {
51    fn default() -> Self {
52        Self {
53            map_tokens: 1024,
54            root: std::env::current_dir().unwrap_or_default(),
55            repo_content_prefix: None,
56            verbose: false,
57            max_context_window: None,
58            map_mul_no_files: 8,
59            refresh: RefreshMode::Auto,
60            force_refresh: false,
61            exclude_unranked: false,
62            self_edge_weight: 0.1,
63            max_line_length: 100,
64            pagerank_damping: 0.85,
65            pagerank_tol: 1e-6,
66            pagerank_max_iter: 100,
67            anchor_fnames: Vec::new(),
68            anchor_idents: HashSet::new(),
69            anchor_scoped: Vec::new(),
70            anchor_weight_multiplier: 10.0,
71        }
72    }
73}
74
75/// Builder for RepoMapConfig.
76#[derive(Debug, Default)]
77pub struct RepoMapConfigBuilder {
78    config: RepoMapConfig,
79}
80
81impl RepoMapConfig {
82    /// Create a new builder.
83    pub fn builder() -> RepoMapConfigBuilder {
84        RepoMapConfigBuilder::default()
85    }
86}
87
88impl RepoMapConfigBuilder {
89    /// Set the token budget for map output (default: 1024).
90    pub fn map_tokens(mut self, n: usize) -> Self {
91        self.config.map_tokens = n;
92        self
93    }
94
95    /// Set the repository root directory.
96    pub fn root(mut self, path: impl Into<PathBuf>) -> Self {
97        self.config.root = path.into();
98        self
99    }
100
101    /// Set a prefix prepended to every map output string.
102    pub fn repo_content_prefix(mut self, prefix: impl Into<String>) -> Self {
103        self.config.repo_content_prefix = Some(prefix.into());
104        self
105    }
106
107    /// Enable or disable verbose diagnostic output.
108    pub fn verbose(mut self, v: bool) -> Self {
109        self.config.verbose = v;
110        self
111    }
112
113    /// Set the LLM context window size.
114    ///
115    /// When set and no chat files are provided, the effective token budget is
116    /// multiplied by `map_mul_no_files` (default 8×).
117    pub fn max_context_window(mut self, n: Option<usize>) -> Self {
118        self.config.max_context_window = n;
119        self
120    }
121
122    /// Set the no-chat-files budget multiplier (default: 8).
123    pub fn map_mul_no_files(mut self, n: usize) -> Self {
124        self.config.map_mul_no_files = n;
125        self
126    }
127
128    /// Set the map cache refresh mode.
129    pub fn refresh(mut self, mode: RefreshMode) -> Self {
130        self.config.refresh = mode;
131        self
132    }
133
134    /// Force cache recomputation on the next call.
135    pub fn force_refresh(mut self, v: bool) -> Self {
136        self.config.force_refresh = v;
137        self
138    }
139
140    /// Exclude files whose PageRank score is ≤ 0.0001.
141    pub fn exclude_unranked(mut self, v: bool) -> Self {
142        self.config.exclude_unranked = v;
143        self
144    }
145
146    /// Set the self-edge weight added for each file (default: 0.1).
147    pub fn self_edge_weight(mut self, w: f64) -> Self {
148        self.config.self_edge_weight = w;
149        self
150    }
151
152    /// Truncate rendered lines longer than this many characters (default: 100).
153    pub fn max_line_length(mut self, n: usize) -> Self {
154        self.config.max_line_length = n;
155        self
156    }
157
158    /// Set the PageRank damping factor (default: 0.85).
159    pub fn pagerank_damping(mut self, d: f64) -> Self {
160        self.config.pagerank_damping = d;
161        self
162    }
163
164    /// Set the PageRank convergence tolerance (default: 1e-6).
165    pub fn pagerank_tol(mut self, t: f64) -> Self {
166        self.config.pagerank_tol = t;
167        self
168    }
169
170    /// Set the maximum number of PageRank iterations (default: 100).
171    pub fn pagerank_max_iter(mut self, n: usize) -> Self {
172        self.config.pagerank_max_iter = n;
173        self
174    }
175
176    /// Files always included in the map and used as PageRank restart seeds.
177    pub fn anchor_fnames(mut self, fnames: Vec<std::path::PathBuf>) -> Self {
178        self.config.anchor_fnames = fnames;
179        self
180    }
181
182    /// Identifiers whose defining files are used as PageRank restart seeds.
183    pub fn anchor_idents(mut self, idents: std::collections::HashSet<String>) -> Self {
184        self.config.anchor_idents = idents;
185        self
186    }
187
188    /// Scoped anchors: `(file, ident)` pairs — file is the restart seed, ident gets an edge-weight boost.
189    pub fn anchor_scoped(mut self, scoped: Vec<(std::path::PathBuf, String)>) -> Self {
190        self.config.anchor_scoped = scoped;
191        self
192    }
193
194    /// Personalization weight multiplier for anchor files (default: 10.0).
195    pub fn anchor_weight_multiplier(mut self, m: f64) -> Self {
196        self.config.anchor_weight_multiplier = m;
197        self
198    }
199
200    /// Build the [`RepoMap`](crate::repo_map::RepoMap) from this configuration.
201    pub fn build(self) -> crate::repo_map::RepoMap {
202        crate::repo_map::RepoMap::new(self.config)
203    }
204}