import { z } from 'zod';
import { type AmplitudeZone } from './constants.js';
export type AmplitudeOrg = {
    id: string;
    name: string;
    projects: Array<{
        id: string;
        name: string;
        environments?: Array<{
            name: string;
            rank: number;
            app: {
                id: string;
                apiKey?: string | null;
            } | null;
        }> | null;
    }>;
};
/**
 * Shared project type for environment helpers.
 *
 * NOTE: In Amplitude's backend GraphQL schema this layer is called a
 * "workspace"; the wizard's wire-level queries still use the `workspaces`
 * field name. The TS surface, session state, and user-facing UI all use
 * "project" to match the website and the rest of the Amplitude product.
 */
export type AmplitudeProject = AmplitudeOrg['projects'][number];
/**
 * Extract the primary Amplitude app ID from a project.
 * Picks the lowest-rank environment that has an app ID.
 * Returns null if no such environment exists.
 *
 * Note: "app" is the canonical term for the ingestion surface that owns an
 * API key, per amplitude/amplitude (`app_id`) and amplitude/javascript
 * (`App` GraphQL type). Amplitude's UI also labels this "Project ID" in
 * some places — it's the numeric app ID, not the project layer above it.
 */
export declare function extractAppId(project: AmplitudeProject): string | null;
export type AmplitudeUserInfo = {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
    orgs: AmplitudeOrg[];
};
export declare class ApiError extends Error {
    readonly statusCode?: number | undefined;
    readonly endpoint?: string | undefined;
    readonly code?: string | undefined;
    constructor(message: string, statusCode?: number | undefined, endpoint?: string | undefined, code?: string | undefined);
}
/**
 * Fetches the authenticated user's org/project info from Amplitude's Data API.
 * Uses the OAuth id_token as the Authorization header (same as ampli CLI).
 *
 * The backend GraphQL response carries a `workspaces` field; we rename it to
 * `projects` at this boundary so the rest of the wizard only sees the
 * user-facing terminology.
 */
export declare function fetchAmplitudeUser(idToken: string, zone: AmplitudeZone): Promise<AmplitudeUserInfo>;
/**
 * Error codes returned by the wizard proxy `POST /projects` endpoint.
 * Match the contract defined with the backend agent.
 */
export type CreateProjectErrorCode = 'NAME_TAKEN' | 'QUOTA_REACHED' | 'FORBIDDEN' | 'INVALID_REQUEST' | 'INTERNAL';
export interface CreateProjectResult {
    appId: string;
    apiKey: string;
    name: string;
}
/** Max project-name length accepted by the backend (inclusive). */
export declare const PROJECT_NAME_MAX_LENGTH = 255;
/**
 * Shape of validation errors returned by `validateProjectName`. Null = ok.
 * Callers surface the human-readable `message` inline in the UI.
 */
export interface ProjectNameValidationIssue {
    code: 'empty' | 'too_long' | 'control_chars';
    message: string;
}
/**
 * Local-only validation for a project name. Mirrors the backend rules
 * (1–255 chars trimmed, no control chars) so the UI can reject bad input
 * without a round-trip.
 */
export declare function validateProjectName(name: string): ProjectNameValidationIssue | null;
/**
 * Derive the wizard proxy base URL (e.g. `https://core.amplitude.com/wizard`)
 * from a zone by starting from the API host and stripping any trailing
 * `/v1/messages` suffix the gateway appends for the Claude SDK.
 *
 * Exported so callers + tests can assert the exact endpoint.
 */
export declare function getWizardProxyBase(zone: AmplitudeZone): string;
/**
 * Create a new Amplitude analytics project (app) in the given org via the
 * wizard proxy.
 *
 * - Expects an OAuth *access token* (not the id_token) — sent as
 *   `Authorization: Bearer <token>`. The wizard-proxy validates it
 *   against Hydra introspection, which only accepts access tokens.
 * - Errors from the backend are surfaced as `ApiError` with `code` set to one
 *   of `CreateProjectErrorCode` so callers can branch (NAME_TAKEN → retry,
 *   QUOTA_REACHED → fallback, etc.).
 *
 * Returns `{ appId, apiKey, name }` on success. `apiKey` is sensitive — never
 * log it, and redact it from any analytics/NDJSON output.
 */
export declare function createAmplitudeApp(accessToken: string, zone: AmplitudeZone, input: {
    orgId: string;
    name: string;
    description?: string;
}): Promise<CreateProjectResult>;
export type AmplitudeBranch = {
    id: string;
    name: string;
    default: boolean;
    currentVersionId: string;
};
/** Fetches branches for a project. */
export declare function fetchBranches(idToken: string, zone: AmplitudeZone, orgId: string, projectId: string): Promise<AmplitudeBranch[]>;
/**
 * Fetches the event type names cataloged in the default branch of a project.
 * Returns an empty array if the project has no events or the query fails.
 */
