ralph/session/
persistence.rs1use std::path::{Path, PathBuf};
17
18use anyhow::{Context, Result};
19
20use crate::constants::paths::SESSION_FILENAME;
21use crate::contracts::SessionState;
22use crate::fsutil;
23use crate::git::error::git_head_commit;
24
25pub fn session_path(cache_dir: &Path) -> PathBuf {
27 cache_dir.join(SESSION_FILENAME)
28}
29
30pub fn session_exists(cache_dir: &Path) -> bool {
32 session_path(cache_dir).exists()
33}
34
35pub fn save_session(cache_dir: &Path, session: &SessionState) -> Result<()> {
37 let path = session_path(cache_dir);
38 let json = serde_json::to_string_pretty(session).context("serialize session state")?;
39 fsutil::write_atomic(&path, json.as_bytes()).context("write session file")?;
40 log::debug!("Session saved: task_id={}", session.task_id);
41 Ok(())
42}
43
44pub fn load_session(cache_dir: &Path) -> Result<Option<SessionState>> {
46 let path = session_path(cache_dir);
47 if !path.exists() {
48 return Ok(None);
49 }
50
51 let content = std::fs::read_to_string(&path).context("read session file")?;
52 let session: SessionState = serde_json::from_str(&content).context("parse session file")?;
53
54 if session.version > crate::contracts::SESSION_STATE_VERSION {
55 log::warn!(
56 "Session file version {} is newer than supported version {}. Attempting to load anyway.",
57 session.version,
58 crate::contracts::SESSION_STATE_VERSION
59 );
60 }
61
62 Ok(Some(session))
63}
64
65pub fn clear_session(cache_dir: &Path) -> Result<()> {
67 let path = session_path(cache_dir);
68 if path.exists() {
69 std::fs::remove_file(&path).context("remove session file")?;
70 log::debug!("Session cleared");
71 }
72 Ok(())
73}
74
75pub fn get_git_head_commit(repo_root: &Path) -> Option<String> {
77 git_head_commit(repo_root).ok()
78}