Skip to main content

oxios_cli/
session.rs

1//! CLI session tracking.
2//!
3//! A session represents a single interactive conversation started
4//! when the user launches the CLI.
5
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use uuid::Uuid;
9
10/// An interactive CLI session.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Session {
13    /// Unique session identifier.
14    pub id: Uuid,
15    /// Optional human-readable label.
16    pub label: Option<String>,
17    /// When the session was created.
18    pub created_at: DateTime<Utc>,
19    /// When the session was last active.
20    pub last_active: DateTime<Utc>,
21    /// Number of messages exchanged in this session.
22    pub message_count: u64,
23}
24
25impl Session {
26    /// Create a new session with the current timestamp.
27    pub fn new(label: Option<String>) -> Self {
28        let now = Utc::now();
29        Self {
30            id: Uuid::new_v4(),
31            label,
32            created_at: now,
33            last_active: now,
34            message_count: 0,
35        }
36    }
37
38    /// Touch the session, updating `last_active` and incrementing the message count.
39    pub fn touch(&mut self) {
40        self.last_active = Utc::now();
41        self.message_count += 1;
42    }
43}
44
45impl std::fmt::Display for Session {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        let label = self.label.as_deref().unwrap_or("(untitled)");
48        write!(
49            f,
50            "Session {} [{}] — {} messages, created {}",
51            self.id,
52            label,
53            self.message_count,
54            self.created_at.format("%Y-%m-%d %H:%M:%S")
55        )
56    }
57}