Skip to content

Commit f0decaf

Browse files
gewenyu99claude
andauthored
feat(analytics): instrument privacy panel, intro menu, and settings-conflict screens (#666)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 928db8c commit f0decaf

4 files changed

Lines changed: 39 additions & 4 deletions

File tree

src/ui/tui/components/PrivacyPanel.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,22 @@
1111
* their browser.
1212
*/
1313

14+
import { useEffect } from 'react';
1415
import { Box, Text } from 'ink';
1516
import {
1617
POSTHOG_ORG_AI_SETTINGS_URL,
1718
POSTHOG_PRIVACY_URL,
1819
POSTHOG_TERMS_URL,
1920
} from '@lib/constants';
21+
import { analytics } from '@utils/analytics';
2022

2123
export const PrivacyPanel = () => {
24+
// Rendered from the intro menu and the auth-screen [I] overlay; either way,
25+
// count the impression once per mount.
26+
useEffect(() => {
27+
analytics.wizardCapture('privacy panel shown');
28+
}, []);
29+
2230
return (
2331
<Box flexDirection="column" width={64} flexShrink={0}>
2432
<Text>

src/ui/tui/screens/ManagedSettingsScreen.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
*/
1111

1212
import { Box, Text } from 'ink';
13-
import { useSyncExternalStore } from 'react';
13+
import { useEffect, useSyncExternalStore } from 'react';
1414
import type { WizardStore } from '@ui/tui/store';
1515
import { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';
1616
import { Icons } from '@ui/tui/styles';
1717
import type { SettingsConflict } from '@lib/agent/claude-settings';
18+
import { analytics } from '@utils/analytics';
1819

1920
function sourceLabel(source: SettingsConflict['source']): string {
2021
switch (source) {
@@ -44,12 +45,26 @@ export const ManagedSettingsScreen = ({
4445
const conflicts = store.session.settingsConflicts;
4546
const readOnlyConflicts = conflicts?.filter((c) => !c.writable);
4647

48+
const hasManaged = Boolean(
49+
readOnlyConflicts?.some((c) => c.source === 'managed'),
50+
);
51+
const hasReadOnly = Boolean(
52+
readOnlyConflicts && readOnlyConflicts.length > 0,
53+
);
54+
useEffect(() => {
55+
// Read-only conflict — nothing to accept, so impression only.
56+
if (hasReadOnly) {
57+
analytics.wizardCapture('settings conflict shown', {
58+
kind: 'managed',
59+
has_managed: hasManaged,
60+
});
61+
}
62+
}, [hasReadOnly, hasManaged]);
63+
4764
if (!readOnlyConflicts || readOnlyConflicts.length === 0) {
4865
return null;
4966
}
5067

51-
const hasManaged = readOnlyConflicts.some((c) => c.source === 'managed');
52-
5368
return (
5469
<ModalOverlay
5570
borderColor="red"

src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ export const PostHogIntegrationIntroScreen = ({
285285
}
286286

287287
const handleSelect = (value: string) => {
288+
analytics.wizardCapture('intro menu selected', { value, view });
288289
if (view === 'tools') {
289290
if (value === 'back') setView('default');
290291
else launchTool(value, session.installDir);

src/ui/tui/screens/SettingsOverrideScreen.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Box, Text } from 'ink';
2-
import { useState, useSyncExternalStore } from 'react';
2+
import { useEffect, useState, useSyncExternalStore } from 'react';
33
import type { WizardStore } from '@ui/tui/store';
44
import { ConfirmationInput, ModalOverlay } from '@ui/tui/primitives/index';
55
import { Icons } from '@ui/tui/styles';
6+
import { analytics } from '@utils/analytics';
67

78
interface SettingsOverrideScreenProps {
89
store: WizardStore;
@@ -19,6 +20,13 @@ export const SettingsOverrideScreen = ({
1920
const [feedback, setFeedback] = useState<string | null>(null);
2021
const conflicts = store.session.settingsConflicts?.filter((c) => c.writable);
2122

23+
const hasConflicts = Boolean(conflicts && conflicts.length > 0);
24+
useEffect(() => {
25+
if (hasConflicts) {
26+
analytics.wizardCapture('settings conflict shown', { kind: 'override' });
27+
}
28+
}, [hasConflicts]);
29+
2230
if (!conflicts || conflicts.length === 0) {
2331
return null;
2432
}
@@ -35,6 +43,9 @@ export const SettingsOverrideScreen = ({
3543
confirmLabel="Backup & continue [Enter]"
3644
cancelLabel="Exit [Esc]"
3745
onConfirm={() => {
46+
analytics.wizardCapture('settings conflict accepted', {
47+
kind: 'override',
48+
});
3849
const ok = store.backupAndFixSettingsOverride();
3950
if (!ok) {
4051
setFeedback('Could not back up the settings file.');

0 commit comments

Comments
 (0)