Detailed changes
  
  
    
    @@ -581,13 +581,11 @@ impl Item for AgentDiffPane {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
-            Self::new(self.thread.clone(), self.workspace.clone(), window, cx)
-        })))
+        Some(cx.new(|cx| Self::new(self.thread.clone(), self.workspace.clone(), window, cx)))
     }
 
     fn is_dirty(&self, cx: &App) -> bool {
  
  
  
    
    @@ -776,30 +776,26 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
         .unwrap();
 
     // Clients A and B follow each other in split panes
-    workspace_a
-        .update_in(cx_a, |workspace, window, cx| {
-            workspace.split_and_clone(
-                workspace.active_pane().clone(),
-                SplitDirection::Right,
-                window,
-                cx,
-            )
-        })
-        .await;
+    workspace_a.update_in(cx_a, |workspace, window, cx| {
+        workspace.split_and_clone(
+            workspace.active_pane().clone(),
+            SplitDirection::Right,
+            window,
+            cx,
+        );
+    });
     workspace_a.update_in(cx_a, |workspace, window, cx| {
         workspace.follow(client_b.peer_id().unwrap(), window, cx)
     });
     executor.run_until_parked();
-    workspace_b
-        .update_in(cx_b, |workspace, window, cx| {
-            workspace.split_and_clone(
-                workspace.active_pane().clone(),
-                SplitDirection::Right,
-                window,
-                cx,
-            )
-        })
-        .await;
+    workspace_b.update_in(cx_b, |workspace, window, cx| {
+        workspace.split_and_clone(
+            workspace.active_pane().clone(),
+            SplitDirection::Right,
+            window,
+            cx,
+        );
+    });
     workspace_b.update_in(cx_b, |workspace, window, cx| {
         workspace.follow(client_a.peer_id().unwrap(), window, cx)
     });
@@ -1373,11 +1369,9 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
     );
 
     // When client B activates a different pane, it continues following client A in the original pane.
-    workspace_b
-        .update_in(cx_b, |workspace, window, cx| {
-            workspace.split_and_clone(pane_b.clone(), SplitDirection::Right, window, cx)
-        })
-        .await;
+    workspace_b.update_in(cx_b, |workspace, window, cx| {
+        workspace.split_and_clone(pane_b.clone(), SplitDirection::Right, window, cx)
+    });
     assert_eq!(
         workspace_b.update(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
         Some(leader_id.into())
  
  
  
    
    @@ -6748,7 +6748,7 @@ async fn test_preview_tabs(cx: &mut TestAppContext) {
     pane.update(cx, |pane, cx| {
         pane.split(workspace::SplitDirection::Right, cx);
     });
-    cx.run_until_parked();
+
     let right_pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
     pane.update(cx, |pane, cx| {
  
  
  
    
    @@ -498,8 +498,8 @@ impl Item for ChannelView {
         _: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>> {
-        Task::ready(Some(cx.new(|cx| {
+    ) -> Option<Entity<Self>> {
+        Some(cx.new(|cx| {
             Self::new(
                 self.project.clone(),
                 self.workspace.clone(),
@@ -508,7 +508,7 @@ impl Item for ChannelView {
                 window,
                 cx,
             )
-        })))
+        }))
     }
 
     fn navigate(
  
  
  
    
    @@ -693,11 +693,11 @@ impl Item for BufferDiagnosticsEditor {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
+        Some(cx.new(|cx| {
             BufferDiagnosticsEditor::new(
                 self.project_path.clone(),
                 self.project.clone(),
@@ -706,7 +706,7 @@ impl Item for BufferDiagnosticsEditor {
                 window,
                 cx,
             )
-        })))
+        }))
     }
 
     fn deactivated(&mut self, window: &mut Window, cx: &mut Context<Self>) {
  
  
  
    
    @@ -732,11 +732,11 @@ impl Item for ProjectDiagnosticsEditor {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
+        Some(cx.new(|cx| {
             ProjectDiagnosticsEditor::new(
                 self.include_warnings,
                 self.project.clone(),
@@ -744,7 +744,7 @@ impl Item for ProjectDiagnosticsEditor {
                 window,
                 cx,
             )
-        })))
+        }))
     }
 
     fn is_dirty(&self, cx: &App) -> bool {
  
  
  
    
    @@ -762,11 +762,11 @@ impl Item for Editor {
         _workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Editor>>>
+    ) -> Option<Entity<Editor>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| self.clone(window, cx))))
+        Some(cx.new(|cx| self.clone(window, cx)))
     }
 
     fn set_nav_history(
  
  
  
    
    @@ -4,8 +4,8 @@ use editor::{Editor, EditorEvent, MultiBuffer, SelectionEffects, multibuffer_con
 use git::repository::{CommitDetails, CommitDiff, RepoPath};
 use gpui::{
     Action, AnyElement, AnyView, App, AppContext as _, AsyncApp, AsyncWindowContext, Context,
-    Entity, EventEmitter, FocusHandle, Focusable, IntoElement, PromptLevel, Render, Task,
-    WeakEntity, Window, actions,
+    Entity, EventEmitter, FocusHandle, Focusable, IntoElement, PromptLevel, Render, WeakEntity,
+    Window, actions,
 };
 use language::{
     Anchor, Buffer, Capability, DiskState, File, LanguageRegistry, LineEnding, OffsetRangeExt as _,
@@ -561,11 +561,11 @@ impl Item for CommitView {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
+        Some(cx.new(|cx| {
             let editor = cx.new(|cx| {
                 self.editor
                     .update(cx, |editor, cx| editor.clone(window, cx))
@@ -577,7 +577,7 @@ impl Item for CommitView {
                 commit: self.commit.clone(),
                 stash: self.stash,
             }
-        })))
+        }))
     }
 }
 
  
  
  
    
    @@ -625,16 +625,12 @@ impl Item for ProjectDiff {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        let Some(workspace) = self.workspace.upgrade() else {
-            return Task::ready(None);
-        };
-        Task::ready(Some(cx.new(|cx| {
-            ProjectDiff::new(self.project.clone(), workspace, window, cx)
-        })))
+        let workspace = self.workspace.upgrade()?;
+        Some(cx.new(|cx| ProjectDiff::new(self.project.clone(), workspace, window, cx)))
     }
 
     fn is_dirty(&self, cx: &App) -> bool {
  
  
  
    
    @@ -179,15 +179,15 @@ impl Item for ImageView {
         _workspace_id: Option<WorkspaceId>,
         _: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| Self {
+        Some(cx.new(|cx| Self {
             image_item: self.image_item.clone(),
             project: self.project.clone(),
             focus_handle: cx.focus_handle(),
-        })))
+        }))
     }
 
     fn has_deleted_file(&self, cx: &App) -> bool {
  
  
  
    
    @@ -1,7 +1,6 @@
 use gpui::{
     Action, App, AppContext as _, Entity, EventEmitter, FocusHandle, Focusable,
-    KeyBindingContextPredicate, KeyContext, Keystroke, MouseButton, Render, Subscription, Task,
-    actions,
+    KeyBindingContextPredicate, KeyContext, Keystroke, MouseButton, Render, Subscription, actions,
 };
 use itertools::Itertools;
 use serde_json::json;
@@ -158,11 +157,11 @@ impl Item for KeyContextView {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| KeyContextView::new(window, cx))))
+        Some(cx.new(|cx| KeyContextView::new(window, cx)))
     }
 }
 
  
  
  
    
    @@ -3,7 +3,7 @@ use copilot::Copilot;
 use editor::{Editor, EditorEvent, actions::MoveToEnd, scroll::Autoscroll};
 use gpui::{
     AnyView, App, Context, Corner, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
-    ParentElement, Render, Styled, Subscription, Task, WeakEntity, Window, actions, div,
+    ParentElement, Render, Styled, Subscription, WeakEntity, Window, actions, div,
 };
 use itertools::Itertools;
 use language::{LanguageServerId, language_settings::SoftWrap};
