From 7bcdb12b4c5e9de0e4632c770336799e7c8d13d6 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Tue, 7 Apr 2026 17:34:54 -0700 Subject: [PATCH] Remove Agent V2 feature flag (#52792) It's happening. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A --- Cargo.lock | 3 - assets/settings/default.json | 10 +-- crates/agent_settings/src/agent_settings.rs | 19 +--- crates/agent_ui/src/agent_panel.rs | 90 +------------------ crates/agent_ui/src/agent_ui.rs | 61 +++---------- crates/agent_ui/src/conversation_view.rs | 27 +++--- .../src/conversation_view/thread_view.rs | 7 +- crates/agent_ui/src/thread_metadata_store.rs | 36 +------- crates/feature_flags/src/flags.rs | 10 --- crates/platform_title_bar/Cargo.toml | 1 - .../src/platform_title_bar.rs | 3 +- crates/settings_ui/Cargo.toml | 1 - crates/settings_ui/src/page_data.rs | 49 +++++----- crates/sidebar/Cargo.toml | 2 - crates/sidebar/src/sidebar.rs | 6 -- crates/sidebar/src/sidebar_tests.rs | 11 +-- crates/workspace/src/multi_workspace.rs | 3 +- crates/workspace/src/multi_workspace_tests.rs | 2 - crates/workspace/src/persistence.rs | 9 -- crates/zed/src/visual_test_runner.rs | 10 --- crates/zed/src/zed.rs | 17 ---- 21 files changed, 65 insertions(+), 312 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afbf73bf6cc99d7fbb6917c3f1a29d0657d9402c..d296c6c57e12bf2a569e8eed42a2bc0ad129d24f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12890,7 +12890,6 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" name = "platform_title_bar" version = "0.1.0" dependencies = [ - "feature_flags", "gpui", "project", "settings", @@ -15923,7 +15922,6 @@ dependencies = [ "edit_prediction", "edit_prediction_ui", "editor", - "feature_flags", "fs", "futures 0.3.32", "fuzzy", @@ -16073,7 +16071,6 @@ dependencies = [ "anyhow", "chrono", "editor", - "feature_flags", "fs", "git", "gpui", diff --git a/assets/settings/default.json b/assets/settings/default.json index 97fbcd546e09beefa9ff7a67e33806f3faf561d1..8d6f067c9af4e4e02ce1b613911d0dbc59077526 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -717,7 +717,7 @@ // Default width of the project panel. "default_width": 240, // Where to dock the project panel. Can be 'left' or 'right'. - "dock": "left", + "dock": "right", // Spacing between worktree entries in the project panel. Can be 'comfortable' or 'standard'. "entry_spacing": "comfortable", // Whether to show file icons in the project panel. @@ -819,7 +819,7 @@ // Default width of the outline panel. "default_width": 300, // Where to dock the outline panel. Can be 'left' or 'right'. - "dock": "left", + "dock": "right", // Whether to show file icons in the outline panel. "file_icons": true, // Whether to show folder icons or chevrons for directories in the outline panel. @@ -871,7 +871,7 @@ // Whether to show the collaboration panel button in the status bar. "button": true, // Where to dock the collaboration panel. Can be 'left' or 'right'. - "dock": "left", + "dock": "right", // Default width of the collaboration panel. "default_width": 240, }, @@ -879,7 +879,7 @@ // Whether to show the git panel button in the status bar. "button": true, // Where to dock the git panel. Can be 'left' or 'right'. - "dock": "left", + "dock": "right", // Default width of the git panel. "default_width": 360, // Style of the git status indicator in the panel. @@ -944,7 +944,7 @@ // Whether to show the agent panel button in the status bar. "button": true, // Where to dock the agent panel. Can be 'left', 'right' or 'bottom'. - "dock": "right", + "dock": "left", // Whether the agent panel should use flexible (proportional) sizing. // // Default: true diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index a04de2ed3be69d3f5791419a32e427fa0c26791e..f04095662513a31ad5e8b204509669942ec4793f 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -728,14 +728,6 @@ mod tests { use settings::ToolPermissionMode; use settings::ToolPermissionsContent; - fn set_agent_v2_defaults(cx: &mut gpui::App) { - SettingsStore::update_global(cx, |store, cx| { - store.update_default_settings(cx, |defaults| { - PanelLayout::AGENT.write_to(defaults); - }); - }); - } - #[test] fn test_compiled_regex_case_insensitive() { let regex = CompiledRegex::new("rm\\s+-rf", false).unwrap(); @@ -1216,9 +1208,6 @@ mod tests { project::DisableAiSettings::register(cx); AgentSettings::register(cx); - // Test defaults are editor layout; switch to agent V2. - set_agent_v2_defaults(cx); - // Should be Agent with an empty user layout (user hasn't customized). let layout = AgentSettings::get_layout(cx); let WindowLayout::Agent(Some(user_layout)) = layout else { @@ -1351,9 +1340,6 @@ mod tests { project::DisableAiSettings::register(cx); AgentSettings::register(cx); - // Apply the agent V2 defaults. - set_agent_v2_defaults(cx); - // User has agent=left (matches preset) and project_panel=left (does not) SettingsStore::update_global(cx, |store, cx| { store @@ -1442,7 +1428,7 @@ mod tests { cx.run_until_parked(); - // Read back the file and apply it, then switch to agent V2 defaults. + // Read back the file and apply it. let written = fs.load(paths::settings_file().as_path()).await.unwrap(); cx.update(|cx| { SettingsStore::update_global(cx, |store, cx| { @@ -1467,9 +1453,6 @@ mod tests { ); assert_eq!(user_layout.git_panel_dock, Some(DockPosition::Left)); - // Now switch defaults to agent V2. - set_agent_v2_defaults(cx); - // Even though defaults are now agent, the backfilled user settings // keep everything in the editor layout. The user's experience // hasn't changed. diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index eeb8fbf8c32a01a71b8471342d8edc90cc8517cf..c157fbb30925d2a49c72438e3b3bff62a987b175 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -19,7 +19,6 @@ use project::AgentId; use serde::{Deserialize, Serialize}; use settings::{LanguageModelProviderSetting, LanguageModelSelection}; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt as _}; use zed_actions::agent::{ AddSelectionToThread, ConflictContent, ReauthenticateAgent, ResolveConflictedFilesWithAgent, ResolveConflictsWithAgent, ReviewBranchDiff, @@ -923,16 +922,14 @@ impl AgentPanel { panel.selected_agent = agent; } if let Some(ref start_thread_in) = serialized_panel.start_thread_in { - let is_worktree_flag_enabled = - cx.has_flag::(); let is_valid = match &start_thread_in { StartThreadIn::LocalProject => true, StartThreadIn::NewWorktree { .. } => { let project = panel.project.read(cx); - is_worktree_flag_enabled && !project.is_via_collab() + !project.is_via_collab() } StartThreadIn::LinkedWorktree { path, .. } => { - is_worktree_flag_enabled && path.exists() + path.exists() } }; if is_valid { @@ -2083,9 +2080,6 @@ impl AgentPanel { let new_target = match action { StartThreadIn::LocalProject => StartThreadIn::LocalProject, StartThreadIn::NewWorktree { .. } => { - if !cx.has_flag::() { - return; - } if !self.project_has_git_repository(cx) { log::error!( "set_start_thread_in: cannot use worktree mode without a git repository" @@ -2101,9 +2095,6 @@ impl AgentPanel { action.clone() } StartThreadIn::LinkedWorktree { .. } => { - if !cx.has_flag::() { - return; - } if !self.project_has_git_repository(cx) { log::error!( "set_start_thread_in: cannot use LinkedWorktree without a git repository" @@ -3371,47 +3362,6 @@ impl AgentPanel { }) } - fn render_recent_entries_menu( - &self, - icon: IconName, - corner: Corner, - cx: &mut Context, - ) -> impl IntoElement { - let focus_handle = self.focus_handle(cx); - - PopoverMenu::new("agent-nav-menu") - .trigger_with_tooltip( - IconButton::new("agent-nav-menu", icon).icon_size(IconSize::Small), - { - move |_window, cx| { - Tooltip::for_action_in( - "Toggle Recently Updated Threads", - &ToggleNavigationMenu, - &focus_handle, - cx, - ) - } - }, - ) - .anchor(corner) - .with_handle(self.agent_navigation_menu_handle.clone()) - .menu({ - let menu = self.agent_navigation_menu.clone(); - move |window, cx| { - telemetry::event!("View Thread History Clicked"); - - if let Some(menu) = menu.as_ref() { - menu.update(cx, |_, cx| { - cx.defer_in(window, |menu, window, cx| { - menu.rebuild(window, cx); - }); - }) - } - menu.clone() - } - }) - } - fn render_toolbar_back_button(&self, cx: &mut Context) -> impl IntoElement { let focus_handle = self.focus_handle(cx); @@ -3788,8 +3738,6 @@ impl AgentPanel { selected_agent.into_any_element() }; - let show_history_menu = self.has_history_for_selected_agent(cx); - let has_v2_flag = cx.has_flag::(); let is_empty_state = !self.active_thread_has_messages(cx); let is_in_history_or_config = matches!( @@ -3814,7 +3762,7 @@ impl AgentPanel { })) }; - let use_v2_empty_toolbar = has_v2_flag && is_empty_state && !is_in_history_or_config; + let use_v2_empty_toolbar = is_empty_state && !is_in_history_or_config; let max_content_width = AgentSettings::get_global(cx).max_content_width; @@ -3888,11 +3836,7 @@ impl AgentPanel { |this| this.child(self.render_start_thread_in_selector(cx)), ) .when( - has_v2_flag - && matches!( - self.start_thread_in, - StartThreadIn::NewWorktree { .. } - ), + matches!(self.start_thread_in, StartThreadIn::NewWorktree { .. }), |this| this.child(self.render_new_worktree_branch_selector(cx)), ), ) @@ -3903,13 +3847,6 @@ impl AgentPanel { .gap_1() .pl_1() .pr_1() - .when(show_history_menu && !has_v2_flag, |this| { - this.child(self.render_recent_entries_menu( - IconName::MenuAltTemp, - Corner::TopRight, - cx, - )) - }) .child(full_screen_button) .child(self.render_panel_options_menu(window, cx)), ) @@ -3956,13 +3893,6 @@ impl AgentPanel { .pl_1() .pr_1() .child(new_thread_menu) - .when(show_history_menu && !has_v2_flag, |this| { - this.child(self.render_recent_entries_menu( - IconName::MenuAltTemp, - Corner::TopRight, - cx, - )) - }) .child(full_screen_button) .child(self.render_panel_options_menu(window, cx)), ) @@ -4491,7 +4421,6 @@ mod tests { }; use acp_thread::{StubAgentConnection, ThreadStatus}; use agent_servers::CODEX_ID; - use feature_flags::FeatureFlagAppExt; use fs::FakeFs; use gpui::{TestAppContext, VisualTestContext}; use project::Project; @@ -4504,7 +4433,6 @@ mod tests { async fn test_active_thread_serialize_and_load_round_trip(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -4625,7 +4553,6 @@ mod tests { async fn test_non_native_thread_without_metadata_is_not_restored(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -5005,7 +4932,6 @@ mod tests { async fn setup_panel(cx: &mut TestAppContext) -> (Entity, VisualTestContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -5361,7 +5287,6 @@ mod tests { async fn test_thread_target_local_project(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -5469,7 +5394,6 @@ mod tests { async fn test_thread_target_serialization_round_trip(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -5571,7 +5495,6 @@ mod tests { let fs = FakeFs::new(cx.executor()); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); ::set_global(fs.clone(), cx); @@ -5742,7 +5665,6 @@ mod tests { init_test(cx); let app_state = cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -5909,7 +5831,6 @@ mod tests { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -6101,7 +6022,6 @@ mod tests { async fn test_new_workspace_inherits_global_last_used_agent(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); // Use an isolated DB so parallel tests can't overwrite our global key. @@ -6155,7 +6075,6 @@ mod tests { async fn test_workspaces_maintain_independent_agent_selection(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); @@ -6248,7 +6167,6 @@ mod tests { async fn test_new_thread_uses_workspace_selected_agent(cx: &mut TestAppContext) { init_test(cx); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); }); diff --git a/crates/agent_ui/src/agent_ui.rs b/crates/agent_ui/src/agent_ui.rs index 429bc184f5d889990599c196910ae8d0feb28da1..037821d56d00851100488d68b0b44cee0aecbd53 100644 --- a/crates/agent_ui/src/agent_ui.rs +++ b/crates/agent_ui/src/agent_ui.rs @@ -45,9 +45,9 @@ use ::ui::IconName; use agent_client_protocol as acp; use agent_settings::{AgentProfileId, AgentSettings}; use command_palette_hooks::CommandPaletteFilter; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt as _}; +use feature_flags::FeatureFlagAppExt as _; use fs::Fs; -use gpui::{Action, App, Context, Entity, SharedString, UpdateGlobal as _, Window, actions}; +use gpui::{Action, App, Context, Entity, SharedString, Window, actions}; use language::{ LanguageRegistry, language_settings::{AllLanguageSettings, EditPredictionProvider}, @@ -59,7 +59,7 @@ use project::{AgentId, DisableAiSettings}; use prompt_store::PromptBuilder; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use settings::{DockPosition, DockSide, LanguageModelSelection, Settings as _, SettingsStore}; +use settings::{LanguageModelSelection, Settings as _, SettingsStore}; use std::any::TypeId; use workspace::Workspace; @@ -80,7 +80,6 @@ use zed_actions; pub const DEFAULT_THREAD_TITLE: &str = "New Thread"; const PARALLEL_AGENT_LAYOUT_BACKFILL_KEY: &str = "parallel_agent_layout_backfilled"; - actions!( agent, [ @@ -511,43 +510,10 @@ pub fn init( }) .detach(); - // TODO: remove this field when we're ready remove the feature flag - maybe_backfill_editor_layout(fs, is_new_install, false, cx); - - cx.observe_flag::(|is_enabled, cx| { - SettingsStore::update_global(cx, |store, cx| { - store.update_default_settings(cx, |defaults| { - if is_enabled { - defaults.agent.get_or_insert_default().dock = Some(DockPosition::Left); - defaults.project_panel.get_or_insert_default().dock = Some(DockSide::Right); - defaults.outline_panel.get_or_insert_default().dock = Some(DockSide::Right); - defaults.collaboration_panel.get_or_insert_default().dock = - Some(DockPosition::Right); - defaults.git_panel.get_or_insert_default().dock = Some(DockPosition::Right); - } else { - defaults.agent.get_or_insert_default().dock = Some(DockPosition::Right); - defaults.project_panel.get_or_insert_default().dock = Some(DockSide::Left); - defaults.outline_panel.get_or_insert_default().dock = Some(DockSide::Left); - defaults.collaboration_panel.get_or_insert_default().dock = - Some(DockPosition::Left); - defaults.git_panel.get_or_insert_default().dock = Some(DockPosition::Left); - } - }); - }); - }) - .detach(); + maybe_backfill_editor_layout(fs, is_new_install, cx); } -fn maybe_backfill_editor_layout( - fs: Arc, - is_new_install: bool, - should_run: bool, - cx: &mut App, -) { - if !should_run { - return; - } - +fn maybe_backfill_editor_layout(fs: Arc, is_new_install: bool, cx: &mut App) { let kvp = db::kvp::KeyValueStore::global(cx); let already_backfilled = util::ResultExt::log_err(kvp.read_kvp(PARALLEL_AGENT_LAYOUT_BACKFILL_KEY)) @@ -572,7 +538,7 @@ fn maybe_backfill_editor_layout( fn update_command_palette_filter(cx: &mut App) { let disable_ai = DisableAiSettings::get_global(cx).disable_ai; let agent_enabled = AgentSettings::get_global(cx).enabled; - let agent_v2_enabled = cx.has_flag::(); + let edit_prediction_provider = AllLanguageSettings::get_global(cx) .edit_predictions .provider; @@ -641,11 +607,7 @@ fn update_command_palette_filter(cx: &mut App) { filter.show_action_types(&[TypeId::of::()]); } - if agent_v2_enabled { - filter.show_namespace("multi_workspace"); - } else { - filter.hide_namespace("multi_workspace"); - } + filter.show_namespace("multi_workspace"); }); } @@ -714,7 +676,6 @@ mod tests { use command_palette_hooks::CommandPaletteFilter; use db::kvp::KeyValueStore; use editor::actions::AcceptEditPrediction; - use feature_flags::FeatureFlagAppExt; use gpui::{BorrowAppContext, TestAppContext, px}; use project::DisableAiSettings; use settings::{ @@ -883,7 +844,7 @@ mod tests { .is_none() ); - maybe_backfill_editor_layout(fs.clone(), false, true, cx); + maybe_backfill_editor_layout(fs.clone(), false, cx); }); cx.run_until_parked(); @@ -902,7 +863,7 @@ mod tests { let fs = setup_backfill_test(cx).await; cx.update(|cx| { - maybe_backfill_editor_layout(fs.clone(), true, true, cx); + maybe_backfill_editor_layout(fs.clone(), true, cx); }); cx.run_until_parked(); @@ -924,7 +885,7 @@ mod tests { let fs = setup_backfill_test(cx).await; cx.update(|cx| { - maybe_backfill_editor_layout(fs.clone(), false, true, cx); + maybe_backfill_editor_layout(fs.clone(), false, cx); }); cx.run_until_parked(); @@ -932,7 +893,7 @@ mod tests { let after_first = fs.load(paths::settings_file().as_path()).await.unwrap(); cx.update(|cx| { - maybe_backfill_editor_layout(fs.clone(), false, true, cx); + maybe_backfill_editor_layout(fs.clone(), false, cx); }); cx.run_until_parked(); diff --git a/crates/agent_ui/src/conversation_view.rs b/crates/agent_ui/src/conversation_view.rs index e2b02d814be7950afd061ac9778be6587527e016..de02fdc5d384f08c693df848b63f7ef20bdd28f8 100644 --- a/crates/agent_ui/src/conversation_view.rs +++ b/crates/agent_ui/src/conversation_view.rs @@ -22,7 +22,7 @@ use editor::scroll::Autoscroll; use editor::{ Editor, EditorEvent, EditorMode, MultiBuffer, PathKey, SelectionEffects, SizingBehavior, }; -use feature_flags::{AgentSharingFeatureFlag, AgentV2FeatureFlag, FeatureFlagAppExt as _}; +use feature_flags::{AgentSharingFeatureFlag, FeatureFlagAppExt as _}; use file_icons::FileIcons; use fs::Fs; use futures::FutureExt as _; @@ -2645,7 +2645,6 @@ impl ConversationView { impl Render for ConversationView { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { self.sync_queued_message_editors(window, cx); - let v2_flag = cx.has_flag::(); v_flex() .track_focus(&self.focus_handle) @@ -2654,17 +2653,18 @@ impl Render for ConversationView { .child(match &self.server_state { ServerState::Loading { .. } => v_flex() .flex_1() - .when(v2_flag, |this| { - this.size_full().items_center().justify_center().child( - Label::new("Loading…").color(Color::Muted).with_animation( - "loading-agent-label", - Animation::new(Duration::from_secs(2)) - .repeat() - .with_easing(pulsating_between(0.3, 0.7)), - |label, delta| label.alpha(delta), - ), - ) - }) + .size_full() + .items_center() + .justify_center() + .child( + Label::new("Loading…").color(Color::Muted).with_animation( + "loading-agent-label", + Animation::new(Duration::from_secs(2)) + .repeat() + .with_easing(pulsating_between(0.3, 0.7)), + |label, delta| label.alpha(delta), + ), + ) .into_any(), ServerState::LoadError { error: e, .. } => v_flex() .flex_1() @@ -3437,7 +3437,6 @@ pub(crate) mod tests { let fs = FakeFs::new(cx.executor()); cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); agent::ThreadStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); ::set_global(fs.clone(), cx); diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index 63df627cade5b96f47cbc338914780c23934e56d..119942100a2e091f64bf312bbb6ba5fd61572c56 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -3141,7 +3141,7 @@ impl ThreadView { let editor_bg_color = cx.theme().colors().editor_background; let editor_expanded = self.editor_expanded; let has_messages = self.list_state.item_count() > 0; - let v2_empty_state = cx.has_flag::() && !has_messages; + let v2_empty_state = !has_messages; let (expand_icon, expand_tooltip) = if editor_expanded { (IconName::Minimize, "Minimize Message Editor") } else { @@ -5158,7 +5158,7 @@ impl ThreadView { pub(crate) fn sync_editor_mode_for_empty_state(&mut self, cx: &mut Context) { let has_messages = self.list_state.item_count() > 0; - let v2_empty_state = cx.has_flag::() && !has_messages; + let v2_empty_state = !has_messages; let mode = if v2_empty_state { EditorMode::Full { @@ -6393,7 +6393,6 @@ impl ThreadView { .when(is_collapsible || failed_or_canceled, |this| { let diff_for_discard = if has_revealed_diff && is_cancelled_edit - && cx.has_flag::() { tool_call.diffs().next().cloned() } else { @@ -8621,7 +8620,7 @@ impl ThreadView { impl Render for ThreadView { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { let has_messages = self.list_state.item_count() > 0; - let v2_empty_state = cx.has_flag::() && !has_messages; + let v2_empty_state = !has_messages; let max_content_width = AgentSettings::get_global(cx).max_content_width; diff --git a/crates/agent_ui/src/thread_metadata_store.rs b/crates/agent_ui/src/thread_metadata_store.rs index c990427dfd221846d157133ba1fd995032beb40d..7f50482d9d47ae51ffda7ec2dac2907fb6f88095 100644 --- a/crates/agent_ui/src/thread_metadata_store.rs +++ b/crates/agent_ui/src/thread_metadata_store.rs @@ -16,7 +16,6 @@ use db::{ }, sqlez_macros::sql, }; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt}; use futures::{FutureExt as _, future::Shared}; use gpui::{AppContext as _, Entity, Global, Subscription, Task}; use project::AgentId; @@ -28,16 +27,7 @@ use crate::DEFAULT_THREAD_TITLE; pub fn init(cx: &mut App) { ThreadMetadataStore::init_global(cx); - - if cx.has_flag::() { - migrate_thread_metadata(cx); - } - cx.observe_flag::(|has_flag, cx| { - if has_flag { - migrate_thread_metadata(cx); - } - }) - .detach(); + migrate_thread_metadata(cx); } /// Migrate existing thread metadata from native agent thread store to the new metadata storage. @@ -343,10 +333,6 @@ impl ThreadMetadataStore { } pub fn save_all(&mut self, metadata: Vec, cx: &mut Context) { - if !cx.has_flag::() { - return; - } - for metadata in metadata { self.save_internal(metadata); } @@ -359,10 +345,6 @@ impl ThreadMetadataStore { } fn save(&mut self, metadata: ThreadMetadata, cx: &mut Context) { - if !cx.has_flag::() { - return; - } - self.save_internal(metadata); cx.notify(); } @@ -412,10 +394,6 @@ impl ThreadMetadataStore { work_dirs: PathList, cx: &mut Context, ) { - if !cx.has_flag::() { - return; - } - if let Some(thread) = self.threads.get(session_id) { self.save_internal(ThreadMetadata { folder_paths: work_dirs, @@ -490,10 +468,6 @@ impl ThreadMetadataStore { archived: bool, cx: &mut Context, ) { - if !cx.has_flag::() { - return; - } - if let Some(thread) = self.threads.get(session_id) { self.save_internal(ThreadMetadata { archived, @@ -504,10 +478,6 @@ impl ThreadMetadataStore { } pub fn delete(&mut self, session_id: acp::SessionId, cx: &mut Context) { - if !cx.has_flag::() { - return; - } - if let Some(thread) = self.threads.get(&session_id) { if let Some(session_ids) = self.threads_by_paths.get_mut(&thread.folder_paths) { session_ids.remove(&session_id); @@ -997,7 +967,7 @@ mod tests { use action_log::ActionLog; use agent::DbThread; use agent_client_protocol as acp; - use feature_flags::FeatureFlagAppExt; + use gpui::TestAppContext; use project::FakeFs; use project::Project; @@ -1047,7 +1017,6 @@ mod tests { cx.update(|cx| { let settings_store = settings::SettingsStore::test(cx); cx.set_global(settings_store); - cx.update_flags(true, vec!["agent-v2".to_string()]); ThreadMetadataStore::init_global(cx); ThreadStore::init_global(cx); }); @@ -1088,7 +1057,6 @@ mod tests { cx.update(|cx| { let settings_store = settings::SettingsStore::test(cx); cx.set_global(settings_store); - cx.update_flags(true, vec!["agent-v2".to_string()]); ThreadMetadataStore::init_global(cx); }); diff --git a/crates/feature_flags/src/flags.rs b/crates/feature_flags/src/flags.rs index 54dc96ad37f8e51a1074a0a32976f8236cb1a0ed..4a206a2bb4c48db951f1364d1aa408947165c24b 100644 --- a/crates/feature_flags/src/flags.rs +++ b/crates/feature_flags/src/flags.rs @@ -12,16 +12,6 @@ impl FeatureFlag for PanicFeatureFlag { const NAME: &'static str = "panic"; } -pub struct AgentV2FeatureFlag; - -impl FeatureFlag for AgentV2FeatureFlag { - const NAME: &'static str = "agent-v2"; - - fn enabled_for_staff() -> bool { - true - } -} - /// A feature flag for granting access to beta ACP features. /// /// We reuse this feature flag for new betas, so don't delete it if it is not currently in use. diff --git a/crates/platform_title_bar/Cargo.toml b/crates/platform_title_bar/Cargo.toml index 7ecc624a3224025749b65d631031e3e8bf639052..8497877d045b99378c1c03ce8941cebe62bebfd8 100644 --- a/crates/platform_title_bar/Cargo.toml +++ b/crates/platform_title_bar/Cargo.toml @@ -13,7 +13,6 @@ path = "src/platform_title_bar.rs" doctest = false [dependencies] -feature_flags.workspace = true gpui.workspace = true project.workspace = true settings.workspace = true diff --git a/crates/platform_title_bar/src/platform_title_bar.rs b/crates/platform_title_bar/src/platform_title_bar.rs index c009d146403b21e592457d0c9a3f24819e80d642..8b7304e19f00c1d988bf2c5fa0b3166df970b936 100644 --- a/crates/platform_title_bar/src/platform_title_bar.rs +++ b/crates/platform_title_bar/src/platform_title_bar.rs @@ -1,7 +1,6 @@ pub mod platforms; mod system_window_tabs; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt}; use gpui::{ Action, AnyElement, App, Context, Decorations, Entity, Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, StatefulInteractiveElement, Styled, WeakEntity, Window, @@ -111,7 +110,7 @@ impl PlatformTitleBar { } pub fn is_multi_workspace_enabled(cx: &App) -> bool { - cx.has_flag::() && !DisableAiSettings::get_global(cx).disable_ai + !DisableAiSettings::get_global(cx).disable_ai } } diff --git a/crates/settings_ui/Cargo.toml b/crates/settings_ui/Cargo.toml index 0228f6886fc741505ffbe02fe82242d5f3e1dfd4..6c7c07e6c46b703dfbe4354f0ecface0fdbf370a 100644 --- a/crates/settings_ui/Cargo.toml +++ b/crates/settings_ui/Cargo.toml @@ -28,7 +28,6 @@ cpal.workspace = true edit_prediction.workspace = true edit_prediction_ui.workspace = true editor.workspace = true -feature_flags.workspace = true fs.workspace = true futures.workspace = true fuzzy.workspace = true diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index c77bf5a326c6b48dea2c85f0744de0066d8c0236..07e462da9ca2a5c7f7cc766aa6616e956b2f3aea 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -1,4 +1,3 @@ -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt as _}; use gpui::{Action as _, App}; use itertools::Itertools as _; use settings::{ @@ -7188,7 +7187,7 @@ fn ai_page(cx: &App) -> SettingsPage { ] } - fn agent_configuration_section(cx: &App) -> Box<[SettingsPageItem]> { + fn agent_configuration_section(_cx: &App) -> Box<[SettingsPageItem]> { let mut items = vec![ SettingsPageItem::SectionHeader("Agent Configuration"), SettingsPageItem::SubPageLink(SubPageLink { @@ -7202,30 +7201,28 @@ fn ai_page(cx: &App) -> SettingsPage { }), ]; - if cx.has_flag::() { - items.push(SettingsPageItem::SettingItem(SettingItem { - title: "New Thread Location", - description: "Whether to start a new thread in the current local project or in a new Git worktree.", - field: Box::new(SettingField { - json_path: Some("agent.new_thread_location"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .new_thread_location - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .new_thread_location = value; - }, - }), - metadata: None, - files: USER, - })); - } + items.push(SettingsPageItem::SettingItem(SettingItem { + title: "New Thread Location", + description: "Whether to start a new thread in the current local project or in a new Git worktree.", + field: Box::new(SettingField { + json_path: Some("agent.new_thread_location"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .new_thread_location + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .new_thread_location = value; + }, + }), + metadata: None, + files: USER, + })); items.extend([ SettingsPageItem::SettingItem(SettingItem { diff --git a/crates/sidebar/Cargo.toml b/crates/sidebar/Cargo.toml index d76fd139557dd10438d7cf98f9168d87dcae9804..41bf8cdad2068f0c67c38ea06fd176af11f3d560 100644 --- a/crates/sidebar/Cargo.toml +++ b/crates/sidebar/Cargo.toml @@ -24,7 +24,6 @@ agent_ui = { workspace = true, features = ["audio"] } anyhow.workspace = true chrono.workspace = true editor.workspace = true -feature_flags.workspace = true fs.workspace = true git.workspace = true gpui.workspace = true @@ -54,7 +53,6 @@ pretty_assertions.workspace = true prompt_store.workspace = true recent_projects = { workspace = true, features = ["test-support"] } serde_json.workspace = true -feature_flags.workspace = true fs = { workspace = true, features = ["test-support"] } git.workspace = true gpui = { workspace = true, features = ["test-support"] } diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 2646690003f238b2ab97809725244ed8344d4df6..65c5b7566cb496cf93ba9da195e16c12c07a8e08 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -14,7 +14,6 @@ use agent_ui::{ }; use chrono::{DateTime, Utc}; use editor::Editor; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagViewExt as _}; use gpui::{ Action as _, AnyElement, App, Context, Entity, FocusHandle, Focusable, KeyContext, ListState, Pixels, Render, SharedString, WeakEntity, Window, WindowHandle, linear_color_stop, @@ -434,11 +433,6 @@ impl Sidebar { }) .detach(); - cx.observe_flag::(window, |_is_enabled, this, _window, cx| { - this.update_entries(cx); - }) - .detach(); - let workspaces: Vec<_> = multi_workspace.read(cx).workspaces().cloned().collect(); cx.defer_in(window, move |this, window, cx| { for workspace in &workspaces { diff --git a/crates/sidebar/src/sidebar_tests.rs b/crates/sidebar/src/sidebar_tests.rs index eb37c6fd1c22d140ba085631deded64af893aae0..c5043e1bae08194a78e68a70d75970442e344467 100644 --- a/crates/sidebar/src/sidebar_tests.rs +++ b/crates/sidebar/src/sidebar_tests.rs @@ -6,7 +6,6 @@ use agent_ui::{ thread_metadata_store::ThreadMetadata, }; use chrono::DateTime; -use feature_flags::FeatureFlagAppExt as _; use fs::FakeFs; use gpui::TestAppContext; use pretty_assertions::assert_eq; @@ -24,7 +23,6 @@ fn init_test(cx: &mut TestAppContext) { cx.set_global(settings_store); theme_settings::init(theme::LoadThemes::JustBase, cx); editor::init(cx); - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -1220,7 +1218,6 @@ async fn init_test_project_with_agent_panel( ) -> Entity { agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -2078,7 +2075,7 @@ async fn test_focused_thread_tracks_user_intent(cx: &mut TestAppContext) { workspace.panel::(cx).is_some(), "Agent panel should exist" ); - let dock = workspace.right_dock().read(cx); + let dock = workspace.left_dock().read(cx); assert!( dock.is_open(), "Clicking a thread should open the agent panel dock" @@ -2425,7 +2422,6 @@ async fn test_cmd_n_shows_new_thread_entry_in_absorbed_worktree(cx: &mut TestApp // header and highlight it as active. agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -2974,7 +2970,6 @@ async fn test_absorbed_worktree_running_thread_shows_live_status(cx: &mut TestAp // live status (spinner + "(running)") in the sidebar. agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -3077,7 +3072,6 @@ async fn test_absorbed_worktree_running_thread_shows_live_status(cx: &mut TestAp async fn test_absorbed_worktree_completion_triggers_notification(cx: &mut TestAppContext) { agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -3990,7 +3984,6 @@ async fn test_archive_thread_uses_next_threads_own_workspace(cx: &mut TestAppCon // falling back to group_workspace only for Closed workspaces. agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -4772,7 +4765,6 @@ async fn init_multi_project_test( ) -> (Arc, Entity) { agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); @@ -5652,7 +5644,6 @@ mod property_test { ) { agent_ui::test_support::init_test(cx); cx.update(|cx| { - cx.update_flags(false, vec!["agent-v2".into()]); ThreadStore::init_global(cx); ThreadMetadataStore::init_global(cx); language_model::LanguageModelRegistry::test(cx); diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index a52246d3c40288e08e70ca5da3789d4493df3a44..d5308124a8d076914643fcb215c1acfa780c849c 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt}; use gpui::PathPromptOptions; use gpui::{ AnyView, App, Context, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle, Focusable, @@ -438,7 +437,7 @@ impl MultiWorkspace { } pub fn multi_workspace_enabled(&self, cx: &App) -> bool { - cx.has_flag::() && !DisableAiSettings::get_global(cx).disable_ai + !DisableAiSettings::get_global(cx).disable_ai } pub fn toggle_sidebar(&mut self, window: &mut Window, cx: &mut Context) { diff --git a/crates/workspace/src/multi_workspace_tests.rs b/crates/workspace/src/multi_workspace_tests.rs index ab6ca43d5aff482b637add9083b1ad9d388d7993..54677a433dc18624f6ca5c8ca152ab90b4c167e8 100644 --- a/crates/workspace/src/multi_workspace_tests.rs +++ b/crates/workspace/src/multi_workspace_tests.rs @@ -1,5 +1,4 @@ use super::*; -use feature_flags::FeatureFlagAppExt; use fs::FakeFs; use gpui::TestAppContext; use project::{DisableAiSettings, ProjectGroupKey}; @@ -12,7 +11,6 @@ fn init_test(cx: &mut TestAppContext) { cx.set_global(settings_store); theme_settings::init(theme::LoadThemes::JustBase, cx); DisableAiSettings::register(cx); - cx.update_flags(false, vec!["agent-v2".into()]); }); } diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index 2994e9d0f67d73a30838f922c9b6a0b01b21ed14..a0e64c223deeb5c6f7f536f8365f495a866eb521 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -2525,7 +2525,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4082,7 +4081,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4127,7 +4125,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4184,7 +4181,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4275,7 +4271,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4381,7 +4376,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4485,7 +4479,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4542,7 +4535,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); @@ -4702,7 +4694,6 @@ mod tests { cx.update(|cx| { cx.set_staff(true); - cx.update_flags(true, vec!["agent-v2".to_string()]); }); let fs = fs::FakeFs::new(cx.executor()); diff --git a/crates/zed/src/visual_test_runner.rs b/crates/zed/src/visual_test_runner.rs index 9f69cd3458c194228f37cfdeedcf0c9023b9b7bd..af1a60589483443e56506e7eeb7a8424d16a4143 100644 --- a/crates/zed/src/visual_test_runner.rs +++ b/crates/zed/src/visual_test_runner.rs @@ -2527,11 +2527,6 @@ fn run_multi_workspace_sidebar_visual_tests( std::fs::create_dir_all(&workspace1_dir)?; std::fs::create_dir_all(&workspace2_dir)?; - // Enable the agent-v2 feature flag so multi-workspace is active - cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); - }); - // Create both projects upfront so we can build both workspaces during // window creation, before the MultiWorkspace entity exists. // This avoids a re-entrant read panic that occurs when Workspace::new @@ -3082,11 +3077,6 @@ fn run_start_thread_in_selector_visual_tests( ) -> Result { use agent_ui::{AgentPanel, NewWorktreeBranchTarget, StartThreadIn, WorktreeCreationStatus}; - // Enable feature flags so the thread target selector renders - cx.update(|cx| { - cx.update_flags(true, vec!["agent-v2".to_string()]); - }); - // Create a temp directory with a real git repo so "New Worktree" is enabled let temp_dir = tempfile::tempdir()?; let temp_path = temp_dir.keep(); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index e572b5de0dd77931e72065fafa8866cd80a8f2fc..40d87e68787103bdc4d281748577ed6db5e9a5ad 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -2497,10 +2497,6 @@ mod tests { #[gpui::test] async fn test_open_paths_action(cx: &mut TestAppContext) { let app_state = init_test(cx); - cx.update(|cx| { - use feature_flags::FeatureFlagAppExt as _; - cx.update_flags(false, vec!["agent-v2".to_string()]); - }); app_state .fs .as_fake() @@ -5497,10 +5493,6 @@ mod tests { #[gpui::test] async fn test_open_paths_switches_to_best_workspace(cx: &mut TestAppContext) { let app_state = init_test(cx); - cx.update(|cx| { - use feature_flags::FeatureFlagAppExt as _; - cx.update_flags(false, vec!["agent-v2".to_string()]); - }); app_state .fs @@ -5702,10 +5694,6 @@ mod tests { async fn test_quit_checks_all_workspaces_for_dirty_items(cx: &mut TestAppContext) { let app_state = init_test(cx); cx.update(init); - cx.update(|cx| { - use feature_flags::FeatureFlagAppExt as _; - cx.update_flags(false, vec!["agent-v2".to_string()]); - }); app_state .fs @@ -5995,11 +5983,6 @@ mod tests { let app_state = init_test(cx); - cx.update(|cx| { - use feature_flags::FeatureFlagAppExt as _; - cx.update_flags(false, vec!["agent-v2".to_string()]); - }); - let dir1 = path!("/dir1"); let dir2 = path!("/dir2"); let dir3 = path!("/dir3");