/**
 * Configuration schema and loading for MCP proxy and remote server.
 *
 * Config files:
 *   - proxy.config.json  — MCP proxy (local) settings
 *   - remote.config.json — Remote server settings
 *
 * Each loader falls back to a legacy combined config.json (if present)
 * for backward compatibility, then to built-in defaults.
 *
 * Keys directory: ~/.drawlatch/keys/
 */
import type { IngestorConfig } from '../remote/ingestors/types.js';
import type { TriggerRule } from '../remote/triggers/types.js';
import type { TestConnectionConfig, TestIngestorConfig, ListenerConfigSchema } from './listener-config.js';
export type { TestConnectionConfig, TestIngestorConfig, ListenerConfigSchema, } from './listener-config.js';
export type { ListenerConfigField, ListenerConfigOption } from './listener-config.js';
/** Resolve the base config directory at call time (not import time).
 *  Defaults to ~/.drawlatch in the user's home directory.
 *  Override with MCP_CONFIG_DIR env var for custom deployments.
 *
 *  These are functions (not constants) so that process.env.MCP_CONFIG_DIR can
 *  be set at runtime before the first call — important for hosts like
 *  callboard that configure the path after ESM imports are resolved. */
export declare function getConfigDir(): string;
export declare function getConfigPath(): string;
export declare function getProxyConfigPath(): string;
export declare function getRemoteConfigPath(): string;
export declare function getKeysDir(): string;
export declare function getCallerKeysDir(): string;
export declare function getServerKeysDir(): string;
export declare function getEnvFilePath(): string;
/** Category grouping for built-in connection templates.
 *  Matches the subdirectory name under src/connections/. */
