Skip to main content

ai_session/
session_cache.rs

1//! Simple session cache for CLI persistence
2
3use crate::core::{SessionConfig, SessionId};
4use anyhow::Result;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::fs;
8use std::path::PathBuf;
9
10#[derive(Debug, Serialize, Deserialize)]
11pub struct SessionInfo {
12    pub id: SessionId,
13    pub name: Option<String>,
14    pub config: SessionConfig,
15    pub created_at: chrono::DateTime<chrono::Utc>,
16    pub pid: Option<u32>,
17}
18
19pub struct SessionCache {
20    cache_file: PathBuf,
21    sessions: HashMap<SessionId, SessionInfo>,
22}
23
24impl SessionCache {
25    pub fn new() -> Result<Self> {
26        let cache_dir = dirs::cache_dir()
27            .ok_or_else(|| anyhow::anyhow!("Could not determine cache directory"))?
28            .join("ai-session");
29
30        fs::create_dir_all(&cache_dir)?;
31
32        let cache_file = cache_dir.join("sessions.json");
33        let mut cache = Self {
34            cache_file,
35            sessions: HashMap::new(),
36        };
37
38        cache.load()?;
39        Ok(cache)
40    }
41
42    pub fn add_session(&mut self, info: SessionInfo) -> Result<()> {
43        self.sessions.insert(info.id.clone(), info);
44        self.save()
45    }
46
47    pub fn get_session(&self, id: &SessionId) -> Option<&SessionInfo> {
48        self.sessions.get(id)
49    }
50
51    pub fn list_sessions(&self) -> Vec<&SessionInfo> {
52        let mut sessions: Vec<_> = self.sessions.values().collect();
53        sessions.sort_by(|a, b| b.created_at.cmp(&a.created_at));
54        sessions
55    }
56
57    pub fn remove_session(&mut self, id: &SessionId) -> Result<()> {
58        self.sessions.remove(id);
59        self.save()
60    }
61
62    fn load(&mut self) -> Result<()> {
63        if self.cache_file.exists() {
64            let content = fs::read_to_string(&self.cache_file)?;
65            if !content.is_empty() {
66                self.sessions = serde_json::from_str(&content)?;
67            }
68        }
69        Ok(())
70    }
71
72    fn save(&self) -> Result<()> {
73        let json = serde_json::to_string_pretty(&self.sessions)?;
74        fs::write(&self.cache_file, json)?;
75        Ok(())
76    }
77}