/**
 * AgentUI — NDJSON implementation of WizardUI for --agent mode.
 * Every method emits one JSON line to stdout for machine consumption.
 * Prompts auto-approve; no interactivity.
 */
import type { WizardUI, SpinnerHandle, EventPlanDecision } from './wizard-ui';
import type { RetryState, PostAgentStep } from '../lib/wizard-session';
import type { NeedsInputData, InnerAgentStartedData, ToolCallData, FileChangePlannedData, FileChangeAppliedData, EventPlanProposedData, EventPlanConfirmedData, VerificationStartedData, VerificationResultData, SetupContextData, SetupCompleteData } from '../lib/agent-events';
import { z } from 'zod';
/**
 * Stdin response schema for `promptEnvironmentSelection`.
 *
 * External input (from AI orchestrators) — parse with zod rather than an
 * `as` cast so bad shapes get rejected instead of silently falling through
 * to auto-select.
 *
 * Canonical shape: `{ appId }`.
 */
declare const EnvSelectionStdinSchema: z.ZodObject<{
    appId: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
type EnvSelectionStdin = z.infer<typeof EnvSelectionStdinSchema>;
/** Flat choice shape exposed in the prompt event and matched against stdin. */
export interface EnvSelectionChoice {
    orgId: string;
    orgName: string;
    projectId: string;
    projectName: string;
    appId: string | null;
    envName: string;
    rank: number;
    label: string;
}
/** Resolved selection returned from the env-selection prompt. */
export interface EnvSelection {
    orgId: string;
    projectId: string;
    env: string;
}
/**
 * Structured outcome of interpreting a parsed stdin payload against the
 * available choices. Pulled out as a pure function so the matching /
 * rejection logic can be unit-tested without stdin or readline mocks.
 *
 * - `kind: 'selected'` — a valid matching selector was provided.
 * - `kind: 'auto'` — no selector (empty object / missing fields); caller
 *   should auto-select the first environment.
 * - `kind: 'mismatch'` — a selector was provided but didn't match any
 *   choice; caller MUST NOT silently auto-select (throw / error).
 * - `warnings` — deprecation notices the caller should surface as log events.
 */
export type EnvSelectionResolution = {
    kind: 'selected';
    selection: EnvSelection;
    warnings: string[];
} | {
    kind: 'auto';
    warnings: string[];
} | {
    kind: 'mismatch';
    reason: string;
    warnings: string[];
};
export declare function resolveEnvSelectionFromStdin(parsed: EnvSelectionStdin | null, choices: EnvSelectionChoice[]): EnvSelectionResolution;
/**
 * Parse one JSON line from the agent orchestrator. Returns a structured
 * result with any zod rejection issues so the caller can surface them as
 * warning logs. Exported for unit tests.
 */
export declare function parseEnvSelectionStdinLine(line: string | null | undefined): {
    parsed: EnvSelectionStdin | null;
    rejectionMessage: string | null;
};
/**
 * Wire-level cap on the number of environment choices we ship to an
 * orchestrator on a single `needs_input: environment_selection` /
 * `prompt: environment_selection` event. Dogfood accounts can carry
 * 300+ environments — including all of them in the NDJSON envelope
 * inflated a single line to ~600 KB and made the picker UX brittle in
 * orchestrators that use a fixed-size buffer. 50 is comfortably
 * larger than the 95th-percentile org's env count and small enough
 * to render in a searchable picker without scrolling.
 *
 * Above-cap accounts get `pagination.total > pagination.returned`
 * plus the `manualEntry` hint so an orchestrator can prompt the user
 * for `--app-id <id>` directly.
 */
export declare const MAX_ENV_SELECTION_CHOICES = 50;
export declare class AgentUI implements WizardUI {
    intro(message: string): void;
    outro(message: string): void;
    cancel(message: string, options?: {
        docsUrl?: string;
    }): Promise<void>;
    setOutroData(data: import('../lib/wizard-session.js').OutroData): void;
    /**
     * Emit a structured auth_required lifecycle event when the wizard is invoked
     * in --agent mode without valid credentials. Agent orchestrators (Claude
     * Code, Cursor, etc.) can parse the payload, surface the login URL and
     * resume command to the human, and restart the wizard once auth completes.
     *
     * Always paired with process.exit(ExitCode.AUTH_REQUIRED) by the caller.
     */
    emitAuthRequired(data: {
        reason: 'no_stored_credentials' | 'token_expired' | 'refresh_failed' | 'env_selection_failed';
        instruction: string;
        loginCommand: string[];
        resumeCommand?: string[];
        /**
         * When `reason === 'env_selection_failed'` and the failure was
         * caused by a scope flag (`--app-id`, `--project-id`, `--env`,
         * `--org`) that didn't match any known environment, this echoes
         * the bad value back so the orchestrator can render a useful
         * "you passed X, here are valid options" prompt without parsing
         * the human-readable `instruction` string.
         */
        previousAttempt?: {
            flag: '--app-id' | '--project-id' | '--env' | '--org';
            value: string;
            reason: string;
        };
        /**
         * Candidate environments to retry against. Identical shape to
         * the `choices` array in the `needs_input: environment_selection`
         * event — orchestrators that already render that picker can reuse
         * the same widget here without re-discovery. Empty / omitted when
         * the failure isn't selection-related.
         *
         * MUST stay in sync with `EnvSelectionChoice` (above). When that
         * canonical shape gains a field, mirror it here so orchestrators
         * that reuse their env-selection widget don't see `undefined` on
         * what should be a present property.
         */
        choices?: Array<{
            orgId: string;
            orgName: string;
            projectId: string;
            projectName: string;
            appId: string | null;
            envName: string;
            rank: number;
            label: string;
        }>;
    }): void;
    /**
     * NDJSON events for the inline create-project flow. Emitted at each phase
     * so orchestrators can track progress. The `apiKey` is intentionally
     * REDACTED from the success payload — only `appId` and `name` are emitted.
     */
    emitProjectCreateStart(data: {
        orgId: string;
        name: string;
    }): void;
    emitProjectCreateSuccess(data: {
        appId: string;
        name: string;
        orgId: string;
    }): void;
    emitProjectCreateError(data: {
        code: 'NAME_TAKEN' | 'QUOTA_REACHED' | 'FORBIDDEN' | 'INVALID_REQUEST' | 'INTERNAL' | 'MISSING_NAME' | 'MISSING_ORG';
        message: string;
        name?: string;
    }): void;
    /**
     * Emit a structured `signup_input_required` lifecycle event when the
     * wizard is invoked with `--agent --auth-onboarding create-account` but one or more required
     * inputs are missing (region, email, full-name, accept-tos). The
     * orchestrator inspects `missing[]`, prompts the human for the
     * missing values, and re-invokes the wizard with `resumeCommand` plus
     * the gathered flags.
     *
     * Always paired with process.exit(ExitCode.INPUT_REQUIRED) by the caller.
     */
    emitSignupInputsRequired(data: {
        missing: Array<{
            flag: string;
            description: string;
            url?: string;
            pattern?: string;
        }>;
        resumeCommand: string[];
    }): void;
    /**
     * Emit a structured nested_agent lifecycle event when the wizard is
     * invoked from inside another Claude Code / Claude Agent SDK session.
     * The wizard sanitizes inherited Claude env vars before spawning its
     * own SDK subprocess, so nesting is supported — this event is a
     * diagnostic breadcrumb for outer orchestrators, not a failure.
     */
    emitNestedAgent(data: {
        signal: 'claude_code_cli' | 'claude_agent_sdk';
        envVar: string;
        instruction: string;
        bypassEnv: string;
    }): void;
    /**
     * Emit a structured `needs_input` event whenever the wizard would otherwise
     * make a silent default choice. Outer agents inspect `choices` +
     * `recommended`, surface the decision to a human, and resume with one of
     * the `resumeFlags` argv arrays — or pipe a JSON line to stdin matching
     * `responseSchema` when supported.
     *
     * This is the canonical replacement for any `silent auto-select`. When
     * `--auto-approve` is set, callers should still emit this event (for
     * audit) before proceeding with `recommended`. When neither
     * `--auto-approve` nor `--yes` is set in agent mode, the caller should
     * emit + exit `ExitCode.INPUT_REQUIRED` (12).
     */
    emitNeedsInput<V = string>(data: NeedsInputData<V>): void;
    /**
     * Inner Claude SDK has booted and is about to start its first turn.
     * Carries the model name and the wizard phase (plan / apply / verify /
     * wizard) so the outer agent can attribute downstream events.
     */
    emitInnerAgentStarted(data: Omit<InnerAgentStartedData, 'event'>): void;
    /**
     * The inner agent is about to call a tool. Use the helper
     * `summarizeToolInput` from `agent-events` to build a privacy-safe
     * `summary` rather than passing the raw input through.
     */
    emitToolCall(data: Omit<ToolCallData, 'event'>): void;
    /**
     * A write tool has been requested. Emitted from PreToolUse before any
     * file change happens, so outer agents can preview and (optionally)
     * abort. Pairs with `emitFileChangeApplied` on success.
     */
    emitFileChangePlanned(data: Omit<FileChangePlannedData, 'event'>): void;
    /**
     * A write tool has succeeded. Emitted from PostToolUse with the same
     * path as the preceding `file_change_planned`. Outer agents pair these
     * to build an audit trail of what the wizard wrote.
     */
    emitFileChangeApplied(data: Omit<FileChangeAppliedData, 'event'>): void;
    recordFileChangePlanned(data: Omit<FileChangePlannedData, 'event'>): void;
    recordFileChangeApplied(data: Omit<FileChangeAppliedData, 'event'>): void;
    /**
     * The inner agent has called `confirm_event_plan` with a proposed plan.
     * Outer agents see the events list before any `track()` call is written.
     */
    emitEventPlanProposed(data: Omit<EventPlanProposedData, 'event'>): void;
    /**
     * The event plan has been resolved. `source` records who decided
     * (auto / human / flag) so outer agents can audit decisions later.
     */
    emitEventPlanConfirmed(data: Omit<EventPlanConfirmedData, 'event'>): void;
    /** Verification phase has started — paired with `emitVerificationResult`. */
    emitVerificationStarted(data: Omit<VerificationStartedData, 'event'>): void;
    /** Verification phase has completed (success or failure with reasons). */
    emitVerificationResult(data: Omit<VerificationResultData, 'event'>): void;
    log: {
        info(message: string): void;
        warn(message: string): void;
        error(message: string): void;
        success(message: string): void;
        step(message: string): void;
    };
    note(message: string): void;
    pushStatus(message: string): void;
    heartbeat(data: {
        statuses: string[];
        elapsedMs: number;
        attempt?: number;
    }): void;
    spinner(): SpinnerHandle;
    seedPostAgentSteps(steps: PostAgentStep[]): void;
    setPostAgentStep(id: string, patch: {
        status: PostAgentStep['status'];
        reason?: string;
    }): void;
    /**
     * Run-start timestamp (epoch ms). Captured by `startRun()` — read by
     * `emitRunCompleted` to compute `durationMs`. `null` until the run
     * actually begins so duration is reported accurately even when the
     * wizard exits before reaching the inner agent (e.g.
     * `auth_required`, `INPUT_REQUIRED`). In those early-exit cases
     * `emitRunCompleted` reports `durationMs: 0` — orchestrators
     * shouldn't read significance into a zero duration; the structured
     * `outcome` + `exitCode` are the contract.
     */
    private _runStartedAtMs;
    startRun(): void;
    /**
     * Terminal lifecycle event. Emitted exactly once per run, immediately
     * before the process exits via `wizardSuccessExit` / `wizardAbort`.
     * See `RunCompletedData` in `agent-events.ts` for the contract.
     */
    emitRunCompleted(data: {
        outcome: 'success' | 'error' | 'cancelled';
        exitCode: number;
        durationMs: number;
        reason?: string;
    }): void;
    /**
     * Read-only accessor for the run-start timestamp. Used by
     * `wizard-abort.ts` to compute `durationMs` without exposing the
     * private field. Returns `null` if `startRun()` was never called
     * (early-exit paths like `auth_required` / `INPUT_REQUIRED`).
     */
    getRunStartedAtMs(): number | null;
    /**
     * Emit aggregated agent-run metrics at finalize time. See
     * `WizardUI.emitAgentMetrics` for the contract.
     *
     * Lands on the `progress` event type (not `lifecycle` /
     * `result`) because metrics are observability data — orchestrators
     * subscribing to operational telemetry will key on `progress`-type
     * events; subscribers caring only about run outcomes (success /
     * failure) won't be flooded with one-off cost data.
     */
    emitAgentMetrics(data: {
        durationMs: number;
        inputTokens?: number;
        outputTokens?: number;
        cacheReadInputTokens?: number;
        cacheCreationInputTokens?: number;
        costUsd?: number;
        numTurns?: number;
        totalToolCalls?: number;
        totalMessages?: number;
        isError?: boolean;
        toolCallsByTool?: Record<string, number>;
    }): void;
    emitCheckpointSaved(data: {
        path: string;
        bytes: number;
        phase: string;
    }): void;
    emitCheckpointLoaded(data: {
        path: string;
        ageSeconds: number;
    }): void;
    emitCheckpointCleared(data: {
        path: string;
        reason: 'success' | 'manual' | 'logout';
    }): void;
    setRunError(error: Error): Promise<boolean>;
    setCredentials(credentials: {
        accessToken: string;
        projectApiKey: string;
        host: string;
        appId: number;
        orgId?: string | null;
        orgName?: string | null;
        projectId?: string | null;
        projectName?: string | null;
        envName?: string | null;
    }): void;
    setRegion(region: string): void;
    setProjectHasData(value: boolean): void;
    setDetectedFramework(label: string): void;
    setLoginUrl(url: string | null): void;
    onEnterScreen(_screen: string, _fn: () => void): void;
    showServiceStatus(data: {
        description: string;
        statusPageUrl: string;
    }): void;
    setRetryState(state: RetryState | null): void;
    promptConfirm(message: string): Promise<boolean>;
    promptChoice(message: string, options: string[]): Promise<string>;
    /**
     * Agent / CI mode: there is no human in the loop, so this path **always**
     * ends in an approved plan for the inner agent — either from
     * `AMPLITUDE_WIZARD_EVENT_PLAN_DECISION` (apply resume flags) or by emitting
     * `needs_input` + `decision_auto` with the recommended **approved** choice.
     *
     * Orchestrators should treat `event_plan` / `event_plan_set` on the NDJSON
     * stream as the canonical payloads; the `result` line `event_plan auto-approved`
     * records that the wizard did not block on stdin (distinct from env-flag
     * resolutions, which emit `event_plan <decision> (via flag)` and skip
     * `decision_auto`).
     */
    promptEventPlan(events: Array<{
        name: string;
        description: string;
    }>): Promise<EventPlanDecision>;
    syncTodos(todos: Array<{
        content: string;
        status: string;
        activeForm?: string;
    }>): void;
    applyJourneyTransition(stepId: import('../lib/journey-state.js').JourneyStepId, status: import('../lib/journey-state.js').JourneyStatus): void;
    setEventPlan(events: Array<{
        name: string;
        description: string;
    }>): void;
    setEventIngestionDetected(eventNames: string[]): void;
    setDashboardUrl(url: string): void;
    /**
     * Emit a `setup_context` event so the outer agent can show the user
     * exactly which Amplitude scope is about to be modified BEFORE any
     * writes happen. Drops keys with `undefined` values from the wire
     * payload so the orchestrator doesn't have to filter them.
     *
     * Called from:
     *   - `wizard plan` (phase: 'plan') — initial detection
     *   - `wizard apply` (phase: 'apply_started') — after env resolution
     *   - `wizard whoami` (phase: 'whoami') — auth probe
     */
    emitSetupContext(data: {
        phase: SetupContextData['phase'];
        amplitude: SetupContextData['amplitude'];
        sources?: SetupContextData['sources'];
        requiresConfirmation?: boolean;
        resumeFlags?: SetupContextData['resumeFlags'];
    }): void;
    /**
     * Emit the terminal `setup_complete` event. Called exactly once per
     * successful `apply` run, immediately before `run_completed`. The
     * outer agent reads this to lock its project context on `appId` for
     * any follow-up MCP queries. Routed through the `result` event type
     * so orchestrators subscribed to outcome streams pick it up
     * naturally.
     */
    emitSetupComplete(data: Omit<SetupCompleteData, 'event'>): void;
    /**
     * Prompt the agent caller to select an environment from pendingOrgs.
     *
     * Emits an NDJSON `prompt` event with all available orgs/projects/environments,
     * then reads one JSON line from stdin with the selection.
     *
     * Expected stdin response:
     * ```json
     * { "appId": "769610" }
     * ```
     *
     * `appId` alone is sufficient — it's globally unique and resolves to
     * exactly one (org, project, app, env) tuple.
     *
     * Falls back to auto-selecting the first environment if stdin is closed
     * or no response is received within 60 seconds.
     */
    promptEnvironmentSelection(orgs: Array<{
        id: string;
        name: string;
        projects: Array<{
            id: string;
            name: string;
            environments?: Array<{
                name: string;
                rank: number;
                app: {
                    id: string;
                    apiKey?: string | null;
                } | null;
            }> | null;
        }>;
    }>): Promise<{
        orgId: string;
        projectId: string;
        env: string;
    }>;
}
export {};
