use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum AdapterId {
ClaudeCode,
Codex,
Gemini,
}
impl AdapterId {
pub fn as_str(self) -> &'static str {
match self {
AdapterId::ClaudeCode => "claude-code",
AdapterId::Codex => "codex",
AdapterId::Gemini => "gemini",
}
}
pub fn display_name(self) -> &'static str {
match self {
AdapterId::ClaudeCode => "Claude Code",
AdapterId::Codex => "Codex CLI",
AdapterId::Gemini => "Gemini CLI",
}
}
pub fn all() -> &'static [AdapterId] {
&[AdapterId::ClaudeCode, AdapterId::Codex, AdapterId::Gemini]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum AuthKind {
Subscription,
ApiKey,
#[default]
Unknown,
Unauthenticated,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Capabilities {
#[serde(default)]
pub tool_use: bool,
#[serde(default)]
pub mcp: bool,
#[serde(default)]
pub hooks: bool,
#[serde(default)]
pub sessions: bool,
#[serde(default)]
pub streaming: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalAgentSpec {
pub id: String,
pub display_name: String,
pub binary_path: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(default)]
pub auth_kind: AuthKind,
pub capabilities: Capabilities,
#[serde(default)]
pub detected_at: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub health: Option<crate::health::ExternalAgentHealth>,
}