codetether_agent/session/
listing_all.rs1use super::codex_import::discover_codex_sessions_for_directory;
2use super::listing::{SessionSummary, list_sessions_for_directory};
3use anyhow::Result;
4use std::collections::HashMap;
5use std::path::Path;
6
7pub fn list_codex_sessions_for_directory(dir: &Path) -> Result<Vec<SessionSummary>> {
8 Ok(discover_codex_sessions_for_directory(dir)?
9 .into_iter()
10 .map(|session| SessionSummary {
11 id: session.id.clone(),
12 title: Some(format!("[Codex] {}", session.title.unwrap_or(session.id))),
13 created_at: session.created_at,
14 updated_at: session.updated_at,
15 message_count: session.message_count,
16 agent: session.agent,
17 directory: session.directory,
18 })
19 .collect())
20}
21
22pub async fn list_all_sessions_for_directory(dir: &Path) -> Result<Vec<SessionSummary>> {
23 tracing::info!(dir = %dir.display(), "list_all_sessions_for_directory: starting");
24 let mut merged = HashMap::<String, SessionSummary>::new();
25
26 let native = list_sessions_for_directory(dir).await?;
27 tracing::info!(
28 native_count = native.len(),
29 "list_all_sessions_for_directory: native sessions"
30 );
31
32 for session in native {
33 merged.insert(session.id.clone(), session);
34 }
35
36 let codex = match list_codex_sessions_for_directory(dir) {
37 Ok(c) => {
38 tracing::info!(
39 codex_count = c.len(),
40 "list_all_sessions_for_directory: codex sessions"
41 );
42 c
43 }
44 Err(err) => {
45 tracing::warn!(error = %err, "list_all_sessions_for_directory: codex discovery failed");
46 Vec::new()
47 }
48 };
49
50 for session in codex {
51 match merged.get(&session.id) {
52 Some(existing) if existing.updated_at >= session.updated_at => {}
53 _ => {
54 merged.insert(session.id.clone(), session);
55 }
56 }
57 }
58
59 let mut sessions = merged.into_values().collect::<Vec<_>>();
60 sessions.sort_by(|a, b| b.updated_at.cmp(&a.updated_at));
61 tracing::info!(
62 total = sessions.len(),
63 "list_all_sessions_for_directory: done"
64 );
65 Ok(sessions)
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::path::Path;
72
73 #[tokio::test]
74 async fn test_list_sessions_real_directory() {
75 let dir = Path::new("/home/riley/A2A-Server-MCP/codetether-agent");
76 let result = list_all_sessions_for_directory(dir).await;
77 match &result {
78 Ok(sessions) => eprintln!("Found {} sessions", sessions.len()),
79 Err(err) => eprintln!("Error: {err}"),
80 }
81 assert!(
82 result.is_ok(),
83 "list_all_sessions_for_directory should not error"
84 );
85 }
86
87 #[test]
88 fn test_list_codex_sessions_real_directory() {
89 let dir = Path::new("/home/riley/A2A-Server-MCP/codetether-agent");
90 let result = list_codex_sessions_for_directory(dir);
91 match &result {
92 Ok(sessions) => eprintln!("Found {} codex sessions", sessions.len()),
93 Err(err) => eprintln!("Codex error: {err}"),
94 }
95 assert!(
96 result.is_ok(),
97 "list_codex_sessions_for_directory should not error"
98 );
99 }
100}