Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions codex-rs/tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ impl App {
skip_world_writable_scan_once: false,
};

// On startup, if Auto mode (workspace-write) or ReadOnly is active, warn about world-writable dirs on Windows.
// 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()
Expand Down Expand Up @@ -546,7 +546,7 @@ impl App {
AppEvent::OpenWindowsSandboxEnablePrompt { preset } => {
self.chat_widget.open_windows_sandbox_enable_prompt(preset);
}
AppEvent::EnableWindowsSandboxForAuto { preset } => {
AppEvent::EnableWindowsSandboxForAgentMode { preset } => {
#[cfg(target_os = "windows")]
{
let profile = self.active_profile.as_deref();
Expand Down Expand Up @@ -587,8 +587,7 @@ impl App {
self.app_event_tx
.send(AppEvent::UpdateSandboxPolicy(preset.sandbox.clone()));
self.chat_widget.add_info_message(
"Enabled the Windows sandbox feature and switched to Auto mode."
.to_string(),
"Enabled experimental Windows sandbox.".to_string(),
None,
);
}
Expand Down Expand Up @@ -732,7 +731,7 @@ impl App {
"failed to persist world-writable warning acknowledgement"
);
self.chat_widget.add_error_message(format!(
"Failed to save Auto mode warning preference: {err}"
"Failed to save Agent mode warning preference: {err}"
));
}
}
Expand Down
6 changes: 3 additions & 3 deletions codex-rs/tui/src/app_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ pub(crate) enum AppEvent {
failed_scan: bool,
},

/// Prompt to enable the Windows sandbox feature before using Auto mode.
/// Prompt to enable the Windows sandbox feature before using Agent mode.
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
OpenWindowsSandboxEnablePrompt {
preset: ApprovalPreset,
},

/// Enable the Windows sandbox feature and switch to Auto mode.
/// Enable the Windows sandbox feature and switch to Agent mode.
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
EnableWindowsSandboxForAuto {
EnableWindowsSandboxForAgentMode {
preset: ApprovalPreset,
},

Expand Down
92 changes: 41 additions & 51 deletions codex-rs/tui/src/chatwidget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2169,11 +2169,6 @@ impl ChatWidget {
let current_sandbox = self.config.sandbox_policy.clone();
let mut items: Vec<SelectionItem> = Vec::new();
let presets: Vec<ApprovalPreset> = builtin_approval_presets();
#[cfg(target_os = "windows")]
let forced_windows_read_only = self.config.forced_auto_mode_downgraded_on_windows
&& codex_core::get_platform_sandbox().is_none();
#[cfg(not(target_os = "windows"))]
let forced_windows_read_only = false;
for preset in presets.into_iter() {
let is_current =
current_approval == preset.approval && current_sandbox == preset.sandbox;
Expand Down Expand Up @@ -2237,14 +2232,7 @@ impl ChatWidget {
}

self.bottom_pane.show_selection_view(SelectionViewParams {
title: Some(
if forced_windows_read_only {
"Select approval mode (Codex changed your permissions to Read Only because the Windows sandbox is off)"
.to_string()
} else {
"Select Approval Mode".to_string()
},
),
title: Some("Select Approval Mode".to_string()),
footer_hint: Some(standard_popup_hint_line()),
items,
header: Box::new(()),
Expand Down Expand Up @@ -2367,11 +2355,15 @@ impl ChatWidget {
None => (None, None),
};
let mut header_children: Vec<Box<dyn Renderable>> = Vec::new();
let mode_label = match self.config.sandbox_policy {
SandboxPolicy::WorkspaceWrite { .. } => "Auto mode",
let describe_policy = |policy: &SandboxPolicy| match policy {
SandboxPolicy::WorkspaceWrite { .. } => "Agent mode",
SandboxPolicy::ReadOnly => "Read-Only mode",
_ => "Auto mode",
_ => "Agent mode",
};
let mode_label = preset
.as_ref()
.map(|p| describe_policy(&p.sandbox))
.unwrap_or_else(|| describe_policy(&self.config.sandbox_policy));
let info_line = if failed_scan {
Line::from(vec![
"We couldn't complete the world-writable scan, so protections cannot be verified. "
Expand All @@ -2381,11 +2373,8 @@ impl ChatWidget {
])
} else {
Line::from(vec![
"Some important directories on this system are world-writable. ".into(),
format!(
"The Windows sandbox cannot protect writes to these locations in {mode_label}."
)
.fg(Color::Red),
"The Windows sandbox cannot protect writes to folders that are writable by Everyone.".into(),
" Consider removing write access for Everyone from the following folders:".into(),
])
};
header_children.push(Box::new(
Expand All @@ -2395,7 +2384,6 @@ impl ChatWidget {
if !sample_paths.is_empty() {
// Show up to three examples and optionally an "and X more" line.
let mut lines: Vec<Line> = Vec::new();
lines.push(Line::from("Examples:").bold());
lines.push(Line::from(""));
for p in &sample_paths {
lines.push(Line::from(format!(" - {p}")));
Expand Down Expand Up @@ -2470,37 +2458,39 @@ impl ChatWidget {
use ratatui_macros::line;

let mut header = ColumnRenderable::new();
header.push(line![
"Auto mode requires the experimental Windows sandbox.".bold(),
" Turn it on to enable sandboxed commands on Windows."
]);
header.push(*Box::new(
Paragraph::new(vec![
line!["Agent mode on Windows uses an experimental sandbox to limit network and filesystem access.".bold()],
line![
"Learn more: https://github.com/openai/codex/blob/main/docs/sandbox.md#windows"
],
])
.wrap(Wrap { trim: false }),
));

let preset_clone = preset;
let items = vec![SelectionItem {
name: "Turn on Windows sandbox and use Auto mode".to_string(),
description: Some(
"Adds enable_experimental_windows_sandbox = true to config.toml and switches to Auto mode."
.to_string(),
),
actions: vec![Box::new(move |tx| {
tx.send(AppEvent::EnableWindowsSandboxForAuto {
preset: preset_clone.clone(),
});
})],
dismiss_on_select: true,
..Default::default()
}, SelectionItem {
name: "Go Back".to_string(),
description: Some(
"Stay on read-only or full access without enabling the sandbox feature."
.to_string(),
),
actions: vec![Box::new(|tx| {
tx.send(AppEvent::OpenApprovalsPopup);
})],
dismiss_on_select: true,
..Default::default()
}];
let items = vec![
SelectionItem {
name: "Enable experimental sandbox".to_string(),
description: None,
actions: vec![Box::new(move |tx| {
tx.send(AppEvent::EnableWindowsSandboxForAgentMode {
preset: preset_clone.clone(),
});
})],
dismiss_on_select: true,
..Default::default()
},
SelectionItem {
name: "Go back".to_string(),
description: None,
actions: vec![Box::new(|tx| {
tx.send(AppEvent::OpenApprovalsPopup);
})],
dismiss_on_select: true,
..Default::default()
},
];

self.bottom_pane.show_selection_view(SelectionViewParams {
title: None,
Expand Down
10 changes: 7 additions & 3 deletions codex-rs/tui/src/chatwidget/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1490,14 +1490,14 @@ fn windows_auto_mode_prompt_requests_enabling_sandbox_feature() {

let popup = render_bottom_popup(&chat, 120);
assert!(
popup.contains("experimental Windows sandbox"),
popup.contains("Agent mode on Windows uses an experimental sandbox"),
"expected auto mode prompt to mention enabling the sandbox feature, popup: {popup}"
);
}

#[cfg(target_os = "windows")]
#[test]
fn startup_prompts_for_windows_sandbox_when_auto_requested() {
fn startup_prompts_for_windows_sandbox_when_agent_requested() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();

set_windows_sandbox_enabled(false);
Expand All @@ -1507,7 +1507,11 @@ fn startup_prompts_for_windows_sandbox_when_auto_requested() {

let popup = render_bottom_popup(&chat, 120);
assert!(
popup.contains("Turn on Windows sandbox and use Auto mode"),
popup.contains("Agent mode on Windows uses an experimental sandbox"),
"expected startup prompt to explain sandbox: {popup}"
);
assert!(
popup.contains("Enable experimental sandbox"),
"expected startup prompt to offer enabling the sandbox: {popup}"
);

Expand Down
Loading