@@ -763,11 +763,11 @@ impl Item for LspLogView {
         _workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
+        Some(cx.new(|cx| {
             let mut new_view = Self::new(self.project.clone(), self.log_store.clone(), window, cx);
             if let Some(server_id) = self.current_server_id {
                 match self.active_entry_kind {
@@ -778,7 +778,7 @@ impl Item for LspLogView {
                 }
             }
             new_view
-        })))
+        }))
     }
 }
 
  
  
  
    
    @@ -3,7 +3,7 @@ use editor::{Anchor, Editor, ExcerptId, SelectionEffects, scroll::Autoscroll};
 use gpui::{
     App, AppContext as _, Context, Div, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
     Hsla, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, MouseMoveEvent,
-    ParentElement, Render, ScrollStrategy, SharedString, Styled, Task, UniformListScrollHandle,
+    ParentElement, Render, ScrollStrategy, SharedString, Styled, UniformListScrollHandle,
     WeakEntity, Window, actions, div, rems, uniform_list,
 };
 use language::{Buffer, OwnedSyntaxLayer};
@@ -573,17 +573,17 @@ impl Item for SyntaxTreeView {
         _: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
+        Some(cx.new(|cx| {
             let mut clone = Self::new(self.workspace_handle.clone(), None, window, cx);
             if let Some(editor) = &self.editor {
                 clone.set_editor(editor.editor.clone(), window, cx)
             }
             clone
-        })))
+        }))
     }
 }
 
  
  
  
    
    @@ -384,14 +384,14 @@ impl Item for Onboarding {
         _workspace_id: Option<WorkspaceId>,
         _: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>> {
-        Task::ready(Some(cx.new(|cx| Onboarding {
+    ) -> Option<Entity<Self>> {
+        Some(cx.new(|cx| Onboarding {
             workspace: self.workspace.clone(),
             user_store: self.user_store.clone(),
             scroll_handle: ScrollHandle::new(),
             focus_handle: cx.focus_handle(),
             _settings_subscription: cx.observe_global::<SettingsStore>(move |_, cx| cx.notify()),
-        })))
+        }))
     }
 
     fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) {
  
  
  
    
    @@ -139,146 +139,141 @@ impl Project {
             .await
             .unwrap_or_default();
 
-            let builder = project
-                .update(cx, move |_, cx| {
-                    let format_to_run = || {
-                        if let Some(command) = &spawn_task.command {
-                            let mut command: Option<Cow<str>> = shell_kind.try_quote(command);
-                            if let Some(command) = &mut command
-                                && command.starts_with('"')
-                                && let Some(prefix) = shell_kind.command_prefix()
-                            {
-                                *command = Cow::Owned(format!("{prefix}{command}"));
-                            }
-
-                            let args = spawn_task
-                                .args
-                                .iter()
-                                .filter_map(|arg| shell_kind.try_quote(&arg));
-
-                            command.into_iter().chain(args).join(" ")
-                        } else {
-                            // todo: this breaks for remotes to windows
-                            format!("exec {shell} -l")
+            project.update(cx, move |this, cx| {
+                let format_to_run = || {
+                    if let Some(command) = &spawn_task.command {
+                        let mut command: Option<Cow<str>> = shell_kind.try_quote(command);
+                        if let Some(command) = &mut command
+                            && command.starts_with('"')
+                            && let Some(prefix) = shell_kind.command_prefix()
+                        {
+                            *command = Cow::Owned(format!("{prefix}{command}"));
                         }
-                    };
 
-                    let (shell, env) = {
-                        env.extend(spawn_task.env);
-                        match remote_client {
-                            Some(remote_client) => match activation_script.clone() {
-                                activation_script if !activation_script.is_empty() => {
-                                    let activation_script = activation_script.join("; ");
-                                    let to_run = format_to_run();
-                                    let args = vec![
-                                        "-c".to_owned(),
-                                        format!("{activation_script}; {to_run}"),
-                                    ];
-                                    create_remote_shell(
-                                        Some((
-                                            &remote_client
-                                                .read(cx)
-                                                .shell()
-                                                .unwrap_or_else(get_default_system_shell),
-                                            &args,
-                                        )),
-                                        env,
-                                        path,
-                                        remote_client,
-                                        cx,
-                                    )?
-                                }
-                                _ => create_remote_shell(
-                                    spawn_task
-                                        .command
-                                        .as_ref()
-                                        .map(|command| (command, &spawn_task.args)),
+                        let args = spawn_task
+                            .args
+                            .iter()
+                            .filter_map(|arg| shell_kind.try_quote(&arg));
+
+                        command.into_iter().chain(args).join(" ")
+                    } else {
+                        // todo: this breaks for remotes to windows
+                        format!("exec {shell} -l")
+                    }
+                };
+
+                let (shell, env) = {
+                    env.extend(spawn_task.env);
+                    match remote_client {
+                        Some(remote_client) => match activation_script.clone() {
+                            activation_script if !activation_script.is_empty() => {
+                                let activation_script = activation_script.join("; ");
+                                let to_run = format_to_run();
+                                let args =
+                                    vec!["-c".to_owned(), format!("{activation_script}; {to_run}")];
+                                create_remote_shell(
+                                    Some((
+                                        &remote_client
+                                            .read(cx)
+                                            .shell()
+                                            .unwrap_or_else(get_default_system_shell),
+                                        &args,
+                                    )),
                                     env,
                                     path,
                                     remote_client,
                                     cx,
-                                )?,
-                            },
-                            None => match activation_script.clone() {
-                                activation_script if !activation_script.is_empty() => {
-                                    let separator = shell_kind.sequential_commands_separator();
-                                    let activation_script =
-                                        activation_script.join(&format!("{separator} "));
-                                    let to_run = format_to_run();
-
-                                    let mut arg =
-                                        format!("{activation_script}{separator} {to_run}");
-                                    if shell_kind == ShellKind::Cmd {
-                                        // We need to put the entire command in quotes since otherwise CMD tries to execute them
-                                        // as separate commands rather than chaining one after another.
-                                        arg = format!("\"{arg}\"");
-                                    }
+                                )?
+                            }
+                            _ => create_remote_shell(
+                                spawn_task
+                                    .command
+                                    .as_ref()
+                                    .map(|command| (command, &spawn_task.args)),
+                                env,
+                                path,
+                                remote_client,
+                                cx,
+                            )?,
+                        },
+                        None => match activation_script.clone() {
+                            activation_script if !activation_script.is_empty() => {
+                                let separator = shell_kind.sequential_commands_separator();
+                                let activation_script =
+                                    activation_script.join(&format!("{separator} "));
+                                let to_run = format_to_run();
+
+                                let mut arg = format!("{activation_script}{separator} {to_run}");
+                                if shell_kind == ShellKind::Cmd {
+                                    // We need to put the entire command in quotes since otherwise CMD tries to execute them
+                                    // as separate commands rather than chaining one after another.
+                                    arg = format!("\"{arg}\"");
+                                }
 
-                                    let args = shell_kind.args_for_shell(false, arg);
+                                let args = shell_kind.args_for_shell(false, arg);
 
-                                    (
-                                        Shell::WithArguments {
-                                            program: shell,
-                                            args,
-                                            title_override: None,
-                                        },
-                                        env,
-                                    )
-                                }
-                                _ => (
-                                    if let Some(program) = spawn_task.command {
-                                        Shell::WithArguments {
-                                            program,
-                                            args: spawn_task.args,
-                                            title_override: None,
-                                        }
-                                    } else {
-                                        Shell::System
+                                (
+                                    Shell::WithArguments {
+                                        program: shell,
+                                        args,
+                                        title_override: None,
                                     },
                                     env,
-                                ),
-                            },
+                                )
+                            }
+                            _ => (
+                                if let Some(program) = spawn_task.command {
+                                    Shell::WithArguments {
+                                        program,
+                                        args: spawn_task.args,
+                                        title_override: None,
+                                    }
+                                } else {
+                                    Shell::System
+                                },
+                                env,
+                            ),
+                        },
+                    }
+                };
+                TerminalBuilder::new(
+                    local_path.map(|path| path.to_path_buf()),
+                    task_state,
+                    shell,
+                    env,
+                    settings.cursor_shape,
+                    settings.alternate_scroll,
+                    settings.max_scroll_history_lines,
+                    is_via_remote,
+                    cx.entity_id().as_u64(),
+                    Some(completion_tx),
+                    cx,
+                    activation_script,
+                )
+                .map(|builder| {
+                    let terminal_handle = cx.new(|cx| builder.subscribe(cx));
+
+                    this.terminals
+                        .local_handles
+                        .push(terminal_handle.downgrade());
+
+                    let id = terminal_handle.entity_id();
+                    cx.observe_release(&terminal_handle, move |project, _terminal, cx| {
+                        let handles = &mut project.terminals.local_handles;
+
+                        if let Some(index) = handles
+                            .iter()
+                            .position(|terminal| terminal.entity_id() == id)
+                        {
+                            handles.remove(index);
+                            cx.notify();
                         }
-                    };
-                    anyhow::Ok(TerminalBuilder::new(
-                        local_path.map(|path| path.to_path_buf()),
-                        task_state,
-                        shell,
-                        env,
-                        settings.cursor_shape,
-                        settings.alternate_scroll,
-                        settings.max_scroll_history_lines,
-                        is_via_remote,
-                        cx.entity_id().as_u64(),
-                        Some(completion_tx),
-                        cx,
-                        activation_script,
-                    ))
-                })??
-                .await?;
-            project.update(cx, move |this, cx| {
-                let terminal_handle = cx.new(|cx| builder.subscribe(cx));
+                    })
+                    .detach();
 
-                this.terminals
-                    .local_handles
-                    .push(terminal_handle.downgrade());
-
-                let id = terminal_handle.entity_id();
-                cx.observe_release(&terminal_handle, move |project, _terminal, cx| {
-                    let handles = &mut project.terminals.local_handles;
-
-                    if let Some(index) = handles
-                        .iter()
-                        .position(|terminal| terminal.entity_id() == id)
-                    {
-                        handles.remove(index);
-                        cx.notify();
-                    }
+                    terminal_handle
                 })
-                .detach();
-
-                terminal_handle
-            })
+            })?
         })
     }
 
@@ -359,55 +354,53 @@ impl Project {
             })
             .await
             .unwrap_or_default();
-            let builder = project
-                .update(cx, move |_, cx| {
-                    let (shell, env) = {
-                        match remote_client {
-                            Some(remote_client) => {
-                                create_remote_shell(None, env, path, remote_client, cx)?
-                            }
-                            None => (settings.shell, env),
-                        }
-                    };
-                    anyhow::Ok(TerminalBuilder::new(
-                        local_path.map(|path| path.to_path_buf()),
-                        None,
-                        shell,
-                        env,
-                        settings.cursor_shape,
-                        settings.alternate_scroll,
-                        settings.max_scroll_history_lines,
-                        is_via_remote,
-                        cx.entity_id().as_u64(),
-                        None,
-                        cx,
-                        activation_script,
-                    ))
-                })??
-                .await?;
             project.update(cx, move |this, cx| {
-                let terminal_handle = cx.new(|cx| builder.subscribe(cx));
-
-                this.terminals
-                    .local_handles
-                    .push(terminal_handle.downgrade());
-
-                let id = terminal_handle.entity_id();
-                cx.observe_release(&terminal_handle, move |project, _terminal, cx| {
-                    let handles = &mut project.terminals.local_handles;
-
-                    if let Some(index) = handles
-                        .iter()
-                        .position(|terminal| terminal.entity_id() == id)
-                    {
-                        handles.remove(index);
-                        cx.notify();
+                let (shell, env) = {
+                    match remote_client {
+                        Some(remote_client) => {
+                            create_remote_shell(None, env, path, remote_client, cx)?
+                        }
+                        None => (settings.shell, env),
                     }
-                })
-                .detach();
+                };
+                TerminalBuilder::new(
+                    local_path.map(|path| path.to_path_buf()),
+                    None,
+                    shell,
+                    env,
+                    settings.cursor_shape,
+                    settings.alternate_scroll,
+                    settings.max_scroll_history_lines,
+                    is_via_remote,
+                    cx.entity_id().as_u64(),
+                    None,
+                    cx,
+                    activation_script,
+                )
+                .map(|builder| {
+                    let terminal_handle = cx.new(|cx| builder.subscribe(cx));
+
+                    this.terminals
+                        .local_handles
+                        .push(terminal_handle.downgrade());
+
+                    let id = terminal_handle.entity_id();
+                    cx.observe_release(&terminal_handle, move |project, _terminal, cx| {
+                        let handles = &mut project.terminals.local_handles;
+
+                        if let Some(index) = handles
+                            .iter()
+                            .position(|terminal| terminal.entity_id() == id)
+                        {
+                            handles.remove(index);
+                            cx.notify();
+                        }
+                    })
+                    .detach();
 
-                terminal_handle
-            })
+                    terminal_handle
+                })
+            })?
         })
     }
 