export type ConnectionCategory = 'ai' | 'developer-tools' | 'gaming' | 'messaging' | 'productivity' | 'social-media';
/** MCP proxy (local) configuration */
export interface ProxyConfig {
    /** Remote server URL */
    remoteUrl: string;
    /** Connection timeout (ms) */
    connectTimeout: number;
    /** Request timeout (ms) */
    requestTimeout: number;
}
/** A single route / connector definition — scopes secrets and headers to a set of endpoints */
export interface Route {
    /** Alias for referencing this connector from caller connection lists.
     *  Required for custom connectors that callers need to reference by name. */
    alias?: string;
    /** Human-readable name for this route (e.g., "GitHub API", "Stripe Payments").
     *  Optional but recommended for discoverability by the local agent. */
    name?: string;
    /** Short description of what this route provides or what it's used for.
     *  Optional — helps the agent understand the route's purpose. */
    description?: string;
    /** URL linking to API documentation for the service behind this route.
     *  Optional — helps the agent find usage instructions. */
    docsUrl?: string;
    /** URL to an OpenAPI / Swagger spec (JSON or YAML) for this route's API.
     *  Optional — provides more structured, agent-friendly documentation. */
    openApiUrl?: string;
    /** Stability level of this connection: "stable", "beta", or "dev".
     *  Defaults to "dev" if omitted. Helps agents and UIs communicate
     *  whether a connection is production-ready, in testing, or experimental. */
    stability?: 'stable' | 'beta' | 'dev';
    /** Category grouping for this connection template (e.g., "ai", "messaging").
     *  Matches the subdirectory under src/connections/. Only present on built-in
     *  connection templates; custom connectors may omit it. */
    category?: ConnectionCategory;
    /** Headers to inject automatically into outgoing requests for this route.
     *  These MUST NOT conflict with client-provided headers (request is rejected on conflict).
     *  Values may contain ${VAR} placeholders resolved against this route's secrets. */
    headers?: Record<string, string>;
    /** Secrets available for ${VAR} placeholder resolution in this route only.
     *  Values can be literals or "${ENV_VAR}" references resolved at startup. */
    secrets?: Record<string, string>;
    /** Allowlisted URL patterns (glob). A request must match at least one pattern
     *  in this route's list to use this route. Empty = matches nothing. */
    allowedEndpoints: string[];
    /** Whether to resolve ${VAR} placeholders in request bodies.
     *  Defaults to false — prevents agents from exfiltrating secrets by
     *  writing placeholder strings into API resources and reading them back. */
    resolveSecretsInBody?: boolean;
    /** Optional ingestor configuration for real-time event ingestion.
     *  When present, the remote server can start a long-lived ingestor
     *  (WebSocket, webhook listener, or poller) for this connection. */
    ingestor?: IngestorConfig;
    /** Pre-configured test request for verifying connection credentials.
     *  Must be a non-destructive, read-only endpoint with zero side effects. */
    testConnection?: TestConnectionConfig;
    /** Pre-configured test for verifying ingestor / event listener configuration.
     *  Set to null to explicitly indicate this listener cannot be tested.
     *  Omitted if the connection has no ingestor. */
    testIngestor?: TestIngestorConfig | null;
    /** Schema describing configurable fields for this connection's event listener.
     *  Used by UIs and management tools to render configuration forms.
     *  Only present on connections that have an ingestor. */
    listenerConfig?: ListenerConfigSchema;
}
/** A route after secret/header resolution — used at runtime */
export interface ResolvedRoute {
    /** Connection alias (e.g., "github", "discord-bot"). Populated during caller route resolution. */
    alias?: string;
    /** Human-readable name for this route (carried from config) */
    name?: string;
    /** Short description of this route's purpose (carried from config) */
    description?: string;
    /** Link to API documentation for the service behind this route (carried from config) */
    docsUrl?: string;
    /** URL to an OpenAPI / Swagger spec for this route's API (carried from config) */
    openApiUrl?: string;
    /** Stability level (carried from config) */
    stability?: 'stable' | 'beta' | 'dev';
    /** Category grouping (carried from config) */
    category?: ConnectionCategory;
    headers: Record<string, string>;
    secrets: Record<string, string>;
    allowedEndpoints: string[];
    /** Whether to resolve ${VAR} placeholders in request bodies (default: false) */
    resolveSecretsInBody: boolean;
    /** Pre-configured test request for verifying connection credentials (carried from config) */
    testConnection?: TestConnectionConfig;
    /** Pre-configured test for verifying ingestor / event listener (carried from config) */
    testIngestor?: TestIngestorConfig | null;
    /** Listener configuration schema for UI rendering (carried from config) */
    listenerConfig?: ListenerConfigSchema;
    /** Raw ingestor configuration (carried from config, needed by tool handlers) */
    ingestorConfig?: IngestorConfig;
}
/** Per-connection ingestor overrides (all fields optional — omitted fields inherit from template). */
export interface IngestorOverrides {
    /** Override the Discord Gateway intents bitmask. */
    intents?: number;
    /** Override event type filter (e.g., ["MESSAGE_CREATE"]). Empty array = capture all. */
    eventFilter?: string[];
    /** Only buffer events from these guild IDs. Omitted = all guilds. */
    guildIds?: string[];
    /** Only buffer events from these channel IDs. Omitted = all channels. */
    channelIds?: string[];
    /** Only buffer events from these user IDs. Omitted = all users. */
    userIds?: string[];
    /** Override ring buffer capacity. */
    bufferSize?: number;
    /** Disable the ingestor for this connection entirely. */
    disabled?: boolean;
    /** Override the poll interval in milliseconds (poll ingestors only). */
    intervalMs?: number;
    /** Generic parameter bag for listener configuration.
     *  Keys correspond to ListenerConfigField.key values from the connection's
     *  listenerConfig schema. Values are mapped to typed ingestor config fields
     *  during mergeIngestorConfig(). */
    params?: Record<string, unknown>;
}
/** Per-caller access configuration */
export interface CallerConfig {
    /** Human-readable name for this caller (used in audit logs) */
    name?: string;
    /** List of connection aliases — references built-in templates (e.g., "github")
     *  or custom connector aliases defined in the top-level connectors array. */
    connections: string[];
    /** Per-caller environment variable overrides.
     *  Keys = env var names that connectors reference (e.g., "GITHUB_TOKEN").
     *  Values = "${REAL_ENV_VAR}" (redirect to a different env var) or a literal string (direct injection).
     *  These are resolved first, then checked BEFORE process.env during secret resolution. */
    env?: Record<string, string>;
    /** Per-connection ingestor overrides. Keys are connection aliases (e.g., "discord-bot").
     *  Allows callers to customize intents, event filters, guild/channel/user ID filters,
     *  buffer size, or disable an ingestor without modifying the connection template. */
    ingestorOverrides?: Record<string, IngestorOverrides>;
    /** Multi-instance listener definitions keyed by connection alias.
     *  Value is a map of instanceId → IngestorOverrides.
     *  When present for a connection, spawns one ingestor per instanceId instead of
     *  a single default instance. Takes precedence over ingestorOverrides for that connection.
     *  Instance IDs must match /^[a-zA-Z0-9_-]+$/.
     *
     *  Example:
     *  ```json
     *  {
     *    "trello": {
     *      "project-board": { "params": { "boardId": "abc123" } },
     *      "sprint-board":  { "params": { "boardId": "def456" } }
     *    }
     *  }
     *  ``` */
    listenerInstances?: Record<string, Record<string, IngestorOverrides>>;
    /** Trigger rules that map ingestor events to Claude Code remote trigger invocations.
     *  When an ingestor event matches a rule's criteria (source, event type, filter),
     *  the engine dispatches the event to the configured remote trigger. */
    triggerRules?: TriggerRule[];
}
/** Remote server configuration */
export interface RemoteServerConfig {
    /** Host to bind to */
    host: string;
    /** Port to listen on */
    port: number;
    /** Custom connector definitions — a reusable pool referenced by alias from callers.
     *  Each connector scopes secrets and headers to endpoint patterns. */
    connectors?: Route[];
    /** Per-caller access control. Keys are caller aliases (used in audit logs).
     *  Each caller specifies which connections they can use.
     *  Caller public keys are loaded from keys/callers/<alias>/. */
    callers: Record<string, CallerConfig>;
    /** Rate limit: max requests per minute per session */
    rateLimitPerMinute: number;
}
/**
 * Load the MCP proxy (local) config.
 *
 * Resolution order:
 *   1. proxy.config.json (flat ProxyConfig)
 *   2. config.json → .proxy section (legacy combined format)
 *   3. Built-in defaults
 *
 * Key paths are derived automatically:
 *   - Caller keys: keys/callers/{MCP_KEY_ALIAS || "default"}/
 *   - Server keys: keys/server/
 */
