lean_ctx/core/editor_registry/
paths.rs1use std::path::{Path, PathBuf};
2
3pub fn zed_settings_path(home: &std::path::Path) -> PathBuf {
4 if cfg!(target_os = "macos") {
5 home.join("Library/Application Support/Zed/settings.json")
6 } else {
7 home.join(".config/zed/settings.json")
8 }
9}
10
11pub fn zed_config_dir(home: &std::path::Path) -> PathBuf {
12 if cfg!(target_os = "macos") {
13 home.join("Library/Application Support/Zed")
14 } else {
15 home.join(".config/zed")
16 }
17}
18
19pub fn vscode_mcp_path() -> PathBuf {
20 if let Some(home) = dirs::home_dir() {
21 #[cfg(target_os = "macos")]
22 {
23 return home.join("Library/Application Support/Code/User/mcp.json");
24 }
25 #[cfg(target_os = "linux")]
26 {
27 return resolve_vscode_global_storage(&home, "User/mcp.json");
28 }
29 #[cfg(target_os = "windows")]
30 {
31 if let Ok(appdata) = std::env::var("APPDATA") {
32 return PathBuf::from(appdata).join("Code/User/mcp.json");
33 }
34 }
35 #[allow(unreachable_code)]
36 home.join(".config/Code/User/mcp.json")
37 } else {
38 PathBuf::from("/nonexistent")
39 }
40}
41
42pub fn qoder_mcp_path(home: &Path) -> PathBuf {
43 #[cfg(target_os = "windows")]
44 {
45 if let Ok(appdata) = std::env::var("APPDATA") {
46 return PathBuf::from(appdata)
47 .join("Qoder")
48 .join("SharedClientCache")
49 .join("mcp.json");
50 }
51 }
52 home.join(".qoder").join("mcp.json")
53}
54
55#[cfg(target_os = "macos")]
56pub fn qoder_mcp_paths(home: &Path) -> Vec<PathBuf> {
57 let mut paths = vec![qoder_mcp_path(home)];
58 paths.push(home.join("Library/Application Support/Qoder/User/mcp.json"));
59 paths.push(home.join("Library/Application Support/Qoder/SharedClientCache/mcp.json"));
60 paths
61}
62
63#[cfg(not(target_os = "macos"))]
64pub fn qoder_mcp_paths(home: &Path) -> Vec<PathBuf> {
65 vec![qoder_mcp_path(home)]
66}
67
68#[allow(unreachable_code)]
69pub fn cline_mcp_path() -> PathBuf {
70 #[cfg(target_os = "windows")]
71 {
72 if let Ok(appdata) = std::env::var("APPDATA") {
73 return PathBuf::from(appdata).join(
74 "Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json",
75 );
76 }
77 return PathBuf::from("/nonexistent");
78 }
79
80 let Some(home) = dirs::home_dir() else {
81 return PathBuf::from("/nonexistent");
82 };
83 #[cfg(target_os = "macos")]
84 {
85 return home.join("Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json");
86 }
87 #[cfg(target_os = "linux")]
88 {
89 let suffix = "User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json";
90 return resolve_vscode_global_storage(&home, suffix);
91 }
92 PathBuf::from("/nonexistent")
93}
94
95#[allow(unreachable_code)]
96pub fn roo_mcp_path() -> PathBuf {
97 #[cfg(target_os = "windows")]
98 {
99 if let Ok(appdata) = std::env::var("APPDATA") {
100 return PathBuf::from(appdata)
101 .join("Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json");
102 }
103 return PathBuf::from("/nonexistent");
104 }
105
106 let Some(home) = dirs::home_dir() else {
107 return PathBuf::from("/nonexistent");
108 };
109 #[cfg(target_os = "macos")]
110 {
111 return home.join("Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json");
112 }
113 #[cfg(target_os = "linux")]
114 {
115 let suffix =
116 "User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json";
117 return resolve_vscode_global_storage(&home, suffix);
118 }
119 PathBuf::from("/nonexistent")
120}
121
122#[cfg(target_os = "linux")]
130fn resolve_vscode_global_storage(home: &Path, suffix: &str) -> PathBuf {
131 const CANDIDATES: &[&str] = &[
132 ".config/VSCodium",
133 ".config/Code - OSS",
134 ".config/Code",
135 ".config/Code - Insiders",
136 ".vscode-server/data",
137 ];
138 for base in CANDIDATES {
139 let path = home.join(base);
140 if path.exists() {
141 return path.join(suffix);
142 }
143 }
144 home.join(".config/Code").join(suffix)
145}
146
147pub fn qoder_settings_path(home: &Path) -> PathBuf {
148 #[cfg(target_os = "windows")]
149 {
150 if let Ok(appdata) = std::env::var("APPDATA") {
151 return PathBuf::from(appdata)
152 .join("Qoder")
153 .join("SharedClientCache")
154 .join("mcp.json");
155 }
156 }
157 home.join(".qoder/mcp.json")
158}
159
160pub fn qoder_all_mcp_paths(home: &Path) -> Vec<PathBuf> {
161 let paths = vec![qoder_settings_path(home)];
162 #[cfg(target_os = "macos")]
163 let paths = {
164 let mut paths = paths;
165 paths.push(home.join("Library/Application Support/Qoder/User/mcp.json"));
166 paths.push(home.join("Library/Application Support/Qoder/SharedClientCache/mcp.json"));
167 paths
168 };
169 paths
170}
171
172pub fn qoderwork_mcp_path(home: &Path) -> PathBuf {
173 home.join(".qoderwork/mcp.json")
174}
175
176pub fn claude_mcp_json_path(home: &Path) -> PathBuf {
177 if let Ok(dir) = std::env::var("CLAUDE_CONFIG_DIR") {
178 let dir = dir.trim();
179 if !dir.is_empty() {
180 return PathBuf::from(dir).join(".claude.json");
181 }
182 }
183 home.join(".claude.json")
184}
185
186pub fn claude_state_dir(home: &Path) -> PathBuf {
187 if let Ok(dir) = std::env::var("CLAUDE_CONFIG_DIR") {
188 let dir = dir.trim();
189 if !dir.is_empty() {
190 return PathBuf::from(dir);
191 }
192 }
193 home.join(".claude")
194}
195
196pub fn claude_rules_dir(home: &Path) -> PathBuf {
197 claude_state_dir(home).join("rules")
198}
199
200pub fn codebuddy_mcp_json_path(home: &Path) -> PathBuf {
201 codebuddy_state_dir(home).join("mcp.json")
202}
203
204pub fn codebuddy_state_dir(home: &Path) -> PathBuf {
205 if let Ok(dir) = std::env::var("CODEBUDDY_CONFIG_DIR") {
206 let dir = dir.trim();
207 if !dir.is_empty() {
208 return PathBuf::from(dir);
209 }
210 }
211 home.join(".codebuddy")
212}
213
214pub fn codebuddy_rules_dir(home: &Path) -> PathBuf {
215 codebuddy_state_dir(home).join("rules")
216}
217
218pub fn augment_cli_settings_path(home: &Path) -> PathBuf {
219 home.join(".augment/settings.json")
220}
221
222pub fn augment_vscode_mcp_path(home: &Path) -> PathBuf {
232 const TAIL: &str = "globalStorage/augment.vscode-augment/augment-global-state/mcpServers.json";
233
234 #[cfg(target_os = "macos")]
235 {
236 return home
237 .join("Library/Application Support/Code/User")
238 .join(TAIL);
239 }
240 #[cfg(target_os = "linux")]
241 {
242 for path in [
243 ".config/Code/User",
244 ".config/Code - Insiders/User",
245 ".vscode-server/data/User",
246 ] {
247 let full_path = home.join(path).join(TAIL);
248 if full_path.exists() {
249 return full_path;
250 }
251 }
252 return home.join(".config/Code/User").join(TAIL);
254 }
255 #[cfg(target_os = "windows")]
256 {
257 if let Ok(appdata) = std::env::var("APPDATA") {
258 return PathBuf::from(appdata).join("Code/User").join(TAIL);
259 }
260 }
261 #[allow(unreachable_code)]
262 home.join(".config/Code/User").join(TAIL)
263}
264
265#[cfg(test)]
266mod augment_tests {
267 use super::*;
268
269 #[test]
270 fn augment_cli_settings_path_is_under_dot_augment() {
271 let home = Path::new("/home/tester");
272 assert_eq!(
273 augment_cli_settings_path(home),
274 home.join(".augment").join("settings.json")
275 );
276 }
277
278 #[test]
279 #[cfg(target_os = "linux")]
280 fn augment_vscode_mcp_path_uses_linux_globalstorage() {
281 let home = Path::new("/home/tester");
282 assert_eq!(
283 augment_vscode_mcp_path(home),
284 home.join(".config/Code/User/globalStorage/augment.vscode-augment/augment-global-state/mcpServers.json")
285 );
286 }
287
288 #[test]
289 #[cfg(target_os = "macos")]
290 fn augment_vscode_mcp_path_uses_macos_application_support() {
291 let home = Path::new("/Users/tester");
292 assert_eq!(
293 augment_vscode_mcp_path(home),
294 home.join("Library/Application Support/Code/User/globalStorage/augment.vscode-augment/augment-global-state/mcpServers.json")
295 );
296 }
297
298 #[test]
304 #[cfg(target_os = "windows")]
305 fn augment_vscode_mcp_path_ends_with_globalstorage_tail() {
306 let home = Path::new("C:/Users/tester");
307 let path = augment_vscode_mcp_path(home);
308 let s = path.to_string_lossy().replace('\\', "/");
309 assert!(
310 s.ends_with(
311 "Code/User/globalStorage/augment.vscode-augment/augment-global-state/mcpServers.json"
312 ),
313 "unexpected windows path: {s}"
314 );
315 }
316}
317
318#[cfg(all(test, target_os = "macos"))]
319mod tests {
320 use super::*;
321
322 #[test]
323 #[cfg(target_os = "macos")]
324 fn qoder_mcp_paths_include_macos_user_and_shared_cache_locations() {
325 let home = Path::new("/Users/tester");
326 let paths = qoder_mcp_paths(home);
327
328 assert_eq!(
329 paths,
330 vec![
331 home.join(".qoder/mcp.json"),
332 home.join("Library/Application Support/Qoder/User/mcp.json"),
333 home.join("Library/Application Support/Qoder/SharedClientCache/mcp.json"),
334 ]
335 );
336 }
337}