diff --git a/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts b/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts index 07644a8af47c..90c1106b1fdb 100644 --- a/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts +++ b/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts @@ -961,9 +961,11 @@ describe("DesktopBackendConfiguration", () => { const previousWslEnv = process.env.WSLENV; const previousDisabled = process.env.OTEL_SDK_DISABLED; + const previousTelemetry = process.env.T3CODE_TELEMETRY_ENABLED; try { delete process.env.WSLENV; process.env.OTEL_SDK_DISABLED = "true"; + process.env.T3CODE_TELEMETRY_ENABLED = "false"; yield* Effect.gen(function* () { const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration; @@ -971,6 +973,8 @@ describe("DesktopBackendConfiguration", () => { assert.equal(config.env.OTEL_SDK_DISABLED, "true"); assert.include((config.env.WSLENV ?? "").split(":"), "OTEL_SDK_DISABLED"); + assert.equal(config.env.T3CODE_TELEMETRY_ENABLED, "false"); + assert.include((config.env.WSLENV ?? "").split(":"), "T3CODE_TELEMETRY_ENABLED"); }).pipe( Effect.provide( DesktopBackendConfiguration.layer.pipe( @@ -991,6 +995,7 @@ describe("DesktopBackendConfiguration", () => { } finally { restoreEnv("WSLENV", previousWslEnv); restoreEnv("OTEL_SDK_DISABLED", previousDisabled); + restoreEnv("T3CODE_TELEMETRY_ENABLED", previousTelemetry); } }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), ); diff --git a/apps/desktop/src/backend/DesktopBackendConfiguration.ts b/apps/desktop/src/backend/DesktopBackendConfiguration.ts index d1590d1a433d..206c7f1c5e24 100644 --- a/apps/desktop/src/backend/DesktopBackendConfiguration.ts +++ b/apps/desktop/src/backend/DesktopBackendConfiguration.ts @@ -95,6 +95,7 @@ const DESKTOP_BACKEND_ENV_NAMES = [ const WSL_FORWARDED_ENV_NAMES = [ "OPENAI_API_KEY", "ANTHROPIC_API_KEY", + "T3CODE_TELEMETRY_ENABLED", // Otherwise the WSL server keeps exporting to endpoints from the bootstrap. "T3CODE_OTEL_SDK_DISABLED", "OTEL_SDK_DISABLED", diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts index 6a369a4598a2..01c8cc4dadfe 100644 --- a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts +++ b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts @@ -268,11 +268,13 @@ describe("DesktopShellEnvironment", () => { envOutput({ PATH: "/home/linuxbrew/.linuxbrew/bin:/usr/bin", SSH_AUTH_SOCK: "/tmp/secretive.sock", + T3CODE_TELEMETRY_ENABLED: "false", }), }); assert.equal(env.PATH, "/home/linuxbrew/.linuxbrew/bin:/usr/bin"); assert.equal(env.SSH_AUTH_SOCK, "/tmp/secretive.sock"); + assert.equal(env.T3CODE_TELEMETRY_ENABLED, "false"); }), ); diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.ts b/apps/desktop/src/shell/DesktopShellEnvironment.ts index 704b061db363..65e8aa9c6888 100644 --- a/apps/desktop/src/shell/DesktopShellEnvironment.ts +++ b/apps/desktop/src/shell/DesktopShellEnvironment.ts @@ -85,6 +85,7 @@ const LOGIN_SHELL_ENV_NAMES = [ "XDG_SESSION_DESKTOP", "XDG_SESSION_TYPE", "WAYLAND_DISPLAY", + "T3CODE_TELEMETRY_ENABLED", ] as const; const WINDOWS_PROFILE_ENV_NAMES = ["PATH", "FNM_DIR", "FNM_MULTISHELL_PATH"] as const; const LOCALE_ENV_NAMES = ["LANG", "LC_ALL", "LC_CTYPE"] as const; @@ -450,6 +451,8 @@ const installPosixEnvironment = Effect.fn("desktop.shellEnvironment.installPosix "XDG_DATA_HOME", "XDG_RUNTIME_DIR", "WAYLAND_DISPLAY", + // The telemetry opt-out is documented as a shell variable; GUI launches never see it. + "T3CODE_TELEMETRY_ENABLED", ] as const) { if (!config.env[name] && shellEnvironment[name]) { config.env[name] = shellEnvironment[name]; diff --git a/docs/user/telemetry.md b/docs/user/telemetry.md index 5fd4f91c9327..2f7e44825dc6 100644 --- a/docs/user/telemetry.md +++ b/docs/user/telemetry.md @@ -9,3 +9,6 @@ raw provider events, or child-agent output. Child-agent token use is excluded fr To disable collection, set `T3CODE_TELEMETRY_ENABLED=false` in the server's environment before starting it. This stops product events from being recorded or sent. + +The desktop app reads the variable from your shell profile (for example `~/.zshrc`) on macOS and +Linux, so export it there and restart the app. On Windows, set it as a user environment variable.