/**
 * WizardSession — single source of truth for every decision the wizard needs.
 *
 * Populated in layers:
 *   CLI args / env vars  →  populate fields directly
 *   Auto-detection       →  framework, typescript, package manager
 *   TUI screens          →  region, framework disambiguation, etc.
 *   OAuth                →  credentials
 *
 * Business logic reads from the session. Never calls a prompt.
 */
import { z } from 'zod';
import type { AmplitudeZone, Integration } from './constants';
import type { FrameworkConfig } from './framework-config';
/**
 * Whether the user is signing into an existing Amplitude account or
 * provisioning a new one during onboarding (TUI picker or non-interactive flags).
 */
export declare const AuthOnboardingPath: {
    readonly SignIn: "sign_in";
    readonly CreateAccount: "create_account";
};
export type AuthOnboardingPath = (typeof AuthOnboardingPath)[keyof typeof AuthOnboardingPath];
export declare function isCreateAccountOnboarding(session: {
    authOnboardingPath: AuthOnboardingPath;
}): boolean;
/**
 * Numeric Amplitude app id (canonical across Amplitude services).
 * Sourced from `App.id` in the Data API and `app_id` in the Python monorepo.
 */
export declare const AppIdSchema: z.core.$ZodBranded<z.ZodNumber, "AppId", "out">;
export type AppId = z.infer<typeof AppIdSchema>;
/**
 * UUID-shaped Amplitude workspace id. Sourced from `Workspace.id` in the
 * Data API. Distinct from `selectedAppId` (string env app id) and the
 * stringified app id used in some MCP tool calls.
 */
export declare const WorkspaceIdSchema: z.core.$ZodBranded<z.ZodString, "WorkspaceId", "out">;
export type WorkspaceId = z.infer<typeof WorkspaceIdSchema>;
/**
 * Construct an AppId from a raw number. Throws on invalid input — use at
 * trust boundaries (CLI parse, API response decoding, stored config).
 */
export declare function toAppId(value: number): AppId;
/**
 * Best-effort AppId construction. Returns undefined when the input cannot be
 * coerced to a positive integer. Use when accepting user-supplied strings.
 */
export declare function tryToAppId(value: string | number | null | undefined): AppId | undefined;
/**
 * Construct a WorkspaceId from a raw string. Throws on empty input — use at
 * trust boundaries. Most call sites get workspace ids from API responses
 * that have already been validated, so this just attaches the brand.
 */
export declare function toWorkspaceId(value: string): WorkspaceId;
/**
 * `credentials.appId` is `AppId | 0` — `0` is the "unknown" sentinel used
 * when OAuth produced credentials but the user has not yet picked an env.
 * This helper safely coerces raw input (string from CLI, number from API)
 * into the credentials shape: a branded AppId on success, `0` otherwise.
 *
 * Use at the trust boundary where credentials are constructed. After that,
 * the `AppId | 0` type prevents accidental cross-mixing with workspace ids
 * or other unrelated numbers — the same protection PR #62 motivated for
 * the top-level `WizardSession.appId`.
 */
export declare function toCredentialAppId(value: string | number | null | undefined): AppId | 0;
/**
 * Zod schema for CLI args passed to `buildSession()`.
 * Coerces `appId` from string to a branded positive integer.
 * All boolean flags default to false; `installDir` defaults to cwd.
 */
