Files
codex/codex-rs/cli/src/lib.rs
T
Michael Bolin e0ee491df3 cli: add -P sandbox permissions profile alias (#27054)
## Why

`codex sandbox --permissions-profile` is useful when running commands
under a named permissions profile, but the long option is cumbersome for
a debugging-oriented command. `-p` is already used for the config
profile selector, so `-P` gives the permissions profile selector a
compact, non-conflicting alias.

## What Changed

- Added `short = 'P'` to the `permissions_profile` option for the macOS,
Linux, and Windows sandbox command structs in
[`codex-rs/cli/src/lib.rs`](https://github.com/openai/codex/blob/6d9f9c5cdcaa0a156aa2dabbde259ae5e9e8bc0b/codex-rs/cli/src/lib.rs#L29-L112).
- Added parser coverage for `codex sandbox -P :workspace -- echo` in
[`codex-rs/cli/src/main.rs`](https://github.com/openai/codex/blob/6d9f9c5cdcaa0a156aa2dabbde259ae5e9e8bc0b/codex-rs/cli/src/main.rs#L2883-L2896).

## Verification

- `just test -p codex-cli` passed, including the new
`sandbox_parses_permissions_profile_short_alias` parser test.
2026-06-08 20:59:23 +00:00

143 lines
4.8 KiB
Rust

pub(crate) mod debug_sandbox;
mod exit_status;
pub(crate) mod login;
use clap::Parser;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_cli::CliConfigOverrides;
use codex_utils_cli::ProfileV2Name;
use std::path::PathBuf;
pub use debug_sandbox::run_command_under_landlock;
pub use debug_sandbox::run_command_under_seatbelt;
pub use debug_sandbox::run_command_under_windows_sandbox;
pub use login::read_access_token_from_stdin;
pub use login::read_api_key_from_stdin;
pub use login::run_login_status;
pub use login::run_login_with_access_token;
pub use login::run_login_with_api_key;
pub use login::run_login_with_chatgpt;
pub use login::run_login_with_device_code;
pub use login::run_login_with_device_code_fallback_to_browser;
pub use login::run_logout;
// These command structs share common sandbox options, but remain separate
// because each host backend has a slightly different option surface.
#[derive(Debug, Parser)]
pub struct SeatbeltCommand {
/// Named permissions profile to apply from the active configuration stack.
#[arg(long = "permissions-profile", short = 'P', value_name = "NAME")]
pub permissions_profile: Option<String>,
/// Layer $CODEX_HOME/<name>.config.toml on top of the base user config.
#[arg(long = "profile", short = 'p')]
pub config_profile: Option<ProfileV2Name>,
/// Working directory used for profile resolution and command execution.
#[arg(
short = 'C',
long = "cd",
value_name = "DIR",
requires = "permissions_profile"
)]
pub cwd: Option<PathBuf>,
/// Include managed requirements while resolving an explicit permissions profile.
#[arg(
long = "include-managed-config",
default_value_t = false,
requires = "permissions_profile"
)]
pub include_managed_config: bool,
/// Allow the sandboxed command to bind/connect AF_UNIX sockets rooted at this path. Relative paths are resolved against the current directory. Repeat to allow multiple paths.
#[arg(long = "allow-unix-socket", value_parser = parse_allow_unix_socket_path)]
pub allow_unix_sockets: Vec<AbsolutePathBuf>,
/// While the command runs, capture macOS sandbox denials via `log stream` and print them after exit
#[arg(long = "log-denials", default_value_t = false)]
pub log_denials: bool,
#[clap(skip)]
pub config_overrides: CliConfigOverrides,
/// Full command args to run under seatbelt.
#[arg(trailing_var_arg = true)]
pub command: Vec<String>,
}
fn parse_allow_unix_socket_path(raw: &str) -> Result<AbsolutePathBuf, String> {
AbsolutePathBuf::relative_to_current_dir(raw)
.map_err(|err| format!("invalid path {raw}: {err}"))
}
#[derive(Debug, Parser)]
pub struct LandlockCommand {
/// Named permissions profile to apply from the active configuration stack.
#[arg(long = "permissions-profile", short = 'P', value_name = "NAME")]
pub permissions_profile: Option<String>,
/// Layer $CODEX_HOME/<name>.config.toml on top of the base user config.
#[arg(long = "profile", short = 'p')]
pub config_profile: Option<ProfileV2Name>,
/// Working directory used for profile resolution and command execution.
#[arg(
short = 'C',
long = "cd",
value_name = "DIR",
requires = "permissions_profile"
)]
pub cwd: Option<PathBuf>,
/// Include managed requirements while resolving an explicit permissions profile.
#[arg(
long = "include-managed-config",
default_value_t = false,
requires = "permissions_profile"
)]
pub include_managed_config: bool,
#[clap(skip)]
pub config_overrides: CliConfigOverrides,
/// Full command args to run under the Linux sandbox.
#[arg(trailing_var_arg = true)]
pub command: Vec<String>,
}
#[derive(Debug, Parser)]
pub struct WindowsCommand {
/// Named permissions profile to apply from the active configuration stack.
#[arg(long = "permissions-profile", short = 'P', value_name = "NAME")]
pub permissions_profile: Option<String>,
/// Layer $CODEX_HOME/<name>.config.toml on top of the base user config.
#[arg(long = "profile", short = 'p')]
pub config_profile: Option<ProfileV2Name>,
/// Working directory used for profile resolution and command execution.
#[arg(
short = 'C',
long = "cd",
value_name = "DIR",
requires = "permissions_profile"
)]
pub cwd: Option<PathBuf>,
/// Include managed requirements while resolving an explicit permissions profile.
#[arg(
long = "include-managed-config",
default_value_t = false,
requires = "permissions_profile"
)]
pub include_managed_config: bool,
#[clap(skip)]
pub config_overrides: CliConfigOverrides,
/// Full command args to run under Windows restricted token sandbox.
#[arg(trailing_var_arg = true)]
pub command: Vec<String>,
}