mirror of
https://github.com/openai/codex.git
synced 2026-05-04 13:21:54 +03:00
Fix exec inheritance of root shared flags (#18630)
Addresses #18113 Problem: Shared flags provided before the exec subcommand were parsed by the root CLI but not inherited by the exec CLI, so exec sessions could run with stale or default sandbox and model configuration. Solution: Move shared TUI and exec flags into a common option block and merge root selections into exec before dispatch, while preserving exec's global subcommand flag behavior.
This commit is contained in:
@@ -3,6 +3,7 @@ use clap::FromArgMatches;
|
||||
use clap::Parser;
|
||||
use clap::ValueEnum;
|
||||
use codex_utils_cli::CliConfigOverrides;
|
||||
use codex_utils_cli::SharedCliOptions;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@@ -15,65 +16,13 @@ pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Option<Command>,
|
||||
|
||||
/// Optional image(s) to attach to the initial prompt.
|
||||
#[arg(
|
||||
long = "image",
|
||||
short = 'i',
|
||||
value_name = "FILE",
|
||||
value_delimiter = ',',
|
||||
num_args = 1..
|
||||
)]
|
||||
pub images: Vec<PathBuf>,
|
||||
|
||||
/// Model the agent should use.
|
||||
#[arg(long, short = 'm', global = true)]
|
||||
pub model: Option<String>,
|
||||
|
||||
/// Use open-source provider.
|
||||
#[arg(long = "oss", default_value_t = false)]
|
||||
pub oss: bool,
|
||||
|
||||
/// Specify which local provider to use (lmstudio or ollama).
|
||||
/// If not specified with --oss, will use config default or show selection.
|
||||
#[arg(long = "local-provider")]
|
||||
pub oss_provider: Option<String>,
|
||||
|
||||
/// Select the sandbox policy to use when executing model-generated shell
|
||||
/// commands.
|
||||
#[arg(long = "sandbox", short = 's', value_enum)]
|
||||
pub sandbox_mode: Option<codex_utils_cli::SandboxModeCliArg>,
|
||||
|
||||
/// Configuration profile from config.toml to specify default options.
|
||||
#[arg(long = "profile", short = 'p')]
|
||||
pub config_profile: Option<String>,
|
||||
|
||||
/// Convenience alias for low-friction sandboxed automatic execution (--sandbox workspace-write).
|
||||
#[arg(long = "full-auto", default_value_t = false, global = true)]
|
||||
pub full_auto: bool,
|
||||
|
||||
/// Skip all confirmation prompts and execute commands without sandboxing.
|
||||
/// EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed.
|
||||
#[arg(
|
||||
long = "dangerously-bypass-approvals-and-sandbox",
|
||||
alias = "yolo",
|
||||
default_value_t = false,
|
||||
global = true,
|
||||
conflicts_with = "full_auto"
|
||||
)]
|
||||
pub dangerously_bypass_approvals_and_sandbox: bool,
|
||||
|
||||
/// Tell the agent to use the specified directory as its working root.
|
||||
#[clap(long = "cd", short = 'C', value_name = "DIR")]
|
||||
pub cwd: Option<PathBuf>,
|
||||
#[clap(flatten)]
|
||||
pub shared: ExecSharedCliOptions,
|
||||
|
||||
/// Allow running Codex outside a Git repository.
|
||||
#[arg(long = "skip-git-repo-check", global = true, default_value_t = false)]
|
||||
pub skip_git_repo_check: bool,
|
||||
|
||||
/// Additional directories that should be writable alongside the primary workspace.
|
||||
#[arg(long = "add-dir", value_name = "DIR", value_hint = clap::ValueHint::DirPath)]
|
||||
pub add_dir: Vec<PathBuf>,
|
||||
|
||||
/// Run without persisting session files to disk.
|
||||
#[arg(long = "ephemeral", global = true, default_value_t = false)]
|
||||
pub ephemeral: bool,
|
||||
@@ -122,6 +71,71 @@ pub struct Cli {
|
||||
pub prompt: Option<String>,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Cli {
|
||||
type Target = SharedCliOptions;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.shared.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for Cli {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.shared.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ExecSharedCliOptions(SharedCliOptions);
|
||||
|
||||
impl ExecSharedCliOptions {
|
||||
pub fn into_inner(self) -> SharedCliOptions {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ExecSharedCliOptions {
|
||||
type Target = SharedCliOptions;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for ExecSharedCliOptions {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Args for ExecSharedCliOptions {
|
||||
fn augment_args(cmd: clap::Command) -> clap::Command {
|
||||
mark_exec_global_args(SharedCliOptions::augment_args(cmd))
|
||||
}
|
||||
|
||||
fn augment_args_for_update(cmd: clap::Command) -> clap::Command {
|
||||
mark_exec_global_args(SharedCliOptions::augment_args_for_update(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromArgMatches for ExecSharedCliOptions {
|
||||
fn from_arg_matches(matches: &clap::ArgMatches) -> Result<Self, clap::Error> {
|
||||
SharedCliOptions::from_arg_matches(matches).map(Self)
|
||||
}
|
||||
|
||||
fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> {
|
||||
self.0.update_from_arg_matches(matches)
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_exec_global_args(cmd: clap::Command) -> clap::Command {
|
||||
cmd.mut_arg("model", |arg| arg.global(true))
|
||||
.mut_arg("full_auto", |arg| arg.global(true))
|
||||
.mut_arg("dangerously_bypass_approvals_and_sandbox", |arg| {
|
||||
arg.global(true)
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
pub enum Command {
|
||||
/// Resume a previous session by id or pick the most recent with --last.
|
||||
|
||||
@@ -86,6 +86,7 @@ use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_absolute_path::canonicalize_existing_preserving_symlinks;
|
||||
use codex_utils_cli::SharedCliOptions;
|
||||
use codex_utils_oss::ensure_oss_provider_ready;
|
||||
use codex_utils_oss::get_default_model_for_oss_provider;
|
||||
use event_processor_with_human_output::EventProcessorWithHumanOutput;
|
||||
@@ -219,27 +220,31 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
|
||||
|
||||
let Cli {
|
||||
command,
|
||||
images,
|
||||
model: model_cli_arg,
|
||||
oss,
|
||||
oss_provider,
|
||||
config_profile,
|
||||
full_auto,
|
||||
dangerously_bypass_approvals_and_sandbox,
|
||||
cwd,
|
||||
shared,
|
||||
skip_git_repo_check,
|
||||
add_dir,
|
||||
ephemeral,
|
||||
ignore_user_config,
|
||||
ignore_rules,
|
||||
color,
|
||||
last_message_file,
|
||||
json: json_mode,
|
||||
sandbox_mode: sandbox_mode_cli_arg,
|
||||
prompt,
|
||||
output_schema: output_schema_path,
|
||||
config_overrides,
|
||||
} = cli;
|
||||
let shared = shared.into_inner();
|
||||
let SharedCliOptions {
|
||||
images,
|
||||
model: model_cli_arg,
|
||||
oss,
|
||||
oss_provider,
|
||||
config_profile,
|
||||
sandbox_mode: sandbox_mode_cli_arg,
|
||||
full_auto,
|
||||
dangerously_bypass_approvals_and_sandbox,
|
||||
cwd,
|
||||
add_dir,
|
||||
} = shared;
|
||||
|
||||
let (_stdout_with_ansi, stderr_with_ansi) = match color {
|
||||
cli::Color::Always => (true, true),
|
||||
|
||||
Reference in New Issue
Block a user