export declare function fetchProjectEventTypes(idToken: string, zone: AmplitudeZone, orgId: string, projectId: string): Promise<string[]>;
/**
 * Checks whether the authenticated user has any charts or dashboards in their org.
 * Uses the App API org-scoped GraphQL endpoint.
 *
 * Detection is org-scoped — App API has no project-level chart/dashboard listing
 * API. For a typical new-project user this is equivalent to project-scoped.
 *
 * Returns { hasCharts: false, hasDashboards: false } on any error so the
 * checklist falls back to the default empty state rather than crashing.
 */
export declare function fetchOwnedDashboards(accessToken: string, zone: AmplitudeZone, orgId: string): Promise<{
    hasCharts: boolean;
    hasDashboards: boolean;
}>;
export type AmplitudeSource = {
    id: string;
    name: string;
    runtime: {
        id: string;
        platformId: string;
        platformName: string;
        languageId: string;
        languageName: string;
    } | null;
    destinations: Array<{
        name: string;
        serviceId: string;
    }>;
};
/** Fetches sources for a specific branch version. */
export declare function fetchSources(idToken: string, zone: AmplitudeZone, orgId: string, projectId: string, branchId: string, versionId: string): Promise<AmplitudeSource[]>;
export interface McpUser {
    /** Amplitude's internal ID (always present) */
    amplitudeId: string;
    /** App-assigned user ID if setUserId() was called, otherwise null */
    userId: string | null;
}
export interface McpEventsResult {
    hasEvents: boolean;
    /** Kept for API compatibility — always empty (query_dataset was removed from MCP server) */
    csvRows: unknown[][];
    /** Active event names from get_events (isActive=true), up to 10 */
    activeEventNames: string[];
    /** Recent users who fired events, up to 5 */
    activeUsers: McpUser[];
}
/**
 * Checks whether the project has received any events via the Amplitude MCP server.
 * Uses get_users with `_all` as the primary signal (userCount > 0 → events exist),
 * then fetches get_events for display names.
 *
 * Falls back to a Claude agent with the Amplitude MCP configured if the direct
 * HTTP call fails, so the check survives MCP API drift.
 *
 * Requires the numeric Amplitude app ID (from project.environments[].app.id),
 * not the project UUID. The downstream Amplitude MCP tool API still accepts
 * this as a `projectId` parameter (external contract we don't control).
 * Returns false on any error so callers can fall through.
 */
export declare function fetchHasAnyEventsMcp(accessToken: string, appId: string, 
/**
 * Optional abort signal — propagated to the underlying MCP fetch so the
 * caller can cancel an in-flight ingestion poll on shutdown / Ctrl+C
 * instead of letting it run to completion in the background.
 */
abortSignal?: AbortSignal): Promise<McpEventsResult>;
export type ProjectActivationStatus = {
    /** SDK/snippet has been installed (default event tracking source detected) */
    hasDetSource: boolean;
    hasPageViewedEvent: boolean;
    hasSessionStartEvent: boolean;
    hasSessionEndEvent: boolean;
    /** True if at least one event type has been ingested */
    hasAnyEvents: boolean;
};
/**
 * Checks whether an Amplitude project has ingested any events and whether
 * the SDK snippet is configured.
 *
 * Always routes to App API (the main Amplitude app GraphQL server) at
 * /t/graphql/org/:orgId using a Bearer access_token.
 */
export declare function fetchProjectActivationStatus(opts: {
    accessToken: string;
    zone: AmplitudeZone;
    appId: number | string;
    orgId: string;
}): Promise<ProjectActivationStatus>;
/**
 * Fetches the direct Slack OAuth install URL from App API.
 * This lets the wizard open the Slack authorization page directly instead of
 * routing through Amplitude Settings.
 *
 * Returns `null` on any error so callers can fall back to the settings page.
 */
export declare function fetchSlackInstallUrl(accessToken: string, zone: AmplitudeZone, orgId: string, originalPath: string): Promise<string | null>;
/**
 * Checks whether the authenticated user already has Slack connected.
 * Returns `null` on any error so callers treat it as unknown.
 */
export declare function fetchSlackConnectionStatus(accessToken: string, zone: AmplitudeZone, orgId: string): Promise<boolean | null>;
export declare const ApiUserSchema: z.ZodObject<{
    distinct_id: z.ZodString;
}, z.core.$strip>;
export declare const ApiProjectSchema: z.ZodObject<{
    id: z.ZodNumber;
    uuid: z.ZodString;
    organization: z.ZodString;
    api_token: z.ZodString;
    name: z.ZodString;
}, z.core.$strip>;
export type ApiUser = z.infer<typeof ApiUserSchema>;
export type ApiProject = z.infer<typeof ApiProjectSchema>;
/** @deprecated Amplitude stub. Use fetchAmplitudeUser instead. */
export declare function fetchUserData(_accessToken: string, _baseUrl: string): Promise<ApiUser>;
/** @deprecated Amplitude stub. Use fetchAmplitudeUser instead. */
export declare function fetchProjectData(_accessToken: string, _projectId: number, _baseUrl: string): Promise<ApiProject>;
