Compare commits

...

8 Commits

Author SHA1 Message Date
Cole Miller
0b31e3fde5 WIP
Co-authored-by: Agus Zubiaga <hi@aguz.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2025-05-07 11:58:07 -04:00
Cole Miller
9a19fb400e Add failing test
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2025-05-07 09:48:40 -04:00
Antonio Scandurra
a1c5a58521 zed 0.186.1 2025-05-07 13:27:45 +02:00
gcp-cherry-pick-bot[bot]
703af39558 Fix zero-sized message editors when context strip is empty (cherry-pick #30079) (#30086)
Cherry-picked Fix zero-sized message editors when context strip is empty
(#30079)

Release Notes:

- Fixed a bug that would cause the message composer in the agent panel
to not render when the context strip was empty.

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Nathan Sobo <nathan@zed.dev>

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Nathan Sobo <nathan@zed.dev>
2025-05-07 13:12:48 +02:00
gcp-cherry-pick-bot[bot]
dc9b1d316d Avoid panic when opening thread as markdown in non-local project (cherry-pick #30061) (#30063)
Cherry-picked Avoid panic when opening thread as markdown in non-local
project (#30061)

Right now `agent: open active thread as markdown` will always panic when
you try to use it over collab or when SSH remoting. This PR makes it log
an error instead (we should follow up by restoring full remote support).

Release Notes:

- Prevented `agent: open active thread as markdown` from panicking when
used in a non-local project.

Co-authored-by: Cole Miller <cole@zed.dev>
2025-05-07 09:02:52 +03:00
Marshall Bowers
affec54b8e Update onboading modal copy 2025-05-06 21:55:20 -04:00
Marshall Bowers
4cde597d39 agent: Remove feature flag checks (#30055)
This PR removes all of the feature flag checks related to the Agent.

Tried to do this in the least invasive way possible; we can follow up
with a full removal.

Release Notes:

- N/A
2025-05-06 21:44:39 -04:00
Joseph T. Lyons
2e2ad6c80e v0.186.x preview 2025-05-06 19:49:40 -04:00
26 changed files with 161 additions and 199 deletions

8
Cargo.lock generated
View File

@@ -62,7 +62,6 @@ dependencies = [
"chrono",
"client",
"collections",
"command_palette_hooks",
"component",
"context_server",
"convert_case 0.8.0",
@@ -547,7 +546,6 @@ dependencies = [
"collections",
"context_server",
"editor",
"feature_flags",
"fs",
"futures 0.3.31",
"fuzzy",
@@ -597,7 +595,6 @@ dependencies = [
"anyhow",
"collections",
"deepseek",
"feature_flags",
"fs",
"gpui",
"indexmap",
@@ -12015,6 +12012,8 @@ version = "0.1.0"
dependencies = [
"anyhow",
"askpass",
"assistant_tool",
"assistant_tools",
"async-watch",
"backtrace",
"cargo_toml",
@@ -15088,7 +15087,6 @@ dependencies = [
"client",
"collections",
"db",
"feature_flags",
"gpui",
"http_client",
"notifications",
@@ -18697,7 +18695,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.186.0"
version = "0.186.1"
dependencies = [
"activity_indicator",
"agent",

View File

@@ -29,7 +29,6 @@ buffer_diff.workspace = true
chrono.workspace = true
client.workspace = true
collections.workspace = true
command_palette_hooks.workspace = true
component.workspace = true
context_server.workspace = true
convert_case.workspace = true

View File

@@ -3448,6 +3448,11 @@ pub(crate) fn open_active_thread_as_markdown(
.unwrap_or_else(|| "Thread".to_string());
let project = workspace.project().clone();
if !project.read(cx).is_local() {
anyhow::bail!("failed to open active thread as markdown in remote project");
}
let buffer = project.update(cx, |project, cx| {
project.create_local_buffer(&markdown, Some(markdown_language), cx)
});

View File

@@ -29,8 +29,6 @@ use std::sync::Arc;
use assistant_settings::{AgentProfileId, AssistantSettings};
use client::Client;
use command_palette_hooks::CommandPaletteFilter;
use feature_flags::{Assistant2FeatureFlag, FeatureFlagAppExt};
use fs::Fs;
use gpui::{App, actions, impl_actions};
use language::LanguageRegistry;
@@ -107,8 +105,6 @@ impl ManageProfiles {
impl_actions!(agent, [NewThread, ManageProfiles]);
const NAMESPACE: &str = "agent";
/// Initializes the `agent` crate.
pub fn init(
fs: Arc<dyn Fs>,
@@ -136,25 +132,4 @@ pub fn init(
);
cx.observe_new(AddContextServerModal::register).detach();
cx.observe_new(ManageProfilesModal::register).detach();
feature_gate_agent_actions(cx);
}
fn feature_gate_agent_actions(cx: &mut App) {
CommandPaletteFilter::update_global(cx, |filter, _cx| {
filter.hide_namespace(NAMESPACE);
});
cx.observe_flag::<Assistant2FeatureFlag, _>(move |is_enabled, cx| {
if is_enabled {
CommandPaletteFilter::update_global(cx, |filter, _cx| {
filter.show_namespace(NAMESPACE);
});
} else {
CommandPaletteFilter::update_global(cx, |filter, _cx| {
filter.hide_namespace(NAMESPACE);
});
}
})
.detach();
}

View File

@@ -17,7 +17,6 @@ use editor::{
ToDisplayPoint,
},
};
use feature_flags::{Assistant2FeatureFlag, FeatureFlagViewExt as _};
use fs::Fs;
use gpui::{
App, Context, Entity, Focusable, Global, HighlightStyle, Subscription, Task, UpdateGlobal,
@@ -66,15 +65,6 @@ pub fn init(
InlineAssistant::update_global(cx, |inline_assistant, cx| {
inline_assistant.register_workspace(&workspace, window, cx)
});
cx.observe_flag::<Assistant2FeatureFlag, _>(window, {
|is_assistant2_enabled, _workspace, _window, cx| {
InlineAssistant::update_global(cx, |inline_assistant, _cx| {
inline_assistant.is_assistant2_enabled = is_assistant2_enabled;
});
}
})
.detach();
})
.detach();
}
@@ -97,7 +87,6 @@ pub struct InlineAssistant {
prompt_builder: Arc<PromptBuilder>,
telemetry: Arc<Telemetry>,
fs: Arc<dyn Fs>,
is_assistant2_enabled: bool,
}
impl Global for InlineAssistant {}
@@ -119,7 +108,6 @@ impl InlineAssistant {
prompt_builder,
telemetry,
fs,
is_assistant2_enabled: false,
}
}
@@ -188,7 +176,7 @@ impl InlineAssistant {
window: &mut Window,
cx: &mut App,
) {
let is_assistant2_enabled = self.is_assistant2_enabled;
let is_assistant2_enabled = true;
if let Some(editor) = item.act_as::<Editor>(cx) {
editor.update(cx, |editor, cx| {

View File

@@ -17,7 +17,6 @@ use editor::{
AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, EditorEvent,
EditorMode, EditorStyle, MultiBuffer,
};
use feature_flags::{FeatureFlagAppExt, NewBillingFeatureFlag};
use file_icons::FileIcons;
use fs::Fs;
use futures::future::Shared;
@@ -464,10 +463,6 @@ impl MessageEditor {
}
fn render_max_mode_toggle(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
if !cx.has_flag::<NewBillingFeatureFlag>() {
return None;
}
let thread = self.thread.read(cx);
let model = thread.configured_model();
if !model?.model.supports_max_mode() {
@@ -642,7 +637,7 @@ impl MessageEditor {
this.h(vh(0.8, window)).justify_between()
})
.child(
div()
v_flex()
.min_h_16()
.when(is_editor_expanded, |this| this.h_full())
.child({
@@ -1074,10 +1069,6 @@ impl MessageEditor {
}
fn render_usage_callout(&self, line_height: Pixels, cx: &mut Context<Self>) -> Option<Div> {
if !cx.has_flag::<NewBillingFeatureFlag>() {
return None;
}
let is_using_zed_provider = self
.thread
.read(cx)
@@ -1139,10 +1130,6 @@ impl MessageEditor {
token_usage_ratio: TokenUsageRatio,
cx: &mut Context<Self>,
) -> Option<Div> {
if !cx.has_flag::<NewBillingFeatureFlag>() {
return None;
}
let title = if token_usage_ratio == TokenUsageRatio::Exceeded {
"Thread reached the token limit"
} else {

View File

@@ -143,7 +143,7 @@ impl Render for AgentOnboardingModal {
.full_width()
.on_click(cx.listener(Self::view_blog));
let copy = "Zed natively supports agentic editing, enabling seamless collaboration between humans and AI.";
let copy = "Zed now natively supports agentic editing, enabling fluid collaboration between humans and AI.";
base.child(Label::new(copy).color(Color::Muted)).child(
v_flex()

View File

@@ -17,9 +17,7 @@ use editor::{
ToDisplayPoint,
},
};
use feature_flags::{
Assistant2FeatureFlag, FeatureFlagAppExt as _, FeatureFlagViewExt as _, ZedProFeatureFlag,
};
use feature_flags::{FeatureFlagAppExt as _, ZedProFeatureFlag};
use fs::Fs;
use futures::{
SinkExt, Stream, StreamExt, TryStreamExt as _,
@@ -74,25 +72,19 @@ pub fn init(
cx: &mut App,
) {
cx.set_global(InlineAssistant::new(fs, prompt_builder, telemetry));
cx.observe_new(|_, window, cx| {
let Some(window) = window else {
return;
};
let workspace = cx.entity().clone();
InlineAssistant::update_global(cx, |inline_assistant, cx| {
inline_assistant.register_workspace(&workspace, window, cx)
});
cx.observe_flag::<Assistant2FeatureFlag, _>(window, {
|is_assistant2_enabled, _workspace, _window, cx| {
InlineAssistant::update_global(cx, |inline_assistant, _cx| {
inline_assistant.is_assistant2_enabled = is_assistant2_enabled;
});
}
// Don't register now that the Agent is released.
if false {
cx.observe_new(|_, window, cx| {
let Some(window) = window else {
return;
};
let workspace = cx.entity().clone();
InlineAssistant::update_global(cx, |inline_assistant, cx| {
inline_assistant.register_workspace(&workspace, window, cx)
});
})
.detach();
})
.detach();
}
}
const PROMPT_HISTORY_MAX_LEN: usize = 20;
@@ -108,7 +100,6 @@ pub struct InlineAssistant {
prompt_builder: Arc<PromptBuilder>,
telemetry: Arc<Telemetry>,
fs: Arc<dyn Fs>,
is_assistant2_enabled: bool,
}
impl Global for InlineAssistant {}
@@ -130,7 +121,6 @@ impl InlineAssistant {
prompt_builder,
telemetry,
fs,
is_assistant2_enabled: false,
}
}
@@ -199,7 +189,7 @@ impl InlineAssistant {
window: &mut Window,
cx: &mut App,
) {
let is_assistant2_enabled = self.is_assistant2_enabled;
let is_assistant2_enabled = true;
if let Some(editor) = item.act_as::<Editor>(cx) {
editor.update(cx, |editor, cx| {

View File

@@ -22,7 +22,6 @@ clock.workspace = true
collections.workspace = true
context_server.workspace = true
editor.workspace = true
feature_flags.workspace = true
fs.workspace = true
futures.workspace = true
fuzzy.workspace = true

View File

@@ -18,7 +18,6 @@ use editor::{
scroll::Autoscroll,
};
use editor::{FoldPlaceholder, display_map::CreaseId};
use feature_flags::{Assistant2FeatureFlag, FeatureFlagAppExt as _};
use fs::Fs;
use futures::FutureExt;
use gpui::{
@@ -2395,19 +2394,11 @@ impl ContextEditor {
.on_click({
let focus_handle = self.focus_handle(cx).clone();
move |_event, window, cx| {
if cx.has_flag::<Assistant2FeatureFlag>() {
focus_handle.dispatch_action(
&zed_actions::agent::OpenConfiguration,
window,
cx,
);
} else {
focus_handle.dispatch_action(
&zed_actions::assistant::ShowConfiguration,
window,
cx,
);
};
focus_handle.dispatch_action(
&zed_actions::agent::OpenConfiguration,
window,
cx,
);
}
}),
)

View File

@@ -15,7 +15,6 @@ path = "src/assistant_settings.rs"
anthropic = { workspace = true, features = ["schemars"] }
anyhow.workspace = true
collections.workspace = true
feature_flags.workspace = true
gpui.workspace = true
indexmap.workspace = true
language_model.workspace = true

View File

@@ -7,7 +7,6 @@ use anthropic::Model as AnthropicModel;
use anyhow::{Result, bail};
use collections::IndexMap;
use deepseek::Model as DeepseekModel;
use feature_flags::{AgentStreamEditsFeatureFlag, Assistant2FeatureFlag, FeatureFlagAppExt};
use gpui::{App, Pixels, SharedString};
use language_model::{CloudModel, LanguageModel};
use lmstudio::Model as LmStudioModel;
@@ -107,16 +106,13 @@ impl AssistantSettings {
.and_then(|m| m.temperature)
}
pub fn stream_edits(&self, cx: &App) -> bool {
cx.has_flag::<AgentStreamEditsFeatureFlag>() || self.stream_edits
pub fn stream_edits(&self, _cx: &App) -> bool {
// TODO: Remove the `stream_edits` setting.
true
}
pub fn are_live_diffs_enabled(&self, cx: &App) -> bool {
if cx.has_flag::<Assistant2FeatureFlag>() {
return false;
}
cx.is_staff() || self.enable_experimental_live_diffs
pub fn are_live_diffs_enabled(&self, _cx: &App) -> bool {
false
}
pub fn set_inline_assistant_model(&mut self, provider: String, model: String) {

View File

@@ -27,7 +27,6 @@ use std::sync::Arc;
use assistant_settings::AssistantSettings;
use assistant_tool::ToolRegistry;
use copy_path_tool::CopyPathTool;
use feature_flags::{AgentStreamEditsFeatureFlag, FeatureFlagAppExt};
use gpui::{App, Entity};
use http_client::HttpClientWithUrl;
use language_model::LanguageModelRegistry;
@@ -45,7 +44,6 @@ use crate::find_path_tool::FindPathTool;
use crate::grep_tool::GrepTool;
use crate::list_directory_tool::ListDirectoryTool;
use crate::now_tool::NowTool;
use crate::read_file_tool::ReadFileTool;
use crate::streaming_edit_file_tool::StreamingEditFileTool;
use crate::thinking_tool::ThinkingTool;
@@ -53,7 +51,7 @@ pub use create_file_tool::{CreateFileTool, CreateFileToolInput};
pub use edit_file_tool::{EditFileTool, EditFileToolInput};
pub use find_path_tool::FindPathToolInput;
pub use open_tool::OpenTool;
pub use read_file_tool::ReadFileToolInput;
pub use read_file_tool::{ReadFileTool, ReadFileToolInput};
pub use streaming_edit_file_tool::StreamingEditFileToolInput;
pub use terminal_tool::TerminalTool;
@@ -77,8 +75,6 @@ pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut App) {
registry.register_tool(FetchTool::new(http_client));
register_edit_file_tool(cx);
cx.observe_flag::<AgentStreamEditsFeatureFlag, _>(|_, cx| register_edit_file_tool(cx))
.detach();
cx.observe_global::<SettingsStore>(register_edit_file_tool)
.detach();

View File

@@ -581,7 +581,11 @@ async fn test_ssh_collaboration_formatting_with_prettier(
}
#[gpui::test]
async fn test_remote_server_debugger(cx_a: &mut TestAppContext, server_cx: &mut TestAppContext) {
async fn test_remote_server_debugger(
cx_a: &mut TestAppContext,
server_cx: &mut TestAppContext,
executor: BackgroundExecutor,
) {
cx_a.update(|cx| {
release_channel::init(SemanticVersion::default(), cx);
command_palette_hooks::init(cx);
@@ -679,7 +683,7 @@ async fn test_remote_server_debugger(cx_a: &mut TestAppContext, server_cx: &mut
});
client_ssh.update(cx_a, |a, _| {
a.shutdown_processes(Some(proto::ShutdownRemoteServer {}))
a.shutdown_processes(Some(proto::ShutdownRemoteServer {}), executor)
});
shutdown_session.await.unwrap();

View File

@@ -56,41 +56,6 @@ pub trait FeatureFlag {
}
}
/// Controls the values of various feature flags for the Agent launch.
///
/// Change this to `true` when we're ready to build the release candidate.
const AGENT_LAUNCH: bool = true;
pub struct Assistant2FeatureFlag;
impl FeatureFlag for Assistant2FeatureFlag {
const NAME: &'static str = "assistant2";
fn enabled_for_all() -> bool {
AGENT_LAUNCH
}
}
pub struct AgentStreamEditsFeatureFlag;
impl FeatureFlag for AgentStreamEditsFeatureFlag {
const NAME: &'static str = "agent-stream-edits";
fn enabled_for_all() -> bool {
AGENT_LAUNCH
}
}
pub struct NewBillingFeatureFlag;
impl FeatureFlag for NewBillingFeatureFlag {
const NAME: &'static str = "new-billing";
fn enabled_for_all() -> bool {
AGENT_LAUNCH
}
}
pub struct PredictEditsRateCompletionsFeatureFlag;
impl FeatureFlag for PredictEditsRateCompletionsFeatureFlag {
const NAME: &'static str = "predict-edits-rate-completions";

View File

@@ -1,7 +1,7 @@
use std::sync::Arc;
use collections::{HashSet, IndexMap};
use feature_flags::{Assistant2FeatureFlag, ZedProFeatureFlag};
use feature_flags::ZedProFeatureFlag;
use gpui::{
Action, AnyElement, AnyView, App, Corner, DismissEvent, Entity, EventEmitter, FocusHandle,
Focusable, Subscription, Task, WeakEntity, action_with_deprecated_aliases,
@@ -597,13 +597,10 @@ impl PickerDelegate for LanguageModelPickerDelegate {
.icon_color(Color::Muted)
.icon_position(IconPosition::Start)
.on_click(|_, window, cx| {
let configure_action = if cx.has_flag::<Assistant2FeatureFlag>() {
zed_actions::agent::OpenConfiguration.boxed_clone()
} else {
zed_actions::assistant::ShowConfiguration.boxed_clone()
};
window.dispatch_action(configure_action, cx);
window.dispatch_action(
zed_actions::agent::OpenConfiguration.boxed_clone(),
cx,
);
}),
)
.into_any(),

View File

@@ -1130,9 +1130,10 @@ impl Project {
cx.on_release(Self::release),
cx.on_app_quit(|this, cx| {
let shutdown = this.ssh_client.take().and_then(|client| {
client
.read(cx)
.shutdown_processes(Some(proto::ShutdownRemoteServer {}))
client.read(cx).shutdown_processes(
Some(proto::ShutdownRemoteServer {}),
cx.background_executor().clone(),
)
});
cx.background_executor().spawn(async move {
@@ -1472,9 +1473,10 @@ impl Project {
fn release(&mut self, cx: &mut App) {
if let Some(client) = self.ssh_client.take() {
let shutdown = client
.read(cx)
.shutdown_processes(Some(proto::ShutdownRemoteServer {}));
let shutdown = client.read(cx).shutdown_processes(
Some(proto::ShutdownRemoteServer {}),
cx.background_executor().clone(),
);
cx.background_spawn(async move {
if let Some(shutdown) = shutdown {

View File

@@ -18,8 +18,8 @@ use futures::{
select, select_biased,
};
use gpui::{
App, AppContext as _, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Global,
SemanticVersion, Task, WeakEntity,
App, AppContext as _, AsyncApp, Background, BackgroundExecutor, BorrowAppContext, Context,
Entity, EventEmitter, Global, SemanticVersion, Task, WeakEntity,
};
use itertools::Itertools;
use parking_lot::Mutex;
@@ -683,6 +683,7 @@ impl SshRemoteClient {
pub fn shutdown_processes<T: RequestMessage>(
&self,
shutdown_request: Option<T>,
executor: BackgroundExecutor,
) -> Option<impl Future<Output = ()> + use<T>> {
let state = self.state.lock().take()?;
log::info!("shutting down ssh processes");
@@ -705,7 +706,9 @@ impl SshRemoteClient {
// We wait 50ms instead of waiting for a response, because
// waiting for a response would require us to wait on the main thread
// which we want to avoid in an `on_app_quit` callback.
smol::Timer::after(Duration::from_millis(50)).await;
dbg!("before");
executor.timer(Duration::from_millis(50)).await;
dbg!("after");
}
// Drop `multiplex_task` because it owns our ssh_proxy_process, which is a

View File

@@ -80,6 +80,8 @@ node_runtime = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
remote = { workspace = true, features = ["test-support"] }
lsp = { workspace = true, features=["test-support"] }
assistant_tool.workspace = true
assistant_tools.workspace = true
unindent.workspace = true
serde_json.workspace = true

View File

@@ -2,6 +2,8 @@
/// The tests in this file assume that server_cx is running on Windows too.
/// We neead to find a way to test Windows-Non-Windows interactions.
use crate::headless_project::HeadlessProject;
use assistant_tool::Tool as _;
use assistant_tools::{ReadFileTool, ReadFileToolInput};
use client::{Client, UserStore};
use clock::FakeSystemClock;
@@ -1548,6 +1550,71 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
assert_eq!(server_branch.name(), "totally-new-branch");
}
#[gpui::test]
async fn test_remote_agent_fs_tool_calls(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
let fs = FakeFs::new(server_cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"a.txt": "A",
"b.txt": "B",
}),
)
.await;
let (project, headless_project) = init_test(&fs, cx, server_cx).await;
let (worktree, _) = project
.update(cx, |project, cx| {
project.find_or_create_worktree(path!("/project"), true, cx)
})
.await
.unwrap();
cx.run_until_parked();
let action_log = cx.new(|_| assistant_tool::ActionLog::new(project.clone()));
let input = ReadFileToolInput {
path: "project/b.txt".into(),
start_line: None,
end_line: None,
};
let exists_result = cx.update(|cx| {
ReadFileTool::run(
Arc::new(ReadFileTool),
serde_json::to_value(input).unwrap(),
&[],
project.clone(),
action_log.clone(),
None,
cx,
)
});
let output = exists_result.output.await;
assert_eq!(output.unwrap(), "B");
let input = ReadFileToolInput {
path: "project/c.txt".into(),
start_line: None,
end_line: None,
};
let does_not_exist_result = cx.update(|cx| {
ReadFileTool::run(
Arc::new(ReadFileTool),
serde_json::to_value(input).unwrap(),
&[],
project.clone(),
action_log.clone(),
None,
cx,
)
});
let output = does_not_exist_result.output.await;
assert!(output.is_err());
dbg!("HERE");
}
pub async fn init_test(
server_fs: &Arc<FakeFs>,
cx: &mut TestAppContext,

View File

@@ -32,7 +32,6 @@ call.workspace = true
chrono.workspace = true
client.workspace = true
db.workspace = true
feature_flags.workspace = true
gpui.workspace = true
notifications.workspace = true
project.workspace = true

View File

@@ -19,7 +19,6 @@ use crate::platforms::{platform_linux, platform_mac, platform_windows};
use auto_update::AutoUpdateStatus;
use call::ActiveCall;
use client::{Client, UserStore};
use feature_flags::{FeatureFlagAppExt, NewBillingFeatureFlag};
use gpui::{
Action, AnyElement, App, Context, Corner, Decorations, Element, Entity, InteractiveElement,
Interactivity, IntoElement, MouseButton, ParentElement, Render, Stateful,
@@ -678,22 +677,20 @@ impl TitleBar {
PopoverMenu::new("user-menu")
.anchor(Corner::TopRight)
.menu(move |window, cx| {
ContextMenu::build(window, cx, |menu, _, cx| {
menu.when(cx.has_flag::<NewBillingFeatureFlag>(), |menu| {
menu.action(
format!(
"Current Plan: {}",
match plan {
None => "",
Some(proto::Plan::Free) => "Free",
Some(proto::Plan::ZedPro) => "Pro",
Some(proto::Plan::ZedProTrial) => "Pro (Trial)",
}
),
zed_actions::OpenAccountSettings.boxed_clone(),
)
.separator()
})
ContextMenu::build(window, cx, |menu, _, _cx| {
menu.action(
format!(
"Current Plan: {}",
match plan {
None => "",
Some(proto::Plan::Free) => "Free",
Some(proto::Plan::ZedPro) => "Pro",
Some(proto::Plan::ZedProTrial) => "Pro (Trial)",
}
),
zed_actions::OpenAccountSettings.boxed_clone(),
)
.separator()
.action("Settings", zed_actions::OpenSettings.boxed_clone())
.action("Key Bindings", Box::new(zed_actions::OpenKeymap))
.action(

View File

@@ -817,9 +817,20 @@ impl Worktree {
Ok(metadata.map_or(false, |metadata| !metadata.is_dir))
})
}
Worktree::Remote(_) => Task::ready(Err(anyhow!(
"remote worktrees can't yet check file existence"
))),
Worktree::Remote(this) => {
let path = match this.absolutize(path) {
Ok(path) => path,
Err(e) => return Task::ready(Err(e)),
};
let request = this.client.request(proto::GetPathMetadata {
project_id: this.project_id,
path: path.to_proto(),
});
cx.background_spawn(async move {
let metadata = request.await?;
anyhow::Ok(metadata.exists && !metadata.is_dir)
})
}
}
}

View File

@@ -2,7 +2,7 @@
description = "The fast, collaborative code editor."
edition.workspace = true
name = "zed"
version = "0.186.0"
version = "0.186.1"
publish.workspace = true
license = "GPL-3.0-or-later"
authors = ["Zed Team <hi@zed.dev>"]

View File

@@ -1 +1 @@
dev
preview

View File

@@ -19,7 +19,7 @@ use collections::VecDeque;
use debugger_ui::debugger_panel::DebugPanel;
use editor::ProposedChangesEditorToolbar;
use editor::{Editor, MultiBuffer, scroll::Autoscroll};
use feature_flags::{DebuggerFeatureFlag, FeatureFlagAppExt, FeatureFlagViewExt};
use feature_flags::{DebuggerFeatureFlag, FeatureFlagViewExt};
use futures::{StreamExt, channel::mpsc, select_biased};
use git_ui::git_panel::GitPanel;
use git_ui::project_diff::ProjectDiffToolbar;
@@ -53,7 +53,6 @@ use settings::{
};
use std::path::PathBuf;
use std::sync::atomic::{self, AtomicBool};
use std::time::Duration;
use std::{borrow::Cow, path::Path, sync::Arc};
use terminal_view::terminal_panel::{self, TerminalPanel};
use theme::{ActiveTheme, ThemeSettings};
@@ -373,9 +372,6 @@ fn initialize_panels(
window: &mut Window,
cx: &mut Context<Workspace>,
) {
let assistant2_feature_flag =
cx.wait_for_flag_or_timeout::<feature_flags::Assistant2FeatureFlag>(Duration::from_secs(5));
let prompt_builder = prompt_builder.clone();
cx.spawn_in(window, async move |workspace_handle, cx| {
@@ -436,11 +432,7 @@ fn initialize_panels(
workspace.add_panel(git_panel, window, cx);
})?;
let is_assistant2_enabled = if cfg!(test) {
false
} else {
assistant2_feature_flag.await
};
let is_assistant2_enabled = !cfg!(test);
let (assistant_panel, assistant2_panel) = if is_assistant2_enabled {
let assistant2_panel =