From 91772e5bceb1c8eebcd7a502548cfeef262aee3e Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 22 May 2026 16:52:01 +0200 Subject: [PATCH] feat(telemetry): show first-run notice before command output --- packages/cli/src/cli-program-telemetry.test.ts | 5 +++++ packages/cli/src/cli-program.ts | 1 + packages/cli/src/telemetry/index.ts | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/packages/cli/src/cli-program-telemetry.test.ts b/packages/cli/src/cli-program-telemetry.test.ts index 936a0aa4..2b2b28b9 100644 --- a/packages/cli/src/cli-program-telemetry.test.ts +++ b/packages/cli/src/cli-program-telemetry.test.ts @@ -80,6 +80,11 @@ describe('runCommanderKtxCli telemetry', () => { expect(statusIo.stderr()).toContain('"event":"project_stack_snapshot"'); expect(statusIo.stderr()).toContain('"connectionCount"'); expect(statusIo.stderr()).not.toContain(tempDir); + + const noticeIndex = statusIo.stderr().indexOf('ktx collects anonymous usage data'); + const firstTelemetryIndex = statusIo.stderr().indexOf('[telemetry]'); + expect(noticeIndex).toBeGreaterThanOrEqual(0); + expect(firstTelemetryIndex).toBeGreaterThan(noticeIndex); }); it('emits aborted telemetry when project validation aborts after preAction starts', async () => { diff --git a/packages/cli/src/cli-program.ts b/packages/cli/src/cli-program.ts index f7657d31..6e4a33b9 100644 --- a/packages/cli/src/cli-program.ts +++ b/packages/cli/src/cli-program.ts @@ -417,6 +417,7 @@ export function buildKtxProgram(options: BuildKtxProgramOptions): Command { program.hook('preAction', async (_thisCommand, actionCommand) => { const telemetry = await import('./telemetry/index.js'); options.setTelemetryModule?.(telemetry); + await telemetry.showTelemetryNoticeIfNeeded(options.io); const commandNode = actionCommand as CommandPathNode; const path = commandPath(commandNode); const projectDir = resolveCommandProjectDir(commandNode); diff --git a/packages/cli/src/telemetry/index.ts b/packages/cli/src/telemetry/index.ts index f026bcae..badd424e 100644 --- a/packages/cli/src/telemetry/index.ts +++ b/packages/cli/src/telemetry/index.ts @@ -20,6 +20,14 @@ import { buildProjectStackSnapshotFields } from './project-snapshot.js'; export { beginCommandSpan, completeCommandSpan, shutdownTelemetryEmitter }; export type { CommandOutcome, CompletedCommandSpan }; +export async function showTelemetryNoticeIfNeeded(io: KtxCliIo): Promise { + await loadTelemetryIdentity({ + stdoutIsTTY: io.stdout.isTTY === true, + stderr: io.stderr, + env: process.env, + }); +} + type TelemetryEventFields = Omit< TelemetryEventProperties, keyof TelemetryCommonEnvelope