/** * Runtime configuration for @hasna/loops. * * Deployment modes were removed: there is no `local | self_hosted | cloud` * axis, no mode enums, and no `HASNA_LOOPS_STORAGE_MODE`. The only technical * switches left are the server's data backend (`sqlite | postgresql`, selected * by `HASNA_LOOPS_DATABASE_URL`) and the client's connection * (`file | api`, selected by `HASNA_LOOPS_API_URL` + `HASNA_LOOPS_API_KEY`). * * The client connects to a local SQLite file or to the server HTTP API. It * never opens Postgres directly: `HASNA_LOOPS_DATABASE_URL` is server-only and * is never used to connect from the client — at most its *presence* is * reported. A retired `HASNA_LOOPS_STORAGE_MODE` env is rejected with a hard * error (closed matrix: old mode env is never honored). */ export type Env = Record; /** Server-side storage backend; `postgresql` iff HASNA_LOOPS_DATABASE_URL is present. */ export type RuntimeStorage = "sqlite" | "postgresql"; /** Client connection transport: local file or server HTTP API. */ export type RuntimeConnection = "file" | "api"; export interface RuntimeConfig { /** Server-side storage backend this runtime should use. */ storage: RuntimeStorage; /** Client connection transport. */ connection: RuntimeConnection; /** Raw API URL value; never print it — scrub with displayControlPlaneUrl. */ apiUrl?: string; apiUrlPresent: boolean; apiKeyPresent: boolean; databaseUrlPresent: boolean; } /** Presence report for the control-plane env vars; never contains values of keys. */ export interface LoopControlPlaneConfig { apiUrl?: string; apiUrlPresent: boolean; apiKeyPresent: boolean; databaseUrlPresent: boolean; } export type LoopRouteAdmissionGate = "max_dispatch" | "max_active" | "max_active_per_project" | "max_active_per_project_group" | "max_active_scope" | "max_per_profile"; /** Policy gates applied to route admission; kept unchanged from the pre-mode-removal contract. */ export declare const ROUTE_ADMISSION_GATES: readonly ["max_dispatch", "max_active", "max_active_per_project", "max_active_per_project_group", "max_active_scope", "max_per_profile"]; /** * Closed-matrix rejection of the retired mode env: a non-empty * HASNA_LOOPS_STORAGE_MODE is a hard error naming the variable as retired, * never honored. An empty/blank value counts as unset. * * Exported so the client store resolution path (getStore -> resolveCloudStorage) * rejects a leftover env as loudly as status/doctor/serve do, instead of * silently reading the wrong dataset. */ export declare function assertNoRetiredStorageMode(env: Env): void; /** * Resolve the runtime configuration from the environment. * * The connection is `api` iff BOTH HASNA_LOOPS_API_URL and HASNA_LOOPS_API_KEY * are present; a partial remote configuration (exactly one of them) throws, * naming the missing variable. Otherwise the connection is `file`. Server-side * storage is `postgresql` iff HASNA_LOOPS_DATABASE_URL is present; clients * never read the DSN value itself, only its presence. */ export declare function resolveRuntimeConfig(env?: Env): RuntimeConfig; /** * Successor to the pre-mode-removal `loopControlPlaneConfig`: presence booleans * for the control-plane env vars. The API key value is never returned. */ export declare function loopControlPlaneConfig(env?: Env): LoopControlPlaneConfig; /** Server-side storage backend selector for loops-serve. */ export declare function runtimeStorage(env?: Env): RuntimeStorage; /** Storage-kit backend token for loops-serve ("sqlite" | "postgres"). */ export type RuntimeStorageBackend = "sqlite" | "postgres"; export declare function runtimeStorageBackend(env?: Env): RuntimeStorageBackend; /** * Scrub a control-plane URL for display: origin + path only, dropping any * credentials, query, and fragment. Returns "[invalid-url]" for unparsable * values and undefined for empty ones. */ export declare function displayControlPlaneUrl(value: string | undefined): string | undefined;