Skip to main content

apollo/memory/
session_note.rs

1//! Session-end notes → workspace memory/YYYY-MM-DD.md
2
3use std::path::Path;
4
5pub fn daily_note_path(workspace: &Path, day: chrono::NaiveDate) -> std::path::PathBuf {
6    workspace
7        .join("memory")
8        .join(format!("{}.md", day.format("%Y-%m-%d")))
9}
10
11pub fn append_session_note(workspace: &Path, chat_id: &str, line: &str) -> std::io::Result<()> {
12    let dir = workspace.join("memory");
13    std::fs::create_dir_all(&dir)?;
14    let path = daily_note_path(workspace, chrono::Utc::now().date_naive());
15    let stamp = chrono::Utc::now().format("%H:%M");
16    let entry = format!("\n- [{stamp} UTC] chat `{chat_id}`: {line}\n");
17    use std::io::Write;
18    if path.exists() {
19        let mut f = std::fs::OpenOptions::new().append(true).open(&path)?;
20        f.write_all(entry.as_bytes())?;
21    } else {
22        let header = format!(
23            "# Session notes {}\n",
24            chrono::Utc::now().format("%Y-%m-%d")
25        );
26        std::fs::write(&path, format!("{header}{entry}"))?;
27    }
28    Ok(())
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn daily_path_format() {
37        let p = daily_note_path(
38            Path::new("/w"),
39            chrono::NaiveDate::from_ymd_opt(2026, 6, 20).unwrap(),
40        );
41        assert!(p.to_string_lossy().ends_with("2026-06-20.md"));
42    }
43}