import { type Environment } from '../config/environments.js'; /** * What is driving the CLI. * * - `claude-code` — a Claude Code session (its `CLAUDECODE` env var, verified). * - `json` — some agent, unidentified: `--json` is the flag agents pass. * - `tty` — a person at a terminal. * - `pipe` — a script or CI: no `--json`, no terminal. * * Add an agent here only once its marker is verified against the real thing; a * guessed env var never fires and just misleads whoever reads the table. */ export type CliDriver = 'claude-code' | 'json' | 'tty' | 'pipe'; export declare function detectDriver(input: { json: boolean; env: Record; isTTY: boolean; }): CliDriver; /** * `DO_NOT_TRACK` set to anything but `0`/`false`/empty. The convention says * `1`; being generous about the spelling is the polite reading of a signal * that only ever means "please don't". * * Lives here rather than in report.ts because it is consulted BEFORE anything * is collected — `beginCommand` skips the whole snapshot when it is set — and * report.ts already imports this module, so the other direction would close a * cycle. Re-exported from report.ts, which is where callers expect it. */ export declare function isTelemetryDisabled(env: Record): boolean; export interface TokenSnapshot { accessToken: string; /** Epoch milliseconds, as stored. */ expiresAt: number; } export interface CommandContext { /** As typed, so a report reads the way the creator invoked it: `publish`, `generate skybox`. */ name: string; json: boolean; driver: CliDriver; /** * Where this command is talking to, resolved ONCE here through the same * precedence every command uses (`--env` > BITMAGIC_ENV > the project's * bitmagic.json > the stored default). `report.ts` reads it rather than * resolving again: a second resolution is a second chance to disagree, and * one that skipped the project tier would send a project's beacons to a * different environment than the work they describe. * * Null only when resolution threw — an unknown `--env`, or a project whose * `environment` field is not a valid name. The command itself fails with * that message moments later; there is simply nowhere to report it to. */ environment: Environment | null; /** Epoch milliseconds when the command began. */ startedAt: number; /** See the module header: the stored access token at start, for the one command that removes it. */ tokenSnapshot: TokenSnapshot | null; /** * The creator's own request, once, for the whole command — `null` when the flag was absent or * the creator opted out of telemetry. * * It is one value per invocation, so it is captured where every other per-invocation fact is * captured rather than being handed down through each request builder. Threading it meant * sixteen call sites had to remember to pass it, and the three that built their bodies through * their own runners had already been given their own copy of the guard. */ creatorPrompt: string | null; /** What the command learned about the game while running — see {@link annotateCommand}. */ annotations: CommandAnnotations; } /** * Category-shaped facts a command adds to its own beacon before it ends. * * Both exist for the same reason: `ok=false` on a `verify` says the game failed, not HOW, and * `ok=true` on a `judge` says a score came back, not what it was — and both are what an agent * builds a GDK project against, offline, so the beacon is the only place they can be seen. * Categories only, per the beacon's contract: a check name, never the message that carries a * path; an integer score, never the findings. */ export interface CommandAnnotations { /** Which verify checks failed, as category names (`cli/src/verify/categories.ts`). */ checks?: string[]; /** The judge's overall score, 1–10. */ score?: number; } export interface BeginCommandInput { name: string; json: boolean; explicitEnv?: string; /** `--original-prompt`, as typed. See `creator-prompt.ts`. */ creatorPrompt?: string; env?: Record; isTTY?: boolean; now?: () => number; baseDir?: string; /** Where to look for the project's own environment pin; defaults to process.cwd(). */ cwd?: string; } export declare function beginCommand(input: BeginCommandInput): CommandContext; /** * Attach an annotation to the running command. A no-op before `beginCommand` (a module under * test) and under `DO_NOT_TRACK`, where nothing is sent anyway — the beacon reads these at the * end, so the command just says what it learned, whenever it learns it. */ export declare function annotateCommand(extra: CommandAnnotations): void; /** The running command, or null before `beginCommand` — e.g. under a test that calls a module directly. */ export declare function currentCommand(): CommandContext | null; /** Test seam: forget the running command, so one test's context cannot leak into the next. */ export declare function resetCommandContextForTests(): void;