use crate::doctor::DoctorReport;
use crate::error::Result;
use crate::host::{Capabilities, Desired, Outcome, Plugin, Scope, Source};
#[cfg(feature = "claude")]
pub(crate) mod claude;
#[cfg(feature = "codex")]
pub(crate) mod codex;
#[cfg(feature = "codex")]
pub(crate) mod mcptoml;
#[cfg(feature = "amp")]
pub(crate) mod amp;
#[cfg(feature = "antigravity")]
pub(crate) mod antigravity;
#[cfg(feature = "antigravity-cli")]
pub(crate) mod antigravity_cli;
#[cfg(feature = "augment")]
pub(crate) mod augment;
#[cfg(feature = "cline")]
pub(crate) mod cline;
#[cfg(feature = "copilot-cli")]
pub(crate) mod copilot_cli;
#[cfg(feature = "crush")]
pub(crate) mod crush;
#[cfg(feature = "cursor")]
pub(crate) mod cursor;
#[cfg(feature = "devin")]
pub(crate) mod devin;
#[cfg(feature = "droid")]
pub(crate) mod droid;
#[cfg(feature = "gemini")]
pub(crate) mod gemini;
#[cfg(feature = "goose")]
pub(crate) mod goose;
#[cfg(feature = "jetbrains-copilot")]
pub(crate) mod jetbrains_copilot;
#[cfg(feature = "kilo")]
pub(crate) mod kilo;
#[cfg(feature = "kimi")]
pub(crate) mod kimi;
#[cfg(feature = "kiro")]
pub(crate) mod kiro;
#[cfg(feature = "omp")]
pub(crate) mod omp;
#[cfg(feature = "openclaw")]
pub(crate) mod openclaw;
#[cfg(feature = "opencode")]
pub(crate) mod opencode;
#[cfg(feature = "pi")]
pub(crate) mod pi;
#[cfg(feature = "qwen-code")]
pub(crate) mod qwen_code;
#[cfg(feature = "vscode-copilot")]
pub(crate) mod vscode_copilot;
#[cfg(feature = "zed")]
pub(crate) mod zed;
macro_rules! cfg_config_backends {
($item:item) => {
#[cfg(any(
feature = "codex",
feature = "opencode",
feature = "gemini",
feature = "cursor",
feature = "cline",
feature = "devin",
feature = "qwen-code",
feature = "vscode-copilot",
feature = "jetbrains-copilot",
feature = "kimi",
feature = "kiro",
feature = "zed",
feature = "omp",
feature = "openclaw",
feature = "kilo",
feature = "antigravity",
feature = "antigravity-cli",
feature = "goose",
feature = "amp",
feature = "crush",
feature = "droid",
feature = "augment",
))]
$item
};
}
#[cfg(any(feature = "claude", feature = "copilot-cli"))]
#[allow(dead_code)]
pub(crate) mod confedit;
cfg_config_backends! {
#[cfg(not(any(feature = "claude", feature = "copilot-cli")))]
#[allow(dead_code)]
pub(crate) mod confedit;
}
cfg_config_backends! {
#[allow(dead_code)]
pub(crate) mod mcpjson;
}
cfg_config_backends! {
#[allow(dead_code)]
pub(crate) mod cchooks;
}
cfg_config_backends! {
#[allow(dead_code)]
pub(crate) mod report;
}
cfg_config_backends! {
#[allow(dead_code)]
pub(crate) mod skillsdir;
}
#[cfg(any(feature = "omp", feature = "cursor"))]
pub(crate) mod ccregistry;
pub enum BackendState {
Absent,
Healthy,
Disabled,
NeedsRepair,
}
pub trait AgentBackend {
fn id(&self) -> &'static str;
fn detect(&self) -> bool;
fn capabilities(&self) -> Capabilities;
fn probe(&self, plugin: &Plugin, scope: &Scope, source: &Source) -> Result<BackendState>;
fn reconcile(&self, plugin: &Plugin, desired: &Desired, scope: &Scope) -> Result<Outcome>;
fn remove(&self, plugin: &Plugin, scope: &Scope, source: &Source) -> Result<Outcome>;
fn report(&self, plugin: &Plugin, source: &Source) -> DoctorReport;
}
pub const AGENT_IDS: &[&str] = &[
#[cfg(feature = "claude")]
"claude",
#[cfg(feature = "codex")]
"codex",
#[cfg(feature = "opencode")]
"opencode",
#[cfg(feature = "gemini")]
"gemini",
#[cfg(feature = "cursor")]
"cursor",
#[cfg(feature = "cline")]
"cline",
#[cfg(feature = "devin")]
"devin",
#[cfg(feature = "qwen-code")]
"qwen-code",
#[cfg(feature = "copilot-cli")]
"copilot-cli",
#[cfg(feature = "vscode-copilot")]
"vscode-copilot",
#[cfg(feature = "jetbrains-copilot")]
"jetbrains-copilot",
#[cfg(feature = "kimi")]
"kimi",
#[cfg(feature = "kiro")]
"kiro",
#[cfg(feature = "zed")]
"zed",
#[cfg(feature = "omp")]
"omp",
#[cfg(feature = "openclaw")]
"openclaw",
#[cfg(feature = "kilo")]
"kilo",
#[cfg(feature = "antigravity")]
"antigravity",
#[cfg(feature = "antigravity-cli")]
"antigravity-cli",
#[cfg(feature = "pi")]
"pi",
#[cfg(feature = "goose")]
"goose",
#[cfg(feature = "amp")]
"amp",
#[cfg(feature = "crush")]
"crush",
#[cfg(feature = "droid")]
"droid",
#[cfg(feature = "augment")]
"augment",
];
pub fn backend_for(id: &str) -> Option<Box<dyn AgentBackend>> {
match id {
#[cfg(feature = "claude")]
"claude" => Some(Box::new(claude::ClaudeBackend)),
#[cfg(feature = "codex")]
"codex" => Some(Box::new(codex::CodexBackend)),
#[cfg(feature = "opencode")]
"opencode" => Some(Box::new(opencode::OpencodeBackend)),
#[cfg(feature = "gemini")]
"gemini" => Some(Box::new(gemini::GeminiBackend)),
#[cfg(feature = "cursor")]
"cursor" => Some(Box::new(cursor::CursorBackend)),
#[cfg(feature = "cline")]
"cline" => Some(Box::new(cline::ClineBackend)),
#[cfg(feature = "devin")]
"devin" => Some(Box::new(devin::DevinBackend)),
#[cfg(feature = "qwen-code")]
"qwen-code" => Some(Box::new(qwen_code::QwenCodeBackend)),
#[cfg(feature = "copilot-cli")]
"copilot-cli" => Some(Box::new(copilot_cli::CopilotCliBackend)),
#[cfg(feature = "vscode-copilot")]
"vscode-copilot" => Some(Box::new(vscode_copilot::VscodeCopilotBackend)),
#[cfg(feature = "jetbrains-copilot")]
"jetbrains-copilot" => Some(Box::new(jetbrains_copilot::JetbrainsCopilotBackend)),
#[cfg(feature = "kimi")]
"kimi" => Some(Box::new(kimi::KimiBackend)),
#[cfg(feature = "kiro")]
"kiro" => Some(Box::new(kiro::KiroBackend)),
#[cfg(feature = "zed")]
"zed" => Some(Box::new(zed::ZedBackend)),
#[cfg(feature = "omp")]
"omp" => Some(Box::new(omp::OmpBackend)),
#[cfg(feature = "openclaw")]
"openclaw" => Some(Box::new(openclaw::OpenclawBackend)),
#[cfg(feature = "kilo")]
"kilo" => Some(Box::new(kilo::KiloBackend)),
#[cfg(feature = "antigravity")]
"antigravity" => Some(Box::new(antigravity::AntigravityBackend)),
#[cfg(feature = "antigravity-cli")]
"antigravity-cli" => Some(Box::new(antigravity_cli::AntigravityCliBackend)),
#[cfg(feature = "pi")]
"pi" => Some(Box::new(pi::PiBackend)),
#[cfg(feature = "goose")]
"goose" => Some(Box::new(goose::GooseBackend)),
#[cfg(feature = "amp")]
"amp" => Some(Box::new(amp::AmpBackend)),
#[cfg(feature = "crush")]
"crush" => Some(Box::new(crush::CrushBackend)),
#[cfg(feature = "droid")]
"droid" => Some(Box::new(droid::DroidBackend)),
#[cfg(feature = "augment")]
"augment" => Some(Box::new(augment::AugmentBackend)),
_ => None,
}
}