// session.rs — Session state for ambient hooks and agent interactions // // Tracks per-session state (seen set, state directory) across hook // invocations. Created from hook JSON input or POC_SESSION_ID env var. use std::collections::HashSet; use std::fs; use std::path::PathBuf; pub struct Session { pub session_id: String, pub transcript_path: String, pub hook_event: String, pub state_dir: PathBuf, } impl Session { pub fn from_json(input: &str) -> Option { let state_dir = PathBuf::from("/tmp/claude-memory-search"); fs::create_dir_all(&state_dir).ok(); let json: serde_json::Value = serde_json::from_str(input).ok()?; let session_id = json["session_id"].as_str().unwrap_or("").to_string(); if session_id.is_empty() { return None; } let transcript_path = json["transcript_path"].as_str().unwrap_or("").to_string(); let hook_event = json["hook_event_name"].as_str().unwrap_or("").to_string(); Some(Session { session_id, transcript_path, hook_event, state_dir }) } pub fn path(&self, prefix: &str) -> PathBuf { self.state_dir.join(format!("{}-{}", prefix, self.session_id)) } /// Load from POC_SESSION_ID environment variable pub fn from_env() -> Option { let session_id = std::env::var("POC_SESSION_ID").ok()?; if session_id.is_empty() { return None; } let state_dir = PathBuf::from("/tmp/claude-memory-search"); Some(Session { session_id, transcript_path: String::new(), hook_event: String::new(), state_dir, }) } /// Get the seen set for this session pub fn seen(&self) -> HashSet { super::hippocampus::memory_search::load_seen(&self.state_dir, &self.session_id) } }