use std::path::{Path, PathBuf};
pub trait AgentIntegration {
fn name(&self) -> &'static str;
fn id(&self) -> &'static str;
fn install(&self, ctx: &InstallContext) -> crate::errors::Result<()>;
fn uninstall(&self, ctx: &InstallContext) -> crate::errors::Result<()>;
fn healthcheck(&self, dc: &mut DoctorCounters, ctx: &HealthcheckContext);
fn is_detected(&self, _home: &Path) -> bool {
false
}
fn has_tokensave(&self, _home: &Path) -> bool {
false
}
fn supports_local(&self) -> bool {
false
}
fn primary_config_path(&self, _home: &Path) -> Option<PathBuf> {
None
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum InstallScope {
Global,
Local { project_path: PathBuf },
}
pub struct InstallContext {
pub home: PathBuf,
pub tokensave_bin: String,
pub tool_permissions: Vec<String>,
pub scope: InstallScope,
pub force_permission_style: bool,
}
impl InstallContext {
pub fn is_local(&self) -> bool {
matches!(self.scope, InstallScope::Local { .. })
}
pub fn base_dir(&self) -> &Path {
match &self.scope {
InstallScope::Global => &self.home,
InstallScope::Local { project_path } => project_path,
}
}
}
pub struct HealthcheckContext {
pub home: PathBuf,
pub project_path: PathBuf,
}
#[derive(Default)]
pub struct DoctorCounters {
pub issues: u32,
pub warnings: u32,
}
impl DoctorCounters {
pub fn new() -> Self {
Self::default()
}
pub fn pass(&self, msg: &str) {
eprintln!(" \x1b[32m✔\x1b[0m {msg}");
}
pub fn fail(&mut self, msg: &str) {
eprintln!(" \x1b[31m✘\x1b[0m {msg}");
self.issues += 1;
}
pub fn warn(&mut self, msg: &str) {
eprintln!(" \x1b[33m!\x1b[0m {msg}");
self.warnings += 1;
}
pub fn info(&self, msg: &str) {
eprintln!(" {msg}");
}
}