/** * Intake mount builder — the testable factory for the production mount. * * Exports: * buildIntakeMount(ctx, runtimeHandles, cfg) → { launcher, onAccepted, onScaffoldError } * (onScaffoldError comes from scaffold-error-router.ts — the same closure the * production /errors route installs, not a copy of it) * selectScanners(config) → ExternalScannerSpec[] * * This module is the unit-testable seam that index.ts calls; it keeps * index.ts thin and gives the wiring a clean test surface without forking python. */ import type { RuntimeConfig } from "../../runtime/runtime-schema.js"; import type { RuntimeHandle } from "../../runtime/run.js"; import type { Logger } from "../../utils/logger.js"; import type { IntakeContext } from "./intake-context.js"; import type { IntakeSignal } from "./types.js"; import { ScannerLauncher } from "./scanner-launcher.js"; import type { ExternalScannerSpec, SupervisorContract } from "./scanner-launcher.js"; import type { LongRunningSpec } from "../../runtime/supervisor/long-running-supervisor.js"; /** * The base URL the scaffold child POSTs to. The child always reaches the * runtime over loopback regardless of which interface the server binds, so a * wildcard bind host (`0.0.0.0` / `::`) or an empty host is mapped to * `127.0.0.1` — `0.0.0.0` is not a valid connect target on macOS, which would * silently break the supervised intake path under a non-default bind host. */ export declare function intakeUrlFor(host: string, port: number): string; export interface MountConfig { runtimeId: string; wallet: string; /** Already filtered to external scanners with path + entrypoint. */ scanners: ExternalScannerSpec[]; /** Base URL the scaffold POSTs to, e.g. `http://127.0.0.1:`. */ intakeUrl: string; /** Absolute path to the directory that contains the `scaffold/` package. */ scaffoldPackageDir: string; /** Directory where launch-config JSONs are written. */ launchConfigDir: string; logger: Logger; mintScannerId?: () => string; createSupervisor?: (spec: LongRunningSpec, logger: Logger) => SupervisorContract; onSupervisorEvent?: (e: { type: string; pid?: number; [key: string]: unknown; }) => void; supervisorOptions?: Partial; } /** * Build the production launcher + onAccepted closure for one runtime. * * The `onAccepted` closure: * - resolves scanner_id via the shared registry → scannerName + runtimeId, * - looks up the runtime handle, * - maps IntakeSignal → ExternalScannerIngestRequest, * - calls handle.ingestExternalScannerData() fire-and-forget (.catch + log, never throws). * * The `launcher` is a `ScannerLauncher` built over the SHARED IntakeContext so * the route's registry and the launcher's registry are the same object. */ export declare function buildIntakeMount(ctx: IntakeContext, runtimeHandles: Map, cfg: MountConfig): { launcher: ScannerLauncher; onAccepted: (s: IntakeSignal, c: string, id: string) => void; onScaffoldError: (scannerId: string, error: Record) => void; }; /** * Filter a parsed RuntimeConfig to the external scanner specs that should * be supervised by the launcher. * * Returns [] for a config with no external_scanner entries that declare both * `path` and `entrypoint`. Selection is by scanner shape only — `version` is * ignored metadata and never gates supervision. */ export declare function selectScanners(config: RuntimeConfig, baseDir?: string): ExternalScannerSpec[]; /** * Dependencies for the per-runtime launcher factory. * All optional fields are test seams; production uses the injected defaults. */ export interface WireDeps { /** Parsed runtime config (already loaded by the caller). */ runtimeConfig: RuntimeConfig; /** Recipe directory for resolving relative scanner paths; undefined for inline YAML. */ recipeDir: string | undefined; runtimeId: string; wallet: string; /** Shared, already-created intake context (route + launcher share this object). */ sharedCtx: IntakeContext; /** Live handle map the onAccepted closure resolves against. */ runtimeHandles: Map; /** Base URL the scaffold POSTs to, e.g. http://127.0.0.1:. */ intakeUrl: string; /** Absolute path to the dir containing the scaffold/ package. */ scaffoldPackageDir: string; /** Per-runtime state dir; launch-config JSONs go under /scanner-launch. */ runtimeStateDir: string; logger: Logger; mintScannerId?: () => string; createSupervisor?: (spec: LongRunningSpec, logger: Logger) => SupervisorContract; onSupervisorEvent?: (e: { type: string; pid?: number; [k: string]: unknown; }) => void; supervisorOptions?: Partial; /** Injectable orphan sweep; defaults to sweepOrphans in production. */ sweep?: (runtimeId: string, logger: Logger) => void; } /** * Build (do NOT start) the launcher for ONE runtime. * * Returns null for runtimes with no qualifying external scanners. The caller * starts the returned launcher after the API is listening (boot) or immediately * (hot-install, API already listening). * * The launcher's constructor eagerly registers all scanners into sharedCtx.registry * so the route can resolve them before start() is called. start() then spawns * the scaffold children. */ export declare function wireRuntime(deps: WireDeps): ScannerLauncher | null; //# sourceMappingURL=intake-mount.d.ts.map