export declare function loadProxyConfig(): ProxyConfig;
/**
 * Resolve the caller key alias for the MCP proxy.
 *
 * Resolution: MCP_KEY_ALIAS env var > "default"
 */
export declare function resolveCallerKeyAlias(): string;
/**
 * Load the remote server config.
 *
 * Resolution order:
 *   1. remote.config.json (flat RemoteServerConfig)
 *   2. config.json → .remote section (legacy combined format)
 *   3. Built-in defaults
 *
 * Legacy configs with `routes`/`authorizedPeersDir`/`connections` are auto-migrated
 * to the caller-centric format with a deprecation warning.
 */
export declare function loadRemoteConfig(): RemoteServerConfig;
export declare function saveProxyConfig(config: ProxyConfig): void;
export declare function saveRemoteConfig(config: RemoteServerConfig): void;
/**
 * Resolve the effective routes for a specific caller.
 *
 * For each connection name in the caller's `connections` list:
 *   1. Check custom connectors (by alias) first
 *   2. Fall back to built-in connection templates (e.g., "github", "stripe")
 *
 * Returns an array of Route objects ready for `resolveRoutes()`.
 */
export declare function resolveCallerRoutes(config: RemoteServerConfig, callerAlias: string): Route[];
/**
 * Replace ${VAR} placeholders in a string with values from a secrets map.
 * Unknown placeholders are left unchanged (with a warning).
 */
export declare function resolvePlaceholders(str: string, secretsMap: Record<string, string>): string;
/**
 * Load secrets from the config's secrets map, resolving from environment
 * variables. Value can be a literal string or "${VAR_NAME}" to read from env.
 *
 * Resolution order for each ${VAR} reference:
 *   1. `envOverrides[VAR]` — caller's explicit env mapping (pre-resolved)
 *   2. `process.env[PREFIX_VAR]` — prefixed env var (e.g., ALICE_GITHUB_TOKEN)
 *   3. Warning if not found (bare process.env fallback intentionally removed
 *      to prevent cross-caller secret leakage)
 *
 * When `callerAlias` is omitted, step 2 is skipped (used for resolving
 * the caller's own env mapping where prefixing doesn't apply).
 */
export declare function resolveSecrets(secretsMap: Record<string, string>, envOverrides?: Record<string, string>, callerAlias?: string): Record<string, string>;
/**
 * Resolve all routes: resolve secrets from env vars, then resolve header
 * placeholders against each route's own resolved secrets.
 *
 * When `envOverrides` is provided, those pre-resolved values are checked
 * before process.env during secret resolution (used for per-caller env).
 *
 * When `callerAlias` is provided, prefixed env vars (e.g., ALICE_GITHUB_TOKEN)
 * are checked as a fallback before giving up on a ${VAR} reference.
 */
export declare function resolveRoutes(routes: Route[], envOverrides?: Record<string, string>, callerAlias?: string): ResolvedRoute[];
//# sourceMappingURL=config.d.ts.map