import type { InstallCommand, PackageManagerRunner, PackageManagerType } from '@capgo/find-package-manager';
import type { SemVer } from '@std/semver';
import type { Buffer } from 'node:buffer';
import type { UploadSpinner } from './bundle/reporter';
import type { CapacitorConfig, ExtConfigPairs } from './config';
import type { Compatibility, CompatibilityDetails, NativePackage } from './schemas/common';
import type { Organization } from './types/api';
import { trimTrailingSlashes } from './shared/trim-trailing-slashes';
export { trimTrailingSlashes };
export declare const baseKey = ".capgo_key";
export declare const baseKeyV2 = ".capgo_key_v2";
export declare const baseKeyPub = ".capgo_key.pub";
export declare const baseKeyPubV2 = ".capgo_key_v2.pub";
export declare const defaultHost = "https://capgo.app";
export declare const defaultFileHost = "https://files.capgo.app";
export declare const defaultApiHost = "https://api.capgo.app";
export declare const defaultHostWeb = "https://console.capgo.app";
/** Build a console web-app URL (settings, builds, connect, etc.). */
export declare function consoleWebUrl(path?: string): string;
export declare const UPLOAD_TIMEOUT = 120000;
export declare const ALERT_UPLOAD_SIZE_BYTES: number;
export declare const MAX_UPLOAD_LENGTH_BYTES: number;
export declare const MAX_CHUNK_SIZE_BYTES: number;
export declare const TUS_UPLOAD_RETRY_DELAYS: number[];
export declare const MAX_MANIFEST_ENTRIES = 10000;
/** User-facing error when a delta/manifest upload exceeds MAX_MANIFEST_ENTRIES. */
export declare function deltaManifestTooLargeMessage(fileCount: number): string;
/**
 * Stable `name` for the error thrown when the standard (non-TUS) upload hits its
 * wall-clock timeout. Kept typed and constant so error tracking groups every
 * occurrence into a single issue instead of one duplicate per CLI version.
 */
export declare const UPLOAD_TIMEOUT_ERROR_NAME = "BundleUploadTimeoutError";
/** User-facing error when the standard HTTP PUT upload exceeds its wall-clock timeout. */
export declare function uploadTimeoutMessage(timeoutMs: number): string;
export declare const PACKNAME = "package.json";
/** Stable PostHog fingerprint for incomplete Capgo server config before the API client is created. */
export type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
export type { Organization };
export declare const regexSemver: RegExp;
/**
 * Format an error for display. If it's a security policy error,
 * returns a human-readable message with actionable steps.
 */
export declare function formatError(error: any): string;
/**
 * Render the safe, diagnostic part of an error chain for --verbose output.
 *
 * tus-js-client stores its underlying transport error in `causingError`, while
 * native fetch/Undici uses `cause`. Only known diagnostic fields are included;
 * request objects and headers are deliberately ignored, then the result passes
 * through the CLI's secret redactor as a final safeguard.
 */
export declare function formatVerboseError(error: unknown): string;
type TagKey = Lowercase<string>;
/** Tag Type */
type Tags = Record<TagKey, string | number | boolean>;
/**
 * Options for publishing analytics events
 */
interface TrackOptions {
    /**
     * Channel name
     * example: "waitlist"
     */
    channel: string;
    /**
     * Event name
     * example: "User Joined"
     */
    event: string;
    /**
     * Event description
     * example: "joe@example.com joined waitlist"
     */
    description?: string;
    /**
     * User ID
     * example: "user-123"
     */
    user_id?: string;
    /**
     * Organization ID for actor-scoped tracking.
     */
    org_id?: string;
    /**
     * Tracking payload contract version.
     */
    tracking_version?: number;
    /**
     * Event tags
     * example: { username: "mattie" }
     */
    tags?: Tags;
    /**
     * Event timestamp
     */
    timestamp?: number | Date;
}
export declare function wait(ms: number): Promise<unknown>;
interface PromptInteractivityOptions {
    silent?: boolean;
    stdinIsTTY?: boolean;
    stdoutIsTTY?: boolean;
    ci?: boolean;
}
export declare function canPromptInteractively({ silent, stdinIsTTY, stdoutIsTTY, ci, }?: PromptInteractivityOptions): boolean;
interface CanOpenExternalUrlOptions {
    ci?: boolean;
    stdinIsTTY?: boolean;
    stdoutIsTTY?: boolean;
    display?: string | undefined;
    platform?: NodeJS.Platform;
}
/** Whether the CLI may spawn a desktop browser for upgrade/docs links. */
export declare function canOpenExternalUrl(options?: CanOpenExternalUrlOptions): boolean;
/** Best-effort browser open; skipped in CI/headless and when xdg-open is missing. */
export declare function openExternalUrl(url: string): Promise<void>;
export declare function projectIsMonorepo(dir: string): boolean;
export declare function findRoot(dir: string): string;
export declare function getPackageScripts(f?: string, file?: string | undefined): Record<string, string>;
export declare function getBundleVersion(f?: string, file?: string | undefined): string;
/**
 * Get the actual installed version of a package from node_modules (not from package.json)
 * Uses multiple resolution strategies to find the installed version:
 * 1. require.resolve - Works with all package managers
 * 2. Walk up node_modules - Handles hoisted dependencies in monorepos
 * 3. Native config files (iOS/Android) - For @capgo/capacitor-updater only
 * 4. Fallback to declared version in package.json
 *
 * @param packageName - The package name to check
 * @param rootDir - The root directory of the project
 * @param packageJsonPath - Optional custom package.json path provided by user (takes priority if provided)
 */
