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