diff --git a/codex-rs/tui/src/app/config_persistence.rs b/codex-rs/tui/src/app/config_persistence.rs index 8d9afdf888..ec2237c97a 100644 --- a/codex-rs/tui/src/app/config_persistence.rs +++ b/codex-rs/tui/src/app/config_persistence.rs @@ -228,7 +228,6 @@ impl App { approvals_reviewer, Some(permission_profile.clone()), active_permission_profile, - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, @@ -588,12 +587,6 @@ impl App { let auto_review_preset = auto_review_mode(); let mut next_config = self.config.clone(); - let windows_sandbox_changed = updates.iter().any(|(feature, _)| { - matches!( - feature, - Feature::WindowsSandbox | Feature::WindowsSandboxElevated - ) - }); let mut approval_policy_override = None; let mut approvals_reviewer_override = None; let mut permission_profile_override = None; @@ -733,9 +726,6 @@ impl App { &feature_updates_to_apply, ) .await; - if windows_sandbox_changed { - self.propagate_windows_sandbox_turn_context(); - } } return; } @@ -803,7 +793,6 @@ impl App { approvals_reviewer_override, permission_profile_override, active_permission_profile_override, - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, @@ -820,10 +809,6 @@ impl App { } } - if windows_sandbox_changed { - self.propagate_windows_sandbox_turn_context(); - } - if let Some(label) = permissions_history_label { self.chat_widget.add_info_message( format!("Permissions updated to {label}"), @@ -1205,7 +1190,6 @@ impl App { Some(self.config.approvals_reviewer), /*permission_profile*/ None, Some(auto_review_preset.active_permission_profile), - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, @@ -1265,28 +1249,6 @@ impl App { self.chat_widget.add_error_message("Windows sandbox setup completed, but its mode was overridden by the effective configuration.".to_string()); false } - - fn propagate_windows_sandbox_turn_context(&self) { - #[cfg(target_os = "windows")] - { - let windows_sandbox_level = crate::windows_sandbox::level_from_config(&self.config); - self.app_event_tx - .send(AppEvent::CodexOp(AppCommand::override_turn_context( - /*cwd*/ None, - /*approval_policy*/ None, - /*approvals_reviewer*/ None, - /*permission_profile*/ None, - /*active_permission_profile*/ None, - Some(windows_sandbox_level), - /*model*/ None, - /*effort*/ None, - /*summary*/ None, - /*service_tier*/ None, - /*collaboration_mode*/ None, - /*personality*/ None, - ))); - } - } } pub(super) fn overridden_write_message(write_response: &ConfigWriteResponse) -> &str { diff --git a/codex-rs/tui/src/app/event_dispatch.rs b/codex-rs/tui/src/app/event_dispatch.rs index 8b6c43f5aa..c897019843 100644 --- a/codex-rs/tui/src/app/event_dispatch.rs +++ b/codex-rs/tui/src/app/event_dispatch.rs @@ -19,7 +19,7 @@ use crate::pager_overlay::TranscriptHistoryState; use crate::session_resume::cwds_differ; use codex_app_server_protocol::ThreadGoalStatus; #[cfg(target_os = "windows")] -use codex_app_server_protocol::WindowsSandboxSetupMode as WindowsSandboxModeToml; +use codex_app_server_protocol::WindowsSandboxSetupMode; pub(super) const SHUTDOWN_FIRST_EXIT_TIMEOUT: Duration = Duration::from_secs(/*secs*/ 2); @@ -838,15 +838,13 @@ impl App { approvals_reviewer, permission_profile, active_permission_profile, - windows_sandbox_level, .. } = &op && (cwd.is_some() || approval_policy.is_some() || approvals_reviewer.is_some() || permission_profile.is_some() - || active_permission_profile.is_some() - || windows_sandbox_level.is_some()) + || active_permission_profile.is_some()) && self.reject_pending_permission_change() { return Ok(AppRunControl::Continue); @@ -2043,46 +2041,17 @@ impl App { ); } let selected_mode = match mode { - WindowsSandboxEnableMode::Elevated => WindowsSandboxModeToml::Elevated, - WindowsSandboxEnableMode::Legacy => WindowsSandboxModeToml::Unelevated, + WindowsSandboxEnableMode::Elevated => WindowsSandboxSetupMode::Elevated, + WindowsSandboxEnableMode::Legacy => WindowsSandboxSetupMode::Unelevated, }; - let elevated_enabled = selected_mode == WindowsSandboxModeToml::Elevated; + let elevated_enabled = selected_mode == WindowsSandboxSetupMode::Elevated; if self .verify_windows_sandbox_mode_after_setup(app_server, selected_mode) .await { self.chat_widget.windows_sandbox_elevated_setup_complete = elevated_enabled; - if elevated_enabled { - self.config.set_windows_sandbox_enabled(/*value*/ false); - self.config - .set_windows_elevated_sandbox_enabled(/*value*/ true); - } else { - self.config.set_windows_sandbox_enabled(/*value*/ true); - self.config - .set_windows_elevated_sandbox_enabled(/*value*/ false); - } - self.chat_widget.set_windows_sandbox_mode(Some(selected_mode)); - let windows_sandbox_level = - crate::windows_sandbox::level_from_config(&self.config); if let Some(selection) = profile_selection { - self.app_event_tx.send(AppEvent::CodexOp( - AppCommand::override_turn_context( - /*cwd*/ None, - /*approval_policy*/ None, - /*approvals_reviewer*/ None, - /*permission_profile*/ None, - /*active_permission_profile*/ None, - #[cfg(target_os = "windows")] - Some(windows_sandbox_level), - /*model*/ None, - /*effort*/ None, - /*summary*/ None, - /*service_tier*/ None, - /*collaboration_mode*/ None, - /*personality*/ None, - ), - )); if self.apply_permission_profile_selection(selection).await { self.chat_widget.submit_initial_user_message_if_pending(); } @@ -2094,8 +2063,6 @@ impl App { Some(self.config.approvals_reviewer), Some(preset.permission_profile.clone()), Some(preset.active_permission_profile.clone()), - #[cfg(target_os = "windows")] - Some(windows_sandbox_level), /*model*/ None, /*effort*/ None, /*summary*/ None, diff --git a/codex-rs/tui/src/app/platform_actions.rs b/codex-rs/tui/src/app/platform_actions.rs index 2fc94fe22e..aa07479783 100644 --- a/codex-rs/tui/src/app/platform_actions.rs +++ b/codex-rs/tui/src/app/platform_actions.rs @@ -7,7 +7,7 @@ use super::*; #[cfg(all(test, not(target_os = "windows")))] use crate::app_event::WindowsSandboxEnableMode; #[cfg(target_os = "windows")] -use codex_app_server_protocol::WindowsSandboxSetupMode as WindowsSandboxModeToml; +use codex_app_server_protocol::WindowsSandboxSetupMode; #[cfg(any(target_os = "windows", test))] use codex_utils_approval_presets::ApprovalPreset; @@ -158,15 +158,9 @@ impl App { profile_selection: Option, mode: WindowsSandboxEnableMode, ) { - let (setup_mode, config_mode) = match mode { - WindowsSandboxEnableMode::Elevated => ( - codex_app_server_protocol::WindowsSandboxSetupMode::Elevated, - WindowsSandboxModeToml::Elevated, - ), - WindowsSandboxEnableMode::Legacy => ( - codex_app_server_protocol::WindowsSandboxSetupMode::Unelevated, - WindowsSandboxModeToml::Unelevated, - ), + let setup_mode = match mode { + WindowsSandboxEnableMode::Elevated => WindowsSandboxSetupMode::Elevated, + WindowsSandboxEnableMode::Legacy => WindowsSandboxSetupMode::Unelevated, }; if self.windows_sandbox.pending_setup.is_some() { if self.windows_sandbox.setup_started_at.is_none() { @@ -180,7 +174,7 @@ impl App { if !self.refresh_windows_sandbox_config(app_server).await { return; } - if !self.chat_widget.windows_sandbox_config.allows(config_mode) { + if !self.chat_widget.windows_sandbox_config.allows(setup_mode) { self.chat_widget .retain_input_after_failed_permission_selection(); self.chat_widget.add_info_message( diff --git a/codex-rs/tui/src/app/tests.rs b/codex-rs/tui/src/app/tests.rs index af1ea40e27..781f7e9690 100644 --- a/codex-rs/tui/src/app/tests.rs +++ b/codex-rs/tui/src/app/tests.rs @@ -3239,7 +3239,6 @@ default_permissions = "locked-down" approvals_reviewer: None, permission_profile: Some(app.config.permissions.permission_profile().clone()), active_permission_profile: app.config.permissions.active_permission_profile(), - windows_sandbox_level: None, model: None, effort: None, summary: None, @@ -3333,7 +3332,6 @@ async fn update_feature_flags_enabling_guardian_selects_auto_review() -> Result< approvals_reviewer: Some(auto_review.approvals_reviewer), permission_profile: Some(auto_review.permission_profile()), active_permission_profile: Some(auto_review.active_permission_profile.clone()), - windows_sandbox_level: None, model: None, effort: None, summary: None, @@ -3428,7 +3426,6 @@ async fn update_feature_flags_disabling_guardian_clears_review_policy_and_restor approvals_reviewer: Some(ApprovalsReviewer::User), permission_profile: None, active_permission_profile: None, - windows_sandbox_level: None, model: None, effort: None, summary: None, @@ -3509,7 +3506,6 @@ async fn update_feature_flags_enabling_guardian_overrides_explicit_manual_review approvals_reviewer: Some(auto_review.approvals_reviewer), permission_profile: Some(auto_review.permission_profile()), active_permission_profile: Some(auto_review.active_permission_profile.clone()), - windows_sandbox_level: None, model: None, effort: None, summary: None, @@ -3569,7 +3565,6 @@ async fn update_feature_flags_disabling_guardian_clears_manual_review_policy_wit approvals_reviewer: Some(ApprovalsReviewer::User), permission_profile: None, active_permission_profile: None, - windows_sandbox_level: None, model: None, effort: None, summary: None, @@ -8713,7 +8708,6 @@ async fn override_turn_context_sends_thread_settings_update() { Some(ActivePermissionProfile::new( codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE, )), - /*windows_sandbox_level*/ None, Some("gpt-5.4".to_string()), Some(Some(ReasoningEffortConfig::High)), /*summary*/ None, diff --git a/codex-rs/tui/src/app/thread_settings.rs b/codex-rs/tui/src/app/thread_settings.rs index 16ef4d3ddb..2a3eae013f 100644 --- a/codex-rs/tui/src/app/thread_settings.rs +++ b/codex-rs/tui/src/app/thread_settings.rs @@ -157,9 +157,6 @@ impl App { approvals_reviewer, permission_profile: _, active_permission_profile, - // TODO(anp): Support Windows sandbox updates through environment configuration; - // thread/settings/update cannot currently represent this override. - windows_sandbox_level: _, model, effort, summary, diff --git a/codex-rs/tui/src/app_command.rs b/codex-rs/tui/src/app_command.rs index 6ce89a19b8..8b470cb353 100644 --- a/codex-rs/tui/src/app_command.rs +++ b/codex-rs/tui/src/app_command.rs @@ -16,7 +16,6 @@ use codex_protocol::approvals::GuardianAssessmentEvent; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::Personality; use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig; -use codex_protocol::config_types::WindowsSandboxLevel; use codex_protocol::models::ActivePermissionProfile; use codex_protocol::models::PermissionProfile; use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig; @@ -138,7 +137,6 @@ pub(crate) enum AppCommand { approvals_reviewer: Option, permission_profile: Option, active_permission_profile: Option, - windows_sandbox_level: Option, model: Option, effort: Option>, summary: Option, @@ -255,7 +253,6 @@ impl AppCommand { approvals_reviewer: Option, permission_profile: Option, active_permission_profile: Option, - windows_sandbox_level: Option, model: Option, effort: Option>, summary: Option, @@ -269,7 +266,6 @@ impl AppCommand { approvals_reviewer, permission_profile, active_permission_profile, - windows_sandbox_level, model, effort, summary, diff --git a/codex-rs/tui/src/chatwidget/permission_popups.rs b/codex-rs/tui/src/chatwidget/permission_popups.rs index 67067ed50f..a207f2dcc9 100644 --- a/codex-rs/tui/src/chatwidget/permission_popups.rs +++ b/codex-rs/tui/src/chatwidget/permission_popups.rs @@ -274,7 +274,6 @@ impl ChatWidget { Some(approvals_reviewer), Some(permission_profile.clone()), Some(active_permission_profile.clone()), - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, diff --git a/codex-rs/tui/src/chatwidget/rate_limits.rs b/codex-rs/tui/src/chatwidget/rate_limits.rs index cd88e565aa..ca1269d22f 100644 --- a/codex-rs/tui/src/chatwidget/rate_limits.rs +++ b/codex-rs/tui/src/chatwidget/rate_limits.rs @@ -450,7 +450,6 @@ impl ChatWidget { /*approvals_reviewer*/ None, /*permission_profile*/ None, /*active_permission_profile*/ None, - /*windows_sandbox_level*/ None, Some(switch_model_for_events.clone()), Some(Some(default_effort.clone())), /*summary*/ None, diff --git a/codex-rs/tui/src/chatwidget/service_tiers.rs b/codex-rs/tui/src/chatwidget/service_tiers.rs index d898ce88f5..9e6857442c 100644 --- a/codex-rs/tui/src/chatwidget/service_tiers.rs +++ b/codex-rs/tui/src/chatwidget/service_tiers.rs @@ -113,7 +113,6 @@ impl ChatWidget { /*approvals_reviewer*/ None, /*permission_profile*/ None, /*active_permission_profile*/ None, - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, diff --git a/codex-rs/tui/src/chatwidget/settings.rs b/codex-rs/tui/src/chatwidget/settings.rs index 169c0fd1f9..2f8bf9495e 100644 --- a/codex-rs/tui/src/chatwidget/settings.rs +++ b/codex-rs/tui/src/chatwidget/settings.rs @@ -697,7 +697,6 @@ impl ChatWidget { /*approvals_reviewer*/ None, /*permission_profile*/ None, /*active_permission_profile*/ None, - /*windows_sandbox_level*/ None, /*model*/ None, /*effort*/ None, /*summary*/ None, diff --git a/codex-rs/tui/src/chatwidget/tests/permissions.rs b/codex-rs/tui/src/chatwidget/tests/permissions.rs index b5bf1f7add..68f7a1e263 100644 --- a/codex-rs/tui/src/chatwidget/tests/permissions.rs +++ b/codex-rs/tui/src/chatwidget/tests/permissions.rs @@ -1351,7 +1351,6 @@ async fn permissions_selection_sends_approvals_reviewer_in_override_turn_context active_permission_profile: Some(ActivePermissionProfile::new( BUILT_IN_PERMISSION_PROFILE_WORKSPACE, )), - windows_sandbox_level: None, model: None, effort: None, summary: None, diff --git a/codex-rs/tui/src/onboarding/onboarding_screen.rs b/codex-rs/tui/src/onboarding/onboarding_screen.rs index 6ac33ff528..7f328479e9 100644 --- a/codex-rs/tui/src/onboarding/onboarding_screen.rs +++ b/codex-rs/tui/src/onboarding/onboarding_screen.rs @@ -139,6 +139,22 @@ impl OnboardingScreen { tui.frame_requester(), local_settings.tui.animations, ))); + #[cfg(target_os = "windows")] + let show_windows_create_sandbox_hint = if show_trust_screen + && remote_project_trust.is_none() + && let Some(handle) = &app_server_request_handle + { + crate::windows_sandbox::WindowsSandboxConfig::read( + handle.clone(), + config.cwd.display().to_string(), + ) + .await + .is_ok_and(|state| state.level() == WindowsSandboxLevel::Disabled) + } else { + false + }; + #[cfg(not(target_os = "windows"))] + let show_windows_create_sandbox_hint = false; if show_login_screen { let highlighted_mode = if auth_config.is_login_method_allowed(ForcedLoginMethod::Chatgpt) { @@ -163,11 +179,6 @@ impl OnboardingScreen { tracing::warn!("skipping onboarding login step without app-server request handle"); } } - #[cfg(target_os = "windows")] - let show_windows_create_sandbox_hint = remote_project_trust.is_none() - && crate::windows_sandbox::level_from_config(&config) == WindowsSandboxLevel::Disabled; - #[cfg(not(target_os = "windows"))] - let show_windows_create_sandbox_hint = false; let highlighted = TrustDirectorySelection::Trust; if show_trust_screen { let (cwd, trust_target) = match remote_project_trust { diff --git a/codex-rs/tui/src/onboarding/snapshots/codex_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap b/codex-rs/tui/src/onboarding/snapshots/codex_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap index 85ee8bdbfa..69ee9fdb8f 100644 --- a/codex-rs/tui/src/onboarding/snapshots/codex_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap +++ b/codex-rs/tui/src/onboarding/snapshots/codex_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap @@ -13,4 +13,4 @@ expression: terminal.backend() › 1. Trust and continue 2. Quit - Press enter to continue; esc to quit + Press enter to continue and create a sandbox... diff --git a/codex-rs/tui/src/onboarding/trust_directory.rs b/codex-rs/tui/src/onboarding/trust_directory.rs index 79794a96ab..8a4bd77ff9 100644 --- a/codex-rs/tui/src/onboarding/trust_directory.rs +++ b/codex-rs/tui/src/onboarding/trust_directory.rs @@ -298,7 +298,8 @@ mod tests { #[test] fn renders_snapshot_for_git_repo() { - let widget = widget(/*error*/ None); + let mut widget = widget(/*error*/ None); + widget.show_windows_create_sandbox_hint = true; let mut terminal = Terminal::new(VT100Backend::new(/*width*/ 70, /*height*/ 14)).expect("terminal"); diff --git a/codex-rs/tui/src/windows_sandbox.rs b/codex-rs/tui/src/windows_sandbox.rs index f235792e93..95dac25053 100644 --- a/codex-rs/tui/src/windows_sandbox.rs +++ b/codex-rs/tui/src/windows_sandbox.rs @@ -1,6 +1,5 @@ //! Windows sandbox configuration, managed requirements, and executor selection for the TUI. -use crate::legacy_core::config::Config; use codex_app_server_client::AppServerRequestHandle; use codex_app_server_protocol::ClientRequest; use codex_app_server_protocol::ConfigReadResponse; @@ -8,8 +7,6 @@ use codex_app_server_protocol::ConfigRequirementsReadResponse; use codex_app_server_protocol::RequestId; use codex_app_server_protocol::WindowsSandboxImplementation; use codex_app_server_protocol::WindowsSandboxSetupMode; -use codex_config::types::WindowsSandboxModeToml; -use codex_features::Feature; use codex_protocol::config_types::WindowsSandboxLevel; use uuid::Uuid; @@ -131,21 +128,6 @@ impl WindowsSandboxConfig { } } -#[cfg_attr(not(target_os = "windows"), allow(dead_code))] -pub(crate) fn level_from_config(config: &Config) -> WindowsSandboxLevel { - match config.permissions.windows_sandbox_mode { - Some(WindowsSandboxModeToml::Elevated) => WindowsSandboxLevel::Elevated, - Some(WindowsSandboxModeToml::Unelevated) => WindowsSandboxLevel::RestrictedToken, - None if config.features.enabled(Feature::WindowsSandboxElevated) => { - WindowsSandboxLevel::Elevated - } - None if config.features.enabled(Feature::WindowsSandbox) => { - WindowsSandboxLevel::RestrictedToken - } - None => WindowsSandboxLevel::Disabled, - } -} - /// A server-local connection can still select remote executors. Missing selections are unknown. pub(crate) fn host_from_environments( environments: Option<&[codex_app_server_protocol::ThreadEnvironment]>,