mirror of
https://github.com/openai/codex.git
synced 2026-11-10 16:44:38 +00:00
## Why TUI preferences and persistence paths belong to the local client, while thread configuration and account requirements may come from the active app server. Keeping both in the same resolved `Config` can replace live local preferences when a thread is resumed, forked, reconnected, or switched. ## What changed - Add `LocalSettings` as the TUI-owned source for UI, history, notice, and local persistence settings, and preserve it across session lifecycle transitions. - Write preference changes to the selected user config file and reload local settings from disk when changing roots. - Use the app server's account response for authentication-dependent onboarding and status UI instead of the local model-provider configuration. - Retain platform family and OS metadata reported by remote app servers. ## Testing - Cover local setting defaults, overrides, persistence destinations, reloads, and preservation across widget replacement and root switching. - Cover remote platform metadata and server-controlled authentication UI. GitOrigin-RevId: dbc2965fb1d6cbecb3f973f6133f3dcd4467b753
107 lines
3.7 KiB
Rust
107 lines
3.7 KiB
Rust
use super::*;
|
|
use crate::legacy_core::config::ConfigBuilder;
|
|
use crate::legacy_core::config::edit::ConfigEditsBuilder;
|
|
use codex_config::LoaderOverrides;
|
|
use codex_config::types::SessionPickerViewMode;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[tokio::test]
|
|
async fn local_load_preserves_defaults_and_resolved_overrides() -> anyhow::Result<()> {
|
|
for config_text in [
|
|
"",
|
|
r#"
|
|
[tui]
|
|
animations = false
|
|
show_tooltips = false
|
|
auto_recap = false
|
|
vim_mode_default = true
|
|
terminal_resize_reflow_max_rows = 0
|
|
session_picker_view = "comfortable"
|
|
[history]
|
|
persistence = "none"
|
|
max_bytes = 4096
|
|
[notice]
|
|
fast_default_opt_out = true
|
|
"#,
|
|
] {
|
|
let home = tempfile::tempdir()?;
|
|
std::fs::write(home.path().join("config.toml"), config_text)?;
|
|
let config = ConfigBuilder::default()
|
|
.codex_home(home.path().to_path_buf())
|
|
.loader_overrides(LoaderOverrides {
|
|
ignore_project_config: true,
|
|
..LoaderOverrides::without_managed_config_for_tests()
|
|
})
|
|
.cli_overrides(vec![("tui.disable_paste_burst".into(), true.into())])
|
|
.build()
|
|
.await?;
|
|
let local = LocalSettings::from(&config);
|
|
let mut expected: Tui = toml::from_str("")?;
|
|
expected.disable_paste_burst = Some(true);
|
|
expected.session_picker_view = Some(SessionPickerViewMode::Dense);
|
|
if !config_text.is_empty() {
|
|
expected.animations = false;
|
|
expected.show_tooltips = false;
|
|
expected.auto_recap = false;
|
|
expected.vim_mode_default = true;
|
|
expected.terminal_resize_reflow_max_rows = Some(0);
|
|
expected.session_picker_view = Some(SessionPickerViewMode::Comfortable);
|
|
}
|
|
assert_eq!(local.tui, expected);
|
|
assert_eq!(
|
|
local.terminal_resize_reflow(),
|
|
config.terminal_resize_reflow
|
|
);
|
|
assert_eq!(
|
|
(&local.history, &local.notices),
|
|
(&config.history, &config.notices)
|
|
);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn local_writes_preserve_selected_user_file_and_home_destinations() -> anyhow::Result<()> {
|
|
let home = tempfile::tempdir()?;
|
|
let selected = AbsolutePathBuf::from_absolute_path(home.path().join("work.config.toml"))?;
|
|
std::fs::write(&selected, "[tui]\ntheme = \"dracula\"\n")?;
|
|
let overrides = LoaderOverrides {
|
|
user_config_path: Some(selected.clone()),
|
|
user_config_profile: Some("work".parse()?),
|
|
ignore_project_config: true,
|
|
..LoaderOverrides::without_managed_config_for_tests()
|
|
};
|
|
let config = ConfigBuilder::default()
|
|
.codex_home(home.path().to_path_buf())
|
|
.loader_overrides(overrides.clone())
|
|
.build()
|
|
.await?;
|
|
let local = LocalSettings::from(&config);
|
|
assert_eq!(local.user_config_path, selected);
|
|
ConfigEditsBuilder::for_config_path(local.user_config_path.as_path())
|
|
.with_edits([crate::legacy_core::config::edit::syntax_theme_edit("nord")])
|
|
.apply()
|
|
.await?;
|
|
ConfigEditsBuilder::new(local.codex_home.as_path())
|
|
.set_session_picker_view(SessionPickerViewMode::Comfortable)
|
|
.apply()
|
|
.await?;
|
|
let reloaded = ConfigBuilder::default()
|
|
.codex_home(home.path().to_path_buf())
|
|
.loader_overrides(overrides)
|
|
.build()
|
|
.await?;
|
|
assert_eq!(
|
|
LocalSettings::from(&reloaded).tui.theme.as_deref(),
|
|
Some("nord")
|
|
);
|
|
let home_config: toml::Value =
|
|
toml::from_str(&std::fs::read_to_string(home.path().join("config.toml"))?)?;
|
|
assert_eq!(
|
|
home_config["tui"]["session_picker_view"].as_str(),
|
|
Some("comfortable")
|
|
);
|
|
assert_eq!(home_config["tui"].get("theme"), None);
|
|
Ok(())
|
|
}
|