switchx 0.1.1

Universal AI subscription account switcher and rolling quota router for Antigravity, Cursor, Claude Code, and Copilot
Documentation
use super::ProviderAdapter;
use crate::model::AccountProfile;
use anyhow::{Context, Result};
use std::path::{Path, PathBuf};

pub struct CopilotAdapter;

impl CopilotAdapter {
    pub fn new() -> Self {
        Self
    }

    pub fn default_hosts_file() -> PathBuf {
        let base = if let Some(app_data) = std::env::var_os("LOCALAPPDATA") {
            PathBuf::from(app_data).join("github-copilot")
        } else {
            dirs::home_dir()
                .unwrap_or_else(|| PathBuf::from("."))
                .join(".config")
                .join("github-copilot")
        };
        base.join("hosts.json")
    }
}

impl Default for CopilotAdapter {
    fn default() -> Self {
        Self::new()
    }
}

impl ProviderAdapter for CopilotAdapter {
    fn id(&self) -> &'static str {
        "copilot"
    }

    fn display_name(&self) -> &'static str {
        "GitHub Copilot / Codex"
    }

    fn target_auth_path(&self) -> Option<PathBuf> {
        Some(Self::default_hosts_file())
    }

    fn has_active_session(&self) -> bool {
        Self::default_hosts_file().exists()
    }

    fn capture_session(&self, vault_dir: &Path) -> Result<()> {
        std::fs::create_dir_all(vault_dir)?;
        let hosts = Self::default_hosts_file();
        if hosts.exists() {
            std::fs::copy(&hosts, vault_dir.join("hosts.json"))
                .with_context(|| format!("Failed to copy {:?}", hosts))?;
        }
        Ok(())
    }

    fn activate_session(&self, _profile: &AccountProfile, vault_dir: &Path) -> Result<()> {
        let vault_hosts = vault_dir.join("hosts.json");
        if vault_hosts.exists() {
            let target_hosts = Self::default_hosts_file();
            if let Some(parent) = target_hosts.parent() {
                std::fs::create_dir_all(parent)?;
            }
            std::fs::copy(&vault_hosts, &target_hosts)
                .with_context(|| format!("Failed to activate Copilot hosts.json from {:?}", vault_hosts))?;
        }
        Ok(())
    }
}