/** * `host.config.json` schema + I/O. * * This file captures the wizard's output. Subsystems (hosted nodes, NAT, * orchestrator) each own their own files under `/`; this is NOT * an umbrella config. * * Schema version: 3. `version` is a forward guard — a file whose version * does not match `CURRENT_VERSION` is rejected on read rather than * reinterpreted, so a future incompatible layout fails loudly instead of * being silently misread. */ export interface UpdatesConfig { /** When true, the daily-check timer auto-applies updates. Default false. */ autoApply: boolean; /** Optional override for the manifest URL (env var still wins). */ manifestUrl?: string; } /** * Non-secret push (FCM/APNs) settings. The actual private keys (and the FCM * service-account / APNs key identifiers) live in the secret store — see * `src/push/`. Only these app-config bits, which are safe to keep in plaintext * `host.config.json`, are stored here. Absent ⇒ push is not configured. */ export interface PushSettings { /** APNs app-config (the `.p8` private key + key/team ids stay in the secret store). */ apns?: { /** App bundle id → APNs `apns-topic` header. */ bundleId: string; /** `true` → production APNs host; false/undefined → sandbox (dev/TestFlight). */ production?: boolean; }; /** Per-(peer,strand) anti-spam cooldown (ms) forwarded into the node's push block. */ cooldownMs?: number; /** Per-strand burst-coalescing window (ms) forwarded into the node's push block. */ debounceMs?: number; } /** * Which addresses a hosted node's QR code carries (cadre-core's `selectNodeClaimAddresses`). * Absent ⇒ `{ lan: 'auto' }`. Read on every claim-code request, so an edit applies to the * next code shown. */ export interface ClaimAddressSettings { /** * The LAN address a phone at home dials: `'auto'` (the address on the router's subnet, else * the machine's primary one; none in public-IP mode), `'none'` (public addresses only), or an * IP address. Other private addresses (Docker bridges, VPNs) are left out either way. */ lan?: string; /** * Exact addresses to put in every code instead, for an operator who knows better than the * rule, such as one name behind a proxy. Each names no destination peer (a relay address ends * at its `/p2p-circuit` hop); every node's code appends its own peer id. */ addrs?: string[]; } /** Why a `claimAddresses` value is unacceptable, naming the field; undefined when it is fine. */ export declare function claimAddressSettingsProblem(value: unknown): string | undefined; export interface HostConfigFile { version: 3; /** A stable per-install id, for log correlation. */ installId: string; /** Localhost-only management UI + API listener port. */ uiPort: number; /** Self-reference (convenient for service-host ExecStart). */ dataDir: string; /** Whether UPnP/NAT-PMP should be attempted at start time. */ upnpEnabled: boolean; /** ISO timestamp the wizard wrote this file. */ installedAt: string; /** Installer (= package) version that wrote this file. */ installerVersion: string; /** Update-flow settings; defaults: { autoApply: false }. */ updates: UpdatesConfig; /** * Non-secret push settings (bundle id, sandbox/prod toggle, cooldown/debounce). * Optional — absent when push is not configured. Private keys never live here; * they are read from the secret store at node-spawn time (`src/push/`). */ push?: PushSettings; /** Which addresses claim codes carry; absent ⇒ automatic. */ claimAddresses?: ClaimAddressSettings; } export declare function writeHostConfig(filePath: string, cfg: HostConfigFile): void; /** Apply a partial patch to the persisted config (read-modify-write). */ export declare function updateHostConfig(filePath: string, patch: Partial>): HostConfigFile; export declare function readHostConfig(filePath: string): HostConfigFile;