@@ -416,27 +409,20 @@ impl Project {
         terminal: &Entity<Terminal>,
         cx: &mut Context<'_, Project>,
         cwd: Option<PathBuf>,
-    ) -> Task<Result<Entity<Terminal>>> {
-        // We cannot clone the task's terminal, as it will effectively re-spawn the task, which might not be desirable.
-        // For now, create a new shell instead.
-        if terminal.read(cx).task().is_some() {
-            return self.create_terminal_shell(cwd, cx);
-        }
-
+    ) -> Result<Entity<Terminal>> {
         let local_path = if self.is_via_remote_server() {
             None
         } else {
             cwd
         };
 
-        let builder = terminal.read(cx).clone_builder(cx, local_path);
-        cx.spawn(async |project, cx| {
-            let terminal = builder.await?;
-            project.update(cx, |project, cx| {
-                let terminal_handle = cx.new(|cx| terminal.subscribe(cx));
+        terminal
+            .read(cx)
+            .clone_builder(cx, local_path)
+            .map(|builder| {
+                let terminal_handle = cx.new(|cx| builder.subscribe(cx));
 
-                project
-                    .terminals
+                self.terminals
                     .local_handles
                     .push(terminal_handle.downgrade());
 
@@ -456,7 +442,6 @@ impl Project {
 
                 terminal_handle
             })
-        })
     }
 
     pub fn terminal_settings<'a>(
  
  
  
    
    @@ -709,13 +709,11 @@ impl Item for NotebookEditor {
         _workspace_id: Option<workspace::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| {
-            Self::new(self.project.clone(), self.notebook_item.clone(), window, cx)
-        })))
+        Some(cx.new(|cx| Self::new(self.project.clone(), self.notebook_item.clone(), window, cx)))
     }
 
     fn buffer_kind(&self, _: &App) -> workspace::item::ItemBufferKind {
  
  
  
    
    @@ -572,14 +572,12 @@ impl Item for ProjectSearchView {
         _workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
         let model = self.entity.update(cx, |model, cx| model.clone(cx));
-        Task::ready(Some(cx.new(|cx| {
-            Self::new(self.workspace.clone(), model, window, cx, None)
-        })))
+        Some(cx.new(|cx| Self::new(self.workspace.clone(), model, window, cx, None)))
     }
 
     fn added_to_workspace(
@@ -3696,7 +3694,6 @@ pub mod tests {
                 )
             })
             .unwrap()
-            .await
             .unwrap();
         assert_eq!(cx.update(|cx| second_pane.read(cx).items_len()), 1);
 
@@ -3892,7 +3889,6 @@ pub mod tests {
                 )
             })
             .unwrap()