export declare const CliArgsSchema: z.ZodObject<{
    appId: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>, z.ZodTransform<(number & z.core.$brand<"AppId">) | undefined, string | number | undefined>>;
    installDir: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<string, string>>;
    debug: z.ZodDefault<z.ZodBoolean>;
    verbose: z.ZodDefault<z.ZodBoolean>;
    ci: z.ZodDefault<z.ZodBoolean>;
    agent: z.ZodDefault<z.ZodBoolean>;
    forceInstall: z.ZodDefault<z.ZodBoolean>;
    authOnboardingPath: z.ZodDefault<z.ZodEnum<{
        sign_in: "sign_in";
        create_account: "create_account";
    }>>;
    localMcp: z.ZodDefault<z.ZodBoolean>;
    menu: z.ZodDefault<z.ZodBoolean>;
    benchmark: z.ZodDefault<z.ZodBoolean>;
    mode: z.ZodDefault<z.ZodEnum<{
        fast: "fast";
        standard: "standard";
        thorough: "thorough";
    }>>;
    apiKey: z.ZodOptional<z.ZodString>;
    integration: z.ZodOptional<z.ZodString>;
    appName: z.ZodOptional<z.ZodString>;
    signupEmail: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
    signupFullName: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
    acceptTos: z.ZodDefault<z.ZodBoolean>;
    region: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodEnum<{
        us: "us";
        eu: "eu";
    }>>>>;
}, z.core.$strip>;
/**
 * Zod schema for validated Amplitude credentials.
 * Exported for incremental adoption at credential-construction sites.
 */
export declare const CredentialsSchema: z.ZodObject<{
    accessToken: z.ZodString;
    idToken: z.ZodOptional<z.ZodString>;
    projectApiKey: z.ZodString;
    host: z.ZodString;
    appId: z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodNumber, "AppId", "out">, z.ZodLiteral<0>]>;
}, z.core.$strip>;
export type CloudRegion = 'us' | 'eu';
/**
 * Lifecycle phase of the main work (agent run, MCP install, etc.)
 * NOTE: Duplicated in src/ui/tui/session-constants.ts (ESM/CJS workaround).
 * If you change these values, update that file too — a test enforces sync.
 */
export declare const RunPhase: {
    /** Still gathering input (intro, setup screens) */
    readonly Idle: "idle";
    /** Main work is in progress */
    readonly Running: "running";
    /** Main work finished successfully */
    readonly Completed: "completed";
    /** Main work finished with an error */
    readonly Error: "error";
};
export type RunPhase = (typeof RunPhase)[keyof typeof RunPhase];
/**
 * Status of a single post-agent step (commit planned events, create
 * dashboard, etc.) — work that runs between the Claude agent finishing
 * and the wizard transitioning to the MCP screen. Modeled separately
 * from agent TodoWrite tasks because these are framework-controlled,
 * not agent-controlled, and rendering them in the same list would break
 * the `syncTodos` "agent-authoritative" invariant.
 *
 * NOTE: Mirrored in src/ui/tui/session-constants.ts (ESM/CJS workaround).
 */
export declare const PostAgentStepStatus: {
    readonly Pending: "pending";
    readonly InProgress: "in_progress";
    readonly Completed: "completed";
    readonly Skipped: "skipped";
};
export type PostAgentStepStatus = (typeof PostAgentStepStatus)[keyof typeof PostAgentStepStatus];
export interface PostAgentStep {
    /** Stable id (e.g. 'commit-events', 'create-dashboard') */
    id: string;
    /** Past-tense label shown when pending or completed. */
    label: string;
    /** Present-continuous label shown while in progress. */
    activeForm: string;
    status: PostAgentStepStatus;
    /** When `status === 'skipped'`, a short user-facing reason. */
    reason?: string;
    /** Wall-clock ms when this step transitioned to in_progress. */
    startedAt?: number;
}
/** Features discovered by the feature-discovery subagent */
export declare const DiscoveredFeature: {
    readonly Stripe: "stripe";
    readonly LLM: "llm";
    readonly SessionReplay: "session_replay";
    readonly Engagement: "engagement";
};
export type DiscoveredFeature = (typeof DiscoveredFeature)[keyof typeof DiscoveredFeature];
/** Additional features the agent can integrate after the main setup */
export declare const AdditionalFeature: {
    readonly LLM: "llm";
    readonly SessionReplay: "session_replay";
    readonly Engagement: "engagement";
};
export type AdditionalFeature = (typeof AdditionalFeature)[keyof typeof AdditionalFeature];
/** Human-readable labels for additional features (used in TUI progress) */
export declare const ADDITIONAL_FEATURE_LABELS: Record<AdditionalFeature, string>;
/** Agent prompts for each additional feature, injected via the stop hook */
export declare const ADDITIONAL_FEATURE_PROMPTS: Record<AdditionalFeature, string>;
/**
 * Features that the agent configures inline as part of SDK initialization.
 * Their prompts are appended to the initial integration prompt and they are
 * NOT drained by the stop hook or rendered as separate task items.
 */
