/** * Durable metadata and encrypted credentials for managed messaging installs. * * The installation row deliberately contains only provider metadata and an * opaque `app_secrets` key. OAuth access and refresh tokens are serialized as * one bundle and encrypted by the framework secrets vault. List/read helpers * never expose the secret key or token values. */ import type { SecretScope } from "../secrets/register.js"; export type IntegrationInstallationStatus = "connected" | "disconnected" | "revoked" | "error"; export type IntegrationInstallationHealth = "unknown" | "healthy" | "degraded" | "revoked"; export interface IntegrationTokenBundle { accessToken: string; refreshToken?: string; tokenType?: string; expiresAt?: number; } export interface IntegrationInstallation { id: string; platform: string; installationKey: string; teamId: string | null; teamName: string | null; enterpriseId: string | null; enterpriseName: string | null; isEnterpriseInstall: boolean; apiAppId: string | null; botUserId: string | null; scopes: string[]; installedByExternalUserId: string | null; ownerEmail: string; orgId: string | null; status: IntegrationInstallationStatus; health: IntegrationInstallationHealth; lastError: string | null; healthCheckedAt: number | null; lastHealthyAt: number | null; tokenExpiresAt: number | null; createdAt: number; updatedAt: number; disconnectedAt: number | null; } export interface InstallationActor { userEmail: string; orgId?: string | null; isOrgAdmin?: boolean; } export interface UpsertIntegrationInstallationInput { platform: string; installationKey: string; teamId?: string | null; teamName?: string | null; enterpriseId?: string | null; enterpriseName?: string | null; isEnterpriseInstall?: boolean; apiAppId?: string | null; botUserId?: string | null; scopes?: readonly string[]; installedByExternalUserId?: string | null; ownerEmail: string; orgId?: string | null; secretScope: SecretScope; secretScopeId: string; tokenBundle: IntegrationTokenBundle; status?: IntegrationInstallationStatus; health?: IntegrationInstallationHealth; lastError?: string | null; healthCheckedAt?: number | null; lastHealthyAt?: number | null; tokenExpiresAt?: number | null; } export interface IntegrationInstallationUpdate { teamName?: string | null; enterpriseName?: string | null; botUserId?: string | null; scopes?: readonly string[]; status?: IntegrationInstallationStatus; health?: IntegrationInstallationHealth; lastError?: string | null; healthCheckedAt?: number | null; lastHealthyAt?: number | null; tokenExpiresAt?: number | null; } export declare const installationsStore: import("../db/store-registry.js").Store; export declare function ensureTable(): Promise; /** * Create or refresh a managed install. Re-installs may rotate tokens inside * the same owner/org scope, but cannot silently move an existing provider * installation into another Agent-Native tenant. */ export declare function upsertIntegrationInstallation(input: UpsertIntegrationInstallationInput): Promise; export declare function listIntegrationInstallations(actor: InstallationActor, platform?: string): Promise; export declare function getIntegrationInstallation(id: string, actor: InstallationActor): Promise; export declare function updateIntegrationInstallation(id: string, actor: InstallationActor, patch: IntegrationInstallationUpdate): Promise; export declare function disconnectIntegrationInstallation(id: string, actor: InstallationActor): Promise; export declare function resolveIntegrationTokenBundle(platform: string, installationKey: string): Promise; export declare function getActiveIntegrationInstallationByKey(platform: string, installationKey: string): Promise; export declare function getActiveIntegrationInstallationForTenant(platform: string, tenantId: string): Promise; export declare function listActiveIntegrationInstallationsForTenant(platform: string, tenantId: string): Promise;