mirror of
https://github.com/openai/codex.git
synced 2026-11-02 16:20:35 +00:00
Let users remember the working directory for resumed sessions (#33950)
## What changed - Add `tui.resume_cwd` with `current` and `session` modes for resume and fork flows. - Let users persist either mode directly from the working-directory prompt, while preserving one-time choices when no preference is configured. - Apply the preference consistently during startup and in-app resume, honor explicit `--cd` overrides, and reject unsupported or unavailable directory choices with a clear error. ## Testing - Cover configuration parsing and persistence, prompt behavior, startup and in-app flows, session metadata fallback, and remote workspace constraints. GitOrigin-RevId: 7bf144c4b8c55bdb868cc8a71caf397c7740451a
This commit is contained in:
1 parent
82b294c73c
commit
2895d82b5e
21 files changed
+1469
-79
No files matched your search
@@ -55,6 +55,7 @@ use codex_config::types::NotificationMethod;
|
||||
use codex_config::types::Notifications;
|
||||
use codex_config::types::OtelConfigToml;
|
||||
use codex_config::types::OtelExporterKind;
|
||||
use codex_config::types::ResumeCwdMode;
|
||||
use codex_config::types::SandboxWorkspaceWrite;
|
||||
use codex_config::types::SessionPickerViewMode;
|
||||
use codex_config::types::SkillsConfig;
|
||||
@@ -946,6 +947,7 @@ fn config_toml_deserializes_model_availability_nux() {
|
||||
pet: None,
|
||||
pet_anchor: TuiPetAnchor::Composer,
|
||||
session_picker_view: None,
|
||||
resume_cwd: None,
|
||||
keymap: TuiKeymap::default(),
|
||||
model_availability_nux: ModelAvailabilityNuxConfig {
|
||||
shown_count: HashMap::from([
|
||||
@@ -3684,6 +3686,19 @@ session_picker_view = "dense"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tui_resume_cwd_deserializes_from_toml() {
|
||||
let cfg = r#"
|
||||
[tui]
|
||||
resume_cwd = "current"
|
||||
"#;
|
||||
let parsed = toml::from_str::<ConfigToml>(cfg).expect("TOML deserialization should succeed");
|
||||
assert_eq!(
|
||||
parsed.tui.as_ref().and_then(|t| t.resume_cwd),
|
||||
Some(ResumeCwdMode::Current),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tui_pet_deserializes_from_toml() {
|
||||
let cfg = r#"
|
||||
@@ -3785,6 +3800,7 @@ fn tui_config_missing_notifications_field_defaults_to_enabled() {
|
||||
pet: None,
|
||||
pet_anchor: TuiPetAnchor::Composer,
|
||||
session_picker_view: None,
|
||||
resume_cwd: None,
|
||||
keymap: TuiKeymap::default(),
|
||||
model_availability_nux: ModelAvailabilityNuxConfig::default(),
|
||||
terminal_resize_reflow_max_rows: None,
|
||||
@@ -3967,6 +3983,35 @@ async fn runtime_config_resolves_session_picker_view_default_and_override() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn runtime_config_resolves_resume_cwd_default_and_override() {
|
||||
let cfg = Config::load_from_base_config_with_overrides(
|
||||
ConfigToml::default(),
|
||||
ConfigOverrides::default(),
|
||||
tempdir().expect("tempdir").abs(),
|
||||
)
|
||||
.await
|
||||
.expect("load default config");
|
||||
|
||||
assert_eq!(cfg.tui_resume_cwd, None);
|
||||
|
||||
let cfg = Config::load_from_base_config_with_overrides(
|
||||
ConfigToml {
|
||||
tui: Some(Tui {
|
||||
resume_cwd: Some(ResumeCwdMode::Session),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
ConfigOverrides::default(),
|
||||
tempdir().expect("tempdir").abs(),
|
||||
)
|
||||
.await
|
||||
.expect("load root override config");
|
||||
|
||||
assert_eq!(cfg.tui_resume_cwd, Some(ResumeCwdMode::Session));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_sandbox_config_parsing() {
|
||||
let sandbox_full_access = r#"
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::path_utils::write_atomically;
|
||||
use anyhow::Context;
|
||||
use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::types::McpServerConfig;
|
||||
use codex_config::types::ResumeCwdMode;
|
||||
use codex_config::types::SessionPickerViewMode;
|
||||
use codex_config::types::ToolSuggestDisabledTool;
|
||||
use codex_features::FEATURES;
|
||||
@@ -962,6 +963,14 @@ impl ConfigEditsBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_resume_cwd(mut self, mode: ResumeCwdMode) -> Self {
|
||||
self.edits.push(ConfigEdit::SetPath {
|
||||
segments: vec!["tui".to_string(), "resume_cwd".to_string()],
|
||||
value: value(mode.as_str()),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_edits<I>(mut self, edits: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = ConfigEdit>,
|
||||
|
||||
@@ -43,6 +43,7 @@ use codex_config::types::MemoriesConfig;
|
||||
use codex_config::types::ModelAvailabilityNuxConfig;
|
||||
use codex_config::types::Notice;
|
||||
use codex_config::types::OAuthCredentialsStoreMode;
|
||||
use codex_config::types::ResumeCwdMode;
|
||||
use codex_config::types::SessionPickerViewMode;
|
||||
use codex_config::types::ToolSuggestConfig;
|
||||
use codex_config::types::ToolSuggestDisabledTool;
|
||||
@@ -789,6 +790,10 @@ pub struct Config {
|
||||
/// Preferred layout for resume/fork session picker results.
|
||||
pub tui_session_picker_view: SessionPickerViewMode,
|
||||
|
||||
/// Working directory to use when resuming or forking a session.
|
||||
/// When unset, prompt if the current and session directories differ.
|
||||
pub tui_resume_cwd: Option<ResumeCwdMode>,
|
||||
|
||||
/// Terminal resize-reflow tuning knobs.
|
||||
pub terminal_resize_reflow: TerminalResizeReflowConfig,
|
||||
|
||||
@@ -4118,6 +4123,7 @@ impl Config {
|
||||
.as_ref()
|
||||
.and_then(|t| t.session_picker_view)
|
||||
.unwrap_or_default(),
|
||||
tui_resume_cwd: cfg.tui.as_ref().and_then(|t| t.resume_cwd),
|
||||
terminal_resize_reflow,
|
||||
tui_keymap: cfg
|
||||
.tui
|
||||
|
||||
Reference in new issue
Block a user