export declare const INLINE_FEATURES: ReadonlySet<AdditionalFeature>;
/**
 * Features that run as a separate "Set up X" task after the main agent run,
 * drained one at a time via the stop hook and rendered as trailing task items.
 */
export declare const TRAILING_FEATURES: ReadonlySet<AdditionalFeature>;
/**
 * Discovered features that map to an opt-in AdditionalFeature.
 * Stripe is discovered but not opt-in — it's a passive doc link.
 */
export declare const OPT_IN_DISCOVERED_FEATURES: ReadonlySet<string>;
/** Outcome of the MCP server installation step */
export declare const McpOutcome: {
    readonly NoClients: "no_clients";
    readonly Skipped: "skipped";
    readonly Installed: "installed";
    readonly Failed: "failed";
};
export type McpOutcome = (typeof McpOutcome)[keyof typeof McpOutcome];
/** Outcome of the Slack integration setup step */
export declare const SlackOutcome: {
    readonly Skipped: "skipped";
    readonly Configured: "configured";
};
export type SlackOutcome = (typeof SlackOutcome)[keyof typeof SlackOutcome];
/** Outcome kind for the outro screen */
export declare const OutroKind: {
    readonly Success: "success";
    readonly Error: "error";
    readonly Cancel: "cancel";
};
export type OutroKind = (typeof OutroKind)[keyof typeof OutroKind];
export interface OutroData {
    kind: OutroKind;
    message?: string;
    changes?: string[];
    docsUrl?: string;
    continueUrl?: string;
    promptLogin?: boolean;
    canRestart?: boolean;
}
/**
 * Transient state shown while the agent is retrying after a transient LLM /
 * proxy failure. Populated from `api_retry` SDK messages and the manual retry
 * sites in agent-interface.ts. Cleared when the next normal message arrives.
 */
