/**
 * Result of a `checkPaths` lookup. Either a relationship payload (with token
 * and userReference attached) or a redirect prompt when the user isn't
 * signed in to Village.
 */
export declare type CheckPathsResult = {
    relationship?: {
        warmth_score?: number;
        paths?: {
            count?: number;
            avatars?: string[];
        };
        [key: string]: unknown;
    };
    token?: string | false;
    userReference?: string;
    [key: string]: unknown;
} | {
    message: string;
    redirect: true;
} | null;

export declare const EXTERNAL_COMMANDS: readonly ["getExtensionStatus", "livelinessCheck", "fillUpEmail", "GET_MUTUAL_CONNECTIONS"];

export declare type ExternalCommand = ExternalRequest['message'];

export declare type ExternalRequest = {
    message: 'getExtensionStatus';
    shouldTriggerReset?: boolean;
} | {
    message: 'livelinessCheck';
} | {
    message: 'fillUpEmail';
    email: string;
} | {
    message: 'GET_MUTUAL_CONNECTIONS';
    profileSlug: string;
};

export declare type ExternalResponse = ExternalResponseMap[ExternalCommand];

export declare type ExternalResponseMap = {
    getExtensionStatus: UiSettings;
    livelinessCheck: {
        getProfileUserDetails: boolean;
        getContactInfo: boolean;
        getLinkedinLoggedinUserInfo: boolean;
        getProfileConnections: boolean;
    };
    fillUpEmail: {
        success: true;
    };
    GET_MUTUAL_CONNECTIONS: MutualConnectionsResult | {
        error: true;
        message: string;
    };
};

export declare const INTERNAL_COMMANDS: readonly ["village:bind:extension", "saveUISettings", "getUserIntegration", "getSettings", "checkPaths", "tracking", "bridge:relay"];

export declare type InternalCommand = InternalRequest['command'];

export declare type InternalRequest = {
    command: 'village:bind:extension';
    data: VillageBindSettings;
} | {
    command: 'saveUISettings';
    data: UserLoggedObj;
} | {
    command: 'getUserIntegration';
} | {
    command: 'getSettings';
} | {
    command: 'checkPaths';
    url: string;
} | {
    command: 'tracking';
    eventName: string;
    properties?: Record<string, unknown>;
    /**
     * @deprecated Ignored since anonymous capture was removed — events
     * without a logged-in user id are always dropped. Kept so pre-existing
     * hosts sending `force` still typecheck against this wire format.
     */
    force?: boolean;
} | {
    command: 'bridge:relay';
    payload: ExternalRequest;
};

export declare type InternalResponseMap = {
    'village:bind:extension': {
        success: true;
    } | {
        error: string;
    };
    saveUISettings: {
        success: true;
    } | {
        error: string;
    };
    getUserIntegration: {
        success: true;
    } | {
        error: string;
    };
    getSettings: {
        uiSettings: UiSettings;
    };
    checkPaths: CheckPathsResult;
    tracking: {
        success: true;
    } | {
        error: string;
    };
    'bridge:relay': ExternalResponse | {
        error: string;
    } | undefined;
};

export declare function isExternalRequest(m: unknown): m is ExternalRequest;

export declare function isInternalRequest(m: unknown): m is InternalRequest;

export declare type LocalKey = keyof LocalSchema;

/**
 * Local-storage keys the SDK reads or writes. Backed by `browser.storage.local`
 * — larger quota, never syncs. Use for per-device state and debug toggles.
 *
 * `sdk_debug_mode` is an internal SDK toggle controlled via the
 * `self.villageExtension.enableDebug()` console API. Partner code should not
 * read or write it.
 */
export declare interface LocalSchema {
    sdk_debug_mode: boolean;
}

/**
 * Result of `GET_MUTUAL_CONNECTIONS` — array of normalized connection objects
 * pulled from LinkedIn voyager. Order and field availability depend on the
 * endpoint variant (current vs legacy) — fields are best-effort.
 */
export declare type MutualConnection = {
    name?: string;
    slug?: string;
    headline?: string;
    location?: string;
    profileUrl?: string;
    distance?: string;
};

export declare type MutualConnectionsResult = MutualConnection[];

export declare type RequestFor<C extends InternalCommand> = Extract<InternalRequest, {
    command: C;
}>;

export declare type ResponseFor<C extends InternalCommand> = InternalResponseMap[C];

/**
 * @deprecated since 0.3.0 — use `SyncSchema` instead. Kept as an alias for the
 * one-release soak so partner code that imports `StorageSchema` from
 * `@villagehq/extension-sdk/messages` keeps compiling. Removed in a future
 * release once partner repos have updated.
 */
