Split features into codex-features crate (#15253)

- Split the feature system into a new `codex-features` crate.
- Cut `codex-core` and workspace consumers over to the new config and
warning APIs.

Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-03-19 20:12:07 -07:00
committed by GitHub
parent 35f8b87a5b
commit 2e22885e79
135 changed files with 456 additions and 250 deletions

View File

@@ -11,7 +11,9 @@ path = "lib.rs"
anyhow = { workspace = true }
assert_cmd = { workspace = true }
base64 = { workspace = true }
codex-arg0 = { workspace = true }
codex-core = { workspace = true }
codex-features = { workspace = true }
codex-protocol = { workspace = true }
codex-utils-absolute-path = { workspace = true }
codex-utils-cargo-bin = { workspace = true }

View File

@@ -2,8 +2,10 @@
use anyhow::Context as _;
use anyhow::ensure;
use codex_arg0::Arg0PathEntryGuard;
use codex_utils_cargo_bin::CargoBinError;
use ctor::ctor;
use std::sync::OnceLock;
use tempfile::TempDir;
use codex_core::CodexThread;
@@ -24,12 +26,19 @@ pub mod test_codex_exec;
pub mod tracing;
pub mod zsh_fork;
static TEST_ARG0_PATH_ENTRY: OnceLock<Option<Arg0PathEntryGuard>> = OnceLock::new();
#[ctor]
fn enable_deterministic_unified_exec_process_ids_for_tests() {
codex_core::test_support::set_thread_manager_test_mode(/*enabled*/ true);
codex_core::test_support::set_deterministic_process_ids(/*enabled*/ true);
}
#[ctor]
fn configure_arg0_dispatch_for_test_binaries() {
let _ = TEST_ARG0_PATH_ENTRY.get_or_init(codex_arg0::arg0_dispatch);
}
#[ctor]
fn configure_insta_workspace_root_for_snapshot_tests() {
if std::env::var_os("INSTA_WORKSPACE_ROOT").is_some() {
@@ -155,8 +164,7 @@ pub async fn load_default_config_for_test(codex_home: &TempDir) -> Config {
fn default_test_overrides() -> ConfigOverrides {
ConfigOverrides {
codex_linux_sandbox_exe: Some(
codex_utils_cargo_bin::cargo_bin("codex-linux-sandbox")
.expect("should find binary for codex-linux-sandbox"),
find_codex_linux_sandbox_exe().expect("should find binary for codex-linux-sandbox"),
),
..ConfigOverrides::default()
}
@@ -167,6 +175,23 @@ fn default_test_overrides() -> ConfigOverrides {
ConfigOverrides::default()
}
#[cfg(target_os = "linux")]
pub fn find_codex_linux_sandbox_exe() -> Result<PathBuf, CargoBinError> {
if let Ok(path) = std::env::current_exe() {
return Ok(path);
}
if let Some(path) = TEST_ARG0_PATH_ENTRY
.get()
.and_then(Option::as_ref)
.and_then(|path_entry| path_entry.paths().codex_linux_sandbox_exe.clone())
{
return Ok(path);
}
codex_utils_cargo_bin::cargo_bin("codex-linux-sandbox")
}
/// Builds an SSE stream body from a JSON fixture.
///
/// The fixture must contain an array of objects where each object represents a
@@ -482,7 +507,7 @@ macro_rules! codex_linux_sandbox_exe_or_skip {
() => {{
#[cfg(target_os = "linux")]
{
match codex_utils_cargo_bin::cargo_bin("codex-linux-sandbox") {
match $crate::find_codex_linux_sandbox_exe() {
Ok(path) => Some(path),
Err(err) => {
eprintln!("codex-linux-sandbox binary not available, skipping test: {err}");
@@ -498,7 +523,7 @@ macro_rules! codex_linux_sandbox_exe_or_skip {
($return_value:expr $(,)?) => {{
#[cfg(target_os = "linux")]
{
match codex_utils_cargo_bin::cargo_bin("codex-linux-sandbox") {
match $crate::find_codex_linux_sandbox_exe() {
Ok(path) => Some(path),
Err(err) => {
eprintln!("codex-linux-sandbox binary not available, skipping test: {err}");

View File

@@ -11,10 +11,10 @@ use codex_core::ModelProviderInfo;
use codex_core::ThreadManager;
use codex_core::built_in_model_providers;
use codex_core::config::Config;
use codex_core::features::Feature;
use codex_core::models_manager::collaboration_mode_presets::CollaborationModesConfig;
use codex_core::shell::Shell;
use codex_core::shell::get_shell_by_model_provided_path;
use codex_features::Feature;
use codex_protocol::config_types::ServiceTier;
use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::protocol::AskForApproval;

View File

@@ -4,7 +4,7 @@ use std::path::PathBuf;
use anyhow::Result;
use codex_core::config::Config;
use codex_core::config::Constrained;
use codex_core::features::Feature;
use codex_features::Feature;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::SandboxPolicy;