/** * Collector server configuration, read from the environment (see `.env.example`). * Fails fast when a required secret is missing. */ export interface CollectorConfig { host: string; port: number; /** Allowed CORS origins. Empty disables cross-origin browser access. */ corsOrigins: string[]; /** Secret seed for the daily-rotating cookieless visitor hash. */ visitorHashSecret: string; /** Opt-in raw per-session retention; gates the replay/timeline endpoint (ADR 0003). */ enableRawSessionRetention: boolean; /** Liveness window in ms for live presence/follow (ADR 0032 §1). */ liveWindowMs: number; /** Secret for signing short-lived live SSE tokens (ADR 0032 §7). */ liveTokenSecret: string; /** * Whether a dedicated `LIVE_TOKEN_SECRET` was supplied. When false the live * token secret falls back to {@link visitorHashSecret}; the server warns at * startup so production deployments give the two secrets independent values. */ liveTokenSecretIsDedicated: boolean; /** Live SSE token lifetime in ms (ADR 0032 §7). */ liveTokenTtlMs: number; /** Max concurrent live SSE connections per collector (ADR 0032 §6). */ liveMaxConnections: number; /** Interval between pushed presence snapshots / SSE heartbeats, in ms. */ livePresenceIntervalMs: number; /** Max requests per window per client for rate limiting. */ rateLimitMax: number; /** Rate-limit window in ms. */ rateLimitWindowMs: number; /** Stricter, dedicated per-client request budget for the public ingest route. */ ingestRateLimitMax: number; /** Ingest rate-limit window in ms. */ ingestRateLimitWindowMs: number; /** * Trust `X-Forwarded-*` headers from a reverse proxy / load balancer. Required * when the collector runs behind TLS termination so the per-visitor hash and * the rate-limit bucket key on the real client IP rather than the proxy's. * `false` (default) trusts only the direct socket peer. Accepts `true`/`false` * or an IP/subnet/comma-list passed through to Fastify. Hop counts are not * accepted — see `parseTrustProxy`. */ trustProxy: boolean | string; /** Max accepted request body size in bytes (defends against oversized payloads). */ bodyLimit: number; /** Content-Security-Policy for the bundled dashboard: `strict` (default) or `off`. */ cspMode: "strict" | "off"; /** * How long agent-audit rows are kept, in days (ADR 0051 §7). A periodic, * idempotent delete drops anything older. `0` disables the sweep and keeps * rows indefinitely. */ auditRetentionDays: number; /** * Also audit the dashboard's own requests. Off by default: the dashboard * identifies itself with `x-uptimizr-client: dashboard` and its panel queries * would otherwise drown the log the feature exists to make readable. Turn it * on to audit every authenticated request without exception. */ auditDashboardRequests: boolean; /** * Serve MCP over Streamable HTTP at `/mcp` (ADR 0051 §7). **Off by default**: * it is an additional authenticated, long-lived surface, so an operator opts * into it rather than discovering it. When off the route is not registered at * all — `/mcp` simply 404s. */ mcpHttpEnabled: boolean; /** * Max concurrent MCP sessions across the collector, the `/mcp` equivalent of * {@link liveMaxConnections}. Each session holds an MCP server and may hold an * open SSE stream, so the count is bounded; a request that would open the * (cap + 1)-th session is refused with `503`. */ mcpMaxSessions: number; /** * How long an MCP session may go without a request before it is closed and * evicted, in ms. Streamable HTTP has no keep-alive a server can rely on — * a client that disappears without `DELETE /mcp` would otherwise hold its slot * forever. */ mcpSessionTtlMs: number; /** * Run the conditional-subscription scheduler (#311, ADR 0051 §6). **On by * default**, and free until a project actually has an enabled subscription: * the scheduler's whole startup cost is one store read, and it schedules * nothing when that read comes back empty. Set `COLLECTOR_SUBSCRIPTIONS=0` to * keep the API (create, list, test) while running no timers at all — the right * setting when several collector instances share one database and only one of * them should evaluate. */ subscriptions: boolean; /** * How many subscription evaluations may run at once (default 4). Each is one * grouped store read, so this is the knob that keeps a hundred standing * subscriptions from behaving like a hundred concurrent dashboard users. */ subscriptionsMaxConcurrent: number; /** * Hosts a subscription webhook may POST to (`COLLECTOR_WEBHOOK_ALLOWED_HOSTS`, * comma-separated; `*` allows any host). * * **Empty by default, which disables webhook egress entirely.** A subscription * is created over HTTP by an `annotate`-capable key, so its URL is * request-controlled input to an outbound request — the scheme check in * `parseWebhookUrl` is not on its own an SSRF boundary. Naming the hosts is * the operator's explicit consent to reach them; until then a firing is still * recorded and fanned out over SSE, and nothing leaves the process. */ webhookAllowedHosts: string[]; /** * Absolute path to a pre-built static dashboard (`out/`) to serve as an * all-in-one bundle. Unset (the default) keeps the collector headless. */ dashboardDir?: string; } type Env = Record; export declare function loadConfig(env?: Env): CollectorConfig; export {}; //# sourceMappingURL=config.d.ts.map