1use std::path::{Path, PathBuf};
2use std::time::SystemTime;
3
4#[derive(Debug, Clone)]
6pub struct ModifiedSession {
7 pub path: PathBuf,
8 pub mtime: SystemTime,
9}
10
11pub fn find_modified_sessions(claude_dir: &Path, since: Option<SystemTime>) -> Vec<ModifiedSession> {
14 let projects_dir = claude_dir.join("projects");
15 if !projects_dir.exists() {
16 return Vec::new();
17 }
18
19 let mut results = Vec::new();
20 let pattern = format!("{}/**/*.jsonl", projects_dir.display());
21 for entry in glob::glob(&pattern).unwrap_or_else(|_| glob::glob("").unwrap()) {
22 if let Ok(path) = entry {
23 if let Ok(metadata) = std::fs::metadata(&path) {
24 if let Ok(mtime) = metadata.modified() {
25 let dominated = match since {
26 Some(since_time) => mtime > since_time,
27 None => true,
28 };
29 if dominated {
30 results.push(ModifiedSession { path, mtime });
31 }
32 }
33 }
34 }
35 }
36 results
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use tempfile::TempDir;
43 use std::fs;
44
45 #[test]
46 fn test_find_modified_sessions_detects_new_files() {
47 let dir = TempDir::new().unwrap();
48 let sessions_dir = dir.path().join("projects").join("test-project");
49 fs::create_dir_all(&sessions_dir).unwrap();
50
51 let session_file = sessions_dir.join("session1.jsonl");
52 fs::write(&session_file, "{}\n").unwrap();
53
54 let modified = find_modified_sessions(dir.path(), None);
55 assert_eq!(modified.len(), 1);
56 assert!(modified[0].path.ends_with("session1.jsonl"));
57 }
58
59 #[test]
60 fn test_find_modified_sessions_skips_unchanged() {
61 let dir = TempDir::new().unwrap();
62 let sessions_dir = dir.path().join("projects").join("test-project");
63 fs::create_dir_all(&sessions_dir).unwrap();
64
65 let session_file = sessions_dir.join("session1.jsonl");
66 fs::write(&session_file, "{}\n").unwrap();
67
68 let mtime = fs::metadata(&session_file).unwrap()
69 .modified().unwrap();
70
71 let modified = find_modified_sessions(dir.path(), Some(mtime));
72 assert_eq!(modified.len(), 0);
73 }
74}