From 4dd593f839fdec645d5c69edecd257d66ef2c973 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Thu, 21 May 2026 14:55:35 +0100 Subject: [PATCH 1/2] chore: ship profile v2 --- codex-rs/cli/src/main.rs | 17 ++++++----------- codex-rs/config/src/loader/mod.rs | 2 +- codex-rs/config/src/loader/tests.rs | 2 +- codex-rs/protocol/src/config_types.rs | 2 +- codex-rs/utils/cli/src/shared_options.rs | 4 ++-- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 95873191b93..03ed99b802b 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -1477,7 +1477,7 @@ fn profile_v2_for_subcommand<'a>( subcommand: DebugSubcommand::PromptInput(_), }) => Ok(Some(profile_v2)), _ => anyhow::bail!( - "--profile-v2 only applies to runtime commands: `codex`, `codex exec`, `codex review`, `codex resume`, `codex fork`, and `codex debug prompt-input`." + "--profile only applies to runtime commands: `codex`, `codex exec`, `codex review`, `codex resume`, `codex fork`, and `codex debug prompt-input`." ), } } @@ -2286,21 +2286,19 @@ mod tests { #[test] fn profile_v2_is_rejected_for_config_management_subcommands() { - assert!( - profile_v2_for_args(&["codex", "--profile-v2", "work", "features", "list"]).is_err() - ); + assert!(profile_v2_for_args(&["codex", "--profile", "work", "features", "list"]).is_err()); } #[test] fn profile_v2_is_allowed_for_runtime_subcommands() { assert_eq!( - profile_v2_for_args(&["codex", "--profile-v2", "work", "resume"]) + profile_v2_for_args(&["codex", "--profile", "work", "resume"]) .expect("resume supports profile-v2") .as_deref(), Some("work") ); assert_eq!( - profile_v2_for_args(&["codex", "--profile-v2", "work", "debug", "prompt-input"]) + profile_v2_for_args(&["codex", "--profile", "work", "debug", "prompt-input"]) .expect("debug prompt-input supports profile-v2") .as_deref(), Some("work") @@ -2310,8 +2308,7 @@ mod tests { #[test] fn profile_v2_rejects_non_plain_names_at_parse_time() { assert!( - MultitoolCli::try_parse_from(["codex", "--profile-v2", "nested/work", "resume"]) - .is_err() + MultitoolCli::try_parse_from(["codex", "--profile", "nested/work", "resume"]).is_err() ); } @@ -2762,8 +2759,6 @@ mod tests { "-m", "gpt-5.1-test", "-p", - "my-profile", - "--profile-v2", "my-config", "-C", "/tmp", @@ -2776,7 +2771,7 @@ mod tests { assert_eq!(interactive.model.as_deref(), Some("gpt-5.1-test")); assert!(interactive.oss); - assert_eq!(interactive.config_profile.as_deref(), Some("my-profile")); + assert_eq!(interactive.config_profile.as_deref(), None); assert_eq!(interactive.config_profile_v2.as_deref(), Some("my-config")); assert_matches!( interactive.sandbox_mode, diff --git a/codex-rs/config/src/loader/mod.rs b/codex-rs/config/src/loader/mod.rs index 49df306abbb..3f167acb355 100644 --- a/codex-rs/config/src/loader/mod.rs +++ b/codex-rs/config/src/loader/mod.rs @@ -235,7 +235,7 @@ pub async fn load_config_layers_state( return Err(io::Error::new( io::ErrorKind::InvalidData, format!( - "--profile-v2 `{active_user_profile}` cannot be used while {} contains legacy `[profiles.{active_user_profile}]` config; move those settings into {} or remove `[profiles.{active_user_profile}]`", + "--profile `{active_user_profile}` cannot be used while {} contains legacy `[profiles.{active_user_profile}]` config; move those settings into {} or remove `[profiles.{active_user_profile}]`", base_user_file.as_path().display(), active_user_file.as_path().display() ), diff --git a/codex-rs/config/src/loader/tests.rs b/codex-rs/config/src/loader/tests.rs index 2d9462bfa78..f6a242870ff 100644 --- a/codex-rs/config/src/loader/tests.rs +++ b/codex-rs/config/src/loader/tests.rs @@ -120,7 +120,7 @@ model = "gpt-work" ); let message = err.to_string(); assert!( - message.contains("--profile-v2 `work` cannot be used"), + message.contains("--profile `work` cannot be used"), "unexpected error message: {message}" ); assert!( diff --git a/codex-rs/protocol/src/config_types.rs b/codex-rs/protocol/src/config_types.rs index 550dbdaf3a9..9e5c47a5c12 100644 --- a/codex-rs/protocol/src/config_types.rs +++ b/codex-rs/protocol/src/config_types.rs @@ -114,7 +114,7 @@ impl fmt::Display for ProfileV2NameParseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "invalid --profile-v2 value `{}`; pass a plain name such as `work`", + "invalid --profile value `{}`; pass a plain name such as `work`", self.value ) } diff --git a/codex-rs/utils/cli/src/shared_options.rs b/codex-rs/utils/cli/src/shared_options.rs index b59a3b5c853..c99faf27c2a 100644 --- a/codex-rs/utils/cli/src/shared_options.rs +++ b/codex-rs/utils/cli/src/shared_options.rs @@ -31,11 +31,11 @@ pub struct SharedCliOptions { pub oss_provider: Option, /// Configuration profile from config.toml to specify default options. - #[arg(long = "profile", short = 'p')] + #[arg(skip)] pub config_profile: Option, /// Layer $CODEX_HOME/.config.toml on top of the base user config. - #[arg(long = "profile-v2")] + #[arg(long = "profile", short = 'p')] pub config_profile_v2: Option, /// Select the sandbox policy to use when executing model-generated shell From 40a8df9f935d3127aef2cc1efe56e0e656f82f57 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Thu, 21 May 2026 15:31:10 +0100 Subject: [PATCH 2/2] Fix integration test --- codex-rs/core/tests/suite/cli_stream.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/codex-rs/core/tests/suite/cli_stream.rs b/codex-rs/core/tests/suite/cli_stream.rs index bcf49197372..edde7b447e4 100644 --- a/codex-rs/core/tests/suite/cli_stream.rs +++ b/codex-rs/core/tests/suite/cli_stream.rs @@ -196,9 +196,9 @@ async fn exec_cli_applies_model_instructions_file() { ); } -/// Verify that `codex exec --profile ...` preserves the active profile when it -/// starts the in-process app-server thread, so profile-scoped -/// `model_instructions_file` is applied to the outbound request. +/// Verify that `codex exec --profile ...` preserves the active user config +/// profile when it starts the in-process app-server thread, so the selected +/// profile's `model_instructions_file` reaches the outbound request. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn exec_cli_profile_applies_model_instructions_file() { skip_if_no_network!(); @@ -223,8 +223,8 @@ async fn exec_cli_profile_applies_model_instructions_file() { let home = TempDir::new().unwrap(); std::fs::write( - home.path().join("config.toml"), - format!("[profiles.default]\nmodel_instructions_file = \"{custom_path_str}\"\n",), + home.path().join("default.config.toml"), + format!("model_instructions_file = \"{custom_path_str}\"\n"), ) .unwrap();