-            .await
             .unwrap();
         assert_eq!(cx.update(|cx| second_pane.read(cx).items_len()), 1);
         assert!(
  
  
  
    
    @@ -423,233 +423,232 @@ impl TerminalBuilder {
         completion_tx: Option<Sender<Option<ExitStatus>>>,
         cx: &App,
         activation_script: Vec<String>,
-    ) -> Task<Result<TerminalBuilder>> {
-        let version = release_channel::AppVersion::global(cx);
-        cx.background_spawn(async move {
-            // If the parent environment doesn't have a locale set
-            // (As is the case when launched from a .app on MacOS),
-            // and the Project doesn't have a locale set, then
-            // set a fallback for our child environment to use.
-            if std::env::var("LANG").is_err() {
-                env.entry("LANG".to_string())
-                    .or_insert_with(|| "en_US.UTF-8".to_string());
-            }
-
-            env.insert("ZED_TERM".to_string(), "true".to_string());
-            env.insert("TERM_PROGRAM".to_string(), "zed".to_string());
-            env.insert("TERM".to_string(), "xterm-256color".to_string());
-            env.insert("COLORTERM".to_string(), "truecolor".to_string());
-            env.insert("TERM_PROGRAM_VERSION".to_string(), version.to_string());
-
-            #[derive(Default)]
-            struct ShellParams {
+    ) -> Result<TerminalBuilder> {
+        // If the parent environment doesn't have a locale set
+        // (As is the case when launched from a .app on MacOS),
+        // and the Project doesn't have a locale set, then
+        // set a fallback for our child environment to use.
+        if std::env::var("LANG").is_err() {
+            env.entry("LANG".to_string())
+                .or_insert_with(|| "en_US.UTF-8".to_string());
+        }
+
+        env.insert("ZED_TERM".to_string(), "true".to_string());
+        env.insert("TERM_PROGRAM".to_string(), "zed".to_string());
+        env.insert("TERM".to_string(), "xterm-256color".to_string());
+        env.insert("COLORTERM".to_string(), "truecolor".to_string());
+        env.insert(
+            "TERM_PROGRAM_VERSION".to_string(),
+            release_channel::AppVersion::global(cx).to_string(),
+        );
+
+        #[derive(Default)]
+        struct ShellParams {
+            program: String,
+            args: Option<Vec<String>>,
+            title_override: Option<SharedString>,
+        }
+
+        impl ShellParams {
+            fn new(
                 program: String,
                 args: Option<Vec<String>>,
                 title_override: Option<SharedString>,
+            ) -> Self {
+                log::info!("Using {program} as shell");
+                Self {
+                    program,
+                    args,
+                    title_override,
+                }
             }
+        }
 
-            impl ShellParams {
-                fn new(
-                    program: String,
-                    args: Option<Vec<String>>,
-                    title_override: Option<SharedString>,
-                ) -> Self {
-                    log::debug!("Using {program} as shell");
-                    Self {
-                        program,
-                        args,
-                        title_override,
-                    }
+        let shell_params = match shell.clone() {
+            Shell::System => {
+                if cfg!(windows) {
+                    Some(ShellParams::new(
+                        util::shell::get_windows_system_shell(),
+                        None,
+                        None,
+                    ))
+                } else {
+                    None
                 }
             }
+            Shell::Program(program) => Some(ShellParams::new(program, None, None)),
+            Shell::WithArguments {
+                program,
+                args,
+                title_override,
+            } => Some(ShellParams::new(program, Some(args), title_override)),
+        };
+        let terminal_title_override = shell_params.as_ref().and_then(|e| e.title_override.clone());
 
-            let shell_params = match shell.clone() {
-                Shell::System => {
-                    if cfg!(windows) {
-                        Some(ShellParams::new(
-                            util::shell::get_windows_system_shell(),
-                            None,
-                            None,
-                        ))
-                    } else {
-                        None
-                    }
-                }
-                Shell::Program(program) => Some(ShellParams::new(program, None, None)),
-                Shell::WithArguments {
-                    program,
-                    args,
-                    title_override,
-                } => Some(ShellParams::new(program, Some(args), title_override)),
-            };
-            let terminal_title_override =
-                shell_params.as_ref().and_then(|e| e.title_override.clone());
+        #[cfg(windows)]
+        let shell_program = shell_params.as_ref().map(|params| {
+            use util::ResultExt;
 
-            #[cfg(windows)]
-            let shell_program = shell_params.as_ref().map(|params| {
-                use util::ResultExt;
+            Self::resolve_path(¶ms.program)
+                .log_err()
+                .unwrap_or(params.program.clone())
+        });
 
-                Self::resolve_path(¶ms.program)
-                    .log_err()
-                    .unwrap_or(params.program.clone())
+        // Note: when remoting, this shell_kind will scrutinize `ssh` or
+        // `wsl.exe` as a shell and fall back to posix or powershell based on
+        // the compilation target. This is fine right now due to the restricted
+        // way we use the return value, but would become incorrect if we
+        // supported remoting into windows.
+        let shell_kind = shell.shell_kind(cfg!(windows));
+
+        let pty_options = {
+            let alac_shell = shell_params.as_ref().map(|params| {
+                alacritty_terminal::tty::Shell::new(
+                    params.program.clone(),
+                    params.args.clone().unwrap_or_default(),
+                )
             });
 
-            // Note: when remoting, this shell_kind will scrutinize `ssh` or
-            // `wsl.exe` as a shell and fall back to posix or powershell based on
-            // the compilation target. This is fine right now due to the restricted
-            // way we use the return value, but would become incorrect if we
-            // supported remoting into windows.
-            let shell_kind = shell.shell_kind(cfg!(windows));
-
-            let pty_options = {
-                let alac_shell = shell_params.as_ref().map(|params| {
-                    alacritty_terminal::tty::Shell::new(
-                        params.program.clone(),
-                        params.args.clone().unwrap_or_default(),
-                    )
-                });
-
-                alacritty_terminal::tty::Options {
-                    shell: alac_shell,
-                    working_directory: working_directory.clone(),
-                    drain_on_exit: true,
-                    env: env.clone().into_iter().collect(),
-                    // We do not want to escape arguments if we are using CMD as our shell.
-                    // If we do we end up with too many quotes/escaped quotes for CMD to handle.
-                    #[cfg(windows)]
-                    escape_args: shell_kind != util::shell::ShellKind::Cmd,
-                }
-            };
+            alacritty_terminal::tty::Options {
+                shell: alac_shell,
+                working_directory: working_directory.clone(),
+                drain_on_exit: true,
+                env: env.clone().into_iter().collect(),
+                // We do not want to escape arguments if we are using CMD as our shell.
+                // If we do we end up with too many quotes/escaped quotes for CMD to handle.
+                #[cfg(windows)]
+                escape_args: shell_kind != util::shell::ShellKind::Cmd,
+            }
+        };
 
-            let default_cursor_style = AlacCursorStyle::from(cursor_shape);
-            let scrolling_history = if task.is_some() {
-                // Tasks like `cargo build --all` may produce a lot of output, ergo allow maximum scrolling.
-                // After the task finishes, we do not allow appending to that terminal, so small tasks output should not
-                // cause excessive memory usage over time.
-                MAX_SCROLL_HISTORY_LINES
-            } else {
-                max_scroll_history_lines
-                    .unwrap_or(DEFAULT_SCROLL_HISTORY_LINES)
-                    .min(MAX_SCROLL_HISTORY_LINES)
-            };
-            let config = Config {
-                scrolling_history,
-                default_cursor_style,
-                ..Config::default()
-            };
+        let default_cursor_style = AlacCursorStyle::from(cursor_shape);
+        let scrolling_history = if task.is_some() {
+            // Tasks like `cargo build --all` may produce a lot of output, ergo allow maximum scrolling.
+            // After the task finishes, we do not allow appending to that terminal, so small tasks output should not
+            // cause excessive memory usage over time.
+            MAX_SCROLL_HISTORY_LINES
+        } else {
+            max_scroll_history_lines
+                .unwrap_or(DEFAULT_SCROLL_HISTORY_LINES)
+                .min(MAX_SCROLL_HISTORY_LINES)
+        };
+        let config = Config {
+            scrolling_history,
+            default_cursor_style,
+            ..Config::default()
+        };
 
-            //Spawn a task so the Alacritty EventLoop can communicate with us
-            //TODO: Remove with a bounded sender which can be dispatched on &self
-            let (events_tx, events_rx) = unbounded();
-            //Set up the terminal...
-            let mut term = Term::new(
-                config.clone(),
-                &TerminalBounds::default(),
-                ZedListener(events_tx.clone()),
-            );
+        //Spawn a task so the Alacritty EventLoop can communicate with us
+        //TODO: Remove with a bounded sender which can be dispatched on &self
+        let (events_tx, events_rx) = unbounded();
+        //Set up the terminal...
+        let mut term = Term::new(
+            config.clone(),
+            &TerminalBounds::default(),
+            ZedListener(events_tx.clone()),
+        );
 
-            //Alacritty defaults to alternate scrolling being on, so we just need to turn it off.
-            if let AlternateScroll::Off = alternate_scroll {
-                term.unset_private_mode(PrivateMode::Named(NamedPrivateMode::AlternateScroll));
-            }
+        //Alacritty defaults to alternate scrolling being on, so we just need to turn it off.
+        if let AlternateScroll::Off = alternate_scroll {
+            term.unset_private_mode(PrivateMode::Named(NamedPrivateMode::AlternateScroll));
+        }
 
-            let term = Arc::new(FairMutex::new(term));
+        let term = Arc::new(FairMutex::new(term));
 
-            //Setup the pty...
-            let pty = match tty::new(&pty_options, TerminalBounds::default().into(), window_id) {
-                Ok(pty) => pty,
-                Err(error) => {
-                    bail!(TerminalError {
-                        directory: working_directory,
-                        program: shell_params.as_ref().map(|params| params.program.clone()),
-                        args: shell_params.as_ref().and_then(|params| params.args.clone()),
-                        title_override: terminal_title_override,
-                        source: error,
-                    });
-                }
-            };
+        //Setup the pty...
+        let pty = match tty::new(&pty_options, TerminalBounds::default().into(), window_id) {
+            Ok(pty) => pty,
+            Err(error) => {
+                bail!(TerminalError {
+                    directory: working_directory,
+                    program: shell_params.as_ref().map(|params| params.program.clone()),
+                    args: shell_params.as_ref().and_then(|params| params.args.clone()),
+                    title_override: terminal_title_override,
+                    source: error,
+                });
+            }
+        };
 
-            let pty_info = PtyProcessInfo::new(&pty);
+        let pty_info = PtyProcessInfo::new(&pty);
 
-            //And connect them together
-            let event_loop = EventLoop::new(
-                term.clone(),
-                ZedListener(events_tx),
-                pty,
-                pty_options.drain_on_exit,
-                false,
-            )
-            .context("failed to create event loop")?;
+        //And connect them together
+        let event_loop = EventLoop::new(
+            term.clone(),
+            ZedListener(events_tx),
+            pty,
+            pty_options.drain_on_exit,
+            false,
+        )
+        .context("failed to create event loop")?;
 
-            //Kick things off
-            let pty_tx = event_loop.channel();
-            let _io_thread = event_loop.spawn(); // DANGER
+        //Kick things off
+        let pty_tx = event_loop.channel();
+        let _io_thread = event_loop.spawn(); // DANGER
 
-            let no_task = task.is_none();
+        let no_task = task.is_none();
 
-            let terminal = Terminal {
-                task,
-                terminal_type: TerminalType::Pty {
-                    pty_tx: Notifier(pty_tx),
-                    info: pty_info,
-                },
-                completion_tx,
-                term,
-                term_config: config,
-                title_override: terminal_title_override,
-                events: VecDeque::with_capacity(10), //Should never get this high.
-                last_content: Default::default(),
-                last_mouse: None,
-                matches: Vec::new(),
-                selection_head: None,
-                breadcrumb_text: String::new(),
-                scroll_px: px(0.),
-                next_link_id: 0,
-                selection_phase: SelectionPhase::Ended,
-                hyperlink_regex_searches: RegexSearches::new(),
-                vi_mode_enabled: false,
-                is_ssh_terminal,
-                last_mouse_move_time: Instant::now(),
-                last_hyperlink_search_position: None,
-                #[cfg(windows)]
-                shell_program,
-                activation_script: activation_script.clone(),
-                template: CopyTemplate {
-                    shell,
-                    env,
-                    cursor_shape,
-                    alternate_scroll,
-                    max_scroll_history_lines,
-                    window_id,
-                },
-                child_exited: None,
-            };
+        let terminal = Terminal {
+            task,
+            terminal_type: TerminalType::Pty {
+                pty_tx: Notifier(pty_tx),
+                info: pty_info,
+            },
+            completion_tx,
+            term,
+            term_config: config,
+            title_override: terminal_title_override,
+            events: VecDeque::with_capacity(10), //Should never get this high.
+            last_content: Default::default(),
+            last_mouse: None,
+            matches: Vec::new(),
+            selection_head: None,
+            breadcrumb_text: String::new(),
+            scroll_px: px(0.),
+            next_link_id: 0,
+            selection_phase: SelectionPhase::Ended,
+            hyperlink_regex_searches: RegexSearches::new(),
+            vi_mode_enabled: false,
+            is_ssh_terminal,
+            last_mouse_move_time: Instant::now(),
+            last_hyperlink_search_position: None,
+            #[cfg(windows)]
+            shell_program,
+            activation_script: activation_script.clone(),
+            template: CopyTemplate {
+                shell,
+                env,
+                cursor_shape,
+                alternate_scroll,
+                max_scroll_history_lines,
+                window_id,
+            },
+            child_exited: None,
+        };
 
-            if !activation_script.is_empty() && no_task {
-                for activation_script in activation_script {
-                    terminal.write_to_pty(activation_script.into_bytes());
-                    // Simulate enter key press
-                    // NOTE(PowerShell): using `\r\n` will put PowerShell in a continuation mode (infamous >> character)
-                    // and generally mess up the rendering.
-                    terminal.write_to_pty(b"\x0d");
-                }
-                // In order to clear the screen at this point, we have two options:
-                // 1. We can send a shell-specific command such as "clear" or "cls"
-                // 2. We can "echo" a marker message that we will then catch when handling a Wakeup event
-                //    and clear the screen using `terminal.clear()` method
-                // We cannot issue a `terminal.clear()` command at this point as alacritty is evented
-                // and while we have sent the activation script to the pty, it will be executed asynchronously.
-                // Therefore, we somehow need to wait for the activation script to finish executing before we
-                // can proceed with clearing the screen.
-                terminal.write_to_pty(shell_kind.clear_screen_command().as_bytes());
+        if !activation_script.is_empty() && no_task {
+            for activation_script in activation_script {
+                terminal.write_to_pty(activation_script.into_bytes());
                 // Simulate enter key press
+                // NOTE(PowerShell): using `\r\n` will put PowerShell in a continuation mode (infamous >> character)
+                // and generally mess up the rendering.
                 terminal.write_to_pty(b"\x0d");
             }
+            // In order to clear the screen at this point, we have two options:
+            // 1. We can send a shell-specific command such as "clear" or "cls"
+            // 2. We can "echo" a marker message that we will then catch when handling a Wakeup event
+            //    and clear the screen using `terminal.clear()` method
+            // We cannot issue a `terminal.clear()` command at this point as alacritty is evented
+            // and while we have sent the activation script to the pty, it will be executed asynchronously.
+            // Therefore, we somehow need to wait for the activation script to finish executing before we
+            // can proceed with clearing the screen.
+            terminal.write_to_pty(shell_kind.clear_screen_command().as_bytes());
+            // Simulate enter key press
+            terminal.write_to_pty(b"\x0d");
+        }
 
-            Ok(TerminalBuilder {
-                terminal,
-                events_rx,
-            })
+        Ok(TerminalBuilder {
+            terminal,
+            events_rx,
         })
     }
 
@@ -2154,7 +2153,7 @@ impl Terminal {
         self.vi_mode_enabled
     }
 
-    pub fn clone_builder(&self, cx: &App, cwd: Option<PathBuf>) -> Task<Result<TerminalBuilder>> {
+    pub fn clone_builder(&self, cx: &App, cwd: Option<PathBuf>) -> Result<TerminalBuilder> {
         let working_directory = self.working_directory().or_else(|| cwd);
         TerminalBuilder::new(
             working_directory,
@@ -2390,30 +2389,28 @@ mod tests {
         let (completion_tx, completion_rx) = smol::channel::unbounded();
         let (program, args) = ShellBuilder::new(&Shell::System, false)
             .build(Some("echo".to_owned()), &["hello".to_owned()]);
-        let builder = cx
-            .update(|cx| {
-                TerminalBuilder::new(
-                    None,
-                    None,
-                    task::Shell::WithArguments {
-                        program,
-                        args,
-                        title_override: None,
-                    },
-                    HashMap::default(),
-                    CursorShape::default(),
-                    AlternateScroll::On,
-                    None,
-                    false,
-                    0,
-                    Some(completion_tx),
-                    cx,
-                    vec![],
-                )
-            })
-            .await
-            .unwrap();
-        let terminal = cx.new(|cx| builder.subscribe(cx));
+        let terminal = cx.new(|cx| {
+            TerminalBuilder::new(
+                None,
+                None,
+                task::Shell::WithArguments {
+                    program,
+                    args,
+                    title_override: None,
+                },
+                HashMap::default(),
+                CursorShape::default(),
+                AlternateScroll::On,
+                None,
+                false,
+                0,
+                Some(completion_tx),
+                cx,
+                vec![],
+            )
+            .unwrap()
+            .subscribe(cx)
+        });
         assert_eq!(
             completion_rx.recv().await.unwrap(),
             Some(ExitStatus::default())
@@ -2442,27 +2439,25 @@ mod tests {
         cx.executor().allow_parking();
 
         let (completion_tx, completion_rx) = smol::channel::unbounded();
-        let builder = cx
-            .update(|cx| {
-                TerminalBuilder::new(
-                    None,
-                    None,
-                    task::Shell::System,
-                    HashMap::default(),
-                    CursorShape::default(),
-                    AlternateScroll::On,
-                    None,
-                    false,
-                    0,
-                    Some(completion_tx),
-                    cx,
-                    Vec::new(),
-                )
-            })
-            .await
-            .unwrap();
         // Build an empty command, which will result in a tty shell spawned.
-        let terminal = cx.new(|cx| builder.subscribe(cx));
+        let terminal = cx.new(|cx| {
+            TerminalBuilder::new(
+                None,
+                None,
+                task::Shell::System,
+                HashMap::default(),
+                CursorShape::default(),
+                AlternateScroll::On,
+                None,
+                false,
+                0,
+                Some(completion_tx),
+                cx,
+                Vec::new(),
+            )
+            .unwrap()
+            .subscribe(cx)
+        });
 
         let (event_tx, event_rx) = smol::channel::unbounded::<Event>();
         cx.update(|cx| {
@@ -2513,30 +2508,28 @@ mod tests {
         let (completion_tx, completion_rx) = smol::channel::unbounded();
         let (program, args) = ShellBuilder::new(&Shell::System, false)
             .build(Some("asdasdasdasd".to_owned()), &["@@@@@".to_owned()]);
-        let builder = cx
-            .update(|cx| {
-                TerminalBuilder::new(
-                    None,
-                    None,
-                    task::Shell::WithArguments {
-                        program,
-                        args,
-                        title_override: None,
-                    },
-                    HashMap::default(),
-                    CursorShape::default(),
-                    AlternateScroll::On,
-                    None,
-                    false,
-                    0,
-                    Some(completion_tx),
-                    cx,
-                    Vec::new(),
-                )
-            })
-            .await
-            .unwrap();
-        let terminal = cx.new(|cx| builder.subscribe(cx));
+        let terminal = cx.new(|cx| {
+            TerminalBuilder::new(
+                None,
+                None,
+                task::Shell::WithArguments {
+                    program,
+                    args,
+                    title_override: None,
+                },
+                HashMap::default(),
+                CursorShape::default(),
+                AlternateScroll::On,
+                None,
+                false,
+                0,
+                Some(completion_tx),
+                cx,
+                Vec::new(),
+            )
+            .unwrap()
+            .subscribe(cx)
+        });
 
         let (event_tx, event_rx) = smol::channel::unbounded::<Event>();
         cx.update(|cx| {
  
  
  
    
    @@ -214,6 +214,14 @@ async fn deserialize_pane_group(
         }
         SerializedPaneGroup::Pane(serialized_pane) => {
             let active = serialized_pane.active;
+            let new_items = deserialize_terminal_views(
+                workspace_id,
+                project.clone(),
+                workspace.clone(),
+                serialized_pane.children.as_slice(),
+                cx,
+            )
+            .await;
 
             let pane = panel
                 .update_in(cx, |terminal_panel, window, cx| {
@@ -228,71 +236,56 @@ async fn deserialize_pane_group(
                 .log_err()?;
             let active_item = serialized_pane.active_item;
             let pinned_count = serialized_pane.pinned_count;
-            let new_items = deserialize_terminal_views(
-                workspace_id,
-                project.clone(),
-                workspace.clone(),
-                serialized_pane.children.as_slice(),
-                cx,
-            );
-            cx.spawn({
-                let pane = pane.downgrade();
-                async move |cx| {
-                    let new_items = new_items.await;
-
-                    let items = pane.update_in(cx, |pane, window, cx| {
-                        populate_pane_items(pane, new_items, active_item, window, cx);
-                        pane.set_pinned_count(pinned_count);
-                        pane.items_len()
-                    });
+            let terminal = pane
+                .update_in(cx, |pane, window, cx| {
+                    populate_pane_items(pane, new_items, active_item, window, cx);
+                    pane.set_pinned_count(pinned_count);
                     // Avoid blank panes in splits
-                    if items.is_ok_and(|items| items == 0) {
+                    if pane.items_len() == 0 {
                         let working_directory = workspace
                             .update(cx, |workspace, cx| default_working_directory(workspace, cx))
                             .ok()
                             .flatten();
-                        let Some(terminal) = project
-                            .update(cx, |project, cx| {
-                                project.create_terminal_shell(working_directory, cx)
-                            })
-                            .log_err()
-                        else {
-                            return;
-                        };
-
-                        let terminal = terminal.await.log_err();
-                        pane.update_in(cx, |pane, window, cx| {
-                            if let Some(terminal) = terminal {
-                                let terminal_view = Box::new(cx.new(|cx| {
-                                    TerminalView::new(
-                                        terminal,
-                                        workspace.clone(),
-                                        Some(workspace_id),
-                                        project.downgrade(),
-                                        window,
-                                        cx,
-                                    )
-                                }));
-                                pane.add_item(terminal_view, true, false, None, window, cx);
-                            }
-                        })
-                        .ok();
+                        let terminal = project.update(cx, |project, cx| {
+                            project.create_terminal_shell(working_directory, cx)
+                        });
+                        Some(Some(terminal))
+                    } else {
+                        Some(None)
                     }
-                }
-            })
-            .detach();
+                })
+                .ok()
+                .flatten()?;
+            if let Some(terminal) = terminal {
+                let terminal = terminal.await.ok()?;
+                pane.update_in(cx, |pane, window, cx| {
+                    let terminal_view = Box::new(cx.new(|cx| {
+                        TerminalView::new(
+                            terminal,
+                            workspace.clone(),
+                            Some(workspace_id),
+                            project.downgrade(),
+                            window,
+                            cx,
+                        )
+                    }));
+                    pane.add_item(terminal_view, true, false, None, window, cx);
+                })
+                .ok()?;
+            }
             Some((Member::Pane(pane.clone()), active.then_some(pane)))
         }
     }
 }
 
-fn deserialize_terminal_views(
+async fn deserialize_terminal_views(
     workspace_id: WorkspaceId,
     project: Entity<Project>,
     workspace: WeakEntity<Workspace>,
     item_ids: &[u64],
     cx: &mut AsyncWindowContext,
-) -> impl Future<Output = Vec<Entity<TerminalView>>> + use<> {
+) -> Vec<Entity<TerminalView>> {
+    let mut items = Vec::with_capacity(item_ids.len());
     let mut deserialized_items = item_ids
         .iter()
         .map(|item_id| {
@@ -309,15 +302,12 @@ fn deserialize_terminal_views(
             .unwrap_or_else(|e| Task::ready(Err(e.context("no window present"))))
         })
         .collect::<FuturesUnordered<_>>();
-    async move {
-        let mut items = Vec::with_capacity(deserialized_items.len());
-        while let Some(item) = deserialized_items.next().await {
-            if let Some(item) = item.log_err() {
-                items.push(item);
-            }
+    while let Some(item) = deserialized_items.next().await {
+        if let Some(item) = item.log_err() {
+            items.push(item);
         }
-        items
     }
+    items
 }
 
 #[derive(Debug, Serialize, Deserialize)]
  
  
  
    
    @@ -462,11 +462,11 @@ impl TerminalPanel {
         cx.spawn_in(window, async move |panel, cx| {
             let terminal = project
                 .update(cx, |project, cx| match terminal_view {
-                    Some(view) => project.clone_terminal(
+                    Some(view) => Task::ready(project.clone_terminal(
                         &view.read(cx).terminal.clone(),
                         cx,
                         working_directory,
-                    ),
+                    )),
                     None => project.create_terminal_shell(working_directory, cx),
                 })
                 .ok()?
  
  
  
    
    @@ -1220,31 +1220,28 @@ impl Item for TerminalView {
         workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>> {
-        let Ok(terminal) = self.project.update(cx, |project, cx| {
-            let cwd = project
-                .active_project_directory(cx)
-                .map(|it| it.to_path_buf());
-            project.clone_terminal(self.terminal(), cx, cwd)
-        }) else {
-            return Task::ready(None);
-        };
-        cx.spawn_in(window, async move |this, cx| {
-            let terminal = terminal.await.log_err()?;
-            this.update_in(cx, |this, window, cx| {
-                cx.new(|cx| {
-                    TerminalView::new(
-                        terminal,
-                        this.workspace.clone(),
-                        workspace_id,
-                        this.project.clone(),
-                        window,
-                        cx,
-                    )
-                })
+    ) -> Option<Entity<Self>> {
+        let terminal = self
+            .project
+            .update(cx, |project, cx| {
+                let cwd = project
+                    .active_project_directory(cx)
+                    .map(|it| it.to_path_buf());
+                project.clone_terminal(self.terminal(), cx, cwd)
             })
-            .ok()
-        })
+            .ok()?
+            .log_err()?;
+
+        Some(cx.new(|cx| {
+            TerminalView::new(
+                terminal,
+                self.workspace.clone(),
+                workspace_id,
+                self.project.clone(),
+                window,
+                cx,
+            )
+        }))
     }
 
     fn is_dirty(&self, cx: &gpui::App) -> bool {
  
  
  
    
    @@ -11,9 +11,8 @@ use anyhow::Result;
 use client::{Client, proto};
 use futures::{StreamExt, channel::mpsc};
 use gpui::{
-    Action, AnyElement, AnyView, App, AppContext, Context, Entity, EntityId, EventEmitter,
-    FocusHandle, Focusable, Font, HighlightStyle, Pixels, Point, Render, SharedString, Task,
-    WeakEntity, Window,
+    Action, AnyElement, AnyView, App, Context, Entity, EntityId, EventEmitter, FocusHandle,
+    Focusable, Font, HighlightStyle, Pixels, Point, Render, SharedString, Task, WeakEntity, Window,
 };
 use project::{Project, ProjectEntryId, ProjectPath};
 pub use settings::{
@@ -218,11 +217,11 @@ pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {
         _workspace_id: Option<WorkspaceId>,
         _window: &mut Window,
         _: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(None)
+        None
     }
     fn is_dirty(&self, _: &App) -> bool {
         false
@@ -423,7 +422,7 @@ pub trait ItemHandle: 'static + Send {
         workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut App,
-    ) -> Task<Option<Box<dyn ItemHandle>>>;
+    ) -> Option<Box<dyn ItemHandle>>;
     fn added_to_pane(
         &self,
         workspace: &mut Workspace,
@@ -636,12 +635,9 @@ impl<T: Item> ItemHandle for Entity<T> {
         workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut App,
-    ) -> Task<Option<Box<dyn ItemHandle>>> {
-        let task = self.update(cx, |item, cx| item.clone_on_split(workspace_id, window, cx));
-        cx.background_spawn(async move {
-            task.await
-                .map(|handle| Box::new(handle) as Box<dyn ItemHandle>)
-        })
+    ) -> Option<Box<dyn ItemHandle>> {
+        self.update(cx, |item, cx| item.clone_on_split(workspace_id, window, cx))
+            .map(|handle| Box::new(handle) as Box<dyn ItemHandle>)
     }
 
     fn added_to_pane(
@@ -1508,11 +1504,11 @@ pub mod test {
             _workspace_id: Option<WorkspaceId>,
             _: &mut Window,
             cx: &mut Context<Self>,
-        ) -> Task<Option<Entity<Self>>>
+        ) -> Option<Entity<Self>>
         where
             Self: Sized,
         {
-            Task::ready(Some(cx.new(|cx| Self {
+            Some(cx.new(|cx| Self {
                 state: self.state.clone(),
                 label: self.label.clone(),
                 save_count: self.save_count,
@@ -1529,7 +1525,7 @@ pub mod test {
                 workspace_id: self.workspace_id,
                 focus_handle: cx.focus_handle(),
                 serialize: None,
-            })))
+            }))
         }
 
         fn is_dirty(&self, _: &App) -> bool {
  
  
  
    
    @@ -3295,18 +3295,11 @@ impl Pane {
                         else {
                             return;
                         };
-                        let task = item.clone_on_split(database_id, window, cx);
-                        let to_pane = to_pane.downgrade();
-                        cx.spawn_in(window, async move |_, cx| {
-                            if let Some(item) = task.await {
-                                to_pane
-                                    .update_in(cx, |pane, window, cx| {
-                                        pane.add_item(item, true, true, None, window, cx)
-                                    })
-                                    .ok();
-                            }
-                        })
-                        .detach();
+                        if let Some(item) = item.clone_on_split(database_id, window, cx) {
+                            to_pane.update(cx, |pane, cx| {
+                                pane.add_item(item, true, true, None, window, cx);
+                            })
+                        }
                     } else {
                         move_item(&from_pane, &to_pane, item_id, ix, true, window, cx);
                     }
  
  
  
    
    @@ -6,7 +6,7 @@ use call::{RemoteVideoTrack, RemoteVideoTrackView, Room};
 use client::{User, proto::PeerId};
 use gpui::{
     AppContext as _, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
-    ParentElement, Render, SharedString, Styled, Task, div,
+    ParentElement, Render, SharedString, Styled, div,
 };
 use std::sync::Arc;
 use ui::{Icon, IconName, prelude::*};
@@ -114,14 +114,14 @@ impl Item for SharedScreen {
         _workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>> {
-        Task::ready(Some(cx.new(|cx| Self {
+    ) -> Option<Entity<Self>> {
+        Some(cx.new(|cx| Self {
             view: self.view.update(cx, |view, cx| view.clone(window, cx)),
             peer_id: self.peer_id,
             user: self.user.clone(),
             nav_history: Default::default(),
             focus: cx.focus_handle(),
-        })))
+        }))
     }
 
     fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) {
  
  
  
    
    @@ -1,7 +1,5 @@
 #![allow(unused, dead_code)]
-use gpui::{
-    AnyElement, App, Entity, EventEmitter, FocusHandle, Focusable, Hsla, Task, actions, hsla,
-};
+use gpui::{AnyElement, App, Entity, EventEmitter, FocusHandle, Focusable, Hsla, actions, hsla};
 use strum::IntoEnumIterator;
 use theme::all_theme_colors;
 use ui::{
@@ -102,11 +100,11 @@ impl Item for ThemePreview {
         _workspace_id: Option<crate::WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Self>>>
+    ) -> Option<Entity<Self>>
     where
         Self: Sized,
     {
-        Task::ready(Some(cx.new(|cx| Self::new(window, cx))))
+        Some(cx.new(|cx| Self::new(window, cx)))
     }
 }
 
  
  
  
    
    @@ -3627,8 +3627,7 @@ impl Workspace {
         if let Some(pane) = panes.get(action.0).map(|p| (*p).clone()) {
             window.focus(&pane.focus_handle(cx));
         } else {
-            self.split_and_clone(self.active_pane.clone(), SplitDirection::Right, window, cx)
-                .detach();
+            self.split_and_clone(self.active_pane.clone(), SplitDirection::Right, window, cx);
         }
     }
 
@@ -3995,8 +3994,7 @@ impl Workspace {
                 clone_active_item,
             } => {
                 if *clone_active_item {
-                    self.split_and_clone(pane.clone(), *direction, window, cx)
-                        .detach();
+                    self.split_and_clone(pane.clone(), *direction, window, cx);
                 } else {
                     self.split_and_move(pane.clone(), *direction, window, cx);
                 }
@@ -4137,27 +4135,21 @@ impl Workspace {
         direction: SplitDirection,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<Entity<Pane>>> {
-        let Some(item) = pane.read(cx).active_item() else {
-            return Task::ready(None);
-        };
-        let task = item.clone_on_split(self.database_id(), window, cx);
-        cx.spawn_in(window, async move |this, cx| {
-            if let Some(clone) = task.await {
-                this.update_in(cx, |this, window, cx| {
-                    let new_pane = this.add_pane(window, cx);
-                    new_pane.update(cx, |pane, cx| {
-                        pane.add_item(clone, true, true, None, window, cx)
-                    });
-                    this.center.split(&pane, &new_pane, direction).unwrap();
-                    cx.notify();
-                    new_pane
-                })
-                .ok()
+    ) -> Option<Entity<Pane>> {
+        let item = pane.read(cx).active_item()?;
+        let maybe_pane_handle =
+            if let Some(clone) = item.clone_on_split(self.database_id(), window, cx) {
+                let new_pane = self.add_pane(window, cx);
+                new_pane.update(cx, |pane, cx| {
+                    pane.add_item(clone, true, true, None, window, cx)
+                });
+                self.center.split(&pane, &new_pane, direction).unwrap();
+                cx.notify();
+                Some(new_pane)
             } else {
                 None
-            }
-        })
+            };
+        maybe_pane_handle
     }
 
     pub fn join_all_panes(&mut self, window: &mut Window, cx: &mut Context<Self>) {
@@ -8191,27 +8183,19 @@ pub fn clone_active_item(
     let Some(active_item) = source.read(cx).active_item() else {
         return;
     };
-    let destination = destination.downgrade();
-    let task = active_item.clone_on_split(workspace_id, window, cx);
-    window
-        .spawn(cx, async move |cx| {
-            let Some(clone) = task.await else {
-                return;
-            };
-            destination
-                .update_in(cx, |target_pane, window, cx| {
-                    target_pane.add_item(
-                        clone,
-                        focus_destination,
-                        focus_destination,
-                        Some(target_pane.items_len()),
-                        window,
-                        cx,
-                    );
-                })
-                .log_err();
-        })
-        .detach();
+    destination.update(cx, |target_pane, cx| {
+        let Some(clone) = active_item.clone_on_split(workspace_id, window, cx) else {
+            return;
+        };
+        target_pane.add_item(
+            clone,
+            focus_destination,
+            focus_destination,
+            Some(target_pane.items_len()),
+            window,
+            cx,
+        );
+    });
 }
 
 #[derive(Debug)]
@@ -8718,24 +8702,25 @@ mod tests {
                 cx,
             );
 
-            let right_pane =
-                workspace.split_and_clone(left_pane.clone(), SplitDirection::Right, window, cx);
+            let right_pane = workspace
+                .split_and_clone(left_pane.clone(), SplitDirection::Right, window, cx)
+                .unwrap();
 
-            let boxed_clone = single_entry_items[1].boxed_clone();
-            let right_pane = window.spawn(cx, async move |cx| {
-                right_pane.await.inspect(|right_pane| {
-                    right_pane
-                        .update_in(cx, |pane, window, cx| {
-                            pane.add_item(boxed_clone, true, true, None, window, cx);
-                            pane.add_item(Box::new(item_3_4.clone()), true, true, None, window, cx);
-                        })
-                        .unwrap();
-                })
+            right_pane.update(cx, |pane, cx| {
+                pane.add_item(
+                    single_entry_items[1].boxed_clone(),
+                    true,
+                    true,
+                    None,
+                    window,
+                    cx,
+                );
+                pane.add_item(Box::new(item_3_4.clone()), true, true, None, window, cx);
             });
 
             (left_pane, right_pane)
         });
-        let right_pane = right_pane.await.unwrap();
+
         cx.focus(&right_pane);
 
         let mut close = right_pane.update_in(cx, |pane, window, cx| {
@@ -10552,10 +10537,7 @@ mod tests {
                 window,
                 cx,
             );
-        });
-        cx.run_until_parked();
 
-        workspace.update(cx, |workspace, cx| {
             assert_eq!(workspace.panes.len(), 3, "Two new panes were created");
             for pane in workspace.panes() {
                 assert_eq!(
  
  
  
    
    @@ -2839,16 +2839,14 @@ mod tests {
         });
 
         // Split the pane with the first entry, then open the second entry again.
-        let (task1, task2) = window
+        window
             .update(cx, |w, window, cx| {
-                (
-                    w.split_and_clone(w.active_pane().clone(), SplitDirection::Right, window, cx),
-                    w.open_path(file2.clone(), None, true, window, cx),
-                )
+                w.split_and_clone(w.active_pane().clone(), SplitDirection::Right, window, cx);
+                w.open_path(file2.clone(), None, true, window, cx)
             })
+            .unwrap()
+            .await
             .unwrap();
-        task1.await.unwrap();
-        task2.await.unwrap();
 
         window
             .read_with(cx, |w, cx| {
@@ -3471,13 +3469,7 @@ mod tests {
                     SplitDirection::Right,
                     window,
                     cx,
-                )
-            })
-            .unwrap()
-            .await
-            .unwrap();
-        window
-            .update(cx, |workspace, window, cx| {
+                );
                 workspace.open_path(
                     (worktree.read(cx).id(), rel_path("the-new-name.rs")),
                     None,
  
  
  
    
    @@ -720,7 +720,7 @@ impl Item for ComponentPreview {
         _workspace_id: Option<WorkspaceId>,
         window: &mut Window,
         cx: &mut Context<Self>,
-    ) -> Task<Option<gpui::Entity<Self>>>
+    ) -> Option<gpui::Entity<Self>>
     where
         Self: Sized,
     {
@@ -742,13 +742,13 @@ impl Item for ComponentPreview {
             cx,
         );
 
-        Task::ready(match self_result {
+        match self_result {
             Ok(preview) => Some(cx.new(|_cx| preview)),
             Err(e) => {
                 log::error!("Failed to clone component preview: {}", e);
                 None
             }
-        })
+        }
     }
 
     fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) {