export declare function getInstalledVersion(packageName: string, rootDir?: string, packageJsonPath?: string): Promise<string | null>;
export declare function getAllPackagesDependencies(f?: string, file?: string | undefined): Promise<Map<string, string>>;
export declare function getDeclaredPackageVersionMap(f?: string, file?: string | undefined): Promise<Map<string, string>>;
export declare const NO_CAPACITOR_CONFIG_MESSAGE = "No capacitor config file found, run `cap init` first";
export declare function getConfig(silent?: boolean): Promise<ExtConfigPairs>;
/** Loads the source config that a subsequent mutation will write. */
export declare function getConfigForWrite(silent?: boolean): Promise<ExtConfigPairs>;
export declare function updateConfigbyKey(key: string, newConfig: any): Promise<ExtConfigPairs>;
export declare function updateConfigUpdater(newConfig: any): Promise<ExtConfigPairs>;
export declare function getLocalConfig(silent?: boolean): Promise<{
    host: string;
    hostWeb: string;
    hostFilesApi: string;
    hostApi: string;
}>;
interface CapgoHostOverride {
    apiHost?: string;
    filesHost?: string;
}
/**
 * Pin the Capgo API for this CLI process (--api-host / --files-host). Every host
 * lookup (HTTP calls, remote config, files config, TUS uploads) then uses it, so
 * tests and self-hosted backends never leak traffic to Capgo cloud. Library code
 * uses withCapgoHosts instead so concurrent clients never share a host.
 */
export declare function setCapgoHostOverride(hosts: CapgoHostOverride): void;
/**
 * Run `action` with its own Capgo hosts. Empty hosts mean Capgo defaults (env,
 * capacitor config, cloud): a scope never inherits the CLI process pin.
 */
export declare function withCapgoHosts<T>(hosts: CapgoHostOverride, action: () => T): T;
interface CapgoConfig {
    host: string;
    hostWeb: string;
    hostFilesApi: string;
    hostApi: string;
    minCliVersion?: string;
    minCliVersionReason?: string;
}
export declare function getRemoteConfig(silent?: boolean, signal?: AbortSignal, apikey?: string): Promise<{
    host: string;
    hostWeb: string;
    hostFilesApi: string;
    hostApi: string;
    minCliVersion?: string;
    minCliVersionReason?: string;
}>;
export interface CapgoFilesConfig {
    partialUpload: boolean;
    partialUploadForced: boolean;
    TUSUpload: boolean;
    TUSUploadForced: boolean;
    maxUploadLength: number;
    maxChunkSize: number;
    alertUploadSize: number;
}
export declare function getRemoteFileConfig(apikey?: string): Promise<CapgoFilesConfig>;
export declare function formatCapgoApiErrorBody(body: unknown): string;
export declare function channelUpdatePackageCliError(error: unknown): Promise<string | null>;
/** Options that select the Capgo API. */
export interface CapgoHostOptions {
    /** Capgo API base URL (`--api-host`): any Capgo backend, e.g. `https://api.example.com` or `http://127.0.0.1:8787`. */
    apiHost?: string;
    /** Capgo files API base URL (`--files-host`); defaults to apiHost when apiHost is set. */
    filesHost?: string;
}
/** Validate a Capgo API base URL: https (http only on loopback), no credentials/query. */
export declare function normalizeCapgoApiHost(host: string): string;
export interface CapgoApiHosts {
    /** Capgo API base URL. */
    apiHost: string;
    /** Capgo files API base URL (same as apiHost when self-hosting on Edge Functions). */
    filesHost: string;
}
/**
 * Resolve Capgo API hosts: explicit apiHost/filesHost, then the process override,
 * env and capacitor config (see applyCapgoHostOverride), then Capgo cloud.
 */