export interface RetryState {
    /** 1-indexed attempt number that is about to begin. */
    attempt: number;
    /** Max retries the SDK / retry loop was configured with. */
    maxRetries: number;
    /** Absolute timestamp (ms) when the next retry will begin. */
    nextRetryAtMs: number;
    /** HTTP status code, when known (504, 400, …). `null` for stalls / SDK errors. */
    errorStatus: number | null;
    /** Short human-readable reason shown in the banner. */
    reason: string;
    /** Timestamp when this retry state was first set. */
    startedAt: number;
}
export interface WizardSession {
    debug: boolean;
    verbose: boolean;
    forceInstall: boolean;
    installDir: string;
    ci: boolean;
    agent: boolean;
    /**
     * Sign in to an existing Amplitude account vs create a new one during
     * onboarding (includes email capture + ToS on the create-account path).
     */
    authOnboardingPath: AuthOnboardingPath;
    signupEmail: string | null;
    signupFullName: string | null;
    localMcp: boolean;
    apiKey?: string;
    menu: boolean;
    benchmark: boolean;
    /** Agent model tier — 'fast' / 'standard' / 'thorough'. See WizardMode. */
    mode: import('../utils/types').WizardMode;
    /**
     * Free-form context the outer orchestrator wants prepended to every
     * agent turn. Sourced from `--context-file <path>` (or
     * `AMPLITUDE_WIZARD_CONTEXT` env var) at the CLI boundary; threaded
     * into `agent-interface.initializeAgent` and appended after the
     * commandments in the cached system-prompt block.
     *
     * Lets a parent agent inject team conventions ("we use snake_case for
     * events"), existing taxonomy hints, or project-specific instructions
     * WITHOUT modifying any skill content. The wizard treats it as
     * project-authoritative for conventions but never lets it override the
     * hard safety rules at the top of `commandments.ts`.
     *
     * `null` when no context was provided. Capped at the CLI boundary
     * (currently 64 KB) so a runaway file can't bloat the system prompt.
     */
    orchestratorContext: string | null;
    /**
     * UUID v4 generated once per wizard run. Forwarded to the Amplitude LLM
     * gateway as the `x-amp-wizard-session-id` header so every `/v1/messages`
     * call across the wizard's discrete agent phases (taxonomy, integration,
     * chart, dashboard) lands in a single Agent Analytics session. Without
     * this, the proxy falls back to a per-OAuth-token deterministic ID, which
     * collapses every wizard run a user has ever done into one session.
     */
    agentSessionId: string;
    /**
     * Numeric Amplitude app ID from --app-id (or --project-id alias).
     * Matches `app.id` in the Data API and `app_id` in the Python monorepo.
     * Branded — construct via `toAppId()` / `tryToAppId()` from raw input.
     */
    appId?: AppId;
    setupConfirmed: boolean;
    integration: Integration | null;
    frameworkContext: Record<string, unknown>;
    /**
     * Order in which keys were written into `frameworkContext`. Tracks
     * answer history so back-navigation can pop the most recent setup
     * answer. Maintained by `WizardStore.setFrameworkContext` and
     * `popLastFrameworkContextAnswer`.
     */
    frameworkContextAnswerOrder: string[];
    typescript: boolean;
    /** Human-readable label for the detected framework variant (e.g., "Django with Wagtail CMS") */
    detectedFrameworkLabel: string | null;
    /** True once framework detection has run (whether it found something or not) */
    detectionComplete: boolean;
    /** Full results from parallel detection (all frameworks). Available for diagnostics. */
    detectionResults: Array<{
        integration: Integration;
        detected: boolean;
        durationMs: number;
        timedOut: boolean;
        error?: string;
        version?: string;
    }> | null;
    /**
     * Whether the currently selected project has existing event data.
     * null = not yet checked (shown as DataSetup screen)
     * false = no data → route to Framework Detection
     * true = has data → route to Options menu
     */
    projectHasData: boolean | null;
    /**
     * Project selected during SUSI (written to ampli.json as ProjectId).
     *
     * NOTE: Amplitude's backend GraphQL schema still calls this concept a
     * "workspace" (Org → Workspace → Environment → App in the Data API),
     * but every user-facing surface — the website UI, docs, slash commands,
     * and analytics properties — uses "project". These session fields and
     * ampli.json use "project" to match.
     */
    selectedProjectId: string | null;
    selectedProjectName: string | null;
    /**
     * Activation level determined by the API check.
     * null  = not yet checked
     * 'none'    = 0 events, snippet not configured → Framework Detection
     * 'partial' = 1–49 events or snippet installed but limited events → ActivationOptions
     * 'full'    = well-established data (50+ events) → Options
     */
    activationLevel: 'none' | 'partial' | 'full' | null;
    /**
     * True when the local pre-flight check (`isProjectFullyWired`) found a
     * complete prior install — SDK in package.json, source import present,
     * `ampli.json` with org/project scope, and a non-empty event plan on
     * disk. Set alongside `activationLevel = 'full'` so the router's
     * Setup/Run skip predicates fire, but DataIngestionCheck STILL polls
     * (the user may have just re-run pre-deploy, with no remote events
     * yet). Distinct from a remote-confirmed `'full'` activation, which
     * skips the polling screen too.
     */
    localInstrumentationComplete: boolean;
    /** True once the user has responded to the ActivationOptions screen. */
    activationOptionsComplete: boolean;
    /** Whether the SDK snippet is installed in the project (set by DataSetupScreen). */
    snippetConfigured: boolean;
    /**
     * Amplitude data-center region chosen by the user.
     * null = not yet selected (shown as RegionSelect screen)
     * 'us' = US region (api.amplitude.com)
     * 'eu' = EU region (api.eu.amplitude.com)
     *
     * WRITE INVARIANT: this field is written ONLY by intent-bearing sources —
     * the --region CLI flag / env var, /region slash command, RegionSelect
     * screen pick, the "Switch data-center region" flow, checkpoint restore,
     * and OAuth-derived zone after successful authentication (signing into an
     * EU account is regional intent, even though it's not a manual pick).
     * Non-intent code MUST NOT assign to this field as a cache.
     *
     * READ GUIDANCE: code outside the TUI render tree (bin.ts entry points,
     * credential-resolution, agent/CI paths) MUST call
     * `resolveZone(session, fallback)` (src/lib/zone-resolution.ts) to get
     * the effective zone, not read this field directly. The only legitimate
     * direct reads are: display/debug output, checkpoint persistence (we
     * persist intent, not resolved zone), and the RegionSelect gate checks
     * in bin.ts that drive pre-auth flow ordering.
     */
    region: AmplitudeZone | null;
    /**
     * True when the /region slash command forces RegionSelect to re-appear.
     * Cleared once the user picks a region. After re-selection, projectHasData
     * is reset to null so the data setup step re-runs for the new region.
     */
    regionForced: boolean;
    /**
     * Orgs available after OAuth completes, before the user selects one.
     * null = OAuth not yet done (AuthScreen shows spinner)
     * [...] = OAuth done, AuthScreen showing org/project/key selection
     */
    pendingOrgs: 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;
        }>;
    }> | null;
    /** OAuth id_token held during SUSI account-setup steps. */
    pendingAuthIdToken: string | null;
    /** OAuth access_token held during SUSI — used for Hydra-validated proxy auth. */
    pendingAuthAccessToken: string | null;
    /**
     * Set by `resolveCredentials` when the user passed a scope filter
     * (`--app-id`, `--project-id`, etc.) that didn't match any known
     * environment. Drives the structured `auth_required: env_selection_failed`
     * emission in agent mode: the orchestrator gets back the bad value it
     * passed AND the candidate list in one event, instead of having to
     * re-discover environments after a silent fall-through to auto-select.
     *
     * `null` when no scope filters were specified (multi-env path) or
     * filters matched cleanly (success path).
     */
    scopeFilterMismatch: {
        flag: '--app-id' | '--project-id' | '--env' | '--org';
        value: string;
        /** Plain-language explanation: "no environment with appId=99999". */
        reason: string;
    } | null;
    /** Org selected during SUSI (written to ampli.json). */
    selectedOrgId: string | null;
    selectedOrgName: string | null;
    /**
     * Amplitude environment name (e.g. "Production", "Development", "Staging")
     * for the selected project — displayed in the TitleBar.
     *
     * The environment's `app.id` is what Amplitude's UI labels "Project ID"
     * in some places — each environment has its own numeric app ID and its
     * own API key. This field stores the env NAME, not an app ID.
     */
    selectedEnvName: string | null;
    /**
     * Numeric Amplitude app ID for the selected environment (e.g. "769610").
     * Sourced from `workspace.environments[*].app.id`. Canonical term across
     * amplitude/amplitude (Python `app_id`) and amplitude/javascript
     * (TS `appId`, GraphQL `App.id`). Used by DataIngestionCheckScreen to
     * call query_dataset via MCP.
     */
    selectedAppId: string | null;
    /**
     * Notice shown on the API key entry step of AuthScreen.
     * Set when auto-fetch fails (e.g. user is not an org admin) so the user
     * understands why manual entry is required.
     */
    apiKeyNotice: string | null;
    credentials: {
        accessToken: string;
        /** id_token from OAuth — used for Amplitude Data API calls */
        idToken?: string;
        projectApiKey: string;
        host: string;
        /**
         * Numeric Amplitude app ID (canonical). Branded `AppId` once an env is
         * known; `0` is the "unknown" sentinel set when OAuth produced
         * credentials but no env has been picked yet. Construct via
         * `toCredentialAppId(value)` at the trust boundary so raw `Number(x)`
         * conversions can't sneak past the brand. PR #62 ("org data mapping")
         * was the original motivation for branding the related top-level fields.
         */
        appId: AppId | 0;
    } | null;
    /**
     * Ordered queue of framework-controlled steps that run after the
     * Claude agent finishes (commit planned events, create dashboard,
     * etc.). Rendered as the FinalizingPanel under the agent task list
     * so the user sees forward motion during what would otherwise be a
     * silent post-agent gap. Empty until the agent run completes; never
     * re-ordered after seeding.
     */
    postAgentSteps: PostAgentStep[];
    runPhase: RunPhase;
    /**
     * Wall-clock timestamp (ms) when runPhase first transitioned to Running.
     * Null while Idle / before the run starts. Used by the Run screen to
     * compute elapsed time that persists across tab re-mounts.
     */
    runStartedAt: number | null;
    loginUrl: string | null;
    discoveredFeatures: DiscoveredFeature[];
    llmOptIn: boolean;
    sessionReplayOptIn: boolean;
    engagementOptIn: boolean;
    /** True once the user has clicked Continue on the IntroScreen. */
    introConcluded: boolean;
    /**
     * Set to `true` when credentials were resolved silently from disk on a
     * returning run (stored OAuth + persisted API key + ampli.json), instead
     * of being chosen by the user in the SUSI picker this session.
     *
     * The Auth flow gate refuses to advance while this is true — AuthScreen
     * shows a one-shot confirmation step ("continue with org X / project Y,
     * or change") so the user is never silently routed against a project
     * they didn't intend to target. Cleared once they confirm or pick a
     * different project.
     *
     * Forced false in non-interactive modes (`ci` / `agent`) where there is
     * no human to confirm. Those modes already accept the stored selection
     * (or fail loudly via `auth_required: env_selection_failed`).
     */
    requiresAccountConfirmation: boolean;
    /**
     * True from the moment the user invokes `/logout` until the logout flow
     * completes (or is cancelled). Used by the bin.ts re-auth watcher to skip
     * the auto-OAuth retry that would otherwise fire during the brief window
     * where credentials are null but the Logout overlay has not yet been
     * fully resolved as `currentScreen`. Without this flag the watcher could
     * race the logout flow and re-open the browser unexpectedly.
     */
    loggingOut: boolean;
    mcpComplete: boolean;
    mcpOutcome: McpOutcome | null;
    mcpInstalledClients: string[];
    slackComplete: boolean;
    slackOutcome: SlackOutcome | null;
    serviceStatus: {
        description: string;
        statusPageUrl: string;
    } | null;
    retryState: RetryState | null;
    outroData: OutroData | null;
    additionalFeatureQueue: AdditionalFeature[];
    /** The feature currently being processed by the stop hook, if any. */
    additionalFeatureCurrent: AdditionalFeature | null;
    /** Features the stop hook has finished processing, in order. */
    additionalFeatureCompleted: AdditionalFeature[];
    /**
     * True once feature-opt-in resolution has run for this session. The
     * wizard auto-enables every discovered opt-in addon (Session Replay,
     * Guides & Surveys, LLM-when-flag-on) at discovery time rather than
     * showing a picker — this flag is flipped to true alongside that
     * auto-enable so any flow predicate that gates on
     * `optInFeaturesComplete` (and was originally written for the old
     * picker world) still resolves correctly.
     */
    optInFeaturesComplete: boolean;
    frameworkConfig: FrameworkConfig | null;
    /**
     * True when the agent run was skipped because Amplitude was already
     * detected in the project via static analysis. Set in bin.ts before
     * runPhase is set to Completed.
     */
    amplitudePreDetected: boolean;
    /**
     * While true, McpScreen shows a prompt: skip the agent (default) or run
     * the setup wizard anyway. Cleared when the user chooses or when resetting
     * for a forced wizard run.
     */
    amplitudePreDetectedChoicePending: boolean;
    /**
     * True once the activation check confirms events are flowing into the project.
     * Set immediately if activationLevel is already 'full', otherwise set after
     * the DataIngestionCheckScreen detects events via the API.
     */
    dataIngestionConfirmed: boolean;
    /**
     * URL of the dashboard created by the agent during the conclude phase.
     * Set when the agent writes .amplitude-dashboard.json and the watcher
     * picks it up. Shown in OutroScreen as a direct link.
     * Null until the agent creates a dashboard.
     */
    checklistDashboardUrl: string | null;
    /**
     * Lifecycle phase of the post-agent dashboard fallback step
     * (`createDashboardStep` in src/steps/create-dashboard.ts).
     *
     *   `null`         — fallback hasn't started, or the agent already produced
     *                    `.amplitude/dashboard.json` so the fallback short-circuits.
     *   `in_progress`  — fallback is actively running its sub-agent + MCP calls.
     *                    RunScreen surfaces this as a 6th synthetic task so the
     *                    "X / 5 tasks complete" header stops lying while the
     *                    spinner is spinning.
     *   `completed`    — fallback finished (success or graceful skip).
     *
     * When the in-loop agent calls `record_dashboard` (the post-#PR-XXX path),
     * this field stays null end-to-end and the RunScreen never shows a 6th task.
     * The 6th task only appears when the agent didn't do its job and the
     * fallback actually fires — that's the rare case we still want to be
     * transparent about.
     */
    dashboardFallbackPhase: 'in_progress' | 'completed' | null;
    /**
     * Browser magic-link URL from direct account provisioning (`dashboard_url` on
     * the agentic signup API). Never log or NDJSON (query may contain secrets).
     */
    signupMagicLinkUrl: string | null;
    /** Email address of the authenticated user (from ~/.ampli.json stored profile). */
    userEmail: string | null;
    /**
     * Set to true by bin.ts when a crash-recovery checkpoint is loaded.
     * IntroScreen checks this to show a "Resume where you left off" prompt
     * instead of the normal detection flow.
     */
    _restoredFromCheckpoint: boolean;
    /**
     * Terms of Service acceptance state for the create-account onboarding path.
     * null = not yet shown/needed (default)
     * false = shown but not yet accepted
     * true = accepted by user
     */
    tosAccepted: boolean | null;
    /**
     * True once the email capture step is complete on the create-account path.
     * Email is required before showing ToS.
     */
    emailCaptureComplete: boolean;
    /**
     * True if signup tokens were already obtained during EmailCaptureScreen
     * (to skip duplicate signup attempt in bin.ts)
     */
    signupTokensObtained: boolean;
    /**
     * Create-project flow state.
     *
     * `pending` = the user has chosen "Create new project…" from the Auth
     *   picker or invoked `/create-project`. The CreateProjectScreen should
     *   render and collect a name.
     * `null` = not in the create-project flow (default).
     *
     * The picker that triggered the flow is tracked for analytics + so we
     * can route back to the right picker on cancel.
     *
     * We intentionally do NOT store the returned apiKey on the session
     * here — it flows through `setCredentials()` instead (same path as all
     * other API keys) so redaction and persistence stay consistent.
     */
    createProject: {
        /** True when the CreateProjectScreen should be shown. */
        pending: boolean;
        /** Which picker triggered it — used for analytics + cancel routing. */
        source: 'project' | 'environment' | 'slash' | 'cli-flag' | null;
        /** Pre-filled name (e.g. from --project-name CLI flag). */
        suggestedName: string | null;
    };
}
/**
 * Session view after OAuth completes: credentials and an org are set.
 * Fields outside the auth subset remain optional/nullable as in
 * `WizardSession`.
 */
