thor-notify 0.2.0

Notification schema and inbox management for Thor
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum NotificationStatus {
    Success,
    Failure,
    Partial,
    Waiting,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Notification {
    /// Schema version
    pub version: u32,
    /// Unique identifier
    pub id: Uuid,
    /// Full path to the worktree
    pub worktree: PathBuf,
    /// Branch name
    pub branch: String,
    /// Task status
    pub status: NotificationStatus,
    /// Short summary of what was done
    pub summary: String,
    /// When the notification was created
    pub timestamp: DateTime<Utc>,
    /// Agent that created this notification
    pub agent: String,

    // Optional fields
    #[serde(skip_serializing_if = "Option::is_none")]
    pub duration_secs: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub commit: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub files_changed: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stats: Option<FileStats>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub task: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub log_file: Option<PathBuf>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub custom: Option<HashMap<String, serde_json::Value>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileStats {
    pub added: u32,
    pub removed: u32,
}

impl Notification {
    pub fn new(
        worktree: PathBuf,
        branch: String,
        status: NotificationStatus,
        summary: String,
        agent: String,
    ) -> Self {
        Self {
            version: 1,
            id: Uuid::new_v4(),
            worktree,
            branch,
            status,
            summary,
            timestamp: Utc::now(),
            agent,
            duration_secs: None,
            commit: None,
            files_changed: None,
            stats: None,
            task: None,
            log_file: None,
            tags: None,
            custom: None,
        }
    }
}