mirror of
https://github.com/openai/codex.git
synced 2026-11-02 00:18:52 +00:00
remove sandbox globals. (#9797)
Threads sandbox updates through OverrideTurnContext for active turn Passes computed sandbox type into safety/exec
This commit is contained in:
+50
-4
@@ -42,7 +42,6 @@ use codex_core::config::ConfigOverrides;
|
||||
use codex_core::config::edit::ConfigEdit;
|
||||
use codex_core::config::edit::ConfigEditsBuilder;
|
||||
use codex_core::config_loader::ConfigLayerStackOrdering;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_core::features::Feature;
|
||||
use codex_core::models_manager::manager::RefreshStrategy;
|
||||
use codex_core::models_manager::model_presets::HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG;
|
||||
@@ -58,9 +57,13 @@ use codex_core::protocol::SandboxPolicy;
|
||||
use codex_core::protocol::SessionSource;
|
||||
use codex_core::protocol::SkillErrorInfo;
|
||||
use codex_core::protocol::TokenUsage;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use codex_otel::OtelManager;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::config_types::Personality;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::items::TurnItem;
|
||||
use codex_protocol::openai_models::ModelPreset;
|
||||
use codex_protocol::openai_models::ModelUpgrade;
|
||||
@@ -1088,7 +1091,8 @@ impl App {
|
||||
// On startup, if Agent mode (workspace-write) or ReadOnly is active, warn about world-writable dirs on Windows.
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let should_check = codex_core::get_platform_sandbox().is_some()
|
||||
let should_check = WindowsSandboxLevel::from_config(&app.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
&& matches!(
|
||||
app.config.sandbox_policy.get(),
|
||||
codex_core::protocol::SandboxPolicy::WorkspaceWrite { .. }
|
||||
@@ -1684,9 +1688,24 @@ impl App {
|
||||
elevated_enabled,
|
||||
);
|
||||
self.chat_widget.clear_forced_auto_mode_downgrade();
|
||||
let windows_sandbox_level =
|
||||
WindowsSandboxLevel::from_config(&self.config);
|
||||
if let Some((sample_paths, extra_count, failed_scan)) =
|
||||
self.chat_widget.world_writable_warning_details()
|
||||
{
|
||||
self.app_event_tx.send(AppEvent::CodexOp(
|
||||
Op::OverrideTurnContext {
|
||||
cwd: None,
|
||||
approval_policy: None,
|
||||
sandbox_policy: None,
|
||||
windows_sandbox_level: Some(windows_sandbox_level),
|
||||
model: None,
|
||||
effort: None,
|
||||
summary: None,
|
||||
collaboration_mode: None,
|
||||
personality: None,
|
||||
},
|
||||
));
|
||||
self.app_event_tx.send(
|
||||
AppEvent::OpenWorldWritableWarningConfirmation {
|
||||
preset: Some(preset.clone()),
|
||||
@@ -1701,6 +1720,7 @@ impl App {
|
||||
cwd: None,
|
||||
approval_policy: Some(preset.approval),
|
||||
sandbox_policy: Some(preset.sandbox.clone()),
|
||||
windows_sandbox_level: Some(windows_sandbox_level),
|
||||
model: None,
|
||||
effort: None,
|
||||
summary: None,
|
||||
@@ -1839,7 +1859,8 @@ impl App {
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if !matches!(&policy, codex_core::protocol::SandboxPolicy::ReadOnly)
|
||||
|| codex_core::get_platform_sandbox().is_some()
|
||||
|| WindowsSandboxLevel::from_config(&self.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
{
|
||||
self.config.forced_auto_mode_downgraded_on_windows = false;
|
||||
}
|
||||
@@ -1861,7 +1882,8 @@ impl App {
|
||||
return Ok(AppRunControl::Continue);
|
||||
}
|
||||
|
||||
let should_check = codex_core::get_platform_sandbox().is_some()
|
||||
let should_check = WindowsSandboxLevel::from_config(&self.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
&& policy_is_workspace_write_or_ro
|
||||
&& !self.chat_widget.world_writable_warning_hidden();
|
||||
if should_check {
|
||||
@@ -1885,6 +1907,12 @@ impl App {
|
||||
if updates.is_empty() {
|
||||
return Ok(AppRunControl::Continue);
|
||||
}
|
||||
let windows_sandbox_changed = updates.iter().any(|(feature, _)| {
|
||||
matches!(
|
||||
feature,
|
||||
Feature::WindowsSandbox | Feature::WindowsSandboxElevated
|
||||
)
|
||||
});
|
||||
let mut builder = ConfigEditsBuilder::new(&self.config.codex_home)
|
||||
.with_profile(self.active_profile.as_deref());
|
||||
for (feature, enabled) in &updates {
|
||||
@@ -1910,6 +1938,24 @@ impl App {
|
||||
}
|
||||
}
|
||||
}
|
||||
if windows_sandbox_changed {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
self.app_event_tx
|
||||
.send(AppEvent::CodexOp(Op::OverrideTurnContext {
|
||||
cwd: None,
|
||||
approval_policy: None,
|
||||
sandbox_policy: None,
|
||||
windows_sandbox_level: Some(windows_sandbox_level),
|
||||
model: None,
|
||||
effort: None,
|
||||
summary: None,
|
||||
collaboration_mode: None,
|
||||
personality: None,
|
||||
}));
|
||||
}
|
||||
}
|
||||
if let Err(err) = builder.apply().await {
|
||||
tracing::error!(error = %err, "failed to persist feature flags");
|
||||
self.chat_widget.add_error_message(format!(
|
||||
|
||||
@@ -178,6 +178,9 @@ pub(crate) enum AppEvent {
|
||||
mode: WindowsSandboxEnableMode,
|
||||
},
|
||||
|
||||
/// Update the Windows sandbox feature mode without changing approval presets.
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
|
||||
/// Update the current approval policy in the running app and widget.
|
||||
UpdateAskForApprovalPolicy(AskForApproval),
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ pub(crate) struct ChatComposer {
|
||||
config: ChatComposerConfig,
|
||||
collaboration_mode_indicator: Option<CollaborationModeIndicator>,
|
||||
personality_command_enabled: bool,
|
||||
windows_degraded_sandbox_active: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -358,6 +359,7 @@ impl ChatComposer {
|
||||
config,
|
||||
collaboration_mode_indicator: None,
|
||||
personality_command_enabled: false,
|
||||
windows_degraded_sandbox_active: false,
|
||||
};
|
||||
// Apply configuration via the setter to keep side-effects centralized.
|
||||
this.set_disable_paste_burst(disable_paste_burst);
|
||||
@@ -405,6 +407,10 @@ impl ChatComposer {
|
||||
fn image_paste_enabled(&self) -> bool {
|
||||
self.config.image_paste_enabled
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn set_windows_degraded_sandbox_active(&mut self, enabled: bool) {
|
||||
self.windows_degraded_sandbox_active = enabled;
|
||||
}
|
||||
fn layout_areas(&self, area: Rect) -> [Rect; 3] {
|
||||
let footer_props = self.footer_props();
|
||||
let footer_hint_height = self
|
||||
@@ -1728,6 +1734,7 @@ impl ChatComposer {
|
||||
name,
|
||||
self.collaboration_modes_enabled,
|
||||
self.personality_command_enabled,
|
||||
self.windows_degraded_sandbox_active,
|
||||
)
|
||||
.is_some();
|
||||
let prompt_prefix = format!("{PROMPTS_CMD_PREFIX}:");
|
||||
@@ -1904,6 +1911,7 @@ impl ChatComposer {
|
||||
name,
|
||||
self.collaboration_modes_enabled,
|
||||
self.personality_command_enabled,
|
||||
self.windows_degraded_sandbox_active,
|
||||
)
|
||||
{
|
||||
self.textarea.set_text_clearing_elements("");
|
||||
@@ -1931,6 +1939,7 @@ impl ChatComposer {
|
||||
name,
|
||||
self.collaboration_modes_enabled,
|
||||
self.personality_command_enabled,
|
||||
self.windows_degraded_sandbox_active,
|
||||
)
|
||||
&& cmd == SlashCommand::Review
|
||||
{
|
||||
@@ -2391,6 +2400,7 @@ impl ChatComposer {
|
||||
name,
|
||||
self.collaboration_modes_enabled,
|
||||
self.personality_command_enabled,
|
||||
self.windows_degraded_sandbox_active,
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -2447,6 +2457,7 @@ impl ChatComposer {
|
||||
CommandPopupFlags {
|
||||
collaboration_modes_enabled,
|
||||
personality_command_enabled,
|
||||
windows_degraded_sandbox_active: self.windows_degraded_sandbox_active,
|
||||
},
|
||||
);
|
||||
command_popup.on_composer_text_change(first_line.to_string());
|
||||
|
||||
@@ -33,6 +33,7 @@ pub(crate) struct CommandPopup {
|
||||
pub(crate) struct CommandPopupFlags {
|
||||
pub(crate) collaboration_modes_enabled: bool,
|
||||
pub(crate) personality_command_enabled: bool,
|
||||
pub(crate) windows_degraded_sandbox_active: bool,
|
||||
}
|
||||
|
||||
impl CommandPopup {
|
||||
@@ -41,6 +42,7 @@ impl CommandPopup {
|
||||
let builtins = slash_commands::builtins_for_input(
|
||||
flags.collaboration_modes_enabled,
|
||||
flags.personality_command_enabled,
|
||||
flags.windows_degraded_sandbox_active,
|
||||
);
|
||||
// Exclude prompts that collide with builtin command names and sort by name.
|
||||
let exclude: HashSet<String> = builtins.iter().map(|(n, _)| (*n).to_string()).collect();
|
||||
@@ -461,6 +463,7 @@ mod tests {
|
||||
CommandPopupFlags {
|
||||
collaboration_modes_enabled: true,
|
||||
personality_command_enabled: true,
|
||||
windows_degraded_sandbox_active: false,
|
||||
},
|
||||
);
|
||||
popup.on_composer_text_change("/collab".to_string());
|
||||
@@ -478,6 +481,7 @@ mod tests {
|
||||
CommandPopupFlags {
|
||||
collaboration_modes_enabled: true,
|
||||
personality_command_enabled: false,
|
||||
windows_degraded_sandbox_active: false,
|
||||
},
|
||||
);
|
||||
popup.on_composer_text_change("/pers".to_string());
|
||||
@@ -503,6 +507,7 @@ mod tests {
|
||||
CommandPopupFlags {
|
||||
collaboration_modes_enabled: true,
|
||||
personality_command_enabled: true,
|
||||
windows_degraded_sandbox_active: false,
|
||||
},
|
||||
);
|
||||
popup.on_composer_text_change("/personality".to_string());
|
||||
|
||||
@@ -213,6 +213,12 @@ impl BottomPane {
|
||||
self.request_redraw();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn set_windows_degraded_sandbox_active(&mut self, enabled: bool) {
|
||||
self.composer.set_windows_degraded_sandbox_active(enabled);
|
||||
self.request_redraw();
|
||||
}
|
||||
|
||||
pub fn set_collaboration_mode_indicator(
|
||||
&mut self,
|
||||
indicator: Option<CollaborationModeIndicator>,
|
||||
|
||||
@@ -8,20 +8,12 @@ use codex_common::fuzzy_match::fuzzy_match;
|
||||
use crate::slash_command::SlashCommand;
|
||||
use crate::slash_command::built_in_slash_commands;
|
||||
|
||||
/// Whether the Windows degraded-sandbox elevation flow is currently allowed.
|
||||
pub(crate) fn windows_degraded_sandbox_active() -> bool {
|
||||
cfg!(target_os = "windows")
|
||||
&& codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& codex_core::get_platform_sandbox().is_some()
|
||||
&& !codex_core::is_windows_elevated_sandbox_enabled()
|
||||
}
|
||||
|
||||
/// Return the built-ins that should be visible/usable for the current input.
|
||||
pub(crate) fn builtins_for_input(
|
||||
collaboration_modes_enabled: bool,
|
||||
personality_command_enabled: bool,
|
||||
allow_elevate_sandbox: bool,
|
||||
) -> Vec<(&'static str, SlashCommand)> {
|
||||
let allow_elevate_sandbox = windows_degraded_sandbox_active();
|
||||
built_in_slash_commands()
|
||||
.into_iter()
|
||||
.filter(|(_, cmd)| allow_elevate_sandbox || *cmd != SlashCommand::ElevateSandbox)
|
||||
@@ -35,11 +27,16 @@ pub(crate) fn find_builtin_command(
|
||||
name: &str,
|
||||
collaboration_modes_enabled: bool,
|
||||
personality_command_enabled: bool,
|
||||
allow_elevate_sandbox: bool,
|
||||
) -> Option<SlashCommand> {
|
||||
builtins_for_input(collaboration_modes_enabled, personality_command_enabled)
|
||||
.into_iter()
|
||||
.find(|(command_name, _)| *command_name == name)
|
||||
.map(|(_, cmd)| cmd)
|
||||
builtins_for_input(
|
||||
collaboration_modes_enabled,
|
||||
personality_command_enabled,
|
||||
allow_elevate_sandbox,
|
||||
)
|
||||
.into_iter()
|
||||
.find(|(command_name, _)| *command_name == name)
|
||||
.map(|(_, cmd)| cmd)
|
||||
}
|
||||
|
||||
/// Whether any visible built-in fuzzily matches the provided prefix.
|
||||
@@ -47,8 +44,13 @@ pub(crate) fn has_builtin_prefix(
|
||||
name: &str,
|
||||
collaboration_modes_enabled: bool,
|
||||
personality_command_enabled: bool,
|
||||
allow_elevate_sandbox: bool,
|
||||
) -> bool {
|
||||
builtins_for_input(collaboration_modes_enabled, personality_command_enabled)
|
||||
.into_iter()
|
||||
.any(|(command_name, _)| fuzzy_match(command_name, name).is_some())
|
||||
builtins_for_input(
|
||||
collaboration_modes_enabled,
|
||||
personality_command_enabled,
|
||||
allow_elevate_sandbox,
|
||||
)
|
||||
.into_iter()
|
||||
.any(|(command_name, _)| fuzzy_match(command_name, name).is_some())
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ use codex_core::protocol::WarningEvent;
|
||||
use codex_core::protocol::WebSearchBeginEvent;
|
||||
use codex_core::protocol::WebSearchEndEvent;
|
||||
use codex_core::skills::model::SkillMetadata;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use codex_otel::OtelManager;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::account::PlanType;
|
||||
@@ -97,6 +99,8 @@ use codex_protocol::config_types::CollaborationModeMask;
|
||||
use codex_protocol::config_types::ModeKind;
|
||||
use codex_protocol::config_types::Personality;
|
||||
use codex_protocol::config_types::Settings;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::local_image_label_text;
|
||||
use codex_protocol::parse_command::ParsedCommand;
|
||||
use codex_protocol::request_user_input::RequestUserInputEvent;
|
||||
@@ -2057,6 +2061,14 @@ impl ChatWidget {
|
||||
widget.config.features.enabled(Feature::CollaborationModes),
|
||||
);
|
||||
widget.sync_personality_command_enabled();
|
||||
#[cfg(target_os = "windows")]
|
||||
widget.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&widget.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
widget.update_collaboration_mode_indicator();
|
||||
|
||||
widget
|
||||
@@ -2308,6 +2320,14 @@ impl ChatWidget {
|
||||
widget.config.features.enabled(Feature::CollaborationModes),
|
||||
);
|
||||
widget.sync_personality_command_enabled();
|
||||
#[cfg(target_os = "windows")]
|
||||
widget.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&widget.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
widget.update_collaboration_mode_indicator();
|
||||
|
||||
widget
|
||||
@@ -2563,9 +2583,9 @@ impl ChatWidget {
|
||||
SlashCommand::ElevateSandbox => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let windows_degraded_sandbox_enabled = codex_core::get_platform_sandbox()
|
||||
.is_some()
|
||||
&& !codex_core::is_windows_elevated_sandbox_enabled();
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let windows_degraded_sandbox_enabled =
|
||||
matches!(windows_sandbox_level, WindowsSandboxLevel::RestrictedToken);
|
||||
if !windows_degraded_sandbox_enabled
|
||||
|| !codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
{
|
||||
@@ -3340,6 +3360,7 @@ impl ChatWidget {
|
||||
cwd: None,
|
||||
approval_policy: None,
|
||||
sandbox_policy: None,
|
||||
windows_sandbox_level: None,
|
||||
model: Some(switch_model.clone()),
|
||||
effort: Some(Some(default_effort)),
|
||||
summary: None,
|
||||
@@ -3462,6 +3483,7 @@ impl ChatWidget {
|
||||
effort: None,
|
||||
summary: None,
|
||||
collaboration_mode: None,
|
||||
windows_sandbox_level: None,
|
||||
personality: Some(personality),
|
||||
}));
|
||||
tx.send(AppEvent::UpdatePersonality(personality));
|
||||
@@ -3731,6 +3753,7 @@ impl ChatWidget {
|
||||
cwd: None,
|
||||
approval_policy: None,
|
||||
sandbox_policy: None,
|
||||
windows_sandbox_level: None,
|
||||
model: Some(model_for_action.clone()),
|
||||
effort: Some(effort_for_action),
|
||||
summary: None,
|
||||
@@ -3904,6 +3927,7 @@ impl ChatWidget {
|
||||
cwd: None,
|
||||
approval_policy: None,
|
||||
sandbox_policy: None,
|
||||
windows_sandbox_level: None,
|
||||
model: Some(model.clone()),
|
||||
effort: Some(effort),
|
||||
summary: None,
|
||||
@@ -3944,8 +3968,10 @@ impl ChatWidget {
|
||||
let presets: Vec<ApprovalPreset> = builtin_approval_presets();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_degraded_sandbox_enabled = codex_core::get_platform_sandbox().is_some()
|
||||
&& !codex_core::is_windows_elevated_sandbox_enabled();
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_degraded_sandbox_enabled =
|
||||
matches!(windows_sandbox_level, WindowsSandboxLevel::RestrictedToken);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let windows_degraded_sandbox_enabled = false;
|
||||
|
||||
@@ -3986,7 +4012,9 @@ impl ChatWidget {
|
||||
} else if preset.id == "auto" {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
if codex_core::get_platform_sandbox().is_none() {
|
||||
if WindowsSandboxLevel::from_config(&self.config)
|
||||
== WindowsSandboxLevel::Disabled
|
||||
{
|
||||
let preset_clone = preset.clone();
|
||||
if codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& codex_core::windows_sandbox::sandbox_setup_is_complete(
|
||||
@@ -4088,6 +4116,7 @@ impl ChatWidget {
|
||||
cwd: None,
|
||||
approval_policy: Some(approval),
|
||||
sandbox_policy: Some(sandbox_clone.clone()),
|
||||
windows_sandbox_level: None,
|
||||
model: None,
|
||||
effort: None,
|
||||
summary: None,
|
||||
@@ -4591,7 +4620,7 @@ impl ChatWidget {
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn maybe_prompt_windows_sandbox_enable(&mut self) {
|
||||
if self.config.forced_auto_mode_downgraded_on_windows
|
||||
&& codex_core::get_platform_sandbox().is_none()
|
||||
&& WindowsSandboxLevel::from_config(&self.config) == WindowsSandboxLevel::Disabled
|
||||
&& let Some(preset) = builtin_approval_presets()
|
||||
.into_iter()
|
||||
.find(|preset| preset.id == "auto")
|
||||
@@ -4651,7 +4680,7 @@ impl ChatWidget {
|
||||
pub(crate) fn set_sandbox_policy(&mut self, policy: SandboxPolicy) -> ConstraintResult<()> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let should_clear_downgrade = !matches!(&policy, SandboxPolicy::ReadOnly)
|
||||
|| codex_core::get_platform_sandbox().is_some();
|
||||
|| WindowsSandboxLevel::from_config(&self.config) != WindowsSandboxLevel::Disabled;
|
||||
|
||||
self.config.sandbox_policy.set(policy)?;
|
||||
|
||||
@@ -4685,6 +4714,19 @@ impl ChatWidget {
|
||||
self.refresh_model_display();
|
||||
self.request_redraw();
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if matches!(
|
||||
feature,
|
||||
Feature::WindowsSandbox | Feature::WindowsSandboxElevated
|
||||
) {
|
||||
self.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
codex_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&self.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_full_access_warning_acknowledged(&mut self, acknowledged: bool) {
|
||||
|
||||
@@ -92,16 +92,6 @@ use tokio::sync::mpsc::error::TryRecvError;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use toml::Value as TomlValue;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn set_windows_sandbox_enabled(enabled: bool) {
|
||||
codex_core::set_windows_sandbox_enabled(enabled);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn set_windows_elevated_sandbox_enabled(enabled: bool) {
|
||||
codex_core::set_windows_elevated_sandbox_enabled(enabled);
|
||||
}
|
||||
|
||||
async fn test_config() -> Config {
|
||||
// Use base defaults to avoid depending on host state.
|
||||
let codex_home = std::env::temp_dir();
|
||||
@@ -3050,16 +3040,9 @@ async fn approvals_selection_popup_snapshot() {
|
||||
async fn approvals_selection_popup_snapshot_windows_degraded_sandbox() {
|
||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
|
||||
let was_sandbox_enabled = codex_core::get_platform_sandbox().is_some();
|
||||
let was_elevated_enabled = codex_core::is_windows_elevated_sandbox_enabled();
|
||||
|
||||
chat.config.notices.hide_full_access_warning = None;
|
||||
chat.config.features.enable(Feature::WindowsSandbox);
|
||||
chat.config
|
||||
.features
|
||||
.disable(Feature::WindowsSandboxElevated);
|
||||
set_windows_sandbox_enabled(true);
|
||||
set_windows_elevated_sandbox_enabled(false);
|
||||
chat.set_feature_enabled(Feature::WindowsSandbox, true);
|
||||
chat.set_feature_enabled(Feature::WindowsSandboxElevated, false);
|
||||
|
||||
chat.open_approvals_popup();
|
||||
|
||||
@@ -3067,10 +3050,6 @@ async fn approvals_selection_popup_snapshot_windows_degraded_sandbox() {
|
||||
insta::with_settings!({ snapshot_suffix => "windows_degraded" }, {
|
||||
assert_snapshot!("approvals_selection_popup", popup);
|
||||
});
|
||||
|
||||
// Avoid leaking sandbox global state into other tests.
|
||||
set_windows_sandbox_enabled(was_sandbox_enabled);
|
||||
set_windows_elevated_sandbox_enabled(was_elevated_enabled);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -3133,7 +3112,8 @@ async fn windows_auto_mode_prompt_requests_enabling_sandbox_feature() {
|
||||
async fn startup_prompts_for_windows_sandbox_when_agent_requested() {
|
||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||
|
||||
set_windows_sandbox_enabled(false);
|
||||
chat.set_feature_enabled(Feature::WindowsSandbox, false);
|
||||
chat.set_feature_enabled(Feature::WindowsSandboxElevated, false);
|
||||
chat.config.forced_auto_mode_downgraded_on_windows = true;
|
||||
|
||||
chat.maybe_prompt_windows_sandbox_enable();
|
||||
@@ -3151,8 +3131,6 @@ async fn startup_prompts_for_windows_sandbox_when_agent_requested() {
|
||||
popup.contains("Stay in"),
|
||||
"expected startup prompt to offer staying in current mode: {popup}"
|
||||
);
|
||||
|
||||
set_windows_sandbox_enabled(true);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -26,13 +26,14 @@ use codex_core::config::resolve_oss_provider;
|
||||
use codex_core::config_loader::ConfigLoadError;
|
||||
use codex_core::config_loader::format_config_error_with_source;
|
||||
use codex_core::find_thread_path_by_id_str;
|
||||
use codex_core::get_platform_sandbox;
|
||||
use codex_core::path_utils;
|
||||
use codex_core::protocol::AskForApproval;
|
||||
use codex_core::read_session_meta_line;
|
||||
use codex_core::terminal::Multiplexer;
|
||||
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use codex_protocol::config_types::AltScreenMode;
|
||||
use codex_protocol::config_types::SandboxMode;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::protocol::RolloutLine;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -816,7 +817,9 @@ async fn load_config_or_exit_with_fallback_cwd(
|
||||
/// or if the current cwd project is already trusted. If not, we need to
|
||||
/// show the trust screen.
|
||||
fn should_show_trust_screen(config: &Config) -> bool {
|
||||
if cfg!(target_os = "windows") && get_platform_sandbox().is_none() {
|
||||
if cfg!(target_os = "windows")
|
||||
&& WindowsSandboxLevel::from_config(config) == WindowsSandboxLevel::Disabled
|
||||
{
|
||||
// If the experimental sandbox is not enabled, Native Windows cannot enforce sandboxed write access; skip the trust prompt entirely.
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user