export type AuthenticatedSession = WizardSession & {
    credentials: NonNullable<WizardSession['credentials']>;
    selectedOrgId: string;
};
/**
 * Session view once the user has chosen an org/project and a region.
 * This is the minimum needed to talk to the Amplitude Data API.
 */
export type ConfiguredSession = AuthenticatedSession & {
    selectedProjectId: string;
    region: AmplitudeZone;
};
/**
 * Session view while the agent is actively running. Adds an integration
 * and a non-null run start timestamp to the configured baseline.
 */
export type RunningSession = ConfiguredSession & {
    runPhase: typeof RunPhase.Running;
    integration: Integration;
    runStartedAt: number;
};
/**
 * True iff OAuth has produced credentials and an org id is recorded.
 * Callers that only need credentials can use this and stop sprinkling
 * `if (!session.credentials)` early-returns.
 */
export declare function isAuthenticated(session: WizardSession): session is AuthenticatedSession;
/**
 * True iff the session has everything needed to make scoped Data API calls:
 * credentials + org + project + region.
 */
export declare function isConfigured(session: WizardSession): session is ConfiguredSession;
/**
 * True iff the agent run is currently in flight. Used by retry/error paths
 * that should only act on a live run.
 */
export declare function isRunning(session: WizardSession): session is RunningSession;
/**
 * Build a WizardSession from CLI args, pre-populating whatever is known.
 *
 * **Auth path (`sign_in` vs `create_account`):** Prefer `authOnboarding` /
 * `authOnboardingPath` from `--auth-onboarding` (or the Intro menu in TUI).
 * `signup` / `accountCreationFlow` are legacy boolean inputs still merged
 * here so older scripts and env-injected argv keep working; both map to
 * create-account when true.
 */
