use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct InstallContext {
pub repo_root: PathBuf,
pub dry_run: bool,
pub force: bool,
pub schema_version: u32,
}
#[derive(Debug, Clone)]
pub struct InstallReport {
pub agent_id: String,
pub hook_path: PathBuf,
pub settings_path: PathBuf,
pub already_installed: bool,
pub paths_written: Vec<PathBuf>,
pub preview: Option<String>,
}
#[derive(Debug, thiserror::Error)]
pub enum InstallError {
#[error("io error at {path}: {source}")]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(
"{path} exists but does not contain klasp's managed marker. \
Re-run with --force to overwrite, or remove the file manually."
)]
MarkerConflict { path: PathBuf },
#[error("could not parse {path} as JSON: {source}")]
SettingsParse {
path: PathBuf,
#[source]
source: serde_json::Error,
},
#[error("agent surface `{agent_id}` reports: {message}")]
Surface { agent_id: String, message: String },
}
pub trait AgentSurface: Send + Sync {
fn agent_id(&self) -> &'static str;
fn detect(&self, repo_root: &Path) -> bool;
fn install(&self, ctx: &InstallContext) -> Result<InstallReport, InstallError>;
fn uninstall(&self, repo_root: &Path, dry_run: bool) -> Result<Vec<PathBuf>, InstallError>;
fn render_hook_script(&self, ctx: &InstallContext) -> String;
fn hook_path(&self, repo_root: &Path) -> PathBuf;
fn settings_path(&self, repo_root: &Path) -> PathBuf;
}