Skip to main content

sync_auth/
lib.rs

1//! `sync-auth` — Bidirectional auth credential sync for dev tools via Git repositories.
2//!
3//! This library provides a trait-based, extensible system for syncing authentication
4//! credentials for developer tools (GitHub CLI, GitLab CLI, Claude Code, Codex,
5//! Gemini CLI, etc.) through a Git repository backend.
6//!
7//! # Architecture
8//!
9//! - [`AuthProvider`] trait: implement to add support for any dev tool's credentials
10//! - [`GitBackend`] trait: implement to customize how credentials are stored/fetched
11//! - [`SyncEngine`]: orchestrates bidirectional sync between local and remote
12//! - Built-in providers for common tools via [`providers`] module
13//!
14//! # Example
15//!
16//! ```no_run
17//! use sync_auth::{SyncEngine, SyncConfig};
18//!
19//! #[tokio::main]
20//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21//!     let config = SyncConfig {
22//!         repo_url: "https://github.com/user/my-credentials.git".to_string(),
23//!         local_path: "/tmp/sync-auth-repo".into(),
24//!         providers: vec!["gh".to_string(), "claude".to_string()],
25//!         ..Default::default()
26//!     };
27//!     let engine = SyncEngine::new(config)?;
28//!     engine.pull().await?;
29//!     Ok(())
30//! }
31//! ```
32
33pub mod backend;
34pub mod providers;
35
36mod config;
37mod engine;
38mod error;
39
40pub use config::SyncConfig;
41pub use engine::SyncEngine;
42pub use error::SyncError;
43
44/// Package version (matches Cargo.toml version).
45pub const VERSION: &str = env!("CARGO_PKG_VERSION");
46
47/// Credential file entry describing a single file to sync.
48#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
49pub struct CredentialFile {
50    /// Relative path within the provider's namespace in the sync repo.
51    pub relative_path: String,
52    /// Absolute path on the local filesystem.
53    pub local_path: std::path::PathBuf,
54    /// Whether this is a directory (recursive sync).
55    pub is_dir: bool,
56}
57
58/// Result of validating a credential.
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub enum ValidationResult {
61    /// Credential is valid and usable.
62    Valid,
63    /// Credential exists but is expired or invalid.
64    Expired,
65    /// Credential is missing or empty.
66    Missing,
67    /// Validation could not be performed (tool not installed, etc.).
68    Unknown,
69}
70
71/// Trait for auth credential providers.
72///
73/// Implement this trait to add support for syncing credentials of any dev tool.
74/// Each provider declares its name, the credential files it manages, and
75/// optionally a validation method to check credential freshness.
76#[async_trait::async_trait]
77pub trait AuthProvider: Send + Sync {
78    /// Unique name for this provider (e.g. "gh", "claude").
79    fn name(&self) -> &str;
80
81    /// Human-readable display name.
82    fn display_name(&self) -> &str;
83
84    /// List of credential files/directories this provider manages.
85    fn credential_files(&self) -> Vec<CredentialFile>;
86
87    /// Validate whether the current local credentials are still valid.
88    /// Defaults to [`ValidationResult::Unknown`].
89    async fn validate(&self) -> ValidationResult {
90        ValidationResult::Unknown
91    }
92}