export declare function resolveCapgoApiHosts(apiHost?: string, silent?: boolean, filesHost?: string): Promise<CapgoApiHosts>;
export interface CapgoCliInvokeOptions {
    apikey: string;
    method?: string;
    body?: unknown;
    /** Capgo cloud files worker; same as the API host when self-hosting */
    useFilesHost?: boolean;
    /** Capgo API base URL; defaults to capacitor config / Capgo cloud. */
    apiHost?: string;
    signal?: AbortSignal;
    /** Set false for telemetry-internal calls so perf events never recurse. */
    instrument?: boolean;
}
export declare function getCapgoCliHttpStatus(error: unknown): number | undefined;
export declare function readCapgoCliApiErrorPayload(error: unknown): Promise<{
    error?: string;
    message?: string;
    moreInfo?: Record<string, unknown>;
} | null>;
export declare function formatCapgoCliInvokeError(error: unknown): Promise<string>;
/**
 * Call the Capgo HTTP API. Every request carries the API key and the `capgo_api`
 * version header (see buildCliRequestHeaders); the backend owns all data access.
 */
export declare function invokeCapgoCliApi<T = any>(path: string, options: CapgoCliInvokeOptions): Promise<{
    data: T | null;
    error: Error | null;
}>;
export declare function resolveCapgoPublicApiHost(options?: {
    apiHost?: string;
}, silent?: boolean): Promise<string>;
/**
 * Connection to the Capgo HTTP API. The CLI never queries the database directly:
 * every read/write goes through Capgo HTTP endpoints via `invokeCapgoCliApi`.
 */
export interface CapgoClient extends CapgoApiHosts {
    apikey: string;
}
export declare function createCapgoClient(apikey: string, apiHost?: string, silent?: boolean, signal?: AbortSignal, filesHost?: string): Promise<CapgoClient>;
export declare function fetchCliMembers2faStatus(apikey: string, orgId: string, httpOptions?: CliHttpOptions): Promise<Array<{
    'user_id': string;
    '2fa_enabled': boolean;
}>>;
export declare function fetchCliMembersPasswordPolicyStatus(apikey: string, orgId: string, httpOptions?: CliHttpOptions): Promise<Array<{
    user_id: string;
    email: string;
    first_name: string;
    last_name: string;
    password_policy_compliant: boolean;
}>>;
export declare function findSavedKeySilent(): string | undefined;
export declare function findSavedKey(quiet?: boolean, report?: (message: string) => void): string;
export declare function getContentType(filename: string): string;
export declare function findProjectType(options?: {
    quiet?: boolean;
    packageJsonPath?: string;
}): Promise<string>;
export declare function findMainFileForProjectType(projectType: string, isTypeScript: boolean, rootDir?: string): string | null;
export declare function findBuildCommandForProjectType(projectType: string): Promise<"build" | "generate">;
export declare function findMainFile(silent?: boolean, rootDir?: string): Promise<string>;
export declare function uploadUrl(apikey: string, appId: string, name: string, options?: {
    apiHost?: string;
}): Promise<string>;
export declare const BROTLI_MIN_UPDATER_VERSION_V5 = "5.10.0";
export declare const BROTLI_MIN_UPDATER_VERSION_V6 = "6.25.0";
export declare const BROTLI_MIN_UPDATER_VERSION_V7 = "7.0.30";
export declare function isDeprecatedPluginVersion(parsedPluginVersion: SemVer, minFive?: string, minSix?: string, minSeven?: string): boolean;
export declare function generateManifest(path: string): Promise<{
    file: string;
    hash: string;
}[]>;
export type manifestType = Awaited<ReturnType<typeof generateManifest>>;
export declare function zipFile(filePath: string): Promise<Buffer>;
export declare function zipFileUnix(filePath: string): Buffer<ArrayBufferLike>;
export declare function zipFileWindows(filePath: string): Promise<Buffer>;
export declare function appAddHintMessage(appId: string): string;
export declare function isAppNotFoundError(error: unknown): boolean;
export declare function uploadTUS(apikey: string, data: Buffer, orgId: string, appId: string, name: string, spinner: UploadSpinner, localConfig: CapgoConfig, chunkSize: number): Promise<boolean>;
export declare function deletedFailedVersion(apikey: string, appId: string, name: string, options?: {
    apiHost?: string;
}): Promise<void>;
export interface VersionManifestEntry {
    file_name: string;
    s3_path: string;
    file_hash: string;
    file_size_receipt?: string;
}
/**
 * Writes delta manifest rows through the backend (file_size stays 0 until R2 size lookup).
 * Prefer this over writing app_versions.manifest jsonb — old CLIs still use that legacy path.
 */
