From eaf2539cb4f820ebe8f98564615d41c4a827c8c9 Mon Sep 17 00:00:00 2001 From: Katie Geer Date: Wed, 1 Apr 2026 11:48:43 -0700 Subject: [PATCH] Add sidebar toggle, agent panel side, and workspace telemetry events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track three new telemetry signals: - 'Sidebar Toggled' fires in MultiWorkspace::open_sidebar and close_sidebar with action ('open'/'close') and side ('left'/'right'). Covers both mouse (status bar button / sidebar close button) and keyboard (ToggleWorkspaceSidebar / CloseWorkspaceSidebar actions) since all paths funnel through those two methods. - 'Agent Panel Side Changed' fires in AgentPanel::set_position with the new side value. This fires whenever the user moves the panel via drag or the context menu. - 'Workspace Added' fires in MultiWorkspace::add — which is only called during initial workspace restoration, not for user-initiated project opens — with workspace_count so we can understand portfolio size at session start. - 'Sidebar Open Project Clicked' fires on the empty-state 'Open Project' button in the sidebar with the current side value. --- Cargo.lock | 1 + crates/agent_ui/src/agent_panel.rs | 5 +++++ crates/sidebar/Cargo.toml | 1 + crates/sidebar/src/sidebar.rs | 6 ++++++ crates/workspace/src/multi_workspace.rs | 14 ++++++++++++++ 5 files changed, 27 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f744c9bc2d66b54cdbfdea63aa56a5b3bf6d365d..a553927c40cf56e95cf10551ea8f57b4c581bdcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16093,6 +16093,7 @@ dependencies = [ "serde", "serde_json", "settings", + "telemetry", "theme", "theme_settings", "ui", diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 8f51204b14e67248b8857afcc3001750536eb859..9589d37d8ae2786053bb450a117608df52de73bf 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -3344,6 +3344,11 @@ impl Panel for AgentPanel { } fn set_position(&mut self, position: DockPosition, _: &mut Window, cx: &mut Context) { + let side = match position { + DockPosition::Left => "left", + _ => "right", + }; + telemetry::event!("Agent Panel Side Changed", side = side); settings::update_settings_file(self.fs.clone(), cx, move |settings, _| { settings .agent diff --git a/crates/sidebar/Cargo.toml b/crates/sidebar/Cargo.toml index 41bf8cdad2068f0c67c38ea06fd176af11f3d560..60e70464231e42cf29553ecebba67afaab394f84 100644 --- a/crates/sidebar/Cargo.toml +++ b/crates/sidebar/Cargo.toml @@ -35,6 +35,7 @@ remote.workspace = true serde.workspace = true serde_json.workspace = true settings.workspace = true +telemetry.workspace = true theme.workspace = true theme_settings.workspace = true ui.workspace = true diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 6d9117fbd86b2273269b8d667e41ebaed13ca996..33c08e9d540ebab0c226ccede1c92ac8edf4d7fa 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -34,6 +34,7 @@ use settings::Settings as _; use std::collections::{HashMap, HashSet}; use std::mem; use std::rc::Rc; +use telemetry; use theme::ActiveTheme; use ui::{ AgentThreadStatus, CommonAnimationExt, ContextMenu, Divider, HighlightedLabel, KeyBinding, @@ -3521,6 +3522,11 @@ impl Sidebar { .full_width() .key_binding(KeyBinding::for_action(&workspace::Open::default(), cx)) .on_click(|_, window, cx| { + let side = match AgentSettings::get_global(cx).sidebar_side() { + SidebarSide::Left => "left", + SidebarSide::Right => "right", + }; + telemetry::event!("Sidebar Open Project Clicked", side = side); window.dispatch_action( Open { create_new_window: false, diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index fa4f29ecad1ef37852b779837c58e4925840bf23..596a3d2ac936411a53507062a75bbbbc8679cdb6 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -468,6 +468,11 @@ impl MultiWorkspace { } pub fn open_sidebar(&mut self, cx: &mut Context) { + let side = match self.sidebar_side(cx) { + SidebarSide::Left => "left", + SidebarSide::Right => "right", + }; + telemetry::event!("Sidebar Toggled", action = "open", side = side); self.sidebar_open = true; if let ActiveWorkspace::Transient(workspace) = &self.active_workspace { let workspace = workspace.clone(); @@ -485,6 +490,11 @@ impl MultiWorkspace { } pub fn close_sidebar(&mut self, window: &mut Window, cx: &mut Context) { + let side = match self.sidebar_side(cx) { + SidebarSide::Left => "left", + SidebarSide::Right => "right", + }; + telemetry::event!("Sidebar Toggled", action = "close", side = side); self.sidebar_open = false; for workspace in self.workspaces.iter() { workspace.update(cx, |workspace, _cx| { @@ -861,7 +871,11 @@ impl MultiWorkspace { /// persistent list regardless of sidebar state — it's used for system- /// initiated additions like deserialization and worktree discovery. pub fn add(&mut self, workspace: Entity, window: &Window, cx: &mut Context) { + let is_new = !self.workspaces.iter().any(|w| *w == workspace); self.insert_workspace(workspace, window, cx); + if is_new { + telemetry::event!("Workspace Added", workspace_count = self.workspaces.len()); + } } /// Ensures the workspace is in the multiworkspace and makes it the active one.