mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Remove TUI legacy Windows sandbox dependency (#27490)
## Why This is part of an ongoing attempt to eliminate the TUI's direct dependency on core features. When we moved the TUI to the app server, we left a `legacy_core` shim that re-exported some remaining core symbols for the TUI. The intent was to eventually remove all of these. In this PR, we remove the symbols related to the Windows sandbox. The change should be behavior-neutral and low risk because it's just refactoring and removal of code that is now effectively dead. When working on this PR, I noticed a big existing problem that affects mixed-platform remoting. For example, if you run the TUI on a Linux box and remote into a Windows box, the TUI logic doesn't properly handle Windows sandbox setup properly. Fixing this is beyond the scope of this PR, but I've left a TODO comment in place so we don't forget. ## What changed - Move the remaining TUI-specific sandbox level, setup, telemetry, and read-root helpers into `codex-tui`, calling `codex-windows-sandbox` directly. - Remove the Windows sandbox namespace and read-root grant re-exports from the client-side `legacy_core` facade. - Remove the dormant pre-elevation prompt fallback guarded by the permanently enabled `ELEVATED_SANDBOX_NUX_ENABLED` switch. The reachable elevated and non-elevated setup flows remain unchanged.
This commit is contained in:
committed by
GitHub
Unverified
parent
f42780109c
commit
1e5b87b4d7
@@ -77,7 +77,6 @@ pub use crate::remote::RemoteAppServerEndpoint;
|
||||
pub mod legacy_core {
|
||||
pub use codex_core::check_execpolicy_for_warnings;
|
||||
pub use codex_core::format_exec_policy_error_with_source;
|
||||
pub use codex_core::grant_read_root_non_elevated;
|
||||
|
||||
pub mod config {
|
||||
pub use codex_core::config::*;
|
||||
@@ -86,10 +85,6 @@ pub mod legacy_core {
|
||||
pub use codex_core::config::edit::*;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod windows_sandbox {
|
||||
pub use codex_core::windows_sandbox::*;
|
||||
}
|
||||
}
|
||||
|
||||
const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
|
||||
@@ -51,8 +51,6 @@ use crate::legacy_core::config::ConfigBuilder;
|
||||
use crate::legacy_core::config::ConfigOverrides;
|
||||
use crate::legacy_core::config::PermissionProfileSnapshot;
|
||||
use crate::legacy_core::config::edit::ConfigEditsBuilder;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::legacy_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use crate::model_catalog::ModelCatalog;
|
||||
use crate::model_migration::ModelMigrationOutcome;
|
||||
use crate::model_migration::migration_copy_for_models;
|
||||
@@ -1063,7 +1061,7 @@ See the Codex keymap documentation for supported actions and examples."
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let startup_permission_profile = app.config.permissions.effective_permission_profile();
|
||||
let should_check = WindowsSandboxLevel::from_config(&app.config)
|
||||
let should_check = crate::windows_sandbox::level_from_config(&app.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
&& managed_filesystem_sandbox_is_restricted(&startup_permission_profile)
|
||||
&& !app
|
||||
|
||||
@@ -964,7 +964,7 @@ impl App {
|
||||
fn propagate_windows_sandbox_turn_context(&self) {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
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,
|
||||
|
||||
@@ -949,9 +949,7 @@ impl App {
|
||||
|
||||
// If the elevated setup already ran on this machine, don't prompt for
|
||||
// elevation again - just flip the config to use the elevated path.
|
||||
if crate::legacy_core::windows_sandbox::sandbox_setup_is_complete(
|
||||
codex_home.as_path(),
|
||||
) {
|
||||
if crate::windows_sandbox::sandbox_setup_is_complete(codex_home.as_path()) {
|
||||
tx.send(AppEvent::EnableWindowsSandboxForAgentMode {
|
||||
preset,
|
||||
mode: WindowsSandboxEnableMode::Elevated,
|
||||
@@ -964,7 +962,7 @@ impl App {
|
||||
self.windows_sandbox.setup_started_at = Some(Instant::now());
|
||||
let session_telemetry = self.session_telemetry.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let result = crate::legacy_core::windows_sandbox::run_elevated_setup(
|
||||
let result = crate::windows_sandbox::run_elevated_setup(
|
||||
&permission_profile,
|
||||
workspace_roots.as_slice(),
|
||||
command_cwd.as_path(),
|
||||
@@ -988,9 +986,7 @@ impl App {
|
||||
let mut code_tag: Option<String> = None;
|
||||
let mut message_tag: Option<String> = None;
|
||||
if let Some((code, message)) =
|
||||
crate::legacy_core::windows_sandbox::elevated_setup_failure_details(
|
||||
&err,
|
||||
)
|
||||
crate::windows_sandbox::elevated_setup_failure_details(&err)
|
||||
{
|
||||
code_tag = Some(code);
|
||||
message_tag = Some(message);
|
||||
@@ -1003,7 +999,7 @@ impl App {
|
||||
tags.push(("message", message));
|
||||
}
|
||||
session_telemetry.counter(
|
||||
crate::legacy_core::windows_sandbox::elevated_setup_failure_metric_name(
|
||||
crate::windows_sandbox::elevated_setup_failure_metric_name(
|
||||
&err,
|
||||
),
|
||||
/*inc*/ 1,
|
||||
@@ -1074,12 +1070,12 @@ impl App {
|
||||
self.chat_widget.show_windows_sandbox_setup_status();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
if let Err(err) =
|
||||
crate::legacy_core::windows_sandbox::run_legacy_setup_preflight(
|
||||
codex_windows_sandbox::run_windows_sandbox_legacy_preflight(
|
||||
&permission_profile,
|
||||
workspace_roots.as_slice(),
|
||||
codex_home.as_path(),
|
||||
command_cwd.as_path(),
|
||||
&env_map,
|
||||
codex_home.as_path(),
|
||||
)
|
||||
{
|
||||
session_telemetry.counter(
|
||||
@@ -1123,7 +1119,7 @@ impl App {
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let requested_path = PathBuf::from(path);
|
||||
let event = match crate::legacy_core::grant_read_root_non_elevated(
|
||||
let event = match crate::windows_sandbox::grant_read_root_non_elevated(
|
||||
&permission_profile,
|
||||
workspace_roots.as_slice(),
|
||||
command_cwd.as_path(),
|
||||
@@ -1219,7 +1215,7 @@ impl App {
|
||||
self.config.permissions.windows_sandbox_mode,
|
||||
);
|
||||
let windows_sandbox_level =
|
||||
WindowsSandboxLevel::from_config(&self.config);
|
||||
crate::windows_sandbox::level_from_config(&self.config);
|
||||
if let Some((sample_paths, extra_count, failed_scan)) =
|
||||
self.chat_widget.world_writable_warning_details()
|
||||
{
|
||||
@@ -1562,7 +1558,7 @@ impl App {
|
||||
return Ok(AppRunControl::Continue);
|
||||
}
|
||||
|
||||
let should_check = WindowsSandboxLevel::from_config(&self.config)
|
||||
let should_check = crate::windows_sandbox::level_from_config(&self.config)
|
||||
!= WindowsSandboxLevel::Disabled
|
||||
&& permission_profile_is_managed_restricted
|
||||
&& !self.chat_widget.world_writable_warning_hidden();
|
||||
|
||||
@@ -60,8 +60,6 @@ use crate::diff_model::FileChange;
|
||||
use crate::git_action_directives::parse_assistant_markdown;
|
||||
use crate::legacy_core::config::Config;
|
||||
use crate::legacy_core::config::PermissionProfileSnapshot;
|
||||
#[cfg(any(target_os = "windows", test))]
|
||||
use crate::legacy_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use crate::mention_codec::LinkedMention;
|
||||
use crate::mention_codec::encode_history_mentions;
|
||||
use crate::model_catalog::ModelCatalog;
|
||||
@@ -265,7 +263,7 @@ use crate::app_event::AppEvent;
|
||||
use crate::app_event::ExitMode;
|
||||
use crate::app_event::PermissionProfileSelection;
|
||||
use crate::app_event::RateLimitRefreshOrigin;
|
||||
#[cfg(any(target_os = "windows", test))]
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::app_event::WindowsSandboxEnableMode;
|
||||
use crate::app_event_sender::AppEventSender;
|
||||
use crate::auto_review_denials;
|
||||
|
||||
@@ -251,13 +251,12 @@ impl ChatWidget {
|
||||
.bottom_pane
|
||||
.set_queued_message_edit_binding(widget.queued_message_edit_hint_binding);
|
||||
#[cfg(target_os = "windows")]
|
||||
widget.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&widget.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
widget
|
||||
.bottom_pane
|
||||
.set_windows_degraded_sandbox_active(matches!(
|
||||
crate::windows_sandbox::level_from_config(&widget.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
));
|
||||
widget.update_collaboration_mode_indicator();
|
||||
|
||||
widget
|
||||
|
||||
@@ -29,7 +29,7 @@ impl ChatWidget {
|
||||
let presets: Vec<ApprovalPreset> = builtin_approval_presets();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let windows_sandbox_level = crate::windows_sandbox::level_from_config(&self.config);
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_degraded_sandbox_enabled =
|
||||
matches!(windows_sandbox_level, WindowsSandboxLevel::RestrictedToken);
|
||||
@@ -37,9 +37,7 @@ impl ChatWidget {
|
||||
let windows_degraded_sandbox_enabled = false;
|
||||
|
||||
let show_elevate_sandbox_hint =
|
||||
crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& windows_degraded_sandbox_enabled
|
||||
&& presets.iter().any(|preset| preset.id == "auto");
|
||||
windows_degraded_sandbox_enabled && presets.iter().any(|preset| preset.id == "auto");
|
||||
|
||||
let guardian_disabled_reason = |enabled: bool| {
|
||||
let mut next_features = self.config.features.get().clone();
|
||||
@@ -326,13 +324,13 @@ impl ChatWidget {
|
||||
if approvals_reviewer == ApprovalsReviewer::User && preset.id == "auto" {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
if WindowsSandboxLevel::from_config(&self.config) == WindowsSandboxLevel::Disabled {
|
||||
if crate::windows_sandbox::level_from_config(&self.config)
|
||||
== WindowsSandboxLevel::Disabled
|
||||
{
|
||||
let preset = preset.clone();
|
||||
if crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& crate::legacy_core::windows_sandbox::sandbox_setup_is_complete(
|
||||
self.config.codex_home.as_path(),
|
||||
)
|
||||
{
|
||||
if crate::windows_sandbox::sandbox_setup_is_complete(
|
||||
self.config.codex_home.as_path(),
|
||||
) {
|
||||
return vec![Box::new(move |tx| {
|
||||
tx.send(AppEvent::EnableWindowsSandboxForAgentMode {
|
||||
preset: preset.clone(),
|
||||
|
||||
@@ -58,13 +58,11 @@ impl ChatWidget {
|
||||
pub(crate) fn set_windows_sandbox_mode(&mut self, mode: Option<WindowsSandboxModeToml>) {
|
||||
self.config.permissions.windows_sandbox_mode = mode;
|
||||
#[cfg(target_os = "windows")]
|
||||
self.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&self.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
self.bottom_pane
|
||||
.set_windows_degraded_sandbox_active(matches!(
|
||||
crate::windows_sandbox::level_from_config(&self.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
@@ -121,13 +119,11 @@ impl ChatWidget {
|
||||
feature,
|
||||
Feature::WindowsSandbox | Feature::WindowsSandboxElevated
|
||||
) {
|
||||
self.bottom_pane.set_windows_degraded_sandbox_active(
|
||||
crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
&& matches!(
|
||||
WindowsSandboxLevel::from_config(&self.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
),
|
||||
);
|
||||
self.bottom_pane
|
||||
.set_windows_degraded_sandbox_active(matches!(
|
||||
crate::windows_sandbox::level_from_config(&self.config),
|
||||
WindowsSandboxLevel::RestrictedToken
|
||||
));
|
||||
}
|
||||
enabled
|
||||
}
|
||||
|
||||
@@ -317,12 +317,11 @@ impl ChatWidget {
|
||||
SlashCommand::ElevateSandbox => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let windows_sandbox_level =
|
||||
crate::windows_sandbox::level_from_config(&self.config);
|
||||
let windows_degraded_sandbox_enabled =
|
||||
matches!(windows_sandbox_level, WindowsSandboxLevel::RestrictedToken);
|
||||
if !windows_degraded_sandbox_enabled
|
||||
|| !crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED
|
||||
{
|
||||
if !windows_degraded_sandbox_enabled {
|
||||
// This command should not be visible/recognized outside degraded mode,
|
||||
// but guard anyway in case something dispatches it directly.
|
||||
return;
|
||||
@@ -968,7 +967,7 @@ impl ChatWidget {
|
||||
fn builtin_command_flags(&self) -> BuiltinCommandFlags {
|
||||
#[cfg(target_os = "windows")]
|
||||
let allow_elevate_sandbox = {
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let windows_sandbox_level = crate::windows_sandbox::level_from_config(&self.config);
|
||||
matches!(windows_sandbox_level, WindowsSandboxLevel::RestrictedToken)
|
||||
};
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
||||
@@ -15,7 +15,7 @@ impl ChatWidget {
|
||||
|
||||
#[cfg(any(target_os = "windows", test))]
|
||||
pub(super) fn elevated_windows_sandbox_setup_required(&self) -> bool {
|
||||
WindowsSandboxLevel::from_config(&self.config) == WindowsSandboxLevel::Elevated
|
||||
crate::windows_sandbox::level_from_config(&self.config) == WindowsSandboxLevel::Elevated
|
||||
&& self
|
||||
.config
|
||||
.config_layer_stack
|
||||
@@ -23,9 +23,7 @@ impl ChatWidget {
|
||||
.windows_sandbox_mode
|
||||
.source
|
||||
.is_some()
|
||||
&& !crate::legacy_core::windows_sandbox::sandbox_setup_is_complete(
|
||||
self.config.codex_home.as_path(),
|
||||
)
|
||||
&& !crate::windows_sandbox::sandbox_setup_is_complete(self.config.codex_home.as_path())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -226,54 +224,6 @@ impl ChatWidget {
|
||||
) {
|
||||
use ratatui_macros::line;
|
||||
|
||||
if !crate::legacy_core::windows_sandbox::ELEVATED_SANDBOX_NUX_ENABLED {
|
||||
// Legacy flow (pre-NUX): explain the experimental sandbox and let the user enable it
|
||||
// directly (no elevation prompts).
|
||||
let mut header = ColumnRenderable::new();
|
||||
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://developers.openai.com/codex/windows"],
|
||||
])
|
||||
.wrap(Wrap { trim: false }),
|
||||
));
|
||||
|
||||
let preset_clone = preset;
|
||||
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(),
|
||||
mode: WindowsSandboxEnableMode::Legacy,
|
||||
profile_selection: profile_selection.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,
|
||||
footer_hint: Some(standard_popup_hint_line()),
|
||||
items,
|
||||
header: Box::new(header),
|
||||
..Default::default()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
self.session_telemetry.counter(
|
||||
"codex.windows_sandbox.elevated_prompt_shown",
|
||||
/*inc*/ 1,
|
||||
@@ -508,7 +458,7 @@ impl ChatWidget {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn maybe_prompt_windows_sandbox_enable(&mut self, show_now: bool) {
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let windows_sandbox_level = crate::windows_sandbox::level_from_config(&self.config);
|
||||
let setup_is_required = windows_sandbox_level == WindowsSandboxLevel::Disabled
|
||||
|| self.elevated_windows_sandbox_setup_required();
|
||||
if show_now
|
||||
|
||||
@@ -11,8 +11,6 @@ use crate::legacy_core::config::load_config_as_toml_with_cli_and_load_options;
|
||||
use crate::legacy_core::config::resolve_oss_provider;
|
||||
use crate::legacy_core::config::resolve_profile_v2_config_path;
|
||||
use crate::legacy_core::format_exec_policy_error_with_source;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::legacy_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use crate::session_resume::ResolveCwdOutcome;
|
||||
use crate::session_resume::resolve_cwd_for_resume_or_fork;
|
||||
pub use crate::startup_error::LocalStateDbStartupError;
|
||||
@@ -212,6 +210,8 @@ mod version;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
mod voice;
|
||||
mod width;
|
||||
#[cfg(any(target_os = "windows", test))]
|
||||
mod windows_sandbox;
|
||||
mod workspace_command;
|
||||
#[cfg(target_os = "linux")]
|
||||
#[allow(dead_code)]
|
||||
@@ -1741,7 +1741,7 @@ async fn run_ratatui_app(
|
||||
set_default_client_residency_requirement(config.enforce_residency.value());
|
||||
let should_show_trust_screen = should_show_trust_screen(&config);
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&config);
|
||||
let windows_sandbox_level = crate::windows_sandbox::level_from_config(&config);
|
||||
#[cfg(target_os = "windows")]
|
||||
let required_elevated_sandbox_needs_setup = windows_sandbox_level
|
||||
== WindowsSandboxLevel::Elevated
|
||||
@@ -1751,9 +1751,7 @@ async fn run_ratatui_app(
|
||||
.windows_sandbox_mode
|
||||
.source
|
||||
.is_some()
|
||||
&& !crate::legacy_core::windows_sandbox::sandbox_setup_is_complete(
|
||||
config.codex_home.as_path(),
|
||||
);
|
||||
&& !crate::windows_sandbox::sandbox_setup_is_complete(config.codex_home.as_path());
|
||||
#[cfg(target_os = "windows")]
|
||||
let should_prompt_windows_sandbox_nux_at_startup = (trust_decision_was_made
|
||||
&& windows_sandbox_level == WindowsSandboxLevel::Disabled)
|
||||
|
||||
@@ -36,8 +36,6 @@ use crate::config_update::format_config_error;
|
||||
use crate::config_update::write_trusted_project;
|
||||
use crate::key_hint::KeyBindingListExt;
|
||||
use crate::legacy_core::config::Config;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::legacy_core::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use crate::onboarding::auth::AuthModeWidget;
|
||||
use crate::onboarding::auth::SignInOption;
|
||||
use crate::onboarding::auth::SignInState;
|
||||
@@ -143,7 +141,7 @@ impl OnboardingScreen {
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
let show_windows_create_sandbox_hint =
|
||||
WindowsSandboxLevel::from_config(&config) == WindowsSandboxLevel::Disabled;
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
//! TUI-owned Windows sandbox helpers retained while setup still runs in the local client process.
|
||||
//!
|
||||
//! TODO: These helpers inspect and modify the TUI host, so they do not support
|
||||
//! cross-platform remote app servers. Move readiness and setup to the existing
|
||||
//! `windowsSandbox/*` RPCs while preserving the pending permission profile,
|
||||
//! use the server platform reported during initialization, and add a remote
|
||||
//! equivalent for read-root grants.
|
||||
|
||||
use crate::legacy_core::config::Config;
|
||||
use codex_config::types::WindowsSandboxModeToml;
|
||||
use codex_features::Feature;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
#[cfg(target_os = "windows")]
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::path::PathBuf;
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) use codex_windows_sandbox::sandbox_setup_is_complete;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub(crate) fn sandbox_setup_is_complete(_codex_home: &Path) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn run_elevated_setup(
|
||||
permission_profile: &PermissionProfile,
|
||||
workspace_roots: &[AbsolutePathBuf],
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> anyhow::Result<()> {
|
||||
let permissions = codex_windows_sandbox::ResolvedWindowsSandboxPermissions::try_from_permission_profile_for_workspace_roots(
|
||||
permission_profile,
|
||||
workspace_roots,
|
||||
)?;
|
||||
codex_windows_sandbox::run_elevated_setup(
|
||||
codex_windows_sandbox::SandboxSetupRequest {
|
||||
permissions: &permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
proxy_enforced: false,
|
||||
},
|
||||
codex_windows_sandbox::SetupRootOverrides::default(),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn elevated_setup_failure_details(err: &anyhow::Error) -> Option<(String, String)> {
|
||||
let failure = codex_windows_sandbox::extract_setup_failure(err)?;
|
||||
Some((
|
||||
failure.code.as_str().to_string(),
|
||||
codex_windows_sandbox::sanitize_setup_metric_tag_value(&failure.message),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn elevated_setup_failure_metric_name(err: &anyhow::Error) -> &'static str {
|
||||
if codex_windows_sandbox::extract_setup_failure(err).is_some_and(|failure| {
|
||||
matches!(
|
||||
failure.code,
|
||||
codex_windows_sandbox::SetupErrorCode::OrchestratorHelperLaunchCanceled
|
||||
)
|
||||
}) {
|
||||
"codex.windows_sandbox.elevated_setup_canceled"
|
||||
} else {
|
||||
"codex.windows_sandbox.elevated_setup_failure"
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) fn grant_read_root_non_elevated(
|
||||
permission_profile: &PermissionProfile,
|
||||
workspace_roots: &[AbsolutePathBuf],
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
read_root: &Path,
|
||||
) -> anyhow::Result<PathBuf> {
|
||||
if !read_root.is_absolute() {
|
||||
anyhow::bail!("path must be absolute: {}", read_root.display());
|
||||
}
|
||||
if !read_root.exists() {
|
||||
anyhow::bail!("path does not exist: {}", read_root.display());
|
||||
}
|
||||
if !read_root.is_dir() {
|
||||
anyhow::bail!("path must be a directory: {}", read_root.display());
|
||||
}
|
||||
|
||||
let canonical_root = dunce::canonicalize(read_root)?;
|
||||
codex_windows_sandbox::run_setup_refresh_with_extra_read_roots(
|
||||
permission_profile,
|
||||
workspace_roots,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
vec![canonical_root.clone()],
|
||||
/*proxy_enforced*/ false,
|
||||
)?;
|
||||
Ok(canonical_root)
|
||||
}
|
||||
Reference in New Issue
Block a user