export declare function buildSession(args: {
    debug?: boolean;
    verbose?: boolean;
    forceInstall?: boolean;
    installDir?: string;
    ci?: boolean;
    authOnboardingPath?: AuthOnboardingPath;
    /** From `--auth-onboarding` (yargs camelCase: `authOnboarding`). */
    authOnboarding?: 'sign-in' | 'create-account';
    /** @deprecated Hidden argv/env compat — maps to create-account when true. */
    signup?: boolean;
    /** @deprecated Internal/legacy compat — maps to create-account when true. */
    accountCreationFlow?: boolean;
    localMcp?: boolean;
    apiKey?: string;
    menu?: boolean;
    integration?: Integration;
    benchmark?: boolean;
    /** Agent model tier — 'fast' / 'standard' / 'thorough'. Defaults to 'standard'. */
    mode?: import('../utils/types').WizardMode;
    /** From --app-id / --project-id CLI flag. */
    appId?: string;
    /** From --app-name / --project-name CLI flag — pre-fills CreateAppScreen. */
    appName?: string;
    signupEmail?: string;
    signupFullName?: string;
    /**
     * From --accept-tos CLI flag. Explicit consent to the Amplitude Terms of
     * Service. Required (alongside --email / --full-name / --region) when
     * `--auth-onboarding create-account` is used in --ci or --agent modes; in
     * TUI mode the ToSScreen still owns the consent UI, so this flag
     * pre-accepts and skips that screen. Pre-populates `session.tosAccepted =
     * true` when passed.
     */
    acceptTos?: boolean;
    /**
     * From --region CLI flag (--zone is accepted as an alias). Lets non-TUI
     * modes (agent/CI/classic) pick the data center for direct signup, since
     * they have no RegionSelect screen. When provided, pre-populates the
     * session's region so RegionSelect is skipped in the TUI flow too.
     */
    region?: AmplitudeZone;
}): WizardSession;
