From 1953466c78b36d0b176697a829800a49e2bdacc8 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 22 May 2026 16:47:53 +0200 Subject: [PATCH] feat(telemetry): dim first-run notice --- packages/cli/src/telemetry/identity.test.ts | 16 +++++++++++++++- packages/cli/src/telemetry/identity.ts | 9 ++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/telemetry/identity.test.ts b/packages/cli/src/telemetry/identity.test.ts index 14722a22..06d76043 100644 --- a/packages/cli/src/telemetry/identity.test.ts +++ b/packages/cli/src/telemetry/identity.test.ts @@ -54,7 +54,7 @@ describe('telemetry identity', () => { expect(identity.installId).toMatch(/^[0-9a-f-]{36}$/); expect(identity.createdFile).toBe(true); expect(identity.noticeShown).toBe(true); - expect(testIo.stderr()).toBe(`${TELEMETRY_NOTICE}\n`); + expect(testIo.stderr()).toBe(`${TELEMETRY_NOTICE}\n`); const stored = JSON.parse(await readFile(join(homeDir, '.ktx', 'telemetry.json'), 'utf-8')) as { enabled: boolean; @@ -64,6 +64,20 @@ describe('telemetry identity', () => { expect(stored.noticeShownVersion).toBe(1); }); + it('emits the notice without ANSI when NO_COLOR is set', async () => { + const testIo = makeIo(true); + + await loadTelemetryIdentity({ + homeDir, + env: { NO_COLOR: '1' }, + stdoutIsTTY: true, + stderr: testIo.io.stderr, + now: () => new Date('2026-05-22T14:33:02.000Z'), + }); + + expect(testIo.stderr()).toBe(`${TELEMETRY_NOTICE}\n`); + }); + it('does not create a file when env disables telemetry', async () => { const identity = await loadTelemetryIdentity({ homeDir, diff --git a/packages/cli/src/telemetry/identity.ts b/packages/cli/src/telemetry/identity.ts index 069224c5..4d46307c 100644 --- a/packages/cli/src/telemetry/identity.ts +++ b/packages/cli/src/telemetry/identity.ts @@ -25,6 +25,13 @@ export interface TelemetryIdentityEnv { KTX_TELEMETRY_DISABLED?: string; DO_NOT_TRACK?: string; CI?: string; + NO_COLOR?: string; + TERM?: string; +} + +function styleNotice(notice: string, env: TelemetryIdentityEnv): string { + if (env.NO_COLOR || env.TERM === 'dumb') return notice; + return `${notice}`; } export interface LoadTelemetryIdentityOptions { @@ -110,7 +117,7 @@ export async function loadTelemetryIdentity(options: LoadTelemetryIdentityOption }; } - options.stderr.write(`${TELEMETRY_NOTICE}\n`); + options.stderr.write(`${styleNotice(TELEMETRY_NOTICE, env)}\n`); return { installId: next.installId,