Skip to main content

codetether_agent/session/codex_import/
api.rs

1use super::super::Session;
2use super::CodexImportReport;
3use super::discover::find_codex_session_path_by_id;
4use super::meta::read_session_meta;
5use super::parse::parse_codex_session_from_path;
6use super::paths::{codex_home_dir, codex_home_dir_for_path, native_sessions_dir};
7use super::persist::persist_imported_session;
8use anyhow::{Context, Result};
9
10pub async fn import_codex_session_by_id(id: &str) -> Result<Session> {
11    let Some(codex_home) = codex_home_dir() else {
12        anyhow::bail!("Codex home directory not found");
13    };
14    let Some(path) = find_codex_session_path_by_id(&codex_home, id)? else {
15        anyhow::bail!("Codex session not found: {id}");
16    };
17    import_codex_session_path(&path).await
18}
19
20pub async fn import_codex_session_path(path: &std::path::Path) -> Result<Session> {
21    let Some(codex_home) = codex_home_dir_for_path(path) else {
22        anyhow::bail!("Could not resolve Codex home for {}", path.display());
23    };
24    let meta = read_session_meta(path)?
25        .with_context(|| format!("Missing session metadata in {}", path.display()))?;
26    let session = parse_codex_session_from_path(
27        path,
28        super::index::load_session_index(&codex_home)
29            .get(&meta.id)
30            .map(String::as_str),
31    )?;
32    let _ = persist_imported_session(session, &native_sessions_dir()?).await?;
33    Session::load(&meta.id).await
34}
35
36pub async fn import_codex_sessions_for_directory(
37    dir: &std::path::Path,
38) -> Result<CodexImportReport> {
39    let mut report = CodexImportReport::default();
40    for info in super::discover_codex_sessions_for_directory(dir)? {
41        let session = parse_codex_session_from_path(&info.path, info.title.as_deref())?;
42        match persist_imported_session(session, &native_sessions_dir()?).await? {
43            super::info::PersistOutcome::Saved => report.imported += 1,
44            super::info::PersistOutcome::Unchanged => report.skipped += 1,
45        }
46    }
47    Ok(report)
48}
49
50pub async fn load_or_import_session(id: &str) -> Result<Session> {
51    let existing = Session::load(id).await.ok();
52    if let Some(codex_home) = codex_home_dir()
53        && let Some(path) = find_codex_session_path_by_id(&codex_home, id)?
54    {
55        return import_codex_session_path(&path).await;
56    }
57    if let Some(existing) = existing {
58        Ok(existing)
59    } else {
60        import_codex_session_by_id(id).await
61    }
62}