pub mod claude_code;
pub mod codex;
pub mod copilot;
pub mod cursor;
pub mod gemini;
use crate::error::CoreError;
use crate::model::{Session, SessionRef};
pub trait Adapter {
fn id(&self) -> &'static str;
fn detect(&self) -> bool;
fn discover(&self) -> anyhow::Result<Vec<SessionRef>>;
fn parse(&self, r: &SessionRef) -> anyhow::Result<Session>;
}
pub fn all() -> Vec<Box<dyn Adapter>> {
vec![
Box::new(claude_code::ClaudeCode),
Box::new(codex::Codex),
Box::new(gemini::Gemini),
Box::new(copilot::Copilot),
Box::new(cursor::Cursor),
]
}
pub fn by_id(id: &str) -> Result<Box<dyn Adapter>, CoreError> {
all()
.into_iter()
.find(|a| a.id() == id)
.ok_or_else(|| CoreError::UnknownAgent {
requested: id.to_string(),
known: all().iter().map(|a| a.id()).collect::<Vec<_>>().join(", "),
})
}
pub fn auto_detect() -> Option<Box<dyn Adapter>> {
all().into_iter().find(|a| a.detect())
}