Skip to main content

codex_helper_core/
client_config.rs

1use std::env;
2use std::path::{Path, PathBuf};
3
4use dirs::home_dir;
5
6pub const CLAUDE_ABSENT_BACKUP_SENTINEL: &str = "{\"__codex_helper_backup_absent\":true}";
7
8fn resolve_home_dir(env_var: &str, default_dir_name: &str) -> PathBuf {
9    if let Ok(dir) = env::var(env_var) {
10        return PathBuf::from(dir);
11    }
12    home_dir()
13        .unwrap_or_else(|| PathBuf::from("."))
14        .join(default_dir_name)
15}
16
17pub fn codex_home() -> PathBuf {
18    resolve_home_dir("CODEX_HOME", ".codex")
19}
20
21pub fn codex_config_path() -> PathBuf {
22    codex_home().join("config.toml")
23}
24
25pub fn codex_switch_state_path() -> PathBuf {
26    codex_home().join("codex-helper-switch-state.json")
27}
28
29pub fn codex_auth_path() -> PathBuf {
30    codex_home().join("auth.json")
31}
32
33pub fn claude_home() -> PathBuf {
34    resolve_home_dir("CLAUDE_HOME", ".claude")
35}
36
37pub fn claude_settings_path() -> PathBuf {
38    let dir = claude_home();
39    let settings = dir.join("settings.json");
40    if settings.exists() {
41        return settings;
42    }
43    let legacy = dir.join("claude.json");
44    if legacy.exists() {
45        return legacy;
46    }
47    settings
48}
49
50pub fn claude_settings_backup_path_for(path: &Path) -> PathBuf {
51    let mut backup = path.to_path_buf();
52    let file_name = backup
53        .file_name()
54        .map(|name| name.to_string_lossy().to_string())
55        .unwrap_or_else(|| "settings.json".to_string());
56    backup.set_file_name(format!("{file_name}.codex-helper-backup"));
57    backup
58}
59
60pub fn claude_settings_backup_path() -> PathBuf {
61    claude_settings_backup_path_for(&claude_settings_path())
62}
63
64pub fn is_claude_absent_backup_sentinel(text: &str) -> bool {
65    text.trim() == CLAUDE_ABSENT_BACKUP_SENTINEL
66}