use serde::{Deserialize, Serialize};
use crate::agent::spec::AgentKind;
#[derive(Debug, Clone, Serialize)]
pub struct DetectedAgent {
pub kind: AgentKind,
pub binary: String,
pub version: AgentVersion,
}
#[derive(Debug, Clone, Serialize)]
pub struct AgentVersion {
pub version: Option<String>,
pub raw: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct AgentRun {
pub kind: AgentKind,
pub is_error: bool,
pub result: String,
pub raw: serde_json::Value,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ClaudeResult {
#[serde(default)]
pub result: String,
#[serde(default)]
pub is_error: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserializes_claude_result() {
let json = r#"{"type":"result","is_error":false,"result":"hello","total_cost_usd":0.01}"#;
let parsed: ClaudeResult = serde_json::from_str(json).unwrap();
assert!(!parsed.is_error);
assert_eq!(parsed.result, "hello");
}
#[test]
fn claude_result_defaults_missing_fields() {
let parsed: ClaudeResult = serde_json::from_str("{}").unwrap();
assert!(!parsed.is_error);
assert_eq!(parsed.result, "");
}
#[test]
fn agent_run_serializes_to_json() {
let run = AgentRun {
kind: AgentKind::Claude,
is_error: false,
result: "hi".into(),
raw: serde_json::json!({"result": "hi"}),
};
let serialized = serde_json::to_string(&run).unwrap();
assert!(serialized.contains("\"kind\":\"claude\""));
assert!(serialized.contains("\"result\":\"hi\""));
assert!(serialized.contains("\"is_error\":false"));
}
#[test]
fn detected_agent_serializes() {
let detected = DetectedAgent {
kind: AgentKind::Claude,
binary: "claude".into(),
version: AgentVersion {
version: Some("1.2.3".into()),
raw: "1.2.3 (Claude Code)".into(),
},
};
let serialized = serde_json::to_string(&detected).unwrap();
assert!(serialized.contains("\"binary\":\"claude\""));
assert!(serialized.contains("\"version\":\"1.2.3\""));
}
}