used simplified privacy info modal and removed unnecessary components (#8200)

Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
Lifei Zhou
2026-03-31 11:25:36 +11:00
committed by GitHub
parent 5b47740d73
commit b860e0f269
6 changed files with 239 additions and 288 deletions
+2 -2
View File
@@ -14,7 +14,7 @@ import { ErrorUI } from './components/ErrorBoundary';
import { ExtensionInstallModal } from './components/ExtensionInstallModal';
import { ToastContainer } from 'react-toastify';
import AnnouncementModal from './components/AnnouncementModal';
import TelemetryOptOutModal from './components/TelemetryOptOutModal';
import TelemetryConsentPrompt from './components/TelemetryConsentPrompt';
import OnboardingGuard from './components/onboarding/OnboardingGuard';
import { createSession } from './sessions';
@@ -678,7 +678,7 @@ export default function App() {
<AppInner />
</HashRouter>
<AnnouncementModal />
<TelemetryOptOutModal controlled={false} />
<TelemetryConsentPrompt />
</ModelAndProviderProvider>
</FeaturesProvider>
</ThemeProvider>
@@ -0,0 +1,124 @@
import { useState, useEffect } from 'react';
import { Button } from './ui/button';
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from './ui/dialog';
import { TELEMETRY_UI_ENABLED } from '../updates';
import { useConfig } from './ConfigContext';
import {
trackTelemetryPreference,
setTelemetryEnabled as setAnalyticsTelemetryEnabled,
} from '../utils/analytics';
import PrivacyInfoModal from './onboarding/PrivacyInfoModal';
import { defineMessages, useIntl } from '../i18n';
const i18n = defineMessages({
heading: {
id: 'telemetryConsentPrompt.heading',
defaultMessage: 'Help improve goose',
},
description: {
id: 'telemetryConsentPrompt.description',
defaultMessage:
'Would you like to share anonymous usage data to help improve goose? We never collect your conversations, code, or personal data.',
},
learnMore: {
id: 'telemetryConsentPrompt.learnMore',
defaultMessage: 'Learn more',
},
optIn: {
id: 'telemetryConsentPrompt.optIn',
defaultMessage: 'Yes, share anonymous usage data',
},
optOut: {
id: 'telemetryConsentPrompt.optOut',
defaultMessage: 'No thanks',
},
});
const TELEMETRY_CONFIG_KEY = 'GOOSE_TELEMETRY_ENABLED';
export default function TelemetryConsentPrompt() {
const intl = useIntl();
const { read, upsert } = useConfig();
const [showPrompt, setShowPrompt] = useState(false);
const [showPrivacyInfo, setShowPrivacyInfo] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
useEffect(() => {
if (!TELEMETRY_UI_ENABLED) return;
(async () => {
try {
const provider = await read('GOOSE_PROVIDER', false);
if (!provider || provider === '') return;
const telemetryValue = await read(TELEMETRY_CONFIG_KEY, false);
if (telemetryValue === null) {
setShowPrompt(true);
}
} catch (error) {
console.error('Failed to check telemetry config:', error);
}
})();
}, [read]);
const handleChoice = async (enabled: boolean) => {
setIsSubmitting(true);
try {
await upsert(TELEMETRY_CONFIG_KEY, enabled, false);
trackTelemetryPreference(enabled, 'modal');
setAnalyticsTelemetryEnabled(enabled);
} catch (error) {
console.error('Failed to save telemetry preference:', error);
} finally {
setShowPrompt(false);
setIsSubmitting(false);
}
};
if (!showPrompt) return null;
return (
<>
<Dialog
open
onOpenChange={(open) => {
if (!open) setShowPrompt(false);
}}
>
<DialogContent className="w-[440px]">
<DialogHeader>
<DialogTitle className="text-center">{intl.formatMessage(i18n.heading)}</DialogTitle>
</DialogHeader>
<p className="text-text-muted text-sm">
{intl.formatMessage(i18n.description)}{' '}
<button
onClick={() => setShowPrivacyInfo(true)}
className="text-blue-600 dark:text-blue-400 hover:underline"
>
{intl.formatMessage(i18n.learnMore)}
</button>
</p>
<DialogFooter className="flex flex-col gap-2 sm:flex-col">
<Button
autoFocus
onClick={() => handleChoice(true)}
disabled={isSubmitting}
className="w-full"
>
{intl.formatMessage(i18n.optIn)}
</Button>
<Button
variant="ghost"
onClick={() => handleChoice(false)}
disabled={isSubmitting}
className="w-full text-text-secondary hover:text-text-primary"
>
{intl.formatMessage(i18n.optOut)}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<PrivacyInfoModal isOpen={showPrivacyInfo} onClose={() => setShowPrivacyInfo(false)} />
</>
);
}
@@ -1,194 +0,0 @@
import { useState, useEffect } from 'react';
import { BaseModal } from './ui/BaseModal';
import { Button } from './ui/button';
import { Goose } from './icons/Goose';
import { TELEMETRY_UI_ENABLED } from '../updates';
import { toastService } from '../toasts';
import { useConfig } from './ConfigContext';
import { trackTelemetryPreference } from '../utils/analytics';
import { defineMessages, useIntl } from '../i18n';
const i18n = defineMessages({
configError: {
id: 'telemetryOptOutModal.configError',
defaultMessage: 'Configuration Error',
},
configErrorMessage: {
id: 'telemetryOptOutModal.configErrorMessage',
defaultMessage: 'Failed to check telemetry configuration.',
},
optIn: {
id: 'telemetryOptOutModal.optIn',
defaultMessage: 'Yes, share anonymous usage data',
},
optOut: {
id: 'telemetryOptOutModal.optOut',
defaultMessage: 'No thanks',
},
heading: {
id: 'telemetryOptOutModal.heading',
defaultMessage: 'Help improve goose',
},
description: {
id: 'telemetryOptOutModal.description',
defaultMessage:
'Would you like to help improve goose by sharing anonymous usage data? This helps us understand how goose is used and identify areas for improvement.',
},
whatWeCollect: {
id: 'telemetryOptOutModal.whatWeCollect',
defaultMessage: 'What we collect:',
},
collectOs: {
id: 'telemetryOptOutModal.collectOs',
defaultMessage: 'Operating system, version, and architecture',
},
collectVersion: {
id: 'telemetryOptOutModal.collectVersion',
defaultMessage: 'goose version and install method',
},
collectProvider: {
id: 'telemetryOptOutModal.collectProvider',
defaultMessage: 'Provider and model used',
},
collectExtensions: {
id: 'telemetryOptOutModal.collectExtensions',
defaultMessage: 'Extensions and tool usage counts (names only)',
},
collectSession: {
id: 'telemetryOptOutModal.collectSession',
defaultMessage: 'Session metrics (duration, interaction count, token usage)',
},
collectErrors: {
id: 'telemetryOptOutModal.collectErrors',
defaultMessage: 'Error types (e.g., "rate_limit", "auth" - no details)',
},
privacyNote: {
id: 'telemetryOptOutModal.privacyNote',
defaultMessage:
'We never collect your conversations, code, tool arguments, error messages, or any personal data. You can change this setting anytime in Settings → App.',
},
});
const TELEMETRY_CONFIG_KEY = 'GOOSE_TELEMETRY_ENABLED';
type TelemetryOptOutModalProps =
| { controlled: false }
| { controlled: true; isOpen: boolean; onClose: () => void };
export default function TelemetryOptOutModal(props: TelemetryOptOutModalProps) {
const intl = useIntl();
const { read, upsert } = useConfig();
const isControlled = props.controlled;
const controlledIsOpen = isControlled ? props.isOpen : undefined;
const onClose = isControlled ? props.onClose : undefined;
const [showModal, setShowModal] = useState(false);
const [isLoading, setIsLoading] = useState(false);
// Only check telemetry choice on first launch in uncontrolled mode
useEffect(() => {
if (isControlled) return;
const checkTelemetryChoice = async () => {
try {
const provider = await read('GOOSE_PROVIDER', false);
if (!provider || provider === '') {
return;
}
const telemetryEnabled = await read(TELEMETRY_CONFIG_KEY, false);
if (telemetryEnabled === null) {
setShowModal(true);
}
} catch (error) {
console.error('Failed to check telemetry config:', error);
toastService.error({
title: intl.formatMessage(i18n.configError),
msg: intl.formatMessage(i18n.configErrorMessage),
traceback: error instanceof Error ? error.stack || '' : '',
});
}
};
checkTelemetryChoice();
}, [isControlled, read, intl]);
const handleChoice = async (enabled: boolean) => {
setIsLoading(true);
try {
await upsert(TELEMETRY_CONFIG_KEY, enabled, false);
trackTelemetryPreference(enabled, 'modal');
setShowModal(false);
onClose?.();
} catch (error) {
console.error('Failed to set telemetry preference:', error);
setShowModal(false);
onClose?.();
} finally {
setIsLoading(false);
}
};
if (!TELEMETRY_UI_ENABLED) {
return null;
}
const isModalOpen = controlledIsOpen !== undefined ? controlledIsOpen : showModal;
if (!isModalOpen) {
return null;
}
return (
<BaseModal
isOpen={isModalOpen}
actions={
<div className="flex flex-col gap-2 pb-3 px-3">
<Button
variant="default"
onClick={() => handleChoice(true)}
disabled={isLoading}
className="w-full h-[44px] rounded-lg"
>
{intl.formatMessage(i18n.optIn)}
</Button>
<Button
variant="ghost"
onClick={() => handleChoice(false)}
disabled={isLoading}
className="w-full h-[44px] rounded-lg text-text-secondary hover:text-text-primary"
>
{intl.formatMessage(i18n.optOut)}
</Button>
</div>
}
>
<div className="px-2 py-3">
<div className="flex justify-center mb-4">
<Goose className="size-10 text-text-primary" />
</div>
<h2 className="text-2xl font-regular dark:text-white text-gray-900 text-center mb-3">
{intl.formatMessage(i18n.heading)}
</h2>
<p className="text-text-primary text-sm mb-3">
{intl.formatMessage(i18n.description)}
</p>
<div className="text-text-secondary text-xs space-y-1">
<p className="font-medium text-text-primary">{intl.formatMessage(i18n.whatWeCollect)}</p>
<ul className="list-disc list-inside space-y-0.5 ml-1">
<li>{intl.formatMessage(i18n.collectOs)}</li>
<li>{intl.formatMessage(i18n.collectVersion)}</li>
<li>{intl.formatMessage(i18n.collectProvider)}</li>
<li>{intl.formatMessage(i18n.collectExtensions)}</li>
<li>{intl.formatMessage(i18n.collectSession)}</li>
<li>{intl.formatMessage(i18n.collectErrors)}</li>
</ul>
<p className="mt-3 text-text-secondary">
{intl.formatMessage(i18n.privacyNote)}
</p>
</div>
</div>
</BaseModal>
);
}
@@ -21,45 +21,106 @@ import { NavigationProvider, useNavigationContextSafe } from '../../Layout/Navig
const i18n = defineMessages({
appearanceTitle: { id: 'settings.appearance.title', defaultMessage: 'Appearance' },
appearanceDesc: { id: 'settings.appearance.description', defaultMessage: 'Configure how goose appears on your system' },
appearanceDesc: {
id: 'settings.appearance.description',
defaultMessage: 'Configure how goose appears on your system',
},
notifications: { id: 'settings.notifications.title', defaultMessage: 'Notifications' },
notificationsDesc: { id: 'settings.notifications.description', defaultMessage: 'Notifications are managed by your OS - {link}' },
notificationsDesc: {
id: 'settings.notifications.description',
defaultMessage: 'Notifications are managed by your OS - {link}',
},
configGuide: { id: 'settings.notifications.configGuide', defaultMessage: 'Configuration guide' },
openSettings: { id: 'settings.notifications.openSettings', defaultMessage: 'Open Settings' },
menuBarIcon: { id: 'settings.menuBarIcon.title', defaultMessage: 'Menu bar icon' },
menuBarIconDesc: { id: 'settings.menuBarIcon.description', defaultMessage: 'Show goose in the menu bar' },
menuBarIconDesc: {
id: 'settings.menuBarIcon.description',
defaultMessage: 'Show goose in the menu bar',
},
dockIcon: { id: 'settings.dockIcon.title', defaultMessage: 'Dock icon' },
dockIconDesc: { id: 'settings.dockIcon.description', defaultMessage: 'Show goose in the dock' },
preventSleep: { id: 'settings.preventSleep.title', defaultMessage: 'Prevent Sleep' },
preventSleepDesc: { id: 'settings.preventSleep.description', defaultMessage: 'Keep your computer awake while goose is running a task (screen can still lock)' },
preventSleepDesc: {
id: 'settings.preventSleep.description',
defaultMessage:
'Keep your computer awake while goose is running a task (screen can still lock)',
},
costTracking: { id: 'settings.costTracking.title', defaultMessage: 'Cost Tracking' },
costTrackingDesc: { id: 'settings.costTracking.description', defaultMessage: 'Show model pricing and usage costs' },
costTrackingDesc: {
id: 'settings.costTracking.description',
defaultMessage: 'Show model pricing and usage costs',
},
themeTitle: { id: 'settings.theme.title', defaultMessage: 'Theme' },
themeDesc: { id: 'settings.theme.description', defaultMessage: 'Customize the look and feel of goose' },
themeDesc: {
id: 'settings.theme.description',
defaultMessage: 'Customize the look and feel of goose',
},
navigationTitle: { id: 'settings.navigation.title', defaultMessage: 'Navigation' },
navigationDesc: { id: 'settings.navigation.description', defaultMessage: 'Customize navigation layout and behavior' },
navigationDesc: {
id: 'settings.navigation.description',
defaultMessage: 'Customize navigation layout and behavior',
},
navMode: { id: 'settings.navigation.mode', defaultMessage: 'Mode' },
navStyle: { id: 'settings.navigation.style', defaultMessage: 'Style' },
navPosition: { id: 'settings.navigation.position', defaultMessage: 'Position' },
navCustomize: { id: 'settings.navigation.customize', defaultMessage: 'Customize Items' },
helpTitle: { id: 'settings.help.title', defaultMessage: 'Help & feedback' },
helpDesc: { id: 'settings.help.description', defaultMessage: 'Help us improve goose by reporting issues or requesting new features' },
helpDesc: {
id: 'settings.help.description',
defaultMessage: 'Help us improve goose by reporting issues or requesting new features',
},
reportBug: { id: 'settings.help.reportBug', defaultMessage: 'Report a Bug' },
requestFeature: { id: 'settings.help.requestFeature', defaultMessage: 'Request a Feature' },
versionTitle: { id: 'settings.version.title', defaultMessage: 'Version' },
updatesTitle: { id: 'settings.updates.title', defaultMessage: 'Updates' },
updatesDesc: { id: 'settings.updates.description', defaultMessage: 'Check for and install updates to keep goose running at its best' },
notificationsModalTitle: { id: 'settings.notifications.modal.title', defaultMessage: 'How to Enable Notifications' },
notificationsMacInstructions: { id: 'settings.notifications.modal.macInstructions', defaultMessage: 'To enable notifications on macOS:' },
notificationsMacStep1: { id: 'settings.notifications.modal.macStep1', defaultMessage: 'Open System Preferences' },
notificationsMacStep2: { id: 'settings.notifications.modal.macStep2', defaultMessage: 'Click on Notifications' },
notificationsMacStep3: { id: 'settings.notifications.modal.macStep3', defaultMessage: 'Find and select goose in the application list' },
notificationsMacStep4: { id: 'settings.notifications.modal.macStep4', defaultMessage: 'Enable notifications and adjust settings as desired' },
notificationsWinInstructions: { id: 'settings.notifications.modal.winInstructions', defaultMessage: 'To enable notifications on Windows:' },
notificationsWinStep1: { id: 'settings.notifications.modal.winStep1', defaultMessage: 'Open Settings' },
notificationsWinStep2: { id: 'settings.notifications.modal.winStep2', defaultMessage: 'Go to System > Notifications' },
notificationsWinStep3: { id: 'settings.notifications.modal.winStep3', defaultMessage: 'Find and select goose in the application list' },
notificationsWinStep4: { id: 'settings.notifications.modal.winStep4', defaultMessage: 'Toggle notifications on and adjust settings as desired' },
updatesDesc: {
id: 'settings.updates.description',
defaultMessage: 'Check for and install updates to keep goose running at its best',
},
notificationsModalTitle: {
id: 'settings.notifications.modal.title',
defaultMessage: 'How to Enable Notifications',
},
notificationsMacInstructions: {
id: 'settings.notifications.modal.macInstructions',
defaultMessage: 'To enable notifications on macOS:',
},
notificationsMacStep1: {
id: 'settings.notifications.modal.macStep1',
defaultMessage: 'Open System Preferences',
},
notificationsMacStep2: {
id: 'settings.notifications.modal.macStep2',
defaultMessage: 'Click on Notifications',
},
notificationsMacStep3: {
id: 'settings.notifications.modal.macStep3',
defaultMessage: 'Find and select goose in the application list',
},
notificationsMacStep4: {
id: 'settings.notifications.modal.macStep4',
defaultMessage: 'Enable notifications and adjust settings as desired',
},
notificationsWinInstructions: {
id: 'settings.notifications.modal.winInstructions',
defaultMessage: 'To enable notifications on Windows:',
},
notificationsWinStep1: {
id: 'settings.notifications.modal.winStep1',
defaultMessage: 'Open Settings',
},
notificationsWinStep2: {
id: 'settings.notifications.modal.winStep2',
defaultMessage: 'Go to System > Notifications',
},
notificationsWinStep3: {
id: 'settings.notifications.modal.winStep3',
defaultMessage: 'Find and select goose in the application list',
},
notificationsWinStep4: {
id: 'settings.notifications.modal.winStep4',
defaultMessage: 'Toggle notifications on and adjust settings as desired',
},
close: { id: 'settings.close', defaultMessage: 'Close' },
});
@@ -94,23 +155,31 @@ const NavigationSettingsContent: React.FC = () => {
{isExpanded && (
<CardContent className="pt-4 px-4 space-y-6">
<div>
<h3 className="text-sm font-medium text-text-primary mb-3">{intl.formatMessage(i18n.navMode)}</h3>
<h3 className="text-sm font-medium text-text-primary mb-3">
{intl.formatMessage(i18n.navMode)}
</h3>
<NavigationModeSelector />
</div>
{!isOverlayMode && (
<div>
<h3 className="text-sm font-medium text-text-primary mb-3">{intl.formatMessage(i18n.navStyle)}</h3>
<h3 className="text-sm font-medium text-text-primary mb-3">
{intl.formatMessage(i18n.navStyle)}
</h3>
<NavigationStyleSelector />
</div>
)}
{!isOverlayMode && (
<div>
<h3 className="text-sm font-medium text-text-primary mb-3">{intl.formatMessage(i18n.navPosition)}</h3>
<h3 className="text-sm font-medium text-text-primary mb-3">
{intl.formatMessage(i18n.navPosition)}
</h3>
<NavigationPositionSelector />
</div>
)}
<div>
<h3 className="text-sm font-medium text-text-primary mb-3">{intl.formatMessage(i18n.navCustomize)}</h3>
<h3 className="text-sm font-medium text-text-primary mb-3">
{intl.formatMessage(i18n.navCustomize)}
</h3>
<NavigationCustomizationSettings />
</div>
</CardContent>
@@ -267,7 +336,9 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
<CardContent className="pt-4 space-y-4 px-4">
<div className="flex items-center justify-between">
<div>
<h3 className="text-text-primary text-xs">{intl.formatMessage(i18n.notifications)}</h3>
<h3 className="text-text-primary text-xs">
{intl.formatMessage(i18n.notifications)}
</h3>
<p className="text-xs text-text-secondary max-w-md mt-[2px]">
{intl.formatMessage(i18n.notificationsDesc, {
link: (
@@ -386,14 +457,12 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
{/* Navigation Settings */}
<NavigationSettingsCard />
<TelemetrySettings isWelcome={false} />
<TelemetrySettings />
<Card className="rounded-lg">
<CardHeader className="pb-0">
<CardTitle className="mb-1">{intl.formatMessage(i18n.helpTitle)}</CardTitle>
<CardDescription>
{intl.formatMessage(i18n.helpDesc)}
</CardDescription>
<CardDescription>{intl.formatMessage(i18n.helpDesc)}</CardDescription>
</CardHeader>
<CardContent className="pt-4 px-4">
<div className="flex space-x-4">
@@ -452,9 +521,7 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
<Card className="rounded-lg">
<CardHeader className="pb-0">
<CardTitle className="mb-1">{intl.formatMessage(i18n.updatesTitle)}</CardTitle>
<CardDescription>
{intl.formatMessage(i18n.updatesDesc)}
</CardDescription>
<CardDescription>{intl.formatMessage(i18n.updatesDesc)}</CardDescription>
</CardHeader>
<CardContent className="px-4">
<UpdateSection />
@@ -3,7 +3,7 @@ import { Switch } from '../../ui/switch';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../ui/card';
import { useConfig } from '../../ConfigContext';
import { TELEMETRY_UI_ENABLED } from '../../../updates';
import TelemetryOptOutModal from '../../TelemetryOptOutModal';
import PrivacyInfoModal from '../../onboarding/PrivacyInfoModal';
import { toastService } from '../../../toasts';
import {
setTelemetryEnabled as setAnalyticsTelemetryEnabled,
@@ -48,11 +48,7 @@ const i18n = defineMessages({
const TELEMETRY_CONFIG_KEY = 'GOOSE_TELEMETRY_ENABLED';
interface TelemetrySettingsProps {
isWelcome: boolean;
}
export default function TelemetrySettings({ isWelcome = false }: TelemetrySettingsProps) {
export default function TelemetrySettings() {
const intl = useIntl();
const { read, upsert } = useConfig();
const [telemetryEnabled, setTelemetryEnabled] = useState(true);
@@ -84,7 +80,7 @@ export default function TelemetrySettings({ isWelcome = false }: TelemetrySettin
await upsert(TELEMETRY_CONFIG_KEY, checked, false);
setTelemetryEnabled(checked);
setAnalyticsTelemetryEnabled(checked);
trackTelemetryPreference(checked, isWelcome ? 'onboarding' : 'settings');
trackTelemetryPreference(checked, 'settings');
} catch (error) {
console.error('Failed to update telemetry status:', error);
toastService.error({
@@ -127,15 +123,13 @@ export default function TelemetrySettings({ isWelcome = false }: TelemetrySettin
/>
);
const modal = <TelemetryOptOutModal controlled isOpen={showModal} onClose={handleModalClose} />;
const modal = <PrivacyInfoModal isOpen={showModal} onClose={handleModalClose} />;
const toggleRow = (
<div className="flex items-center justify-between">
<div>
<h4 className={isWelcome ? 'text-text-primary text-sm' : 'text-text-primary text-xs'}>
{toggleLabel}
</h4>
<p className={`${isWelcome ? 'text-sm' : 'text-xs'} text-text-secondary max-w-md mt-[2px]`}>
<h4 className="text-text-primary text-xs">{toggleLabel}</h4>
<p className="text-xs text-text-secondary max-w-md mt-[2px]">
{toggleDescription} {learnMoreLink}
</p>
</div>
@@ -143,19 +137,6 @@ export default function TelemetrySettings({ isWelcome = false }: TelemetrySettin
</div>
);
if (isWelcome) {
return (
<>
<div className="w-full p-4 sm:p-6 bg-transparent border rounded-xl">
<h3 className="font-medium text-text-primary text-sm sm:text-base mb-1">{title}</h3>
<p className="text-text-secondary text-sm sm:text-base mb-4">{description}</p>
{toggleRow}
</div>
{modal}
</>
);
}
return (
<>
<Card className="rounded-lg">
+8 -35
View File
@@ -4334,48 +4334,21 @@
"switchModelModal.useOtherProvider": {
"defaultMessage": "Use other provider"
},
"telemetryOptOutModal.collectErrors": {
"defaultMessage": "Error types (e.g., \"rate_limit\", \"auth\" - no details)"
"telemetryConsentPrompt.description": {
"defaultMessage": "Would you like to share anonymous usage data to help improve goose? We never collect your conversations, code, or personal data."
},
"telemetryOptOutModal.collectExtensions": {
"defaultMessage": "Extensions and tool usage counts (names only)"
},
"telemetryOptOutModal.collectOs": {
"defaultMessage": "Operating system, version, and architecture"
},
"telemetryOptOutModal.collectProvider": {
"defaultMessage": "Provider and model used"
},
"telemetryOptOutModal.collectSession": {
"defaultMessage": "Session metrics (duration, interaction count, token usage)"
},
"telemetryOptOutModal.collectVersion": {
"defaultMessage": "goose version and install method"
},
"telemetryOptOutModal.configError": {
"defaultMessage": "Configuration Error"
},
"telemetryOptOutModal.configErrorMessage": {
"defaultMessage": "Failed to check telemetry configuration."
},
"telemetryOptOutModal.description": {
"defaultMessage": "Would you like to help improve goose by sharing anonymous usage data? This helps us understand how goose is used and identify areas for improvement."
},
"telemetryOptOutModal.heading": {
"telemetryConsentPrompt.heading": {
"defaultMessage": "Help improve goose"
},
"telemetryOptOutModal.optIn": {
"telemetryConsentPrompt.learnMore": {
"defaultMessage": "Learn more"
},
"telemetryConsentPrompt.optIn": {
"defaultMessage": "Yes, share anonymous usage data"
},
"telemetryOptOutModal.optOut": {
"telemetryConsentPrompt.optOut": {
"defaultMessage": "No thanks"
},
"telemetryOptOutModal.privacyNote": {
"defaultMessage": "We never collect your conversations, code, tool arguments, error messages, or any personal data. You can change this setting anytime in Settings → App."
},
"telemetryOptOutModal.whatWeCollect": {
"defaultMessage": "What we collect:"
},
"telemetrySettings.configErrorTitle": {
"defaultMessage": "Configuration Error"
},