From 17a9df60e420b58e3edc55efb1bb052e39492bbc Mon Sep 17 00:00:00 2001 From: "Adam Perry @ OpenAI" Date: Tue, 29 Sep 2026 23:16:10 +0000 Subject: [PATCH] Add an experimental flag for bundled tools in login shells (#49403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What changed Register `login_shell_package_path` as a disabled-by-default experimental feature and add it to the configuration schema. Expose it in `/experimental` as “Bundled tools in login shells,” with a description explaining its intended use when login shell startup resets `PATH`. ## Testing Extend the experimental feature metadata snapshot test to cover the new feature's label, description, and unchecked default state. GitOrigin-RevId: dc110486ccd8d2d76ac788ba5a413a1374699ff8 --- codex-rs/core/config.schema.json | 6 +++ codex-rs/features/src/lib.rs | 12 ++++++ .../experimental_features_view_tests.rs | 41 +++++++++++-------- ...tal_features_login_shell_package_path.snap | 16 ++++++++ 4 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_login_shell_package_path.snap diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index a3e5627aac..d5521009b9 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -954,6 +954,9 @@ "local_thread_store_shared_compression": { "type": "boolean" }, + "login_shell_package_path": { + "type": "boolean" + }, "mcp_2026_07_28": { "type": "boolean" }, @@ -6978,6 +6981,9 @@ "local_thread_store_shared_compression": { "type": "boolean" }, + "login_shell_package_path": { + "type": "boolean" + }, "mcp_2026_07_28": { "type": "boolean" }, diff --git a/codex-rs/features/src/lib.rs b/codex-rs/features/src/lib.rs index db35cd4d44..2b6d26acb3 100644 --- a/codex-rs/features/src/lib.rs +++ b/codex-rs/features/src/lib.rs @@ -168,6 +168,8 @@ pub enum Feature { UseLegacyLandlock, /// Experimental shell snapshotting. ShellSnapshot, + /// Restore bundled tools to PATH after Codex's login shell starts. + LoginShellPackagePath, /// Expose the selected PowerShell execution host's bounded major/minor version. PowerShellShellVersion, /// Keep policy-filtered shell snapshots entirely in executor memory. @@ -1018,6 +1020,16 @@ pub const FEATURES: &[FeatureSpec] = &[ stage: Stage::Stable, default_enabled: true, }, + FeatureSpec { + id: Feature::LoginShellPackagePath, + key: "login_shell_package_path", + stage: Stage::Experimental { + name: "Bundled tools in login shells", + menu_description: "Keep bundled tools such as ripgrep available when login shell startup resets PATH.", + announcement: "", + }, + default_enabled: false, + }, FeatureSpec { id: Feature::PowerShellShellVersion, key: "powershell_shell_version", diff --git a/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs b/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs index 38110e6358..6c103f5f61 100644 --- a/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs +++ b/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs @@ -47,25 +47,30 @@ fn experimental_features_keep_following_choice_at_wrap_boundary() { insta::assert_snapshot!(snapshots.join("\n\n")); } +/// Experimental settings show each feature's label, description, and default state. #[test] -fn experimental_features_analytics_plan_history() { - let feature = Feature::AnalyticsPlanHistory; - let stage = feature.stage(); - let (app_tx, _app_rx) = tokio::sync::mpsc::unbounded_channel(); - let view = ExperimentalFeaturesView::new( - vec![ExperimentalFeatureItem { - key: feature.key().to_string(), - name: stage.experimental_menu_name().unwrap().to_string(), - description: stage.experimental_menu_description().unwrap().to_string(), - enabled: feature.default_enabled(), - writable: true, - }], - ThreadId::new(), - /*catalog_rx*/ None, - AppEventSender::new(app_tx), - crate::keymap::RuntimeKeymap::defaults().list, - ); - snapshot_view("experimental_features_analytics_plan_history", &view); +fn experimental_features_display_metadata() { + for feature in [ + Feature::AnalyticsPlanHistory, + Feature::LoginShellPackagePath, + ] { + let stage = feature.stage(); + let (app_tx, _app_rx) = tokio::sync::mpsc::unbounded_channel(); + let view = ExperimentalFeaturesView::new( + vec![ExperimentalFeatureItem { + key: feature.key().to_string(), + name: stage.experimental_menu_name().unwrap().to_string(), + description: stage.experimental_menu_description().unwrap().to_string(), + enabled: feature.default_enabled(), + writable: true, + }], + ThreadId::new(), + /*catalog_rx*/ None, + AppEventSender::new(app_tx), + crate::keymap::RuntimeKeymap::defaults().list, + ); + snapshot_view(&format!("experimental_features_{}", feature.key()), &view); + } } fn server_feature(name: &str) -> ExperimentalFeature { diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_login_shell_package_path.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_login_shell_package_path.snap new file mode 100644 index 0000000000..3cb14de549 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_login_shell_package_path.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/bottom_pane/experimental_features_view_tests.rs +expression: buffer_text(&buffer) +--- + + Experimental features + Checked features are configured on. Some experimental features take effect + only in new tasks or after restarting the Codex server. + + +› [ ] Bundled tools in login shells Keep bundled tools such as ripgrep + available when login shell startup resets + PATH. + + + space toggle · enter save · esc save/close