csusage-adapter-goose 0.0.2

Coding agent CLI usage reports (ccusage fork with Claude Science support)
use std::{collections::HashSet, env, path::PathBuf};

use crate::Result;

const GOOSE_PATH_ROOT_ENV: &str = "GOOSE_PATH_ROOT";
pub(super) const GOOSE_DB_FILE_NAME: &str = "sessions.db";

pub(super) fn goose_db_paths() -> Result<Vec<PathBuf>> {
    let candidates = if let Ok(root) = env::var(GOOSE_PATH_ROOT_ENV) {
        let root = root.trim();
        if root.is_empty() {
            default_goose_db_candidates()?
        } else {
            vec![
                PathBuf::from(root)
                    .join("data")
                    .join("sessions")
                    .join(GOOSE_DB_FILE_NAME),
            ]
        }
    } else {
        default_goose_db_candidates()?
    };

    let mut paths = Vec::new();
    let mut seen = HashSet::new();
    for path in candidates {
        let path = path.canonicalize().unwrap_or(path);
        if path.is_file() && seen.insert(path.clone()) {
            paths.push(path);
        }
    }
    Ok(paths)
}

fn default_goose_db_candidates() -> Result<Vec<PathBuf>> {
    let home =
        crate::home::home_dir().ok_or_else(|| crate::cli_error("home directory is not set"))?;
    Ok(vec![
        home.join(".local/share/goose/sessions")
            .join(GOOSE_DB_FILE_NAME),
        home.join("Library/Application Support/goose/sessions")
            .join(GOOSE_DB_FILE_NAME),
        home.join(".local/share/Block/goose/sessions")
            .join(GOOSE_DB_FILE_NAME),
    ])
}

#[cfg(test)]
mod tests {
    use std::path::Path;

    use super::*;
    use csusage_test_support::{EnvVarGuard, fs_fixture};

    #[test]
    fn discovers_goose_path_root_database() {
        let fixture = fs_fixture!({
            "data/sessions/sessions.db": "",
        });
        let _cleanup = EnvVarGuard::set(GOOSE_PATH_ROOT_ENV, fixture.root());

        let paths = goose_db_paths().unwrap();

        assert_eq!(paths.len(), 1);
        assert!(paths[0].ends_with(Path::new("data/sessions/sessions.db")));
    }
}