From 938c6dd3880c3a38708e0b1d2bbe54dc2fe10683 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Tue, 3 Mar 2026 09:50:52 +0000 Subject: [PATCH] fix: db windows path (#13336) --- codex-rs/core/src/rollout/metadata.rs | 55 ++++++++++++++++++++++++++- codex-rs/core/src/state_db.rs | 2 +- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/codex-rs/core/src/rollout/metadata.rs b/codex-rs/core/src/rollout/metadata.rs index e42c67d12..0bee69b6a 100644 --- a/codex-rs/core/src/rollout/metadata.rs +++ b/codex-rs/core/src/rollout/metadata.rs @@ -2,6 +2,7 @@ use crate::config::Config; use crate::rollout; use crate::rollout::list::parse_timestamp_uuid_from_filename; use crate::rollout::recorder::RolloutRecorder; +use crate::state_db::normalize_cwd_for_state_db; use chrono::DateTime; use chrono::NaiveDateTime; use chrono::Timelike; @@ -279,6 +280,7 @@ pub(crate) async fn backfill_sessions( ); } let mut metadata = outcome.metadata; + metadata.cwd = normalize_cwd_for_state_db(&metadata.cwd); let memory_mode = outcome.memory_mode.unwrap_or_else(|| "enabled".to_string()); if rollout.archived && metadata.archived_at.is_none() { let fallback_archived_at = metadata.updated_at; @@ -728,11 +730,62 @@ mod tests { assert!(state.last_success_at.is_some()); } + #[tokio::test] + async fn backfill_sessions_normalizes_cwd_before_upsert() { + let dir = tempdir().expect("tempdir"); + let codex_home = dir.path().to_path_buf(); + let thread_uuid = Uuid::new_v4(); + let session_cwd = codex_home.join("."); + let rollout_path = write_rollout_in_sessions_with_cwd( + codex_home.as_path(), + "2026-01-27T12-34-56", + "2026-01-27T12:34:56Z", + thread_uuid, + session_cwd.clone(), + ); + + let runtime = + codex_state::StateRuntime::init(codex_home.clone(), "test-provider".to_string(), None) + .await + .expect("initialize runtime"); + + let mut config = crate::config::test_config(); + config.codex_home = codex_home.clone(); + config.model_provider_id = "test-provider".to_string(); + backfill_sessions(runtime.as_ref(), &config, None).await; + + let thread_id = ThreadId::from_string(&thread_uuid.to_string()).expect("thread id"); + let stored = runtime + .get_thread(thread_id) + .await + .expect("get thread") + .expect("thread should be backfilled"); + + assert_eq!(stored.rollout_path, rollout_path); + assert_eq!(stored.cwd, normalize_cwd_for_state_db(&session_cwd)); + } + fn write_rollout_in_sessions( codex_home: &Path, filename_ts: &str, event_ts: &str, thread_uuid: Uuid, + ) -> PathBuf { + write_rollout_in_sessions_with_cwd( + codex_home, + filename_ts, + event_ts, + thread_uuid, + codex_home.to_path_buf(), + ) + } + + fn write_rollout_in_sessions_with_cwd( + codex_home: &Path, + filename_ts: &str, + event_ts: &str, + thread_uuid: Uuid, + cwd: PathBuf, ) -> PathBuf { let id = ThreadId::from_string(&thread_uuid.to_string()).expect("thread id"); let sessions_dir = codex_home.join("sessions"); @@ -742,7 +795,7 @@ mod tests { id, forked_from_id: None, timestamp: event_ts.to_string(), - cwd: codex_home.to_path_buf(), + cwd, originator: "cli".to_string(), cli_version: "0.0.0".to_string(), source: SessionSource::default(), diff --git a/codex-rs/core/src/state_db.rs b/codex-rs/core/src/state_db.rs index fb73961f8..43641402f 100644 --- a/codex-rs/core/src/state_db.rs +++ b/codex-rs/core/src/state_db.rs @@ -157,7 +157,7 @@ fn cursor_to_anchor(cursor: Option<&Cursor>) -> Option { Some(codex_state::Anchor { ts, id }) } -fn normalize_cwd_for_state_db(cwd: &Path) -> PathBuf { +pub(crate) fn normalize_cwd_for_state_db(cwd: &Path) -> PathBuf { normalize_for_path_comparison(cwd).unwrap_or_else(|_| cwd.to_path_buf()) }