From 4347f94d5539880e8583028a50a19df5b202d9fa Mon Sep 17 00:00:00 2001 From: Benjamin Carlsson Date: Tue, 25 Aug 2026 05:29:43 +0000 Subject: [PATCH] Register the transcript v2 feature flag (#40554) ## What changed - Add the under-development `transcript_v2` feature for the interactive transcript composer and turn-selection UI. - Keep it disabled by default and expose it through the configuration schema and `codex features enable transcript_v2`. ## Testing - Verify explicit configuration overrides and CLI persistence for the new feature. GitOrigin-RevId: 138ab7851621c066e8121cc3eb6cd4e7299f9c31 --- codex-rs/cli/tests/features.rs | 20 ++++++++++++-------- codex-rs/core/config.schema.json | 6 ++++++ codex-rs/features/src/lib.rs | 8 ++++++++ codex-rs/features/src/tests.rs | 9 +++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/codex-rs/cli/tests/features.rs b/codex-rs/cli/tests/features.rs index d84dd206f7..3aad6fdc2b 100644 --- a/codex-rs/cli/tests/features.rs +++ b/codex-rs/cli/tests/features.rs @@ -133,15 +133,19 @@ fn strict_config_is_not_supported_for_cloud_command() -> Result<()> { async fn features_enable_writes_feature_flag_to_config() -> Result<()> { let codex_home = TempDir::new()?; - let mut cmd = codex_command(codex_home.path())?; - cmd.args(["features", "enable", "unified_exec"]) - .assert() - .success() - .stdout(contains("Enabled feature `unified_exec` in config.toml.")); + for feature in ["unified_exec", "transcript_v2"] { + let mut cmd = codex_command(codex_home.path())?; + cmd.args(["features", "enable", feature]) + .assert() + .success() + .stdout(contains(format!( + "Enabled feature `{feature}` in config.toml." + ))); - let config = std::fs::read_to_string(codex_home.path().join("config.toml"))?; - assert!(config.contains("[features]")); - assert!(config.contains("unified_exec = true")); + let config = std::fs::read_to_string(codex_home.path().join("config.toml"))?; + assert!(config.contains("[features]")); + assert!(config.contains(&format!("{feature} = true"))); + } Ok(()) } diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index e934ad844a..b6a078b3da 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -931,6 +931,9 @@ "tool_suggest": { "type": "boolean" }, + "transcript_v2": { + "type": "boolean" + }, "tui_app_server": { "type": "boolean" }, @@ -5934,6 +5937,9 @@ "tool_suggest": { "type": "boolean" }, + "transcript_v2": { + "type": "boolean" + }, "tui_app_server": { "type": "boolean" }, diff --git a/codex-rs/features/src/lib.rs b/codex-rs/features/src/lib.rs index 26443b6a8a..d6a36f95dd 100644 --- a/codex-rs/features/src/lib.rs +++ b/codex-rs/features/src/lib.rs @@ -88,6 +88,8 @@ impl Stage { /// Unique features toggled via configuration. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Feature { + /// Enable the interactive transcript composer and turn-selection UI. + TranscriptV2, // Stable. /// Enable the default shell tool. ShellTool, @@ -834,6 +836,12 @@ pub struct FeatureSpec { } pub const FEATURES: &[FeatureSpec] = &[ + FeatureSpec { + id: Feature::TranscriptV2, + key: "transcript_v2", + stage: Stage::UnderDevelopment, + default_enabled: false, + }, // Stable features. FeatureSpec { id: Feature::GhostCommit, diff --git a/codex-rs/features/src/tests.rs b/codex-rs/features/src/tests.rs index 2e10d91b14..4725a54ad1 100644 --- a/codex-rs/features/src/tests.rs +++ b/codex-rs/features/src/tests.rs @@ -14,6 +14,15 @@ use std::collections::BTreeMap; use toml::Table; use toml::Value as TomlValue; +#[test] +fn transcript_v2_resolves_explicit_config_overrides() { + let mut features = Features::with_defaults(); + for enabled in [false, true, false] { + features.apply_map(&BTreeMap::from([("transcript_v2".to_string(), enabled)])); + assert_eq!(features.enabled(Feature::TranscriptV2), enabled); + } +} + #[test] fn under_development_features_are_disabled_by_default() { for spec in crate::FEATURES {