mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
add a slash command to grant sandbox read access to inaccessible directories (#11512)
There is an edge case where a directory is not readable by the sandbox. In practice, we've seen very little of it, but it can happen so this slash command unlocks users when it does. Future idea is to make this a tool that the agent knows about so it can be more integrated.
This commit is contained in:
@@ -1826,6 +1826,63 @@ impl App {
|
||||
let _ = preset;
|
||||
}
|
||||
}
|
||||
AppEvent::BeginWindowsSandboxGrantReadRoot { path } => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
self.chat_widget
|
||||
.add_to_history(history_cell::new_info_event(
|
||||
format!("Granting sandbox read access to {path} ..."),
|
||||
None,
|
||||
));
|
||||
|
||||
let policy = self.config.sandbox_policy.get().clone();
|
||||
let policy_cwd = self.config.cwd.clone();
|
||||
let command_cwd = self.config.cwd.clone();
|
||||
let env_map: std::collections::HashMap<String, String> =
|
||||
std::env::vars().collect();
|
||||
let codex_home = self.config.codex_home.clone();
|
||||
let tx = self.app_event_tx.clone();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let requested_path = PathBuf::from(path);
|
||||
let event = match codex_core::windows_sandbox_read_grants::grant_read_root_non_elevated(
|
||||
&policy,
|
||||
policy_cwd.as_path(),
|
||||
command_cwd.as_path(),
|
||||
&env_map,
|
||||
codex_home.as_path(),
|
||||
requested_path.as_path(),
|
||||
) {
|
||||
Ok(canonical_path) => AppEvent::WindowsSandboxGrantReadRootCompleted {
|
||||
path: canonical_path,
|
||||
error: None,
|
||||
},
|
||||
Err(err) => AppEvent::WindowsSandboxGrantReadRootCompleted {
|
||||
path: requested_path,
|
||||
error: Some(err.to_string()),
|
||||
},
|
||||
};
|
||||
tx.send(event);
|
||||
});
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
let _ = path;
|
||||
}
|
||||
}
|
||||
AppEvent::WindowsSandboxGrantReadRootCompleted { path, error } => match error {
|
||||
Some(err) => {
|
||||
self.chat_widget
|
||||
.add_to_history(history_cell::new_error_event(format!("Error: {err}")));
|
||||
}
|
||||
None => {
|
||||
self.chat_widget
|
||||
.add_to_history(history_cell::new_info_event(
|
||||
format!("Sandbox read access granted for {}", path.display()),
|
||||
None,
|
||||
));
|
||||
}
|
||||
},
|
||||
AppEvent::EnableWindowsSandboxForAgentMode { preset, mode } => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
|
||||
@@ -218,6 +218,19 @@ pub(crate) enum AppEvent {
|
||||
preset: ApprovalPreset,
|
||||
},
|
||||
|
||||
/// Begin a non-elevated grant of read access for an additional directory.
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
BeginWindowsSandboxGrantReadRoot {
|
||||
path: String,
|
||||
},
|
||||
|
||||
/// Result of attempting to grant read access for an additional directory.
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
WindowsSandboxGrantReadRootCompleted {
|
||||
path: PathBuf,
|
||||
error: Option<String>,
|
||||
},
|
||||
|
||||
/// Enable the Windows sandbox feature and switch to Agent mode.
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
EnableWindowsSandboxForAgentMode {
|
||||
|
||||
@@ -3342,6 +3342,11 @@ impl ChatWidget {
|
||||
// Not supported; on non-Windows this command should never be reachable.
|
||||
};
|
||||
}
|
||||
SlashCommand::SandboxReadRoot => {
|
||||
self.add_error_message(
|
||||
"Usage: /sandbox-add-read-dir <absolute-directory-path>".to_string(),
|
||||
);
|
||||
}
|
||||
SlashCommand::Experimental => {
|
||||
self.open_experimental_popup();
|
||||
}
|
||||
@@ -3544,6 +3549,18 @@ impl ChatWidget {
|
||||
});
|
||||
self.bottom_pane.drain_pending_submission_state();
|
||||
}
|
||||
SlashCommand::SandboxReadRoot if !trimmed.is_empty() => {
|
||||
let Some((prepared_args, _prepared_elements)) =
|
||||
self.bottom_pane.prepare_inline_args_submission(false)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.app_event_tx
|
||||
.send(AppEvent::BeginWindowsSandboxGrantReadRoot {
|
||||
path: prepared_args,
|
||||
});
|
||||
self.bottom_pane.drain_pending_submission_state();
|
||||
}
|
||||
_ => self.dispatch_command(cmd),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ pub enum SlashCommand {
|
||||
Permissions,
|
||||
#[strum(serialize = "setup-default-sandbox")]
|
||||
ElevateSandbox,
|
||||
#[strum(serialize = "sandbox-add-read-dir")]
|
||||
SandboxReadRoot,
|
||||
Experimental,
|
||||
Skills,
|
||||
Review,
|
||||
@@ -84,7 +86,10 @@ impl SlashCommand {
|
||||
SlashCommand::Agent => "switch the active agent thread",
|
||||
SlashCommand::Approvals => "choose what Codex is allowed to do",
|
||||
SlashCommand::Permissions => "choose what Codex is allowed to do",
|
||||
SlashCommand::ElevateSandbox => "set up default agent sandbox",
|
||||
SlashCommand::ElevateSandbox => "set up elevated agent sandbox",
|
||||
SlashCommand::SandboxReadRoot => {
|
||||
"let sandbox read a directory: /sandbox-add-read-dir <absolute_path>"
|
||||
}
|
||||
SlashCommand::Experimental => "toggle experimental features",
|
||||
SlashCommand::Mcp => "list configured MCP tools",
|
||||
SlashCommand::Apps => "manage apps",
|
||||
@@ -104,7 +109,10 @@ impl SlashCommand {
|
||||
pub fn supports_inline_args(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
SlashCommand::Review | SlashCommand::Rename | SlashCommand::Plan
|
||||
SlashCommand::Review
|
||||
| SlashCommand::Rename
|
||||
| SlashCommand::Plan
|
||||
| SlashCommand::SandboxReadRoot
|
||||
)
|
||||
}
|
||||
|
||||
@@ -122,6 +130,7 @@ impl SlashCommand {
|
||||
| SlashCommand::Approvals
|
||||
| SlashCommand::Permissions
|
||||
| SlashCommand::ElevateSandbox
|
||||
| SlashCommand::SandboxReadRoot
|
||||
| SlashCommand::Experimental
|
||||
| SlashCommand::Review
|
||||
| SlashCommand::Plan
|
||||
@@ -151,6 +160,7 @@ impl SlashCommand {
|
||||
|
||||
fn is_visible(self) -> bool {
|
||||
match self {
|
||||
SlashCommand::SandboxReadRoot => cfg!(target_os = "windows"),
|
||||
SlashCommand::Rollout | SlashCommand::TestApproval => cfg!(debug_assertions),
|
||||
_ => true,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user