feat: Add opt-out setting for anonymous usage reporting (#743)

* refactor: align VS Code update checks with web runtime parity

- VS Code now uses file-based installId (shared with web server)
- Accepts platform/arch from webview for consistent behavior
- Usage data collection now matches web implementation

* feat: Add opt-out setting for anonymous usage reporting in Appearance

- Add privacy control in Appearance settings to opt-out of anonymous usage reports
- Usage data includes only app version, platform, and runtime - no personal data or code collected
- Setting persists across all runtimes and controls the reportUsage parameter in update checks
This commit is contained in:
Bohdan Triapitsyn
2026-03-22 23:02:53 +02:00
committed by GitHub
parent 53c2a0d919
commit 64b55025e1
9 changed files with 116 additions and 25 deletions
+7 -3
View File
@@ -558,10 +558,8 @@ interface UIStore {
stickyUserHeader: boolean;
showMobileSessionStatusBar: boolean;
isMobileSessionStatusBarCollapsed: boolean;
viewPagerPage: 'left' | 'center' | 'right';
isExpandedInput: boolean;
reportUsage: boolean;
shortcutOverrides: Record<string, ShortcutCombo>;
setTheme: (theme: 'light' | 'dark' | 'system') => void;
@@ -669,11 +667,13 @@ interface UIStore {
setStickyUserHeader: (value: boolean) => void;
setShowMobileSessionStatusBar: (value: boolean) => void;
setIsMobileSessionStatusBarCollapsed: (value: boolean) => void;
viewPagerPage: 'left' | 'center' | 'right';
setViewPagerPage: (page: 'left' | 'center' | 'right') => void;
toggleExpandedInput: () => void;
setExpandedInput: (value: boolean) => void;
openMultiRunLauncher: () => void;
openMultiRunLauncherWithPrompt: (prompt: string) => void;
setReportUsage: (value: boolean) => void;
setShortcutOverride: (actionId: string, combo: ShortcutCombo) => void;
clearShortcutOverride: (actionId: string) => void;
resetAllShortcutOverrides: () => void;
@@ -782,6 +782,7 @@ export const useUIStore = create<UIStore>()(
showMobileSessionStatusBar: true,
isMobileSessionStatusBarCollapsed: false,
isExpandedInput: false,
reportUsage: true,
shortcutOverrides: {},
setTheme: (theme) => {
@@ -1690,6 +1691,9 @@ export const useUIStore = create<UIStore>()(
setIsMobileSessionStatusBarCollapsed: (value) => {
set({ isMobileSessionStatusBarCollapsed: value });
},
setReportUsage: (value) => {
set({ reportUsage: value });
},
viewPagerPage: 'center',
setViewPagerPage: (page: 'left' | 'center' | 'right') => {
set({ viewPagerPage: page });
+5 -1
View File
@@ -1,6 +1,7 @@
import { create } from 'zustand';
import type { UpdateInfo, UpdateProgress } from '@/lib/desktop';
import { getDeviceInfo } from '@/lib/device';
import { useUIStore } from './useUIStore';
import {
checkForDesktopUpdates,
downloadDesktopUpdate,
@@ -66,7 +67,10 @@ function detectPlatform(): 'macos' | 'windows' | 'linux' | 'web' {
}
function mapRuntimeParams(runtime: ClientRuntime): URLSearchParams {
const params = new URLSearchParams({ reportUsage: 'true' });
// Check if user has opted out of usage reporting (default: true/enabled from UI store)
const shouldReportUsage = useUIStore.getState().reportUsage;
const params = new URLSearchParams({ reportUsage: shouldReportUsage ? 'true' : 'false' });
params.set('deviceClass', detectDeviceClass());
params.set('arch', detectArch());
params.set('platform', detectPlatform());