agent: Allow to force uninstall extension if it provides more than the MCP server (#33279)

Danilo Leal created

Change summary

crates/agent_ui/src/agent_configuration.rs | 47 ++++++++++++++++++++++-
1 file changed, 44 insertions(+), 3 deletions(-)

Detailed changes

crates/agent_ui/src/agent_configuration.rs 🔗

@@ -940,15 +940,56 @@ fn show_unable_to_uninstall_extension_with_context_server(
     id: ContextServerId,
     cx: &mut App,
 ) {
+    let workspace_handle = workspace.weak_handle();
+    let context_server_id = id.clone();
+
     let status_toast = StatusToast::new(
         format!(
-            "Unable to uninstall the {} extension, as it provides more than just the MCP server.",
+            "The {} extension provides more than just the MCP server. Proceed to uninstall anyway?",
             id.0
         ),
         cx,
-        |this, _cx| {
+        move |this, _cx| {
+            let workspace_handle = workspace_handle.clone();
+            let context_server_id = context_server_id.clone();
+
             this.icon(ToastIcon::new(IconName::Warning).color(Color::Warning))
-                .action("Dismiss", |_, _| {})
+                .dismiss_button(true)
+                .action("Uninstall", move |_, _cx| {
+                    if let Some((extension_id, _)) =
+                        resolve_extension_for_context_server(&context_server_id, _cx)
+                    {
+                        ExtensionStore::global(_cx).update(_cx, |store, cx| {
+                            store
+                                .uninstall_extension(extension_id, cx)
+                                .detach_and_log_err(cx);
+                        });
+
+                        workspace_handle
+                            .update(_cx, |workspace, cx| {
+                                let fs = workspace.app_state().fs.clone();
+                                cx.spawn({
+                                    let context_server_id = context_server_id.clone();
+                                    async move |_workspace_handle, cx| {
+                                        cx.update(|cx| {
+                                            update_settings_file::<ProjectSettings>(
+                                                fs,
+                                                cx,
+                                                move |settings, _| {
+                                                    settings
+                                                        .context_servers
+                                                        .remove(&context_server_id.0);
+                                                },
+                                            );
+                                        })?;
+                                        anyhow::Ok(())
+                                    }
+                                })
+                                .detach_and_log_err(cx);
+                            })
+                            .log_err();
+                    }
+                })
         },
     );