pub mod claude_code;
pub mod codex;
pub mod grok;
mod keychain;
use std::path::PathBuf;
use bitrouter_ai::auth::credentials::OAuthToken;
#[derive(Debug, Clone)]
pub enum ImportSource {
Keychain(&'static str),
File(PathBuf),
}
impl std::fmt::Display for ImportSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImportSource::Keychain(service) => write!(f, "OS keyring ({service})"),
ImportSource::File(path) => write!(f, "{}", path.display()),
}
}
}
#[derive(Debug, Clone)]
pub struct Imported {
pub token: OAuthToken,
pub source: ImportSource,
}
#[derive(Debug, thiserror::Error)]
pub enum ImportError {
#[error("could not resolve the home directory (set HOME)")]
NoHome,
#[error("reading {path}: {source}")]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("parsing {origin} credentials: {source}")]
Json {
origin: String,
#[source]
source: serde_json::Error,
},
#[error("{cli} credential is missing an access token")]
MissingAccessToken {
cli: &'static str,
},
#[error("reading the OS keyring: {0}")]
Keyring(String),
}
pub(crate) fn home_dir() -> Option<PathBuf> {
std::env::var_os("HOME")
.filter(|v| !v.is_empty())
.or_else(|| std::env::var_os("USERPROFILE").filter(|v| !v.is_empty()))
.map(PathBuf::from)
}