export declare function setVersionManifest(apikey: string, appId: string, name: string, manifest: VersionManifestEntry[], options?: {
    apiHost?: string;
}): Promise<void>;
type SendEventPayload = TrackOptions & {
    nonPersonTags?: Record<string, unknown>;
} & ({
    notifyConsole: true;
    icon?: string;
} | {
    notifyConsole?: false;
    icon?: never;
});
export declare function sendEvent(capgkey: string, payload: SendEventPayload, verbose?: boolean, signal?: AbortSignal, apiHost?: string, redirect?: RequestInit['redirect']): Promise<void>;
export declare function show2FADeniedError(organizationName?: string): never;
/** Capgo API selection for helpers that are not handed a CapgoClient. */
export interface CliHttpOptions {
    apiHost?: string;
}
/** API key plus optional host: a CapgoClient, or command options before a client exists. */
export interface CapgoApiTarget {
    apikey: string;
    apiHost?: string;
    filesHost?: string;
}
/** Call the Capgo API with a client's key and host. */
export declare function invokeCliHttpFromClient<T>(client: CapgoApiTarget, path: string, options?: {
    method?: string;
    body?: unknown;
    query?: Record<string, string | undefined>;
    useFilesHost?: boolean;
    signal?: AbortSignal;
}): Promise<{
    data: T | null;
    error: Error | null;
}>;
/** Host options matching a Capgo client, for helpers that take CliHttpOptions. */
export declare function hostOptionsFromClient(client: CapgoClient): CliHttpOptions;
/**
 * Organizations visible to the API key. With `permission`, each row carries
 * `allowed`: whether the key holds that permission in the org.
 */
export declare function fetchOrganizations(apikey: string, httpOptions?: CliHttpOptions, permission?: string): Promise<Array<Organization & {
    allowed?: boolean;
}>>;
export interface CliOrganizationDetails {
    name: string;
    management_email?: string;
    created_by?: string;
    enforcing_2fa: boolean;
    password_policy_config: {
        enabled: boolean;
        min_length: number;
        require_uppercase: boolean;
        require_number: boolean;
        require_special: boolean;
    } | null;
    require_apikey_expiration: boolean;
    max_apikey_expiration_days: number | null;
    enforce_hashed_api_keys: boolean;
}
export declare function fetchCliOrganization(apikey: string, orgId: string, httpOptions?: CliHttpOptions): Promise<CliOrganizationDetails>;
export declare function getOrganizationListWithPermission(client: CapgoClient, apikey: string, permissionKey: string, httpOptions?: CliHttpOptions): Promise<{
    allOrganizations: Organization[];
    allowedOrganizations: Organization[];
}>;
export declare function getOrganizationWithPermission(client: CapgoClient, apikey: string, permissionKey: string): Promise<Organization>;
export declare function resolveUserIdFromApiKey(client: CapgoClient, apikey: string, silent?: boolean, httpOptions?: CliHttpOptions): Promise<string>;
interface CliPermissionScope {
    orgId?: string | null;
    appId?: string | null;
    channelId?: number | null;
}
/** Ask the backend which of these RBAC permissions the client key holds in one scope. */
export declare function fetchCliPermissions(client: CapgoClient, permissionKeys: string[], scope?: CliPermissionScope): Promise<Record<string, boolean>>;
export declare function hasCliPermission(client: CapgoClient, _apikey: string, permissionKey: string, scope?: CliPermissionScope, silent?: boolean): Promise<boolean>;
export declare function assertCliPermission(client: CapgoClient, apikey: string, permissionKey: string, scope?: CliPermissionScope, options?: {
    message?: string;
    silent?: boolean;
}): Promise<void>;
export declare function assertOrgPermission(client: CapgoClient, apikey: string, permissionKey: string, orgId: string, message: string, silent: boolean): Promise<void>;
export declare function getOrganizationId(apikey: string, appId: string, options?: {
    apiHost?: string;
}): Promise<string>;
export declare function getHumanDate(createdA: string | null): string;
export declare function getPMAndCommand(): {
    pm: PackageManagerType;
    command: InstallCommand;
    installCommand: string;
    runner: PackageManagerRunner;
};
export declare function setPMAndCommand(next: {
    pm: PackageManagerType;
    command: InstallCommand;
    runner: PackageManagerRunner;
}): void;
export declare function getNativeProjectResetAdvice(platformRunner: string, nativePlatform: 'ios' | 'android'): {
    summary: string;
    command: string;
};
export declare function getLocalDependencies(packageJsonPath: string | undefined, nodeModulesString: string | undefined): Promise<{
    name: string;
    version: string;
    requested_version?: string;
    native: boolean;
    ios_checksum?: string;
    android_checksum?: string;
}[]>;
export declare function getRemoteDependencies(apikey: string, appId: string, channel: string, httpOptions?: CliHttpOptions): Promise<Map<string, NativePackage>>;
export declare function getRemoteChecksums(apikey: string, appId: string, channel: string, httpOptions?: CliHttpOptions): Promise<string | null>;
export type { NativePackage } from './schemas/common';
export declare function convertNativePackages(nativePackages: NativePackage[]): Map<string, NativePackage>;
export type { Compatibility, CompatibilityDetails } from './schemas/common';
export declare function getAppId(appId: string | undefined, config: CapacitorConfig | undefined): any;
/**
 * Check if a package is compatible and return detailed reasons if not
 */
