codex_helper_core/
client_config.rs1use 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_sqlite_dir() -> PathBuf {
26 codex_home().join("sqlite")
27}
28
29pub fn codex_app_db_path() -> PathBuf {
30 codex_sqlite_dir().join("codex-dev.db")
31}
32
33pub fn codex_switch_state_path() -> PathBuf {
34 codex_home().join("codex-helper-switch-state.json")
35}
36
37pub fn codex_auth_path() -> PathBuf {
38 codex_home().join("auth.json")
39}
40
41pub fn claude_home() -> PathBuf {
42 resolve_home_dir("CLAUDE_HOME", ".claude")
43}
44
45pub fn claude_settings_path() -> PathBuf {
46 let dir = claude_home();
47 let settings = dir.join("settings.json");
48 if settings.exists() {
49 return settings;
50 }
51 let legacy = dir.join("claude.json");
52 if legacy.exists() {
53 return legacy;
54 }
55 settings
56}
57
58pub fn claude_settings_backup_path_for(path: &Path) -> PathBuf {
59 let mut backup = path.to_path_buf();
60 let file_name = backup
61 .file_name()
62 .map(|name| name.to_string_lossy().to_string())
63 .unwrap_or_else(|| "settings.json".to_string());
64 backup.set_file_name(format!("{file_name}.codex-helper-backup"));
65 backup
66}
67
68pub fn claude_settings_backup_path() -> PathBuf {
69 claude_settings_backup_path_for(&claude_settings_path())
70}
71
72pub fn is_claude_absent_backup_sentinel(text: &str) -> bool {
73 text.trim() == CLAUDE_ABSENT_BACKUP_SENTINEL
74}