From ced5d77ad26b1c5de37f6afcdb70090457ee4295 Mon Sep 17 00:00:00 2001 From: Charles Cunningham Date: Thu, 29 Jan 2026 15:21:36 -0800 Subject: [PATCH] Skip cwd prompt for shared forks --- codex-rs/tui/src/lib.rs | 60 +++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index c0ec86d585..67c0e7a8b2 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -554,7 +554,7 @@ async fn run_ratatui_app( None } }; - let mut fatal_exit = |message: String| { + let fatal_exit = |tui: &mut Tui, message: String| { error!("{message}"); restore(); session_log::log_session_end(); @@ -567,10 +567,13 @@ async fn run_ratatui_app( exit_reason: ExitReason::Fatal(message), }) }; - let mut missing_session_exit = |id_str: &str, action: &str| { - fatal_exit(format!( - "No saved session found with ID {id_str}. Run `codex {action}` without an ID to choose from existing sessions." - )) + let missing_session_exit = |tui: &mut Tui, id_str: &str, action: &str| { + fatal_exit( + tui, + format!( + "No saved session found with ID {id_str}. Run `codex {action}` without an ID to choose from existing sessions." + ), + ) }; let use_fork = cli.fork_picker || cli.fork_last || cli.fork_session_id.is_some(); @@ -587,10 +590,10 @@ async fn run_ratatui_app( Some(path) => resume_picker::SessionSelection::Fork(path), None => { let Some(storage_url) = config.session_object_storage_url.as_deref() else { - return missing_session_exit(id_str, "fork"); + return missing_session_exit(&mut tui, id_str, "fork"); }; let Ok(session_id) = ThreadId::from_string(id_str) else { - return missing_session_exit(id_str, "fork"); + return missing_session_exit(&mut tui, id_str, "fork"); }; match download_rollout_if_available(storage_url, session_id, &config.codex_home) .await @@ -599,11 +602,12 @@ async fn run_ratatui_app( remote_fork_downloaded = true; resume_picker::SessionSelection::Fork(path) } - Ok(None) => return missing_session_exit(id_str, "fork"), + Ok(None) => return missing_session_exit(&mut tui, id_str, "fork"), Err(err) => { - return fatal_exit(format!( - "Failed to fetch remote session {id_str}: {err}" - )); + return fatal_exit( + &mut tui, + format!("Failed to fetch remote session {id_str}: {err}"), + ); } } } @@ -655,7 +659,7 @@ async fn run_ratatui_app( }; match path { Some(path) => resume_picker::SessionSelection::Resume(path), - None => return missing_session_exit(id_str, "resume"), + None => return missing_session_exit(&mut tui, id_str, "resume"), } } else if cli.resume_last { let provider_filter = vec![config.model_provider_id.clone()]; @@ -698,12 +702,13 @@ async fn run_ratatui_app( resume_picker::SessionSelection::StartFresh }; + let current_owner = auth_manager + .auth_cached() + .and_then(|auth| auth.get_account_email()); + if let resume_picker::SessionSelection::Resume(path) = &session_selection { match local_share_owner(path) { Ok(Some(owner)) => { - let current_owner = auth_manager - .auth_cached() - .and_then(|auth| auth.get_account_email()); if current_owner.as_deref() != Some(owner.as_str()) { let session_id = read_session_meta_line(path) .await @@ -716,14 +721,20 @@ async fn run_ratatui_app( "Use `codex fork` to select it instead.".to_string(), ), }; - return fatal_exit(format!( - "Cannot resume shared session {id_display} owned by {owner}. {fork_hint}" - )); + return fatal_exit( + &mut tui, + format!( + "Cannot resume shared session {id_display} owned by {owner}. {fork_hint}" + ), + ); } } Ok(None) => {} Err(err) => { - return fatal_exit(format!("Failed to read shared session metadata: {err}")); + return fatal_exit( + &mut tui, + format!("Failed to read shared session metadata: {err}"), + ); } } } @@ -737,7 +748,16 @@ async fn run_ratatui_app( }; let fallback_cwd = match action_and_path_if_resume_or_fork { Some((action, path)) => { - let prefer_current_cwd = remote_fork_downloaded && action == CwdPromptAction::Fork; + let shared_owner = match action { + CwdPromptAction::Fork => local_share_owner(path).ok().flatten(), + CwdPromptAction::Resume => None, + }; + let shared_by_other = shared_owner + .as_deref() + .map(|owner| current_owner.as_deref() != Some(owner)) + .unwrap_or(false); + let prefer_current_cwd = + (remote_fork_downloaded || shared_by_other) && action == CwdPromptAction::Fork; resolve_cwd_for_resume_or_fork( &mut tui, ¤t_cwd,