use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EventType {
SessionStart,
SessionEnd,
ProcessExec,
FileChange,
GitCommit,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Actor {
pub r#type: ActorType,
#[serde(skip_serializing_if = "Option::is_none")]
pub agent_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ActorType {
Ai,
Human,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Event {
pub event_id: String,
pub timestamp: DateTime<Utc>,
pub session_id: String,
pub r#type: EventType,
pub actor: Actor,
pub payload: Payload,
}
impl Event {
pub fn new(session_id: String, event_type: EventType, actor: Actor, payload: Payload) -> Self {
Self {
event_id: Uuid::new_v4().to_string(),
timestamp: Utc::now(),
session_id,
r#type: event_type,
actor,
payload,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Payload {
SessionStart {
cwd: String,
command: String,
},
SessionEnd {
exit_code: i32,
duration_ms: u64,
},
ProcessExec {
command: String,
args: Vec<String>,
},
FileChange {
file: String,
lines_added: usize,
lines_removed: usize,
#[serde(skip_serializing_if = "Option::is_none")]
diff: Option<String>,
},
GitCommit {
hash: String,
message: String,
},
Error {
message: String,
},
}