From 6f2594712f11403a450e43fcc93fe655fe0193ba Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Tue, 21 Jul 2026 10:15:42 -0600 Subject: [PATCH] refactor: Standardized paths module function names to not use 'path' in the name and to just always be either 'dir' or 'file' --- src/client/oauth.rs | 5 +- src/config/agent.rs | 2 +- src/config/app_config.rs | 4 +- src/config/mod.rs | 2 +- src/config/paths.rs | 86 +++++++++++++++++------------------ src/config/request_context.rs | 14 +++--- src/function/memory.rs | 2 +- src/main.rs | 4 +- src/mcp/oauth.rs | 4 +- src/sandbox/mod.rs | 2 +- src/utils/logs.rs | 2 +- src/vault/mod.rs | 2 +- 12 files changed, 63 insertions(+), 66 deletions(-) diff --git a/src/client/oauth.rs b/src/client/oauth.rs index 596917c..49d340d 100644 --- a/src/client/oauth.rs +++ b/src/client/oauth.rs @@ -357,10 +357,7 @@ async fn run_client_credentials_flow( Ok(()) } -async fn run_device_code_flow( - provider: &dyn OAuthProvider, - client_name: &str, -) -> Result<()> { +async fn run_device_code_flow(provider: &dyn OAuthProvider, client_name: &str) -> Result<()> { let device_auth_url = provider.device_authorization_url().ok_or_else(|| { anyhow!( "Provider '{}' is configured with flow: device_code but has no device_authorization_url. \ diff --git a/src/config/agent.rs b/src/config/agent.rs index e135bea..b18c02c 100644 --- a/src/config/agent.rs +++ b/src/config/agent.rs @@ -221,7 +221,7 @@ impl Agent { && !matches!(agent_config.memory, Some(false)) && !matches!(app.memory, Some(false)) { - let memory_exists = paths::global_memory_index_path().exists() + let memory_exists = paths::global_memory_index_file().exists() || env::current_dir() .ok() .and_then(|cwd| memory::discover_workspace_memory(&cwd)) diff --git a/src/config/app_config.rs b/src/config/app_config.rs index a501bf8..0c19ede 100644 --- a/src/config/app_config.rs +++ b/src/config/app_config.rs @@ -329,7 +329,7 @@ impl AppConfig { return path.clone(); } - if let Some(translated) = paths::translate_sandboxed_home_path(path) + if let Some(translated) = paths::translate_sandboxed_home_dir(path) && translated.exists() { info!( @@ -380,7 +380,7 @@ impl AppConfig { let theme = if self.highlight { let theme_mode = if self.light_theme() { "light" } else { "dark" }; let theme_filename = format!("{theme_mode}.tmTheme"); - let theme_path = paths::local_path(&theme_filename); + let theme_path = paths::local_dir(&theme_filename); if theme_path.exists() { let theme = ThemeSet::get_theme(&theme_path) .with_context(|| format!("Invalid theme at '{}'", theme_path.display()))?; diff --git a/src/config/mod.rs b/src/config/mod.rs index 1af7d66..022e937 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -481,7 +481,7 @@ fn confirm_asset_overwrite(category: AssetCategory, label: &str, target: &Path) pub fn default_sessions_dir() -> PathBuf { match env::var(get_env_name("sessions_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => paths::local_path(SESSIONS_DIR_NAME), + Err(_) => paths::local_dir(SESSIONS_DIR_NAME), } } diff --git a/src/config/paths.rs b/src/config/paths.rs index 9ac45a9..543b140 100644 --- a/src/config/paths.rs +++ b/src/config/paths.rs @@ -30,11 +30,11 @@ pub fn config_dir() -> PathBuf { } } -pub fn local_path(name: &str) -> PathBuf { +pub fn local_dir(name: &str) -> PathBuf { config_dir().join(name) } -pub fn cache_path() -> PathBuf { +pub fn cache_dir() -> PathBuf { if let Ok(v) = env::var(get_env_name("cache_dir")) { PathBuf::from(v) } else if let Ok(v) = env::var("XDG_CACHE_HOME") { @@ -49,7 +49,7 @@ pub fn sandbox_kit_override() -> Option { env::var_os(get_env_name("sandbox_kit")).map(PathBuf::from) } -pub fn translate_sandboxed_home_path(path: &Path) -> Option { +pub fn translate_sandboxed_home_dir(path: &Path) -> Option { env::var_os("IS_SANDBOX")?; let s = path.to_str()?; @@ -62,7 +62,7 @@ pub fn translate_sandboxed_home_path(path: &Path) -> Option { return Some(translated); } - translate_windows_users_path(s) + translate_windows_users_dir(s) } fn translate_unix_home_style(s: &str, prefix: &str) -> Option { @@ -83,7 +83,7 @@ fn translate_unix_home_style(s: &str, prefix: &str) -> Option { }) } -fn translate_windows_users_path(s: &str) -> Option { +fn translate_windows_users_dir(s: &str) -> Option { let bytes = s.as_bytes(); if bytes.len() < 4 || !bytes[0].is_ascii_alphabetic() || bytes[1] != b':' || bytes[2] != b'\\' { return None; @@ -128,20 +128,20 @@ pub fn find_workspace_sbx_mixin(start: &Path) -> Option { None } -pub fn oauth_tokens_path() -> PathBuf { - cache_path().join("oauth") +pub fn oauth_tokens_dir() -> PathBuf { + cache_dir().join("oauth") } pub fn token_file(client_name: &str) -> PathBuf { - oauth_tokens_path().join(format!("{client_name}_oauth_tokens.json")) + oauth_tokens_dir().join(format!("{client_name}_oauth_tokens.json")) } -pub fn log_path() -> PathBuf { - cache_path().join(format!("{}.log", env!("CARGO_CRATE_NAME"))) +pub fn log_file() -> PathBuf { + cache_dir().join(format!("{}.log", env!("CARGO_CRATE_NAME"))) } pub fn sbx_kit_dir() -> PathBuf { - cache_path().join(SBX_KIT_DIR_NAME) + cache_dir().join(SBX_KIT_DIR_NAME) } pub fn sbx_kit_hash_file() -> PathBuf { @@ -149,7 +149,7 @@ pub fn sbx_kit_hash_file() -> PathBuf { } pub fn sbx_vault_mixins_dir() -> PathBuf { - cache_path().join(SBX_VAULT_MIXINS_DIR_NAME) + cache_dir().join(SBX_VAULT_MIXINS_DIR_NAME) } pub fn sbx_vault_mixins_hash_file() -> PathBuf { @@ -157,20 +157,20 @@ pub fn sbx_vault_mixins_hash_file() -> PathBuf { } pub fn sbx_mixin_kits_dir() -> PathBuf { - cache_path().join(SBX_MIXIN_KITS_DIR_NAME) + cache_dir().join(SBX_MIXIN_KITS_DIR_NAME) } pub fn config_file() -> PathBuf { match env::var(get_env_name("config_file")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(CONFIG_FILE_NAME), + Err(_) => local_dir(CONFIG_FILE_NAME), } } pub fn roles_dir() -> PathBuf { match env::var(get_env_name("roles_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(ROLES_DIR_NAME), + Err(_) => local_dir(ROLES_DIR_NAME), } } @@ -181,7 +181,7 @@ pub fn role_file(name: &str) -> PathBuf { pub fn skills_dir() -> PathBuf { match env::var(get_env_name("skills_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(SKILLS_DIR_NAME), + Err(_) => local_dir(SKILLS_DIR_NAME), } } @@ -243,7 +243,7 @@ pub fn validate_skill_name(name: &str) -> Result<()> { pub fn macros_dir() -> PathBuf { match env::var(get_env_name("macros_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(MACROS_DIR_NAME), + Err(_) => local_dir(MACROS_DIR_NAME), } } @@ -254,21 +254,21 @@ pub fn macro_file(name: &str) -> PathBuf { pub fn env_file() -> PathBuf { match env::var(get_env_name("env_file")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(ENV_FILE_NAME), + Err(_) => local_dir(ENV_FILE_NAME), } } pub fn rags_dir() -> PathBuf { match env::var(get_env_name("rags_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(RAGS_DIR_NAME), + Err(_) => local_dir(RAGS_DIR_NAME), } } pub fn functions_dir() -> PathBuf { match env::var(get_env_name("functions_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => local_path(FUNCTIONS_DIR_NAME), + Err(_) => local_dir(FUNCTIONS_DIR_NAME), } } @@ -293,7 +293,7 @@ pub fn bash_prompt_utils_file() -> PathBuf { } pub fn agents_data_dir() -> PathBuf { - local_path(AGENTS_DIR_NAME) + local_dir(AGENTS_DIR_NAME) } pub fn agent_data_dir(name: &str) -> PathBuf { @@ -339,14 +339,14 @@ pub fn agent_functions_file(name: &str) -> Result { } pub fn models_override_file() -> PathBuf { - local_path("models-override.yaml") + local_dir("models-override.yaml") } pub fn global_memory_dir() -> PathBuf { config_dir().join(MEMORY_DIR_NAME) } -pub fn global_memory_index_path() -> PathBuf { +pub fn global_memory_index_file() -> PathBuf { global_memory_dir().join(MEMORY_INDEX_FILE_NAME) } @@ -356,12 +356,12 @@ pub fn workspace_memory_dir_for(workspace_root: &Path) -> PathBuf { .join(MEMORY_DIR_NAME) } -pub fn workspace_memory_index_path_for(workspace_root: &Path) -> PathBuf { +pub fn workspace_memory_index_file_for(workspace_root: &Path) -> PathBuf { workspace_memory_dir_for(workspace_root).join(MEMORY_INDEX_FILE_NAME) } pub fn repl_history_dir() -> PathBuf { - cache_path().join(REPL_HISTORY_DIR_NAME) + cache_dir().join(REPL_HISTORY_DIR_NAME) } pub fn repl_history_file(session: &Option) -> PathBuf { @@ -384,7 +384,7 @@ pub fn log_config() -> Result<(LevelFilter, Option)> { }); let resolved_log_path = match env::var(get_env_name("log_path")) { Ok(v) => Some(PathBuf::from(v)), - Err(_) => Some(log_path()), + Err(_) => Some(log_file()), }; Ok((log_level, resolved_log_path)) } @@ -571,7 +571,7 @@ mod tests { fn returns_none_when_not_in_sandbox() { without_sandbox(|| { let p = Path::new("/home/atusa/.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } @@ -581,7 +581,7 @@ mod tests { with_sandbox(|| { let p = Path::new("/home/atusa/.coyote_password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.coyote_password")) ); }); @@ -589,11 +589,11 @@ mod tests { #[test] #[serial] - fn translates_nested_host_home_path() { + fn translates_nested_host_home_dir() { with_sandbox(|| { let p = Path::new("/home/atusa/.config/coyote/.password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.config/coyote/.password")) ); }); @@ -604,7 +604,7 @@ mod tests { fn returns_none_when_path_already_targets_agent_home() { with_sandbox(|| { let p = Path::new("/home/agent/.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } @@ -613,7 +613,7 @@ mod tests { fn returns_none_when_path_is_outside_home() { with_sandbox(|| { let p = Path::new("/etc/coyote/.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } @@ -622,7 +622,7 @@ mod tests { fn returns_none_for_relative_path() { with_sandbox(|| { let p = Path::new(".coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } @@ -631,17 +631,17 @@ mod tests { fn returns_none_for_first_segment_not_home() { with_sandbox(|| { let p = Path::new("/opt/atusa/.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } #[test] #[serial] - fn translates_macos_users_path() { + fn translates_macos_users_dir() { with_sandbox(|| { let p = Path::new("/Users/atusa/.coyote_password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.coyote_password")) ); }); @@ -649,11 +649,11 @@ mod tests { #[test] #[serial] - fn translates_macos_nested_path() { + fn translates_macos_nested_dir() { with_sandbox(|| { let p = Path::new("/Users/atusa/.config/coyote/.password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.config/coyote/.password")) ); }); @@ -661,10 +661,10 @@ mod tests { #[test] #[serial] - fn returns_none_when_macos_path_already_targets_agent() { + fn returns_none_when_macos_dir_already_targets_agent() { with_sandbox(|| { let p = Path::new("/Users/agent/.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } @@ -674,7 +674,7 @@ mod tests { with_sandbox(|| { let p = Path::new("C:\\Users\\atusa\\.coyote_password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.coyote_password")) ); }); @@ -686,7 +686,7 @@ mod tests { with_sandbox(|| { let p = Path::new("D:\\Users\\atusa\\.config\\coyote\\.password"); assert_eq!( - translate_sandboxed_home_path(p), + translate_sandboxed_home_dir(p), Some(PathBuf::from("/home/agent/.config/coyote/.password")) ); }); @@ -697,7 +697,7 @@ mod tests { fn returns_none_when_windows_path_already_targets_agent() { with_sandbox(|| { let p = Path::new("C:\\Users\\agent\\.coyote_password"); - assert_eq!(translate_sandboxed_home_path(p), None); + assert_eq!(translate_sandboxed_home_dir(p), None); }); } } diff --git a/src/config/request_context.rs b/src/config/request_context.rs index 978ed28..cfc44ae 100644 --- a/src/config/request_context.rs +++ b/src/config/request_context.rs @@ -440,9 +440,9 @@ impl RequestContext { match &self.agent { None => match env::var(get_env_name("messages_file")) { Ok(value) => PathBuf::from(value), - Err(_) => paths::cache_path().join(MESSAGES_FILE_NAME), + Err(_) => paths::cache_dir().join(MESSAGES_FILE_NAME), }, - Some(agent) => paths::cache_path() + Some(agent) => paths::cache_dir() .join(AGENTS_DIR_NAME) .join(agent.name()) .join(MESSAGES_FILE_NAME), @@ -453,7 +453,7 @@ impl RequestContext { match &self.agent { None => match env::var(get_env_name("sessions_dir")) { Ok(value) => PathBuf::from(value), - Err(_) => paths::local_path(SESSIONS_DIR_NAME), + Err(_) => paths::local_dir(SESSIONS_DIR_NAME), }, Some(agent) => paths::agent_data_dir(agent.name()).join(SESSIONS_DIR_NAME), } @@ -927,7 +927,7 @@ impl RequestContext { let store = cwd.as_deref().map(MemoryStore::new); let workspace = store.as_ref().and_then(|s| s.workspace.clone()); - let global_exists = paths::global_memory_index_path().exists(); + let global_exists = paths::global_memory_index_file().exists(); let workspace_exists = workspace.is_some(); if !global_exists && !workspace_exists { @@ -5609,7 +5609,7 @@ mod tests { #[serial] fn use_session_creates_temp_session() { let _guard = TestConfigDirGuard::new(); - let sessions_dir = paths::local_path("sessions"); + let sessions_dir = paths::local_dir("sessions"); create_dir_all(&sessions_dir).unwrap(); let mut ctx = create_test_ctx(); @@ -5625,7 +5625,7 @@ mod tests { #[serial] fn use_session_creates_named_session() { let _guard = TestConfigDirGuard::new(); - let sessions_dir = paths::local_path("sessions"); + let sessions_dir = paths::local_dir("sessions"); create_dir_all(&sessions_dir).unwrap(); let mut ctx = create_test_ctx(); @@ -5641,7 +5641,7 @@ mod tests { #[serial] fn exit_session_roundtrip() { let _guard = TestConfigDirGuard::new(); - let sessions_dir = paths::local_path("sessions"); + let sessions_dir = paths::local_dir("sessions"); create_dir_all(&sessions_dir).unwrap(); let mut ctx = create_test_ctx(); diff --git a/src/function/memory.rs b/src/function/memory.rs index 7782a44..dba89ff 100644 --- a/src/function/memory.rs +++ b/src/function/memory.rs @@ -321,7 +321,7 @@ pub fn handle_memory_tool(ctx: &mut RequestContext, cmd_name: &str, args: &Value Ok(json!({ "files": entries, - "global_index_exists": paths::global_memory_index_path().exists(), + "global_index_exists": paths::global_memory_index_file().exists(), "workspace": store.workspace.as_ref().map(workspace_label), })) } diff --git a/src/main.rs b/src/main.rs index 8a75b54..1afa726 100644 --- a/src/main.rs +++ b/src/main.rs @@ -388,14 +388,14 @@ async fn run( if let Some(scope) = cli.init_memory { let (path, content) = match scope { MemoryScope::Global => ( - paths::global_memory_index_path(), + paths::global_memory_index_file(), "# Global Memory\n\n\n\n", ), MemoryScope::Workspace => { let cwd = env::current_dir()?; let root = memory::find_git_root(&cwd).unwrap_or(cwd); ( - paths::workspace_memory_index_path_for(&root), + paths::workspace_memory_index_file_for(&root), "# Workspace Memory Index\n\n\n\n", ) } diff --git a/src/mcp/oauth.rs b/src/mcp/oauth.rs index 4bccecb..2c2cbc2 100644 --- a/src/mcp/oauth.rs +++ b/src/mcp/oauth.rs @@ -142,7 +142,7 @@ fn mcp_token_key(server_name: &str) -> String { } fn load_registered_client_id(server_name: &str) -> Option { - let path = paths::oauth_tokens_path().join(format!("mcp_{server_name}_registration.json")); + let path = paths::oauth_tokens_dir().join(format!("mcp_{server_name}_registration.json")); let content = fs::read_to_string(path).ok()?; let reg: McpRegistration = serde_json::from_str(&content).ok()?; @@ -150,7 +150,7 @@ fn load_registered_client_id(server_name: &str) -> Option { } fn save_registered_client_id(server_name: &str, client_id: &str) -> Result<()> { - let dir = paths::oauth_tokens_path(); + let dir = paths::oauth_tokens_dir(); fs::create_dir_all(&dir)?; let path = dir.join(format!("mcp_{server_name}_registration.json")); diff --git a/src/sandbox/mod.rs b/src/sandbox/mod.rs index d687652..9f8856c 100644 --- a/src/sandbox/mod.rs +++ b/src/sandbox/mod.rs @@ -388,7 +388,7 @@ fn copy_host_files(name: &str) -> Result<()> { ); } - let oauth_tokens_dir = paths::oauth_tokens_path(); + let oauth_tokens_dir = paths::oauth_tokens_dir(); if oauth_tokens_dir.exists() { let sandbox_oauth_dir = "/home/agent/.cache/coyote/oauth"; ensure_sandbox_dir(name, sandbox_oauth_dir)?; diff --git a/src/utils/logs.rs b/src/utils/logs.rs index b7da422..ff3f506 100644 --- a/src/utils/logs.rs +++ b/src/utils/logs.rs @@ -9,7 +9,7 @@ use tokio::time::sleep; pub async fn tail_logs(no_color: bool) { let re = Regex::new(r"^(?P\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+<(?P[^\s>]+)>\s+\[(?P[A-Z]+)\]\s+(?P[^:]+):(?P\d+)\s+-\s+(?P.*)$").unwrap(); - let file_path = paths::log_path(); + let file_path = paths::log_file(); let file = File::open(&file_path).expect("Cannot open file"); let mut reader = BufReader::new(file); diff --git a/src/vault/mod.rs b/src/vault/mod.rs index a8e9ca7..317f3d8 100644 --- a/src/vault/mod.rs +++ b/src/vault/mod.rs @@ -34,7 +34,7 @@ fn apply_sandboxed_home_translation(provider_def: &mut LocalProvider) { return; } - let Some(translated) = paths::translate_sandboxed_home_path(pf) else { + let Some(translated) = paths::translate_sandboxed_home_dir(pf) else { return; };