From 881cf191d72da0edfc90cbc9fd5b3c30cb6eb9bc Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Thu, 4 Jun 2026 11:05:54 -0700 Subject: [PATCH] app-server: support -c config overrides (#26436) ## Why The standalone `codex-app-server` binary already routed a `CliConfigOverrides` value into app-server startup, but its own clap args did not expose the shared `-c/--config` option. That meant `codex-app-server -c key=value` was rejected before the existing config override path could run, unlike the main `codex` CLI. ## What Changed - Flatten `CliConfigOverrides` into `AppServerArgs` in `codex-rs/app-server/src/main.rs`. - Pass parsed overrides to `run_main_with_transport_options` instead of always using `CliConfigOverrides::default()`. - Add a binary parser test covering both `-c` and `--config` for the standalone app-server. ## Verification - `just test -p codex-app-server app_server_accepts_cli_config_overrides` The broader `just test -p codex-app-server` run was also attempted. It compiled and ran 812 tests, with 796 passing, but failed in this local sandbox on unrelated `sandbox-exec: sandbox_apply: Operation not permitted` command-exec/turn integration paths and a skills watcher timeout. --- codex-rs/app-server/src/main.rs | 10 +++++++- codex-rs/app-server/src/main_tests.rs | 37 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 codex-rs/app-server/src/main_tests.rs diff --git a/codex-rs/app-server/src/main.rs b/codex-rs/app-server/src/main.rs index 2435c532e..2412f8c3c 100644 --- a/codex-rs/app-server/src/main.rs +++ b/codex-rs/app-server/src/main.rs @@ -19,6 +19,9 @@ const DISABLE_MANAGED_CONFIG_ENV_VAR: &str = "CODEX_APP_SERVER_DISABLE_MANAGED_C #[derive(Debug, Parser)] #[command(version)] struct AppServerArgs { + #[command(flatten)] + config_overrides: CliConfigOverrides, + /// Transport endpoint URL. Supported values: `stdio://` (default), /// `unix://`, `unix://PATH`, `ws://IP:PORT`, `off`. #[arg( @@ -58,6 +61,7 @@ struct AppServerArgs { fn main() -> anyhow::Result<()> { arg0_dispatch_or_else(|arg0_paths: Arg0DispatchPaths| async move { let AppServerArgs { + config_overrides, listen, session_source, auth, @@ -84,7 +88,7 @@ fn main() -> anyhow::Result<()> { run_main_with_transport_options( arg0_paths, - CliConfigOverrides::default(), + config_overrides, loader_overrides, strict_config, /*default_analytics_enabled*/ false, @@ -123,3 +127,7 @@ fn managed_config_path_from_debug_env() -> Option { None } + +#[cfg(test)] +#[path = "main_tests.rs"] +mod tests; diff --git a/codex-rs/app-server/src/main_tests.rs b/codex-rs/app-server/src/main_tests.rs new file mode 100644 index 000000000..57d0e5217 --- /dev/null +++ b/codex-rs/app-server/src/main_tests.rs @@ -0,0 +1,37 @@ +use super::AppServerArgs; +use clap::Parser; +use pretty_assertions::assert_eq; +use toml::Value as TomlValue; + +#[test] +fn app_server_accepts_cli_config_overrides() { + let args = AppServerArgs::try_parse_from([ + "codex-app-server", + "-c", + "model=\"gpt-5-codex\"", + "--config", + "sandbox_mode=\"read-only\"", + "--listen", + "off", + ]) + .expect("parse app-server args"); + + let parsed_overrides = args + .config_overrides + .parse_overrides() + .expect("parse config overrides"); + + assert_eq!( + parsed_overrides, + vec![ + ( + "model".to_string(), + TomlValue::String("gpt-5-codex".to_string()), + ), + ( + "sandbox_mode".to_string(), + TomlValue::String("read-only".to_string()), + ), + ] + ); +}