export declare function getCompatibilityDetails(pkg: Compatibility): CompatibilityDetails;
/**
 * Simple compatibility check (backward compatible)
 */
export declare function isCompatible(pkg: Compatibility): boolean;
export declare function checkCompatibilityCloud(apikey: string, appId: string, channel: string, packageJsonPath: string | undefined, nodeModules: string | undefined, httpOptions?: CliHttpOptions): Promise<{
    finalCompatibility: {
        name: string;
        localVersion?: string | undefined;
        remoteVersion?: string | undefined;
        localRequestedVersion?: string | undefined;
        remoteRequestedVersion?: string | undefined;
        localIosChecksum?: string | undefined;
        remoteIosChecksum?: string | undefined;
        localAndroidChecksum?: string | undefined;
        remoteAndroidChecksum?: string | undefined;
    }[];
    localDependencies: {
        name: string;
        version: string;
        requested_version?: string;
        native: boolean;
        ios_checksum?: string;
        android_checksum?: string;
    }[];
}>;
export declare function checkCompatibilityNativePackages(apikey: string, appId: string, channel: string, nativePackages: NativePackage[], httpOptions?: CliHttpOptions): Promise<{
    finalCompatibility: {
        name: string;
        localVersion?: string | undefined;
        remoteVersion?: string | undefined;
        localRequestedVersion?: string | undefined;
        remoteRequestedVersion?: string | undefined;
        localIosChecksum?: string | undefined;
        remoteIosChecksum?: string | undefined;
        localAndroidChecksum?: string | undefined;
        remoteAndroidChecksum?: string | undefined;
    }[];
    localDependencies: {
        name: string;
        version: string;
        requested_version?: string | undefined;
        ios_checksum?: string | undefined;
        android_checksum?: string | undefined;
    }[];
}>;
export interface IosUpdaterSyncValidationResult {
    shouldCheck: boolean;
    valid: boolean;
    details: string[];
}
/**
 * Validate whether the iOS native project is correctly synced for capacitor-updater.
 *
 * `shouldCheck` is `false` when no iOS project is present or no updater signals are detected
 * (no dependency declaration, installed package, or native references). `shouldCheck` is `true`
 * as soon as any signal indicates updater should be wired, then both dependency definitions
 * (`Podfile` or SPM `Package.swift`) and generated native outputs (`Podfile.lock`,
 * `capacitor.plugins.json`, or `ios/App/App/capacitor.config.json`) must include
 * updater markers for `valid` to be `true`.
 */
export declare function validateIosUpdaterSync(rootDir?: string, packageJsonPath?: string): IosUpdaterSyncValidationResult;
interface PromptAndSyncOptions {
    validateIosUpdater?: boolean;
    packageJsonPath?: string;
}
export type IosUpdaterSyncValidation = ReturnType<typeof validateIosUpdaterSync>;
export declare function throwIfIosUpdaterSyncInvalid(syncValidation: IosUpdaterSyncValidation, platformRunner: string, onFailure?: () => void): void;
export declare function promptAndSyncCapacitor(isInit?: boolean, orgId?: string, apikey?: string, options?: PromptAndSyncOptions): Promise<void>;
