feat: add PostHog telemetry and privacy toggle in settings (#409)
This commit is contained in:
committed by
GitHub
Unverified
parent
d11e266cbb
commit
da8ed3bb32
@@ -13,6 +13,7 @@ import { createMenu } from './menu';
|
||||
import { appUpdater, registerUpdateHandlers } from './updater';
|
||||
import { logger } from '../utils/logger';
|
||||
import { warmupNetworkOptimization } from '../utils/uv-env';
|
||||
import { initTelemetry, shutdownTelemetry } from '../utils/telemetry';
|
||||
|
||||
import { ClawHubService } from '../gateway/clawhub';
|
||||
import { ensureClawXContext, repairClawXOnlyBootstrapFiles } from '../utils/openclaw-workspace';
|
||||
@@ -156,6 +157,9 @@ async function initialize(): Promise<void> {
|
||||
// Warm up network optimization (non-blocking)
|
||||
void warmupNetworkOptimization();
|
||||
|
||||
// Initialize Telemetry early
|
||||
await initTelemetry();
|
||||
|
||||
// Apply persisted proxy settings before creating windows or network requests.
|
||||
await applyProxySettings();
|
||||
|
||||
@@ -377,6 +381,10 @@ app.on('before-quit', () => {
|
||||
setQuitting();
|
||||
hostEventBus.closeAll();
|
||||
hostApiServer?.close();
|
||||
// Flush telemetry data
|
||||
void shutdownTelemetry().catch((err) => {
|
||||
logger.warn('Failed to shutdown telemetry:', err);
|
||||
});
|
||||
// Fire-and-forget: do not await gatewayManager.stop() here.
|
||||
// Awaiting inside before-quit can stall Electron's quit sequence.
|
||||
void gatewayManager.stop().catch((err) => {
|
||||
|
||||
@@ -25,7 +25,10 @@ export interface AppSettings {
|
||||
language: string;
|
||||
startMinimized: boolean;
|
||||
launchAtStartup: boolean;
|
||||
|
||||
telemetryEnabled: boolean;
|
||||
machineId: string;
|
||||
hasReportedInstall: boolean;
|
||||
|
||||
// Gateway
|
||||
gatewayAutoStart: boolean;
|
||||
gatewayPort: number;
|
||||
@@ -36,17 +39,17 @@ export interface AppSettings {
|
||||
proxyHttpsServer: string;
|
||||
proxyAllServer: string;
|
||||
proxyBypassRules: string;
|
||||
|
||||
|
||||
// Update
|
||||
updateChannel: 'stable' | 'beta' | 'dev';
|
||||
autoCheckUpdate: boolean;
|
||||
autoDownloadUpdate: boolean;
|
||||
skippedVersions: string[];
|
||||
|
||||
|
||||
// UI State
|
||||
sidebarCollapsed: boolean;
|
||||
devModeUnlocked: boolean;
|
||||
|
||||
|
||||
// Presets
|
||||
selectedBundles: string[];
|
||||
enabledSkills: string[];
|
||||
@@ -62,7 +65,10 @@ const defaults: AppSettings = {
|
||||
language: 'en',
|
||||
startMinimized: false,
|
||||
launchAtStartup: false,
|
||||
|
||||
telemetryEnabled: true,
|
||||
machineId: '',
|
||||
hasReportedInstall: false,
|
||||
|
||||
// Gateway
|
||||
gatewayAutoStart: true,
|
||||
gatewayPort: 18789,
|
||||
@@ -73,17 +79,17 @@ const defaults: AppSettings = {
|
||||
proxyHttpsServer: '',
|
||||
proxyAllServer: '',
|
||||
proxyBypassRules: '<local>;localhost;127.0.0.1;::1',
|
||||
|
||||
|
||||
// Update
|
||||
updateChannel: 'stable',
|
||||
autoCheckUpdate: true,
|
||||
autoDownloadUpdate: false,
|
||||
skippedVersions: [],
|
||||
|
||||
|
||||
// UI State
|
||||
sidebarCollapsed: false,
|
||||
devModeUnlocked: false,
|
||||
|
||||
|
||||
// Presets
|
||||
selectedBundles: ['productivity', 'developer'],
|
||||
enabledSkills: [],
|
||||
|
||||
79
electron/utils/telemetry.ts
Normal file
79
electron/utils/telemetry.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { PostHog } from 'posthog-node';
|
||||
import { machineIdSync } from 'node-machine-id';
|
||||
import { app } from 'electron';
|
||||
import { getSetting, setSetting } from './store';
|
||||
import { logger } from './logger';
|
||||
|
||||
const POSTHOG_API_KEY = 'phc_aGNegeJQP5FzNiF2rEoKqQbkuCpiiETMttplibXpB0n';
|
||||
const POSTHOG_HOST = 'https://us.i.posthog.com';
|
||||
|
||||
let posthogClient: PostHog | null = null;
|
||||
let distinctId: string = '';
|
||||
|
||||
/**
|
||||
* Initialize PostHog telemetry
|
||||
*/
|
||||
export async function initTelemetry(): Promise<void> {
|
||||
try {
|
||||
const telemetryEnabled = await getSetting('telemetryEnabled');
|
||||
if (!telemetryEnabled) {
|
||||
logger.info('Telemetry is disabled in settings');
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize PostHog client
|
||||
posthogClient = new PostHog(POSTHOG_API_KEY, { host: POSTHOG_HOST });
|
||||
|
||||
// Get or generate machine ID
|
||||
distinctId = await getSetting('machineId');
|
||||
if (!distinctId) {
|
||||
distinctId = machineIdSync();
|
||||
await setSetting('machineId', distinctId);
|
||||
logger.debug(`Generated new machine ID for telemetry: ${distinctId}`);
|
||||
}
|
||||
|
||||
// Common properties for all events
|
||||
const properties = {
|
||||
$app_version: app.getVersion(),
|
||||
$os: process.platform,
|
||||
arch: process.arch,
|
||||
};
|
||||
|
||||
// Check if this is a new installation
|
||||
const hasReportedInstall = await getSetting('hasReportedInstall');
|
||||
if (!hasReportedInstall) {
|
||||
posthogClient.capture({
|
||||
distinctId,
|
||||
event: 'app_installed',
|
||||
properties,
|
||||
});
|
||||
await setSetting('hasReportedInstall', true);
|
||||
logger.info('Reported app_installed event');
|
||||
}
|
||||
|
||||
// Always report app opened
|
||||
posthogClient.capture({
|
||||
distinctId,
|
||||
event: 'app_opened',
|
||||
properties,
|
||||
});
|
||||
logger.debug('Reported app_opened event');
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Failed to initialize telemetry:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure PostHog flushes all pending events before shutting down
|
||||
*/
|
||||
export async function shutdownTelemetry(): Promise<void> {
|
||||
if (posthogClient) {
|
||||
try {
|
||||
await posthogClient.shutdown();
|
||||
logger.debug('Flushed telemetry events on shutdown');
|
||||
} catch (error) {
|
||||
logger.error('Error shutting down telemetry:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,8 @@
|
||||
"clawhub": "^0.5.0",
|
||||
"electron-store": "^11.0.2",
|
||||
"electron-updater": "^6.8.3",
|
||||
"node-machine-id": "^1.1.12",
|
||||
"posthog-node": "^5.28.0",
|
||||
"ws": "^8.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
137
pnpm-lock.yaml
generated
137
pnpm-lock.yaml
generated
@@ -20,6 +20,12 @@ importers:
|
||||
electron-updater:
|
||||
specifier: ^6.8.3
|
||||
version: 6.8.3
|
||||
node-machine-id:
|
||||
specifier: ^1.1.12
|
||||
version: 1.1.12
|
||||
posthog-node:
|
||||
specifier: ^5.28.0
|
||||
version: 5.28.0
|
||||
ws:
|
||||
specifier: ^8.19.0
|
||||
version: 8.19.0
|
||||
@@ -278,10 +284,6 @@ packages:
|
||||
resolution: {integrity: sha512-ag7Qx78m1K3Dv7xlFgeHS4jBdopGZUISgVBMUy7Cj4fIgVH9EBmsc5K4hWozL8BJQctWke8Wsl96O7Gd+HCGhg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-bedrock@3.1000.0':
|
||||
resolution: {integrity: sha512-wGU8uJXrPW/hZuHdPNVe1kAFIBiKcslBcoDBN0eYBzS13um8p5jJiQJ9WsD1nSpKCmyx7qZXc6xjcbIQPyOrrA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-bedrock@3.1006.0':
|
||||
resolution: {integrity: sha512-CWUrrlWaFDYZIK2rNIa9FUVn3wC3lZszz0r6bq5yRiRj1P+dSd+ZpGdlRYDAi6Nq9dsainEXdpadiuUwzL6YZQ==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
@@ -422,10 +424,6 @@ packages:
|
||||
resolution: {integrity: sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/token-providers@3.1000.0':
|
||||
resolution: {integrity: sha512-eOI+8WPtWpLdlYBGs8OCK3k5uIMUHVsNG3AFO4kaRaZcKReJ/2OO6+2O2Dd/3vTzM56kRjSKe7mBOCwa4PdYqg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/token-providers@3.1005.0':
|
||||
resolution: {integrity: sha512-vMxd+ivKqSxU9bHx5vmAlFKDAkjGotFU56IOkDa5DaTu1WWwbcse0yFHEm9I537oVvodaiwMl3VBwgHfzQ2rvw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
@@ -1748,6 +1746,9 @@ packages:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@posthog/core@1.23.2':
|
||||
resolution: {integrity: sha512-zTDdda9NuSHrnwSOfFMxX/pyXiycF4jtU1kTr8DL61dHhV+7LF6XF1ndRZZTuaGGbfbb/GJYkEsjEX9SXfNZeQ==}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2':
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
|
||||
@@ -3828,9 +3829,6 @@ packages:
|
||||
discord-api-types@0.38.37:
|
||||
resolution: {integrity: sha512-Cv47jzY1jkGkh5sv0bfHYqGgKOWO1peOrGMkDFM4UmaGMOTgOW8QSexhvixa9sVOiz8MnVOBryWYyw/CEVhj7w==}
|
||||
|
||||
discord-api-types@0.38.40:
|
||||
resolution: {integrity: sha512-P/His8cotqZgQqrt+hzrocp9L8RhQQz1GkrCnC9TMJ8Uw2q0tg8YyqJyGULxhXn/8kxHETN4IppmOv+P2m82lQ==}
|
||||
|
||||
discord-api-types@0.38.42:
|
||||
resolution: {integrity: sha512-qs1kya7S84r5RR8m9kgttywGrmmoHaRifU1askAoi+wkoSefLpZP6aGXusjNw5b0jD3zOg3LTwUa3Tf2iHIceQ==}
|
||||
|
||||
@@ -4405,10 +4403,6 @@ packages:
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
grammy@1.41.0:
|
||||
resolution: {integrity: sha512-CAAu74SLT+/QCg40FBhUuYJalVsxxCN3D0c31TzhFBsWWTdXrMXYjGsKngBdfvN6hQ/VzHczluj/ugZVetFNCQ==}
|
||||
engines: {node: ^12.20.0 || >=14.13.1}
|
||||
|
||||
grammy@1.41.1:
|
||||
resolution: {integrity: sha512-wcHAQ1e7svL3fJMpDchcQVcWUmywhuepOOjHUHmMmWAwUJEIyK5ea5sbSjZd+Gy1aMpZeP8VYJa+4tP+j1YptQ==}
|
||||
engines: {node: ^12.20.0 || >=14.13.1}
|
||||
@@ -5335,6 +5329,9 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
node-machine-id@1.1.12:
|
||||
resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==}
|
||||
|
||||
node-readable-to-web-readable-stream@0.4.2:
|
||||
resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==}
|
||||
|
||||
@@ -5694,6 +5691,15 @@ packages:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
posthog-node@5.28.0:
|
||||
resolution: {integrity: sha512-EETYV0zA+7BLQmXzY+vGyDMoQK8uHf8f/1utbRjKncI41gPkw+4piGP7l4UT5Luld+4vQpJPOR1q1YrbXm7XjQ==}
|
||||
engines: {node: ^20.20.0 || >=22.22.0}
|
||||
peerDependencies:
|
||||
rxjs: ^7.0.0
|
||||
peerDependenciesMeta:
|
||||
rxjs:
|
||||
optional: true
|
||||
|
||||
postject@1.0.0-alpha.6:
|
||||
resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -7046,51 +7052,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
'@aws-sdk/client-bedrock@3.1000.0':
|
||||
dependencies:
|
||||
'@aws-crypto/sha256-browser': 5.2.0
|
||||
'@aws-crypto/sha256-js': 5.2.0
|
||||
'@aws-sdk/core': 3.973.15
|
||||
'@aws-sdk/credential-provider-node': 3.972.14
|
||||
'@aws-sdk/middleware-host-header': 3.972.6
|
||||
'@aws-sdk/middleware-logger': 3.972.6
|
||||
'@aws-sdk/middleware-recursion-detection': 3.972.6
|
||||
'@aws-sdk/middleware-user-agent': 3.972.15
|
||||
'@aws-sdk/region-config-resolver': 3.972.6
|
||||
'@aws-sdk/token-providers': 3.1000.0
|
||||
'@aws-sdk/types': 3.973.4
|
||||
'@aws-sdk/util-endpoints': 3.996.3
|
||||
'@aws-sdk/util-user-agent-browser': 3.972.6
|
||||
'@aws-sdk/util-user-agent-node': 3.973.0
|
||||
'@smithy/config-resolver': 4.4.9
|
||||
'@smithy/core': 3.23.6
|
||||
'@smithy/fetch-http-handler': 5.3.11
|
||||
'@smithy/hash-node': 4.2.10
|
||||
'@smithy/invalid-dependency': 4.2.10
|
||||
'@smithy/middleware-content-length': 4.2.10
|
||||
'@smithy/middleware-endpoint': 4.4.20
|
||||
'@smithy/middleware-retry': 4.4.37
|
||||
'@smithy/middleware-serde': 4.2.11
|
||||
'@smithy/middleware-stack': 4.2.10
|
||||
'@smithy/node-config-provider': 4.3.10
|
||||
'@smithy/node-http-handler': 4.4.12
|
||||
'@smithy/protocol-http': 5.3.10
|
||||
'@smithy/smithy-client': 4.12.0
|
||||
'@smithy/types': 4.13.0
|
||||
'@smithy/url-parser': 4.2.10
|
||||
'@smithy/util-base64': 4.3.1
|
||||
'@smithy/util-body-length-browser': 4.2.1
|
||||
'@smithy/util-body-length-node': 4.2.2
|
||||
'@smithy/util-defaults-mode-browser': 4.3.36
|
||||
'@smithy/util-defaults-mode-node': 4.2.39
|
||||
'@smithy/util-endpoints': 3.3.1
|
||||
'@smithy/util-middleware': 4.2.10
|
||||
'@smithy/util-retry': 4.2.10
|
||||
'@smithy/util-utf8': 4.2.1
|
||||
tslib: 2.8.1
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
'@aws-sdk/client-bedrock@3.1006.0':
|
||||
dependencies:
|
||||
'@aws-crypto/sha256-browser': 5.2.0
|
||||
@@ -7613,18 +7574,6 @@ snapshots:
|
||||
'@smithy/types': 4.13.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/token-providers@3.1000.0':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.973.15
|
||||
'@aws-sdk/nested-clients': 3.996.3
|
||||
'@aws-sdk/types': 3.973.4
|
||||
'@smithy/property-provider': 4.2.10
|
||||
'@smithy/shared-ini-file-loader': 4.4.5
|
||||
'@smithy/types': 4.13.0
|
||||
tslib: 2.8.1
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
'@aws-sdk/token-providers@3.1005.0':
|
||||
dependencies:
|
||||
'@aws-sdk/core': 3.973.19
|
||||
@@ -8286,21 +8235,11 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@grammyjs/runner@2.0.3(grammy@1.41.0(encoding@0.1.13))':
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
grammy: 1.41.0(encoding@0.1.13)
|
||||
|
||||
'@grammyjs/runner@2.0.3(grammy@1.41.1(encoding@0.1.13))':
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
grammy: 1.41.1(encoding@0.1.13)
|
||||
|
||||
'@grammyjs/transformer-throttler@1.2.1(grammy@1.41.0(encoding@0.1.13))':
|
||||
dependencies:
|
||||
bottleneck: 2.19.5
|
||||
grammy: 1.41.0(encoding@0.1.13)
|
||||
|
||||
'@grammyjs/transformer-throttler@1.2.1(grammy@1.41.1(encoding@0.1.13))':
|
||||
dependencies:
|
||||
bottleneck: 2.19.5
|
||||
@@ -9068,6 +9007,10 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@posthog/core@1.23.2':
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
|
||||
'@protobufjs/aspromise@1.1.2': {}
|
||||
|
||||
'@protobufjs/base64@1.1.2': {}
|
||||
@@ -11161,11 +11104,11 @@ snapshots:
|
||||
clawdbot@2026.1.24-3(@discordjs/opus@0.10.0(encoding@0.1.13))(@types/express@5.0.6)(devtools-protocol@0.0.1596832)(encoding@0.1.13)(opusscript@0.1.1)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@agentclientprotocol/sdk': 0.13.1(zod@4.3.6)
|
||||
'@aws-sdk/client-bedrock': 3.1000.0
|
||||
'@aws-sdk/client-bedrock': 3.1006.0
|
||||
'@buape/carbon': 0.14.0(@discordjs/opus@0.10.0(encoding@0.1.13))(hono@4.11.4)(opusscript@0.1.1)
|
||||
'@clack/prompts': 0.11.0
|
||||
'@grammyjs/runner': 2.0.3(grammy@1.41.0(encoding@0.1.13))
|
||||
'@grammyjs/transformer-throttler': 1.2.1(grammy@1.41.0(encoding@0.1.13))
|
||||
'@grammyjs/runner': 2.0.3(grammy@1.41.1(encoding@0.1.13))
|
||||
'@grammyjs/transformer-throttler': 1.2.1(grammy@1.41.1(encoding@0.1.13))
|
||||
'@homebridge/ciao': 1.3.5
|
||||
'@line/bot-sdk': 10.6.0
|
||||
'@lydell/node-pty': 1.2.0-beta.3
|
||||
@@ -11187,11 +11130,11 @@ snapshots:
|
||||
commander: 14.0.3
|
||||
croner: 9.1.0
|
||||
detect-libc: 2.1.2
|
||||
discord-api-types: 0.38.40
|
||||
discord-api-types: 0.38.42
|
||||
dotenv: 17.3.1
|
||||
express: 5.2.1
|
||||
file-type: 21.3.0
|
||||
grammy: 1.41.0(encoding@0.1.13)
|
||||
grammy: 1.41.1(encoding@0.1.13)
|
||||
hono: 4.11.4
|
||||
jiti: 2.6.1
|
||||
json5: 2.2.3
|
||||
@@ -11322,7 +11265,7 @@ snapshots:
|
||||
node-api-headers: 1.8.0
|
||||
rc: 1.2.8
|
||||
semver: 7.7.4
|
||||
tar: 7.5.9
|
||||
tar: 7.5.11
|
||||
url-join: 4.0.1
|
||||
which: 6.0.1
|
||||
yargs: 17.7.2
|
||||
@@ -11543,8 +11486,6 @@ snapshots:
|
||||
|
||||
discord-api-types@0.38.37: {}
|
||||
|
||||
discord-api-types@0.38.40: {}
|
||||
|
||||
discord-api-types@0.38.42: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
@@ -12302,16 +12243,6 @@ snapshots:
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
grammy@1.41.0(encoding@0.1.13):
|
||||
dependencies:
|
||||
'@grammyjs/types': 3.25.0
|
||||
abort-controller: 3.0.0
|
||||
debug: 4.4.3
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
grammy@1.41.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
'@grammyjs/types': 3.25.0
|
||||
@@ -13537,6 +13468,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
node-machine-id@1.1.12: {}
|
||||
|
||||
node-readable-to-web-readable-stream@0.4.2:
|
||||
optional: true
|
||||
|
||||
@@ -13956,6 +13889,10 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
posthog-node@5.28.0:
|
||||
dependencies:
|
||||
'@posthog/core': 1.23.2
|
||||
|
||||
postject@1.0.0-alpha.6:
|
||||
dependencies:
|
||||
commander: 9.5.0
|
||||
|
||||
@@ -194,7 +194,9 @@
|
||||
}
|
||||
},
|
||||
"devMode": "Developer Mode",
|
||||
"devModeDesc": "Show developer tools and shortcuts"
|
||||
"devModeDesc": "Show developer tools and shortcuts",
|
||||
"telemetry": "Anonymous Usage Data",
|
||||
"telemetryDesc": "Allow providing anonymous basic usage data to improve ClawX"
|
||||
},
|
||||
"developer": {
|
||||
"title": "Developer",
|
||||
|
||||
@@ -194,7 +194,9 @@
|
||||
}
|
||||
},
|
||||
"devMode": "开发者模式",
|
||||
"devModeDesc": "显示开发者工具和快捷方式"
|
||||
"devModeDesc": "显示开发者工具和快捷方式",
|
||||
"telemetry": "匿名使用数据",
|
||||
"telemetryDesc": "允许提供匿名的基础使用数据,用于改进 ClawX"
|
||||
},
|
||||
"developer": {
|
||||
"title": "开发者",
|
||||
|
||||
@@ -73,6 +73,8 @@ export function Settings() {
|
||||
setAutoDownloadUpdate,
|
||||
devModeUnlocked,
|
||||
setDevModeUnlocked,
|
||||
telemetryEnabled,
|
||||
setTelemetryEnabled,
|
||||
} = useSettingsStore();
|
||||
|
||||
const { status: gatewayStatus, restart: restartGateway } = useGatewayStore();
|
||||
@@ -367,7 +369,7 @@ export function Settings() {
|
||||
return (
|
||||
<div className="flex flex-col -m-6 dark:bg-background h-[calc(100vh-2.5rem)] overflow-hidden">
|
||||
<div className="w-full max-w-4xl mx-auto flex flex-col h-full p-10 pt-16">
|
||||
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex flex-col md:flex-row md:items-start justify-between mb-12 shrink-0 gap-4">
|
||||
<div>
|
||||
@@ -454,13 +456,13 @@ export function Settings() {
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<div className={cn(
|
||||
"flex items-center gap-1.5 px-3 py-1.5 rounded-full text-[13px] font-medium border",
|
||||
gatewayStatus.state === 'running' ? "bg-green-500/10 text-green-600 dark:text-green-500 border-green-500/20" :
|
||||
gatewayStatus.state === 'error' ? "bg-red-500/10 text-red-600 dark:text-red-500 border-red-500/20" :
|
||||
"bg-black/5 dark:bg-white/5 text-muted-foreground border-transparent"
|
||||
gatewayStatus.state === 'running' ? "bg-green-500/10 text-green-600 dark:text-green-500 border-green-500/20" :
|
||||
gatewayStatus.state === 'error' ? "bg-red-500/10 text-red-600 dark:text-red-500 border-red-500/20" :
|
||||
"bg-black/5 dark:bg-white/5 text-muted-foreground border-transparent"
|
||||
)}>
|
||||
<div className={cn("w-1.5 h-1.5 rounded-full",
|
||||
gatewayStatus.state === 'running' ? "bg-green-500" :
|
||||
gatewayStatus.state === 'error' ? "bg-red-500" : "bg-muted-foreground"
|
||||
<div className={cn("w-1.5 h-1.5 rounded-full",
|
||||
gatewayStatus.state === 'running' ? "bg-green-500" :
|
||||
gatewayStatus.state === 'error' ? "bg-red-500" : "bg-muted-foreground"
|
||||
)} />
|
||||
{gatewayStatus.state}
|
||||
</div>
|
||||
@@ -519,7 +521,20 @@ export function Settings() {
|
||||
<Switch
|
||||
checked={devModeUnlocked}
|
||||
onCheckedChange={setDevModeUnlocked}
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<Label className="text-[15px] font-medium text-foreground">{t('advanced.telemetry')}</Label>
|
||||
<p className="text-[13px] text-muted-foreground mt-1">
|
||||
{t('advanced.telemetryDesc')}
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={telemetryEnabled}
|
||||
onCheckedChange={setTelemetryEnabled}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ interface SettingsState {
|
||||
language: string;
|
||||
startMinimized: boolean;
|
||||
launchAtStartup: boolean;
|
||||
telemetryEnabled: boolean;
|
||||
|
||||
// Gateway
|
||||
gatewayAutoStart: boolean;
|
||||
@@ -45,6 +46,7 @@ interface SettingsState {
|
||||
setLanguage: (language: string) => void;
|
||||
setStartMinimized: (value: boolean) => void;
|
||||
setLaunchAtStartup: (value: boolean) => void;
|
||||
setTelemetryEnabled: (value: boolean) => void;
|
||||
setGatewayAutoStart: (value: boolean) => void;
|
||||
setGatewayPort: (port: number) => void;
|
||||
setProxyEnabled: (value: boolean) => void;
|
||||
@@ -72,6 +74,7 @@ const defaultSettings = {
|
||||
})(),
|
||||
startMinimized: false,
|
||||
launchAtStartup: false,
|
||||
telemetryEnabled: true,
|
||||
gatewayAutoStart: true,
|
||||
gatewayPort: 18789,
|
||||
proxyEnabled: false,
|
||||
@@ -113,23 +116,30 @@ export const useSettingsStore = create<SettingsState>()(
|
||||
void hostApiFetch('/api/settings/language', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ value: language }),
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
},
|
||||
setStartMinimized: (startMinimized) => set({ startMinimized }),
|
||||
setLaunchAtStartup: (launchAtStartup) => set({ launchAtStartup }),
|
||||
setTelemetryEnabled: (telemetryEnabled) => {
|
||||
set({ telemetryEnabled });
|
||||
void hostApiFetch('/api/settings/telemetryEnabled', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ value: telemetryEnabled }),
|
||||
}).catch(() => { });
|
||||
},
|
||||
setGatewayAutoStart: (gatewayAutoStart) => {
|
||||
set({ gatewayAutoStart });
|
||||
void hostApiFetch('/api/settings/gatewayAutoStart', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ value: gatewayAutoStart }),
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
},
|
||||
setGatewayPort: (gatewayPort) => {
|
||||
set({ gatewayPort });
|
||||
void hostApiFetch('/api/settings/gatewayPort', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ value: gatewayPort }),
|
||||
}).catch(() => {});
|
||||
}).catch(() => { });
|
||||
},
|
||||
setProxyEnabled: (proxyEnabled) => set({ proxyEnabled }),
|
||||
setProxyServer: (proxyServer) => set({ proxyServer }),
|
||||
|
||||
Reference in New Issue
Block a user