From bbeeab6dcf86f19ff6964734c81699e7dd37dc26 Mon Sep 17 00:00:00 2001 From: Katie Geer Date: Wed, 29 Apr 2026 00:44:06 -0700 Subject: [PATCH] onboarding: Telemetry for new AI setup buttons (#55145) Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ x] Unsafe blocks (if any) have justifying comments - [ x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ n/a] Tests cover the new/changed behavior - [ n/a] Performance impact has been considered and is acceptable Release Notes: - N/A --------- Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com> --- crates/onboarding/src/basics_page.rs | 5 +++- crates/onboarding/src/onboarding.rs | 37 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs index 4817e897f7..7d021c5444 100644 --- a/crates/onboarding/src/basics_page.rs +++ b/crates/onboarding/src/basics_page.rs @@ -528,7 +528,8 @@ fn render_import_settings_section(tab_index: &mut isize, cx: &mut App) -> impl I .child(h_flex().gap_1().child(vscode).child(cursor)) } -const FEATURED_AGENT_IDS: &[&str] = &["claude-acp", "codex-acp", "github-copilot-cli", "cursor"]; +pub(crate) const FEATURED_AGENT_IDS: &[&str] = + &["claude-acp", "codex-acp", "github-copilot-cli", "cursor"]; fn render_registry_agent_button( agent: &RegistryAgent, @@ -565,6 +566,7 @@ fn render_registry_agent_button( .state(state_element) .disabled(installed) .on_click(move |_, _, cx| { + telemetry::event!("Welcome Agent Install Clicked", agent = agent_id.as_str()); let agent_id = agent_id.clone(); update_settings_file(fs.clone(), cx, move |settings, _| { let agent_servers = settings.agent_servers.get_or_insert_default(); @@ -645,6 +647,7 @@ fn render_zed_agent_button(user_store: &Entity, cx: &mut App) -> impl }) } else { this.on_click(move |_, _, cx| { + telemetry::event!("Welcome Zed Agent Sign In Clicked"); let client = Client::global(cx); cx.spawn(async move |cx| client.sign_in_with_optional_connect(true, cx).await) .detach_and_log_err(cx); diff --git a/crates/onboarding/src/onboarding.rs b/crates/onboarding/src/onboarding.rs index ce9a383a60..652febbda4 100644 --- a/crates/onboarding/src/onboarding.rs +++ b/crates/onboarding/src/onboarding.rs @@ -1,5 +1,6 @@ use crate::multibuffer_hint::MultibufferHint; use client::{Client, UserStore, zed_urls}; +use cloud_api_types::Plan; use db::kvp::KeyValueStore; use fs::Fs; use gpui::{ @@ -8,6 +9,7 @@ use gpui::{ Subscription, Task, WeakEntity, Window, actions, }; use notifications::status_toast::StatusToast; +use project::agent_server_store::AllAgentServersSettings; use schemars::JsonSchema; use serde::Deserialize; use settings::{SettingsStore, VsCodeSettingsSource}; @@ -216,6 +218,41 @@ impl Onboarding { fn new(workspace: &Workspace, cx: &mut App) -> Entity { let font_family_cache = theme::FontFamilyCache::global(cx); + let installed_agents = cx + .global::() + .get::(None) + .clone(); + let client = Client::global(cx); + let status = *client.status().borrow(); + let plan = workspace.user_store().read(cx).plan(); + let zed_agent_state = if status.is_signed_out() + || matches!( + status, + client::Status::AuthenticationError | client::Status::ConnectionError + ) { + "signed_out" + } else if status.is_signing_in() { + "signing_in" + } else { + match plan { + Some(Plan::ZedPro) => "pro", + Some(Plan::ZedProTrial) => "trial", + Some(Plan::ZedBusiness) => "business", + Some(Plan::ZedStudent) => "student", + Some(Plan::ZedFree) | None => "free", + } + }; + let agents_installed = basics_page::FEATURED_AGENT_IDS + .iter() + .filter(|id| installed_agents.contains_key(**id)) + .copied() + .collect::>(); + telemetry::event!( + "Welcome Agent Setup Viewed", + zed_agent = zed_agent_state, + agents_installed = agents_installed, + ); + cx.new(|cx| { cx.spawn(async move |this, cx| { font_family_cache.prefetch(cx).await;