import type { Options } from "@yanlinglabs/winter-agent-sdk"; import type { RuntimeSdkPeers } from "../sdk.js"; import type { RuntimeDirectory } from "../seams/directory.js"; import type { RuntimeDirectoryEntry } from "../seams/directory-store.js"; import type { PermissionClassLabel } from "../seams/messaging-contract.js"; import type { RouterMessagingAdapter } from "./dispatch.js"; import type { ChildSelectionInput } from "../selection/runtime-selection.js"; import type { AttachedSessionRegistry, AttachedWinterSession } from "./sessions.js"; import type { RunHome, RunHomeFor, RunHomeOutcome } from "../run-home/types.js"; /** * WS-21 §3.1: what the cold resume needs to run on a run home. The ROUTER supplies it (never a host * through `GlobalMessagingOptions`): `apply` is the router's own check-and-apply, bound to its brand and * store, so this path and `query()` cannot apply a run home two different ways. */ export interface WinterColdResumeRunHomes { /** The router was created with `requireRunHome`: no cold resume without a run home. */ require: boolean; runHomeFor?: RunHomeFor; apply(options: Options, runHome: RunHome): Options; record(runId: string, outcome: RunHomeOutcome): void; } export interface WinterMessagingAdapterDeps { peers: RuntimeSdkPeers; directory: RuntimeDirectory; sessions: AttachedSessionRegistry; /** * The `Options` a COLD RESUME is opened with, beside the `resume` the adapter supplies itself. * * A resume needs a cwd, a model, a permission mode — session facts the messaging layer does not * hold and must not invent. Absent means an empty options object, which is a legitimate resume (the * transcript carries the session's own configuration) and is what the hermetic tests use. */ resumeOptions?: (entry: RuntimeDirectoryEntry) => Options | Promise; /** * WS-13c §8 / WS-10's Phase 6.6 amendment: the catalogue a RESUMED CHILD re-resolves against. * * `resumeChildSelection` answers "is the row this child is RECORDED on still servable?" — and a * refusal is `{ status: "unavailable", retryable: false, reason: "child-provider-unavailable: …" }` * WITH NO GENERATION STARTED, which is why the check runs before the parent's facet is touched. * Absent: nothing re-resolves, and the child's own persisted record stands — which is the correct * fallback rather than a silent skip, because WS-13c §8 makes that record authoritative anyway; the * check only detects DRIFT, and a host with no catalogue has nothing to detect it against. */ childResumeContext?: (entry: RuntimeDirectoryEntry) => Omit | undefined; /** * The permission class of a session this process holds no FACET for — the host's own declaration. * * A live facet answers from the session's live permission mode and always wins. This is the fallback * for a session the router drives through a plain input-stream writer, or one it has a record of and * no handle at all: without it every such receiver is `unknown`, and since review r1's D2 made an * unknown receiver FAIL CLOSED (its mail is held until the class is known), a host would have no way * to say what it launched the session with. */ permissionClass?: (entry: RuntimeDirectoryEntry) => Promise | PermissionClassLabel; /** WS-21: the router's run-home door for the cold resume. Set by `createRuntimeSdk`, never by a host. */ runHomes?: WinterColdResumeRunHomes; } /** The adapter plus the one thing the router attaches to it: the live-session registry. */ export interface WinterMessagingAdapter extends RouterMessagingAdapter { readonly sessions: AttachedSessionRegistry; } export declare function createWinterMessagingAdapter(deps: WinterMessagingAdapterDeps): WinterMessagingAdapter;