export declare type StorageSchema = SyncSchema;

export declare type SwToContentMessage = {
    type: 'pathsEverywhere';
} | {
    type: 'fillUpEmail';
    email: string;
} | {
    type: 'bridge:push';
    event: string;
    data: unknown;
};

export declare type SyncKey = keyof SyncSchema;

/**
 * Sync-storage keys the SDK reads or writes. Frozen public contract: partner
 * extensions may read these directly via `chrome.storage.sync.get`.
 *
 * Backed by `browser.storage.sync` — small per-key quota, syncs across
 * Chrome profile signed-in devices. Use for cross-device user state.
 */
export declare interface SyncSchema {
    linkedin_login: boolean;
    frontend_login: boolean;
    linkedin_loggedin_email: string | null;
    user_logged_obj: UserLoggedObj;
    user_integration: UserIntegration;
    saved_profile: boolean;
    fetched_connections: boolean;
    /**
     * @deprecated since 0.3.0 — superseded by
     * `'village.paths-everywhere.is-active'` (`'ENABLED' | 'DISABLED'` shape).
     * `paths-trigger.ts` opportunistically migrates this key to the new one and
     * deletes the legacy entry. Will be removed in a future Phase C release once
     * Sentry breadcrumbs confirm zero in-the-wild migrations remain.
     */
    isPathsEverywhereActive: boolean;
    'village.paths-everywhere.is-active': 'ENABLED' | 'DISABLED';
    VILLAGE_TOKEN: string;
    'village:bind:extension': VillageBindSettings;
}

/**
 * Snapshot of login + manifest state returned by `getSettings` / the
 * `getExtensionStatus` external command. Boolean-ish because the underlying
 * storage values may be `null` when never written.
 */
export declare interface UiSettings {
    linkedin_login: boolean | null;
    linkedin_loggedin_email: string | null;
    frontend_login: boolean | null;
    user_logged_obj: UserLoggedObj | null;
    version: string;
}

/**
 * Backend integration record for the current user — describes which sync
 * pipelines have completed (profile, connection IDs, etc.). Persisted under
 * the `user_integration` storage key.
 */
export declare interface UserIntegration {
    sync_data?: {
        user_profile?: unknown;
        connection_ids?: {
            is_finished?: boolean;
            start_from?: number;
        };
        delta_sync?: {
            cursor_ms?: number | null;
            [key: string]: unknown;
        };
        [key: string]: unknown;
    };
    [key: string]: unknown;
}

/**
 * Domain object shapes used by the message map.
 *
 * These are the runtime shapes the SDK observes from the Village backend and
 * LinkedIn voyager API. They're intentionally permissive: most are partial
 * snapshots of opaque server responses. Phase B will tighten these once the
 * backend ships proper schemas.
 */
/**
 * Authenticated Village user, persisted under the `user_logged_obj` storage
 * key. The SDK reads `id`, `name`, and `app.config.*` for paths-everywhere
 * branding; everything else is forwarded to partner code as-is.
 */
export declare interface UserLoggedObj {
    id?: string;
    name?: string;
    email?: string;
    app?: Record<string, unknown>;
    cacheDate?: string;
    [key: string]: unknown;
}

/**
 * Payload carried by `village:bind:extension`. Opaque from the SDK's
 * perspective — the host extension sets it, partner extensions read it back.
 *
 * @deprecated since 0.3.0 — use `VillageBindSettings` (`{ enabled: boolean }`)
 * from `@villagehq/extension-sdk/messages`. Pre-0.3.0 hosts that send a
 * JSON-stringified boolean still work via the one-release `bindExtension`
 * shim and will be dropped in 0.4.0.
 */
export declare interface VillageBindData {
    [key: string]: unknown;
}

/**
 * Settings stored under the `village:bind:extension` sync-storage key.
 * Re-declared (instead of imported from `messages.ts`) to keep this module
 * free of cross-imports from the message map.
 */
export declare interface VillageBindSettings {
    enabled: boolean;
}

export declare type VillageBridgeMessage = {
    source: 'VillageBridge';
    type: 'announce';
} | {
    source: 'VillageBridge';
    type: 'request';
    correlationId: string;
    payload: ExternalRequest;
} | {
    source: 'VillageBridge';
    type: 'response';
    correlationId: string;
    payload: ExternalResponse | null;
    error?: string;
} | {
    source: 'VillageBridge';
    type: 'push';
    event: string;
    data: unknown;
};

export { }
