codex-helper-core 0.15.0

Core library for codex-helper.
Documentation
use std::env;
use std::path::{Path, PathBuf};

use dirs::home_dir;

pub const CLAUDE_ABSENT_BACKUP_SENTINEL: &str = "{\"__codex_helper_backup_absent\":true}";

fn resolve_home_dir(env_var: &str, default_dir_name: &str) -> PathBuf {
    if let Ok(dir) = env::var(env_var) {
        return PathBuf::from(dir);
    }
    home_dir()
        .unwrap_or_else(|| PathBuf::from("."))
        .join(default_dir_name)
}

pub fn codex_home() -> PathBuf {
    resolve_home_dir("CODEX_HOME", ".codex")
}

pub fn codex_config_path() -> PathBuf {
    codex_home().join("config.toml")
}

pub fn codex_switch_state_path() -> PathBuf {
    codex_home().join("codex-helper-switch-state.json")
}

pub fn codex_auth_path() -> PathBuf {
    codex_home().join("auth.json")
}

pub fn claude_home() -> PathBuf {
    resolve_home_dir("CLAUDE_HOME", ".claude")
}

pub fn claude_settings_path() -> PathBuf {
    let dir = claude_home();
    let settings = dir.join("settings.json");
    if settings.exists() {
        return settings;
    }
    let legacy = dir.join("claude.json");
    if legacy.exists() {
        return legacy;
    }
    settings
}

pub fn claude_settings_backup_path_for(path: &Path) -> PathBuf {
    let mut backup = path.to_path_buf();
    let file_name = backup
        .file_name()
        .map(|name| name.to_string_lossy().to_string())
        .unwrap_or_else(|| "settings.json".to_string());
    backup.set_file_name(format!("{file_name}.codex-helper-backup"));
    backup
}

pub fn claude_settings_backup_path() -> PathBuf {
    claude_settings_backup_path_for(&claude_settings_path())
}

pub fn is_claude_absent_backup_sentinel(text: &str) -> bool {
    text.trim() == CLAUDE_ABSENT_BACKUP_SENTINEL
}