From c704085408e140557158c2a6e633b5dea1bdd132 Mon Sep 17 00:00:00 2001 From: Gabriel Gordon-Hall Date: Tue, 12 Aug 2025 09:53:15 +0100 Subject: [PATCH] prompt telemetry opt-in on upgrade to v3 (#452) --- crates/local-deployment/src/container.rs | 2 +- crates/services/src/services/config/mod.rs | 14 +-- .../src/services/config/versions/mod.rs | 1 + .../src/services/config/versions/v3.rs | 90 +++++++++++++++++++ 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 crates/services/src/services/config/versions/v3.rs diff --git a/crates/local-deployment/src/container.rs b/crates/local-deployment/src/container.rs index e5d205eb..5c5bd0f3 100644 --- a/crates/local-deployment/src/container.rs +++ b/crates/local-deployment/src/container.rs @@ -352,7 +352,7 @@ impl LocalContainerService { } // Fire event when CodingAgent execution has finished - if let Some(true) = config.read().await.analytics_enabled + if config.read().await.analytics_enabled == Some(true) && matches!( &ctx.execution_process.run_reason, ExecutionProcessRunReason::CodingAgent diff --git a/crates/services/src/services/config/mod.rs b/crates/services/src/services/config/mod.rs index 7d662eee..9df8da41 100644 --- a/crates/services/src/services/config/mod.rs +++ b/crates/services/src/services/config/mod.rs @@ -12,13 +12,13 @@ pub enum ConfigError { Json(#[from] serde_json::Error), } -pub type Config = versions::v2::Config; -pub type NotificationConfig = versions::v2::NotificationConfig; -pub type EditorConfig = versions::v2::EditorConfig; -pub type ThemeMode = versions::v2::ThemeMode; -pub type SoundFile = versions::v2::SoundFile; -pub type EditorType = versions::v2::EditorType; -pub type GitHubConfig = versions::v2::GitHubConfig; +pub type Config = versions::v3::Config; +pub type NotificationConfig = versions::v3::NotificationConfig; +pub type EditorConfig = versions::v3::EditorConfig; +pub type ThemeMode = versions::v3::ThemeMode; +pub type SoundFile = versions::v3::SoundFile; +pub type EditorType = versions::v3::EditorType; +pub type GitHubConfig = versions::v3::GitHubConfig; /// Will always return config, trying old schemas or eventually returning default pub async fn load_config_from_file(config_path: &PathBuf) -> Config { diff --git a/crates/services/src/services/config/versions/mod.rs b/crates/services/src/services/config/versions/mod.rs index 8e5a3fae..3bb4664b 100644 --- a/crates/services/src/services/config/versions/mod.rs +++ b/crates/services/src/services/config/versions/mod.rs @@ -1,2 +1,3 @@ pub(super) mod v1; pub(super) mod v2; +pub(super) mod v3; diff --git a/crates/services/src/services/config/versions/v3.rs b/crates/services/src/services/config/versions/v3.rs new file mode 100644 index 00000000..2267bf8e --- /dev/null +++ b/crates/services/src/services/config/versions/v3.rs @@ -0,0 +1,90 @@ +use anyhow::Error; +use serde::{Deserialize, Serialize}; +use ts_rs::TS; +pub use v2::{EditorConfig, EditorType, GitHubConfig, NotificationConfig, SoundFile, ThemeMode}; + +use crate::services::config::versions::v2; + +#[derive(Clone, Debug, Serialize, Deserialize, TS)] +pub struct Config { + pub config_version: String, + pub theme: ThemeMode, + pub profile: String, + pub disclaimer_acknowledged: bool, + pub onboarding_acknowledged: bool, + pub github_login_acknowledged: bool, + pub telemetry_acknowledged: bool, + pub notifications: NotificationConfig, + pub editor: EditorConfig, + pub github: GitHubConfig, + pub analytics_enabled: Option, + pub workspace_dir: Option, +} + +impl Config { + pub fn from_previous_version(raw_config: &str) -> Result { + let old_config = match serde_json::from_str::(raw_config) { + Ok(cfg) => cfg, + Err(e) => { + tracing::error!("❌ Failed to parse config: {}", e); + tracing::error!(" at line {}, column {}", e.line(), e.column()); + return Err(e.into()); + } + }; + + Ok(Self { + config_version: "v3".to_string(), + theme: old_config.theme, + profile: old_config.profile, + disclaimer_acknowledged: old_config.disclaimer_acknowledged, + onboarding_acknowledged: old_config.onboarding_acknowledged, + github_login_acknowledged: old_config.github_login_acknowledged, + telemetry_acknowledged: false, + notifications: old_config.notifications, + editor: old_config.editor, + github: old_config.github, + analytics_enabled: old_config.analytics_enabled, + workspace_dir: old_config.workspace_dir, + }) + } +} + +impl From for Config { + fn from(raw_config: String) -> Self { + if let Ok(config) = serde_json::from_str::(&raw_config) { + if config.config_version == "v3" { + return config; + } + } + + match Self::from_previous_version(&raw_config) { + Ok(config) => { + tracing::info!("Config upgraded to v3"); + config + } + Err(e) => { + tracing::warn!("Config migration failed: {}, using default", e); + Self::default() + } + } + } +} + +impl Default for Config { + fn default() -> Self { + Self { + config_version: "v3".to_string(), + theme: ThemeMode::System, + profile: String::from("claude-code"), + disclaimer_acknowledged: false, + onboarding_acknowledged: false, + github_login_acknowledged: false, + telemetry_acknowledged: false, + notifications: NotificationConfig::default(), + editor: EditorConfig::default(), + github: GitHubConfig::default(), + analytics_enabled: None, + workspace_dir: None, + } + } +}