{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Prompt.ts","../../../src/core/PromptClient.ts","../../../src/core/TerminalManager.ts","../../../src/core/stores/MemoryTerminalStore.ts","../../../src/core/stores/DatabaseTerminalStore.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { PromptRole, PromptTheme } from './types.js'\nimport { CSI, ESC, freezeStyle, STATUS_ICONS } from '@orkestrel/console'\n\n// The constant DATA the pure terminal core reads: key decoding, rendering, and transport defaults.\n// UPPER_SNAKE, `Object.freeze`d, every member exported. Control bytes are built with\n// `String.fromCharCode` so no raw control character appears in source, and the escape lead and the\n// CSI prefix come from `@orkestrel/console`, which publishes both.\n\n// === Control bytes (named, no raw control characters in source)\n\n/** Names the carriage return byte (`\\r`, U+000D) — Enter on most terminals. */\nexport const RETURN = String.fromCharCode(13)\n/** Names the line feed byte (`\\n`, U+000A) — Enter on some terminals / pasted input. */\nexport const NEWLINE = String.fromCharCode(10)\n/** Names the tab byte (`\\t`, U+0009). */\nexport const TAB = String.fromCharCode(9)\n/** Names the backspace byte (BS, U+0008) — Ctrl+H / some terminals' Backspace. */\nexport const BACKSPACE = String.fromCharCode(8)\n/** Names the delete byte (DEL, U+007F) — the usual Backspace byte on a Unix TTY. */\nexport const DELETE = String.fromCharCode(127)\n/** Names the space byte (U+0020). */\nexport const SPACE = ' '\n/** Names the Ctrl+C byte (ETX, U+0003) — interrupt / cancel. */\nexport const CTRL_C = String.fromCharCode(3)\n/** Names the Ctrl+D byte (EOT, U+0004) — end-of-transmission / finish (the editor's commit key). */\nexport const CTRL_D = String.fromCharCode(4)\n/** Names the Ctrl+U byte (NAK, U+0015) — clear the current line. */\nexport const CTRL_U = String.fromCharCode(21)\n/** Names the Ctrl+A byte (SOH, U+0001) — move to start of line. */\nexport const CTRL_A = String.fromCharCode(1)\n/** Names the Ctrl+E byte (ENQ, U+0005) — move to end of line. */\nexport const CTRL_E = String.fromCharCode(5)\n\n/**\n * Names the Single Shift Three lead (`ESCO`) — the alternate arrow-key prefix some terminals emit\n * (`ESC O A`). Built from the console module's own {@link import('@orkestrel/console').ESC}; the\n * navigation keys' CSI lead is that module's {@link import('@orkestrel/console').CSI}, which this\n * package reuses rather than redeclaring.\n */\nexport const KEY_SS3 = `${ESC}O`\n\n/**\n * Holds the exact escape sequence to canonical key name table\n * {@link import('./helpers.js').parseKey} consults for the navigation and editing keys. Covers the\n * CSI form (`ESC[A`…) and the SS3 form (`ESCOA`…) of the arrows, plus the `home` / `end` / `delete`\n * CSI sequences with their numeric-tilde variants. The source of truth for the multi-byte key\n * decode; frozen.\n *\n * @remarks\n * Terminals disagree on these: a cursor key is `ESC[A` (normal) or `ESCOA` (application mode),\n * and Home / End / Delete each have a letter form (`ESC[H` / `ESC[F`) and a numeric form\n * (`ESC[1~` / `ESC[4~` / `ESC[3~`). Every accepted spelling maps to one name so a reducer never\n * sees the wire encoding.\n */\nexport const SEQUENCE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n\t[`${CSI}A`]: 'up',\n\t[`${CSI}B`]: 'down',\n\t[`${CSI}C`]: 'right',\n\t[`${CSI}D`]: 'left',\n\t[`${KEY_SS3}A`]: 'up',\n\t[`${KEY_SS3}B`]: 'down',\n\t[`${KEY_SS3}C`]: 'right',\n\t[`${KEY_SS3}D`]: 'left',\n\t[`${CSI}H`]: 'home',\n\t[`${CSI}F`]: 'end',\n\t[`${CSI}1~`]: 'home',\n\t[`${CSI}4~`]: 'end',\n\t[`${CSI}3~`]: 'delete',\n\t[`${CSI}7~`]: 'home',\n\t[`${CSI}8~`]: 'end',\n})\n\n/**\n * Holds the control byte (or CRLF pair) to key descriptor table\n * {@link import('./helpers.js').parseKey} consults for the one-byte keys and the two-byte CRLF\n * Enter chunk. Each entry carries the canonical `name` and whether it is a `ctrl` combination. The\n * source of truth for that decode; frozen.\n *\n * @remarks\n * `return` / `newline` / `return + newline` all map to `return` (one canonical Enter name) — a\n * terminal or a paste can deliver Enter as `\\r`, `\\n`, or the `\\r\\n` pair in one chunk;\n * `delete` / `backspace` both map to `backspace` (the Backspace bytes); the Ctrl combos\n * (`c` / `d` / `u` / `a` / `e`) carry `ctrl: true` so a reducer can match\n * `key.ctrl && key.name === 'c'`. `escape` / `tab` / `space` are plain named keys.\n */\nexport const CONTROL_NAMES: Readonly<\n\tRecord<string, { readonly name: string; readonly ctrl: boolean }>\n> = Object.freeze({\n\t[RETURN]: Object.freeze({ name: 'return', ctrl: false }),\n\t[NEWLINE]: Object.freeze({ name: 'return', ctrl: false }),\n\t[`${RETURN}${NEWLINE}`]: Object.freeze({ name: 'return', ctrl: false }),\n\t[TAB]: Object.freeze({ name: 'tab', ctrl: false }),\n\t[ESC]: Object.freeze({ name: 'escape', ctrl: false }),\n\t[BACKSPACE]: Object.freeze({ name: 'backspace', ctrl: false }),\n\t[DELETE]: Object.freeze({ name: 'backspace', ctrl: false }),\n\t[SPACE]: Object.freeze({ name: 'space', ctrl: false }),\n\t[CTRL_C]: Object.freeze({ name: 'c', ctrl: true }),\n\t[CTRL_D]: Object.freeze({ name: 'd', ctrl: true }),\n\t[CTRL_U]: Object.freeze({ name: 'u', ctrl: true }),\n\t[CTRL_A]: Object.freeze({ name: 'a', ctrl: true }),\n\t[CTRL_E]: Object.freeze({ name: 'e', ctrl: true }),\n})\n\n// === Prompt defaults\n\n/** Names the default mask glyph {@link import('./helpers.js').createPasswordState} uses — `*`. */\nexport const DEFAULT_MASK = '*'\n\n// === Prompt-view icons\n\n/**\n * Holds the terminal-owned glyphs {@link DEFAULT_PROMPT_THEME} assembles its `icons` from, beside\n * the console module's own success and error marks. Read only when the default theme is assembled;\n * a view reads its resolved theme and never this constant. Frozen.\n *\n * @remarks\n * - `question` — the leading mark on a prompt's message line.\n * - `pointer` — the cursor before the input / the focused choice row.\n * - `dot` / `selected` — an unfocused / focused row marker in a select list.\n * - `checked` / `unchecked` — a checked / unchecked box in a checkbox list.\n */\nexport const PROMPT_ICONS = Object.freeze({\n\tquestion: '?',\n\tpointer: '›',\n\tdot: '○',\n\tselected: '●',\n\tchecked: '☑',\n\tunchecked: '☐',\n})\n\n// === The default prompt theme\n\n/**\n * Holds every {@link import('./types.js').PromptRole}, in one frozen list — the role axis's source of\n * truth. {@link import('./helpers.js').createPromptTheme} walks it to merge a partial theme, and\n * a consumer building a complete role map reads it rather than retyping every name.\n */\nexport const PROMPT_ROLES: readonly PromptRole[] = Object.freeze([\n\t'question',\n\t'pointer',\n\t'message',\n\t'content',\n\t'success',\n\t'error',\n\t'selected',\n\t'focus',\n\t'hint',\n\t'muted',\n\t'description',\n])\n\n/**\n * Holds the {@link import('./types.js').PromptTheme} every prompt renders with unless its options supply\n * another — the glyph set assembled from {@link PROMPT_ICONS} plus the console\n * {@link import('@orkestrel/console').STATUS_ICONS} `success` / `error` marks, and the console\n * {@link import('@orkestrel/console').Style} each role is painted with. Deeply frozen through the\n * console module's own {@link import('@orkestrel/console').freezeStyle}; the baseline\n * {@link import('./helpers.js').createPromptTheme} merges a partial theme over.\n *\n * @remarks\n * The default roles reproduce the views' historical coloring exactly: `question` / `pointer` cyan,\n * `message` / `focus` bold, `success` / `selected` green, `error` red, `hint` / `muted` /\n * `description` dim, and `content` the EMPTY style — an empty style renders bare text, so primary\n * content keeps the bytes it had before it became themeable.\n * Two roles sharing a style today are still two roles — re-mapping one leaves the other alone.\n */\nexport const DEFAULT_PROMPT_THEME: PromptTheme = Object.freeze({\n\ticons: Object.freeze({\n\t\tquestion: PROMPT_ICONS.question,\n\t\tpointer: PROMPT_ICONS.pointer,\n\t\tdot: PROMPT_ICONS.dot,\n\t\tselected: PROMPT_ICONS.selected,\n\t\tchecked: PROMPT_ICONS.checked,\n\t\tunchecked: PROMPT_ICONS.unchecked,\n\t\tsuccess: STATUS_ICONS.success,\n\t\terror: STATUS_ICONS.error,\n\t}),\n\troles: Object.freeze({\n\t\tquestion: freezeStyle({ foreground: 'cyan', attributes: [] }),\n\t\tpointer: freezeStyle({ foreground: 'cyan', attributes: [] }),\n\t\tmessage: freezeStyle({ attributes: ['bold'] }),\n\t\tcontent: freezeStyle({ attributes: [] }),\n\t\tsuccess: freezeStyle({ foreground: 'green', attributes: [] }),\n\t\terror: freezeStyle({ foreground: 'red', attributes: [] }),\n\t\tselected: freezeStyle({ foreground: 'green', attributes: [] }),\n\t\tfocus: freezeStyle({ attributes: ['bold'] }),\n\t\thint: freezeStyle({ attributes: ['dim'] }),\n\t\tmuted: freezeStyle({ attributes: ['dim'] }),\n\t\tdescription: freezeStyle({ attributes: ['dim'] }),\n\t}),\n})\n\n// === Broker + SSE-bridge defaults\n\n/** Holds how long (ms) the {@link import('./types.js').PromptInterface} broker parks an unanswered form before it expires — 5 minutes. */\nexport const DEFAULT_PROMPT_TIMEOUT_MS = 300_000\n\n/** Holds how long (ms) the {@link import('./types.js').PromptClientInterface} waits before each reconnect attempt — 2 seconds. */\nexport const DEFAULT_RECONNECT_DELAY_MS = 2_000\n\n/**\n * Holds the SSE `event:` names the broker emits and the\n * {@link import('./types.js').PromptClientInterface} dispatches on — `pending`, `expire`, and\n * `destroy`. Frozen; the source of truth for the wire event vocabulary.\n *\n * @remarks\n * - `pending` — a serialized {@link import('./types.js').PendingForm} to dispatch and answer.\n * - `expire` — an `{ id }` payload: the broker expired or released a parked form (the client drops it).\n * - `destroy` — the broker is going away; the client disconnects (no auto-reconnect) but stays reusable.\n */\nexport const SSE_EVENTS = Object.freeze({\n\tpending: 'pending',\n\texpire: 'expire',\n\tdestroy: 'destroy',\n})\n\n/**\n * Names the auth-token request header the {@link import('./types.js').PromptClientInterface} sends\n * when a `token` is configured — `x-orkestrel-token`.\n */\nexport const HEADER_TOKEN = 'x-orkestrel-token'\n\n/** Names the `Accept` header value that opens the broker's SSE stream — `text/event-stream`. */\nexport const ACCEPT_EVENT_STREAM = 'text/event-stream'\n\n/**\n * Sets the maximum number of characters the {@link import('./types.js').PromptClientInterface} lets its\n * SSE parser buffer before treating the stream as hostile — 1 MiB, comfortably above any\n * legitimate prompt payload. Passed as the `limit` to `createSSEParser` so an unterminated\n * or oversized `data:` field cannot grow the buffer without bound (a memory-exhaustion guard).\n */\nexport const SSE_BUFFER_LIMIT = 1_048_576\n","import type { TerminalErrorCode } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n// `.claude/rules/typescript.md` § Errors and outcomes: a real error type, not a sentinel. Callers\n// branch on the machine-readable\n// `error.code` rather than parsing the message, and the guard narrows with `instanceof`,\n// mirroring the agents-module errors.\n\n/**\n * Represents the error the terminal surfaces for its own refusals: parking on a destroyed or full broker, an\n * unusable driver stream, a manager routing fault, or a ctrl-c cancellation. A parked form's own\n * lifecycle failures reject through the form's `answer` with the form package's error, never with\n * this one.\n *\n * @remarks\n * Carries a {@link TerminalErrorCode} and an optional `context` bag naming the offending values:\n * `{ cap }` on `LIMIT`, `{ to, known }` on `TARGET`, and `{ from, to, path }` on `DEADLOCK`. Narrow\n * a caught value with {@link isTerminalError} and branch on `error.code`.\n */\nexport class TerminalError extends Error {\n\t/** Holds the machine-readable condition — see {@link TerminalErrorCode}. */\n\treadonly code: TerminalErrorCode\n\t/** Holds an optional context bag naming the offending values — see the class {@link TerminalError remarks}. */\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\t/**\n\t * Builds one terminal refusal.\n\t *\n\t * @param code - The machine-readable {@link TerminalErrorCode} a caller branches on\n\t * @param message - The human-readable reason\n\t * @param context - The optional bag naming the offending values — see the class {@link TerminalError remarks}\n\t */\n\tconstructor(\n\t\tcode: TerminalErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'TerminalError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link TerminalError}, so a caller can branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding or a rejected prompt call)\n * @returns True if `value` is a {@link TerminalError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tawait terminal.ask(form)\n * } catch (error) {\n * \tif (isTerminalError(error) && error.code === 'CANCEL') {\n * \t\t// the person aborted\n * \t}\n * }\n * ```\n */\nexport function isTerminalError(value: unknown): value is TerminalError {\n\treturn isInstance(value, TerminalError)\n}\n","import type { PendingForm, PendingFormStatus, TerminalSnapshot, WireEvent } from './types.js'\nimport type { Guard } from '@orkestrel/contract'\nimport {\n\tisNonEmptyString,\n\tisNumber,\n\tisRecord,\n\tisString,\n\tliteralOf,\n\trecordOf,\n} from '@orkestrel/contract'\n\n/**\n * Narrows an unknown value to a {@link PendingFormStatus}.\n *\n * @param value - The candidate ticket status\n * @returns True if the value is one of the declared ticket statuses; false otherwise\n */\nexport const isPendingFormStatus: Guard<PendingFormStatus> = literalOf(\n\t'pending',\n\t'answered',\n\t'expired',\n)\n\n/**\n * Narrows an unknown wire value to a {@link PendingForm} envelope — the envelope alone, because the\n * form package's `parseForm` owns the schema payload.\n *\n * @remarks\n * This guard checks the transport record and proves only that `schema` is a record. The Form\n * package's `parseForm` owns the schema payload and its semantic audit.\n *\n * @param value - The decoded wire value to inspect\n * @returns True if the value is a complete pending-form envelope; false otherwise\n */\nexport function isPendingForm(value: unknown): value is PendingForm {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isNonEmptyString,\n\t\t\tschema: isRecord,\n\t\t\tstatus: isPendingFormStatus,\n\t\t\ttime: isNumber,\n\t\t\tfrom: isString,\n\t\t\tto: isString,\n\t\t},\n\t\t['from', 'to'],\n\t)(value)\n}\n\n/**\n * Narrows an unknown value to a transport-neutral {@link WireEvent} — the guard a consumer's own\n * transport applies to an inbound frame.\n *\n * @param value - The candidate wire event\n * @returns True if the value carries an event name, serialized data, and an optional id; false otherwise\n */\nexport const isWireEvent: Guard<WireEvent> = recordOf(\n\t{ event: isString, data: isString, id: isString },\n\t['id'],\n)\n\n/**\n * Narrows an unknown value to a {@link TerminalSnapshot} — a non-empty `id` and an optional numeric\n * `timeout`, the read boundary a store applies to an untrusted persisted row.\n *\n * @param value - The candidate snapshot read back from storage\n * @returns True if the value carries a non-empty `id` and an optional numeric `timeout`; false otherwise\n */\nexport const isTerminalSnapshot: Guard<TerminalSnapshot> = recordOf(\n\t{ id: isNonEmptyString, timeout: isNumber },\n\t['timeout'],\n)\n","import type {\n\tCheckboxState,\n\tConfirmState,\n\tEditorState,\n\tFetchInit,\n\tInputState,\n\tKeyEvent,\n\tPasswordState,\n\tPendingForm,\n\tPromptIcon,\n\tPromptRole,\n\tPromptStep,\n\tPromptTheme,\n\tPromptThemeOptions,\n\tSelectState,\n\tTimerCancelFunction,\n\tWireEvent,\n} from './types.js'\nimport type { Style, StylerInterface } from '@orkestrel/console'\nimport type {\n\tCheckboxField,\n\tConfirmField,\n\tEditorField,\n\tFormField,\n\tFormSchema,\n\tPasswordField,\n\tSelectField,\n\tTextField,\n} from '@orkestrel/form'\nimport {\n\tCONTROL_NAMES,\n\tDEFAULT_MASK,\n\tDEFAULT_PROMPT_THEME,\n\tPROMPT_ROLES,\n\tSEQUENCE_NAMES,\n} from './constants.js'\nimport { isError, isString } from '@orkestrel/contract'\nimport { createStyler, freezeStyle, strip, stripControls } from '@orkestrel/console'\n\n// The PURE prompt core implementation — all EXPORTED, all pure, all unit-tested:\n// the key decoder, schema sanitization, per-field view renderers, and the `create*State`\n// factories with their `reduce*` reducers. No `node:*`, no I/O, no events. Form owns validation and\n// settlement; these reducers only turn keys into candidate field values.\n\n// === Key decoding\n\n/**\n * Decodes one keypress's bytes into a {@link KeyEvent} — total, never throws. A `Uint8Array` is\n * read as UTF-8; the resulting string is matched against the known control bytes and the CRLF pair\n * ({@link CONTROL_NAMES}) and escape sequences ({@link SEQUENCE_NAMES}), falling back to a single\n * printable character. An unrecognized sequence carries no `name`, with the raw `sequence`\n * preserved.\n *\n * @remarks\n * - **Single control byte.** A one-character control input (`return` / `backspace` / `tab` /\n *   `escape` / `space`, or a Ctrl combo `c` / `d` / `u` / `a` / `e`), or the two-byte `\\r\\n`\n *   CRLF pair, is looked up in {@link CONTROL_NAMES}, carrying its `ctrl` flag.\n * - **Escape sequence.** A multi-byte ESC sequence (`up` / `down` / `left` / `right` in both the\n *   `ESC[A` and `ESCOA` forms, plus `home` / `end` / `delete`) is looked up in\n *   {@link SEQUENCE_NAMES} and flagged `meta`.\n * - **Printable character.** A single printable character becomes `name` = that character, with\n *   `shift` set when it is an uppercase letter. A multi-code-point printable (an emoji, a pasted\n *   run) keeps its first code point as the name and the whole input as `sequence`.\n * - **Unknown.** Anything else (an unrecognized escape, an empty input) yields an event with NO\n *   `name` — absence, never an empty string — total, so the driver never crashes on a stray byte.\n *\n * @param input - The raw keypress bytes, as a string or `Uint8Array`\n * @returns The decoded {@link KeyEvent}\n *\n * @example\n * ```ts\n * parseKey('\\r')        // { name: 'return', sequence: '\\r', ctrl: false, meta: false, shift: false }\n * parseKey('\\r\\n')      // { name: 'return', sequence: '\\r\\n', ctrl: false, meta: false, shift: false }\n * parseKey('\\x1b[A')    // { name: 'up', sequence: '\\x1b[A', ctrl: false, meta: true, shift: false }\n * parseKey('A')         // { name: 'A', sequence: 'A', ctrl: false, meta: false, shift: true }\n * parseKey('\\x03')      // { name: 'c', sequence: '\\x03', ctrl: true, meta: false, shift: false }\n * ```\n */\nexport function parseKey(input: string | Uint8Array): KeyEvent {\n\tconst sequence = isString(input) ? input : new TextDecoder().decode(input)\n\n\t// A known multi-byte escape sequence (arrows / home / end / delete) — flagged `meta`.\n\tconst sequenceName = SEQUENCE_NAMES[sequence]\n\tif (sequenceName !== undefined) {\n\t\treturn { name: sequenceName, sequence, ctrl: false, meta: true, shift: false }\n\t}\n\n\t// A known single control byte (return / backspace / tab / escape / space / a ctrl combo),\n\t// or the two-byte CRLF pair.\n\tconst control = CONTROL_NAMES[sequence]\n\tif (control !== undefined) {\n\t\treturn { name: control.name, sequence, ctrl: control.ctrl, meta: false, shift: false }\n\t}\n\n\t// A printable character — one or more code points, the first naming the key.\n\tconst points = [...sequence]\n\tconst first = points[0]\n\tif (first !== undefined && isPrintable(first)) {\n\t\treturn { name: first, sequence, ctrl: false, meta: false, shift: first !== first.toLowerCase() }\n\t}\n\n\t// Anything else (an unrecognized escape, an empty input) — total, never a throw. The name is\n\t// OMITTED rather than emptied, so a caller reads absence instead of a sentinel.\n\treturn { sequence, ctrl: false, meta: false, shift: false }\n}\n\n/**\n * Checks whether a single character is printable — the fallback test {@link parseKey} applies after\n * the control bytes and the escape sequences, so the C0 controls and DEL are excluded.\n *\n * @param character - The single character to test\n * @returns True if the character is at or above space and is not DEL; false otherwise\n */\nexport function isPrintable(character: string): boolean {\n\tif (character.length === 0) return false\n\tconst code = character.codePointAt(0)\n\tif (code === undefined) return false\n\t// Exclude the C0 controls (0–31) and DEL (127); everything at or above space is printable.\n\treturn code >= 32 && code !== 127\n}\n\n// === Prompt theme\n\n/**\n * Builds a complete {@link PromptTheme} by merging a partial one over\n * {@link DEFAULT_PROMPT_THEME}, leaf by leaf — each supplied icon replaces that glyph, each\n * supplied role replaces that {@link Style}, and everything else keeps its default. Each supplied\n * style is snapshotted through the console module's own\n * {@link import('@orkestrel/console').freezeStyle}, so the result is deeply frozen and a caller\n * mutating its own attribute list afterwards cannot reach into a built theme.\n *\n * @param options - The partial theme to merge, or `undefined` for the defaults\n * @returns The resolved, deeply frozen theme every prompt state carries\n *\n * @example\n * ```ts\n * createPromptTheme() // the defaults\n * createPromptTheme({\n * \ticons: { pointer: '=>' },\n * \troles: { message: { foreground: 'magenta', attributes: ['bold'] } },\n * })\n * ```\n */\nexport function createPromptTheme(options?: PromptThemeOptions): PromptTheme {\n\tconst icons: Record<PromptIcon, string> = { ...DEFAULT_PROMPT_THEME.icons, ...options?.icons }\n\tconst roles: Record<PromptRole, Style> = { ...DEFAULT_PROMPT_THEME.roles }\n\tfor (const role of PROMPT_ROLES) {\n\t\tconst style = options?.roles?.[role]\n\t\tif (style !== undefined) roles[role] = freezeStyle(style)\n\t}\n\treturn Object.freeze({ icons: Object.freeze(icons), roles: Object.freeze(roles) })\n}\n\n/**\n * Sanitizes text for one single-line display slot. Composes console's ANSI {@link strip} and C0\n * {@link stripControls} passes with removal of tab, line feed, and carriage return.\n *\n * @param text - The text to sanitize for a glyph or hint slot\n * @returns The text with ANSI sequences, every C0 control character, and DEL removed\n *\n * @example\n * ```ts\n * sanitizeDisplayText('Q\\rOVERWRITE\\nNEXT\\tX') // 'QOVERWRITENEXTX'\n * ```\n */\nexport function sanitizeDisplayText(text: string): string {\n\treturn stripControls(strip(text)).replaceAll('\\t', '').replaceAll('\\n', '').replaceAll('\\r', '')\n}\n\n/**\n * Sanitizes every terminal-readable string in a parsed form schema, keeping every identity and\n * answer string verbatim and dropping field metadata.\n *\n * @remarks\n * Display strings pass through {@link sanitizeDisplayText}: labels, help, placeholders, masks,\n * choice labels and help, file accept entries, and pattern sources. Identity and answer strings\n * stay verbatim: schema, group, and field names, group references, choice values, and defaults.\n * Rewriting those would sever the rendering copy from the authoritative form. Field metadata is\n * removed because terminal neither renders nor interprets it. Pattern sources are sanitized as\n * text only and are never compiled or executed here.\n *\n * @param schema - A schema already accepted by the Form package's `parseForm`\n * @returns A new schema with terminal-readable strings sanitized and field metadata omitted\n *\n * @example\n * ```ts\n * sanitizeSchema({ fields: [{ control: 'text', name: 'na\\u001bme', label: 'N\\u0000ame' }] })\n * // { fields: [{ control: 'text', name: 'na\\u001bme', label: 'Name' }] }\n * ```\n */\nexport function sanitizeSchema(schema: FormSchema): FormSchema {\n\tconst groups = schema.groups?.map((group) => ({\n\t\tname: group.name,\n\t\tlabel: sanitizeDisplayText(group.label),\n\t\t...(group.help !== undefined ? { help: sanitizeDisplayText(group.help) } : {}),\n\t}))\n\tconst fields: FormField[] = []\n\tfor (const source of schema.fields) {\n\t\tconst { meta: _meta, ...field } = source\n\t\tconst rule =\n\t\t\tfield.rule === undefined\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\t...field.rule,\n\t\t\t\t\t\t...(field.rule.pattern !== undefined\n\t\t\t\t\t\t\t? { pattern: sanitizeDisplayText(field.rule.pattern) }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t}\n\t\tconst shared = {\n\t\t\tname: field.name,\n\t\t\t...(field.label !== undefined ? { label: sanitizeDisplayText(field.label) } : {}),\n\t\t\t...(field.help !== undefined ? { help: sanitizeDisplayText(field.help) } : {}),\n\t\t\t...(field.group !== undefined ? { group: field.group } : {}),\n\t\t\t...(rule !== undefined ? { rule } : {}),\n\t\t}\n\n\t\tswitch (field.control) {\n\t\t\tcase 'text':\n\t\t\tcase 'editor':\n\t\t\tcase 'number': {\n\t\t\t\tfields.push({\n\t\t\t\t\t...field,\n\t\t\t\t\t...shared,\n\t\t\t\t\t...(field.placeholder !== undefined\n\t\t\t\t\t\t? { placeholder: sanitizeDisplayText(field.placeholder) }\n\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'password': {\n\t\t\t\tfields.push({\n\t\t\t\t\t...field,\n\t\t\t\t\t...shared,\n\t\t\t\t\t...(field.mask !== undefined ? { mask: sanitizeDisplayText(field.mask) } : {}),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'date':\n\t\t\tcase 'time':\n\t\t\tcase 'datetime':\n\t\t\tcase 'color':\n\t\t\tcase 'confirm': {\n\t\t\t\tfields.push({\n\t\t\t\t\t...field,\n\t\t\t\t\t...shared,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'select':\n\t\t\tcase 'checkbox': {\n\t\t\t\tfields.push({\n\t\t\t\t\t...field,\n\t\t\t\t\t...shared,\n\t\t\t\t\tchoices: field.choices.map((choice) => ({\n\t\t\t\t\t\t...choice,\n\t\t\t\t\t\tvalue: choice.value,\n\t\t\t\t\t\tlabel: sanitizeDisplayText(choice.label),\n\t\t\t\t\t\t...(choice.help !== undefined ? { help: sanitizeDisplayText(choice.help) } : {}),\n\t\t\t\t\t})),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'file': {\n\t\t\t\tfields.push({\n\t\t\t\t\t...field,\n\t\t\t\t\t...shared,\n\t\t\t\t\t...(field.accept !== undefined ? { accept: field.accept.map(sanitizeDisplayText) } : {}),\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\t...(schema.name !== undefined ? { name: schema.name } : {}),\n\t\t...(schema.label !== undefined ? { label: sanitizeDisplayText(schema.label) } : {}),\n\t\t...(schema.help !== undefined ? { help: sanitizeDisplayText(schema.help) } : {}),\n\t\t...(groups !== undefined ? { groups } : {}),\n\t\tfields,\n\t}\n}\n\n/**\n * Sanitizes every glyph a wire-supplied {@link PromptThemeOptions} carries for a single-line display\n * slot. Only the icons need it: a role is guard-narrowed to a console {@link Style}, whose colors\n * and attributes are fixed name sets, so no role can carry a byte a terminal would act on.\n *\n * @param theme - The narrowed theme options a remote prompt supplied\n * @returns The same theme with every supplied glyph sanitized for a single-line display slot\n */\nexport function sanitizeThemeIcons(theme: PromptThemeOptions): PromptThemeOptions {\n\tconst icons = theme.icons\n\tif (icons === undefined) return theme\n\tconst sanitized: Record<string, string> = {}\n\tfor (const [icon, glyph] of Object.entries(icons)) sanitized[icon] = sanitizeDisplayText(glyph)\n\treturn { ...theme, icons: sanitized }\n}\n\n// === Shared view helpers\n\n/**\n * Renders the styled question header (`? message`) — the leading line every active prompt view\n * shares, themed by the `question` + `message` roles.\n *\n * @param styler - The console styler that renders each role\n * @param theme - The resolved prompt theme\n * @param message - The prompt's question text\n * @returns The rendered question header\n */\nexport function renderPromptHeader(\n\tstyler: StylerInterface,\n\ttheme: PromptTheme,\n\tmessage: string,\n): string {\n\treturn `${styler.render(theme.roles.question, theme.icons.question)} ${styler.render(theme.roles.message, message)}`\n}\n\n/**\n * Renders a question header followed by a key hint painted with the `hint` role, or the header\n * alone when no hint is supplied.\n *\n * @param styler - The console styler that renders each role\n * @param theme - The resolved prompt theme\n * @param message - The prompt's question text\n * @param hint - The optional key hint to append\n * @returns The rendered header with the optional hint\n */\nexport function renderHintedHeader(\n\tstyler: StylerInterface,\n\ttheme: PromptTheme,\n\tmessage: string,\n\thint?: string,\n): string {\n\tconst head = renderPromptHeader(styler, theme, message)\n\treturn hint === undefined ? head : `${head} ${styler.render(theme.roles.hint, hint)}`\n}\n\n/**\n * Renders the styled submit line (`✔ message`) — the committed header an interactive prompt shows\n * after it resolves, themed by the `success` + `message` roles.\n *\n * @param styler - The console styler that renders each role\n * @param theme - The resolved prompt theme\n * @param message - The settled prompt's question text\n * @returns The rendered committed header\n */\nexport function renderSubmitHeader(\n\tstyler: StylerInterface,\n\ttheme: PromptTheme,\n\tmessage: string,\n): string {\n\treturn `${styler.render(theme.roles.success, theme.icons.success)} ${styler.render(theme.roles.message, message)}`\n}\n\n/**\n * Renders the styled failure line (`✖ message`) a form driver writes for each refused field before\n * it asks that field again.\n *\n * @param styler - The console styler that renders each role\n * @param theme - The resolved prompt theme\n * @param message - The failure text, normally the field's label and the reason\n * @returns The rendered failure line\n */\nexport function renderErrorLine(\n\tstyler: StylerInterface,\n\ttheme: PromptTheme,\n\tmessage: string,\n): string {\n\treturn `${styler.render(theme.roles.error, theme.icons.error)} ${styler.render(theme.roles.error, message)}`\n}\n\n// === Input prompt\n\n/**\n * Builds the initial text-field reducer state — the sanitized label, the declared default, the\n * styler, and the resolved theme.\n *\n * @param field - The text field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createInputState(\n\tfield: TextField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): InputState {\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tdefault: field.default ?? '',\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t\tvalue: '',\n\t}\n}\n\n/**\n * Renders a text-field reducer state as a styled view — the header, the pointer, and the typed\n * value, or the default shown as a hint while nothing is typed.\n *\n * @param state - The text field's current reducer state\n * @returns The rendered single-line view — header, pointer, and the typed value or the default\n */\nexport function renderInputView(state: InputState): string {\n\tconst content = state.value.length > 0 ? state.value : state.default\n\tconst role = state.value.length > 0 ? state.theme.roles.content : state.theme.roles.hint\n\tconst shown = state.styler.render(role, sanitizeDisplayText(content))\n\treturn `${renderPromptHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.pointer, state.theme.icons.pointer)} ${shown}`\n}\n\n/**\n * Advances an input prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`\n * reducer. Printable characters extend the value; backspace shrinks it; ctrl-u clears it; ctrl-c\n * cancels; return produces the candidate value, with an empty line falling back to the default.\n *\n * @param state - The text field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the new state, the rendered view, the status, and the value on submit\n */\nexport function reduceInput(state: InputState, key: KeyEvent): PromptStep<string, InputState> {\n\tif (key.ctrl && key.name === 'c') return { state, view: renderInputView(state), status: 'cancel' }\n\n\tif (key.name === 'return') {\n\t\tconst answer = state.value.length > 0 ? state.value : state.default\n\t\tconst next = { ...state, value: answer }\n\t\treturn {\n\t\t\tstate: next,\n\t\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, sanitizeDisplayText(answer))}`,\n\t\t\tstatus: 'submit',\n\t\t\tvalue: answer,\n\t\t}\n\t}\n\n\tconst value = editLine(state.value, key)\n\tif (value === undefined) return { state, view: renderInputView(state), status: 'active' }\n\tconst next = { ...state, value }\n\treturn { state: next, view: renderInputView(next), status: 'active' }\n}\n\n// === Password prompt\n\n/**\n * Builds the initial password-field reducer state — the text-field state, plus the mask glyph each\n * typed character renders as.\n *\n * @param field - The password field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createPasswordState(\n\tfield: PasswordField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): PasswordState {\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tmask: sanitizeDisplayText(field.mask ?? DEFAULT_MASK),\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t\tvalue: '',\n\t}\n}\n\n/**\n * Renders a password-field reducer state as a styled view, with the value replaced by the mask\n * repeated so the secret is never echoed.\n *\n * @param state - The password field's current reducer state\n * @returns The rendered view, with the mask repeated in place of the typed value\n */\nexport function renderPasswordView(state: PasswordState): string {\n\tconst masked = state.styler.render(\n\t\tstate.theme.roles.content,\n\t\tstate.mask.repeat(state.value.length),\n\t)\n\treturn `${renderPromptHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.pointer, state.theme.icons.pointer)} ${masked}`\n}\n\n/**\n * Advances a password prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`\n * reducer. Identical line-editing to {@link reduceInput} (printable extends, backspace shrinks,\n * ctrl-u clears, ctrl-c cancels) but the view masks the value. Return produces the candidate value.\n *\n * @param state - The password field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the new state, the masked view, the status, and the value on submit\n */\nexport function reducePassword(\n\tstate: PasswordState,\n\tkey: KeyEvent,\n): PromptStep<string, PasswordState> {\n\tif (key.ctrl && key.name === 'c')\n\t\treturn { state, view: renderPasswordView(state), status: 'cancel' }\n\n\tif (key.name === 'return') {\n\t\treturn {\n\t\t\tstate,\n\t\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, state.mask.repeat(state.value.length))}`,\n\t\t\tstatus: 'submit',\n\t\t\tvalue: state.value,\n\t\t}\n\t}\n\n\tconst value = editLine(state.value, key)\n\tif (value === undefined) return { state, view: renderPasswordView(state), status: 'active' }\n\tconst next = { ...state, value }\n\treturn { state: next, view: renderPasswordView(next), status: 'active' }\n}\n\n// === Confirm prompt\n\n/**\n * Builds the initial confirm-field reducer state — the sanitized label and the declared default\n * answer.\n *\n * @param field - The confirm field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createConfirmState(\n\tfield: ConfirmField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): ConfirmState {\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tdefault: field.default ?? false,\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t}\n}\n\n/**\n * Renders a confirm-field reducer state as a styled view — the header and the yes/no group, with\n * the default letter capitalized and painted by the `selected` role.\n *\n * @param state - The confirm field's current reducer state\n * @returns The rendered view — the header and the yes/no group with the default capitalized\n */\nexport function renderConfirmView(state: ConfirmState): string {\n\tconst head = renderPromptHeader(state.styler, state.theme, state.message)\n\tconst answer = state.default\n\t\t? `${state.styler.render(state.theme.roles.selected, 'Y')}${state.styler.render(state.theme.roles.hint, '/n')}`\n\t\t: `${state.styler.render(state.theme.roles.hint, 'y/')}${state.styler.render(state.theme.roles.selected, 'N')}`\n\treturn `${head} ${state.styler.render(state.theme.roles.hint, '(')}${answer}${state.styler.render(state.theme.roles.hint, ')')}`\n}\n\n/**\n * Advances a confirm prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<boolean>`\n * reducer. `y` / `Y` submits `true`, `n` / `N` submits `false`, return on an empty line submits\n * the `default`, ctrl-c cancels; any other key is ignored (stays active).\n *\n * @param state - The confirm field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the state, the rendered view, the status, and the answer on submit\n */\nexport function reduceConfirm(\n\tstate: ConfirmState,\n\tkey: KeyEvent,\n): PromptStep<boolean, ConfirmState> {\n\tif (key.ctrl && key.name === 'c')\n\t\treturn { state, view: renderConfirmView(state), status: 'cancel' }\n\n\tlet answer: boolean | undefined\n\tconst choice = key.name?.toLowerCase()\n\tif (key.name === 'return') answer = state.default\n\telse if (choice === 'y') answer = true\n\telse if (choice === 'n') answer = false\n\n\tif (answer === undefined) return { state, view: renderConfirmView(state), status: 'active' }\n\treturn {\n\t\tstate,\n\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, answer ? 'yes' : 'no')}`,\n\t\tstatus: 'submit',\n\t\tvalue: answer,\n\t}\n}\n\n// === Select prompt\n\n/**\n * Builds the initial select-field reducer state — the offered choices, with the focus pre-placed on\n * the declared default.\n *\n * @param field - The select field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createSelectState(\n\tfield: SelectField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): SelectState {\n\tconst choices = [...field.choices]\n\tconst index = choices.findIndex((choice) => choice.value === field.default)\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tchoices,\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t\tfocused: index >= 0 ? index : 0,\n\t}\n}\n\n/**\n * Renders a select-field reducer state as a multi-line styled view — one row per choice, with the\n * focused row marked and its help shown.\n *\n * @param state - The select field's current reducer state\n * @returns The rendered view — the header, then one row per choice with the focused row marked\n */\nexport function renderSelectView(state: SelectState): string {\n\tconst lines = state.choices.map((choice, index) => {\n\t\tconst active = index === state.focused\n\t\tconst pointer = active\n\t\t\t? state.styler.render(state.theme.roles.pointer, state.theme.icons.pointer)\n\t\t\t: ' '\n\t\tconst marker = active\n\t\t\t? state.styler.render(state.theme.roles.selected, state.theme.icons.selected)\n\t\t\t: state.styler.render(state.theme.roles.muted, state.theme.icons.dot)\n\t\tconst label = active\n\t\t\t? state.styler.render(state.theme.roles.focus, choice.label)\n\t\t\t: state.styler.render(state.theme.roles.content, choice.label)\n\t\tconst description =\n\t\t\tchoice.help === undefined\n\t\t\t\t? ''\n\t\t\t\t: `  ${state.styler.render(state.theme.roles.description, choice.help)}`\n\t\treturn `${pointer} ${marker} ${label}${description}`\n\t})\n\treturn [renderPromptHeader(state.styler, state.theme, state.message), ...lines].join('\\n')\n}\n\n/**\n * Advances a select prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`\n * reducer. `up` / `down` (and `k` / `j`) move the focus, wrapping at the ends; return submits the\n * focused choice's `value`; ctrl-c cancels. An empty choice list can never submit (a higher layer\n * guards against it); any other key is ignored.\n *\n * @param state - The select field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the state, the rendered view, the status, and the chosen value on submit\n */\nexport function reduceSelect(state: SelectState, key: KeyEvent): PromptStep<string, SelectState> {\n\tif (key.ctrl && key.name === 'c')\n\t\treturn { state, view: renderSelectView(state), status: 'cancel' }\n\n\tconst count = state.choices.length\n\tif (count === 0) return { state, view: renderSelectView(state), status: 'active' }\n\n\tif (key.name === 'up' || key.name === 'k') {\n\t\tconst next = { ...state, focused: (state.focused - 1 + count) % count }\n\t\treturn { state: next, view: renderSelectView(next), status: 'active' }\n\t}\n\tif (key.name === 'down' || key.name === 'j') {\n\t\tconst next = { ...state, focused: (state.focused + 1) % count }\n\t\treturn { state: next, view: renderSelectView(next), status: 'active' }\n\t}\n\tif (key.name === 'return') {\n\t\tconst choice = state.choices[state.focused]\n\t\tconst value = choice?.value ?? ''\n\t\treturn {\n\t\t\tstate,\n\t\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, choice?.label ?? '')}`,\n\t\t\tstatus: 'submit',\n\t\t\tvalue,\n\t\t}\n\t}\n\treturn { state, view: renderSelectView(state), status: 'active' }\n}\n\n// === Checkbox prompt\n\n/**\n * Builds the initial checkbox-field reducer state — the offered choices, with every value in the\n * field's `default` list pre-checked.\n *\n * @param field - The checkbox field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createCheckboxState(\n\tfield: CheckboxField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): CheckboxState {\n\tconst choices = [...field.choices]\n\tconst checked: readonly number[] = choices.reduce<number[]>((indices, choice, index) => {\n\t\tif (field.default?.includes(choice.value) === true) indices.push(index)\n\t\treturn indices\n\t}, [])\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tchoices,\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t\tfocused: 0,\n\t\tchecked,\n\t}\n}\n\n/**\n * Renders a checkbox-field reducer state as a multi-line styled view — one box per choice, and the\n * selected count beneath them.\n *\n * @param state - The checkbox field's current reducer state\n * @returns The rendered view — the header, one box per choice, and the selected count\n */\nexport function renderCheckboxView(state: CheckboxState): string {\n\tconst lines = state.choices.map((choice, index) => {\n\t\tconst active = index === state.focused\n\t\tconst ticked = state.checked.includes(index)\n\t\tconst pointer = active\n\t\t\t? state.styler.render(state.theme.roles.pointer, state.theme.icons.pointer)\n\t\t\t: ' '\n\t\tconst box = ticked\n\t\t\t? state.styler.render(state.theme.roles.selected, state.theme.icons.checked)\n\t\t\t: state.styler.render(state.theme.roles.muted, state.theme.icons.unchecked)\n\t\tconst label = active\n\t\t\t? state.styler.render(state.theme.roles.focus, choice.label)\n\t\t\t: state.styler.render(state.theme.roles.content, choice.label)\n\t\tconst description =\n\t\t\tchoice.help === undefined\n\t\t\t\t? ''\n\t\t\t\t: `  ${state.styler.render(state.theme.roles.description, choice.help)}`\n\t\treturn `${pointer} ${box} ${label}${description}`\n\t})\n\tconst summary = state.styler.render(state.theme.roles.hint, `${state.checked.length} selected`)\n\tconst body = [\n\t\trenderPromptHeader(state.styler, state.theme, state.message),\n\t\t...lines,\n\t\tsummary,\n\t].join('\\n')\n\treturn body\n}\n\n/**\n * Advances a checkbox prompt by one {@link KeyEvent} — the pure\n * `(state, key) → PromptStep<readonly string[]>` reducer. `up` / `down` (and `k` / `j`) move the\n * focus (wrapping); `space` toggles the focused index in the checked set; return submits the\n * checked values in choice order; ctrl-c cancels. The form applies selection-count rules.\n *\n * @param state - The checkbox field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the state, the rendered view, the status, and the ticked values on submit\n */\nexport function reduceCheckbox(\n\tstate: CheckboxState,\n\tkey: KeyEvent,\n): PromptStep<readonly string[], CheckboxState> {\n\tif (key.ctrl && key.name === 'c')\n\t\treturn { state, view: renderCheckboxView(state), status: 'cancel' }\n\n\tconst count = state.choices.length\n\n\tif ((key.name === 'up' || key.name === 'k') && count > 0) {\n\t\tconst next = {\n\t\t\t...state,\n\t\t\tfocused: (state.focused - 1 + count) % count,\n\t\t}\n\t\treturn { state: next, view: renderCheckboxView(next), status: 'active' }\n\t}\n\tif ((key.name === 'down' || key.name === 'j') && count > 0) {\n\t\tconst next = { ...state, focused: (state.focused + 1) % count }\n\t\treturn { state: next, view: renderCheckboxView(next), status: 'active' }\n\t}\n\tif (key.name === 'space' && count > 0) {\n\t\tconst checked = toggleIndex(state.checked, state.focused)\n\t\tconst next = { ...state, checked }\n\t\treturn { state: next, view: renderCheckboxView(next), status: 'active' }\n\t}\n\tif (key.name === 'return') {\n\t\tconst ordered = [...state.checked].sort((a, b) => a - b)\n\t\tconst values = ordered\n\t\t\t.map((index) => state.choices[index]?.value)\n\t\t\t.filter((value): value is string => value !== undefined)\n\t\tconst summary = ordered\n\t\t\t.map((index) => state.choices[index]?.label)\n\t\t\t.filter((name): name is string => name !== undefined)\n\t\t\t.join(', ')\n\t\treturn {\n\t\t\tstate,\n\t\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, summary)}`,\n\t\t\tstatus: 'submit',\n\t\t\tvalue: values,\n\t\t}\n\t}\n\treturn { state, view: renderCheckboxView(state), status: 'active' }\n}\n\n/**\n * Toggles `index` in a readonly index list — copy-on-write, returning the new sorted-by-insertion\n * list; the primitive {@link reduceCheckbox} calls.\n *\n * @param indices - The ticked indices, in tick order\n * @param index - The index to add when absent, or drop when present\n * @returns A new list carrying the toggled membership; the input is never mutated\n */\nexport function toggleIndex(indices: readonly number[], index: number): readonly number[] {\n\treturn indices.includes(index) ? indices.filter((i) => i !== index) : [...indices, index]\n}\n\n// === Editor prompt\n\n/**\n * Builds the initial editor-field reducer state — the committed lines empty, and the declared\n * default held for a finish with nothing typed.\n *\n * @param field - The editor field to render\n * @param styler - The styler used to render the view\n * @param theme - The optional terminal theme\n * @returns The initial immutable key state\n */\nexport function createEditorState(\n\tfield: EditorField,\n\tstyler: StylerInterface = createStyler(),\n\ttheme?: PromptThemeOptions,\n): EditorState {\n\tconst lines: readonly string[] = []\n\treturn {\n\t\tmessage: sanitizeDisplayText(field.label ?? field.name),\n\t\tdefault: field.default ?? '',\n\t\tstyler,\n\t\ttheme: createPromptTheme(theme),\n\t\tlines,\n\t\tcurrent: '',\n\t}\n}\n\n/**\n * Renders an editor-field reducer state as a multi-line styled view — the finish hint, the\n * committed lines, and the line in progress.\n *\n * @param state - The editor field's current reducer state\n * @returns The rendered view — the hinted header, the committed lines, and the line in progress\n */\nexport function renderEditorView(state: EditorState): string {\n\tconst head = renderHintedHeader(state.styler, state.theme, state.message, '(Ctrl+D to finish)')\n\tconst pointer = state.styler.render(state.theme.roles.pointer, state.theme.icons.pointer)\n\tconst committed = state.lines.map((line) => state.styler.render(state.theme.roles.content, line))\n\tconst body = [\n\t\t...committed,\n\t\t`${pointer} ${state.styler.render(state.theme.roles.content, state.current)}`,\n\t]\n\treturn [head, ...body].join('\\n')\n}\n\n/**\n * Advances an editor prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`\n * reducer. Printable characters extend the current line; backspace shrinks it; return commits the\n * current line and starts a fresh one; ctrl-d finishes, joining every line and falling back to the\n * default when empty; ctrl-c cancels. The form validates the candidate after the driver fills it.\n *\n * @param state - The editor field's current reducer state\n * @param key - The decoded keypress to apply\n * @returns The next step — the state, the rendered view, the status, and the joined text on submit\n */\nexport function reduceEditor(state: EditorState, key: KeyEvent): PromptStep<string, EditorState> {\n\tif (key.ctrl && key.name === 'c')\n\t\treturn { state, view: renderEditorView(state), status: 'cancel' }\n\n\tif (key.ctrl && key.name === 'd') {\n\t\tconst lines = state.current.length > 0 ? [...state.lines, state.current] : state.lines\n\t\tconst joined = lines.join('\\n')\n\t\tconst answer = joined.length > 0 ? joined : state.default\n\t\treturn {\n\t\t\tstate,\n\t\t\tview: `${renderSubmitHeader(state.styler, state.theme, state.message)} ${state.styler.render(state.theme.roles.hint, `${String(lines.length)} line${lines.length === 1 ? '' : 's'}`)}`,\n\t\t\tstatus: 'submit',\n\t\t\tvalue: answer,\n\t\t}\n\t}\n\n\tif (key.name === 'return') {\n\t\tconst next = {\n\t\t\t...state,\n\t\t\tlines: [...state.lines, state.current],\n\t\t\tcurrent: '',\n\t\t}\n\t\treturn { state: next, view: renderEditorView(next), status: 'active' }\n\t}\n\n\tconst current = editLine(state.current, key)\n\tif (current === undefined) return { state, view: renderEditorView(state), status: 'active' }\n\tconst next = { ...state, current }\n\treturn { state: next, view: renderEditorView(next), status: 'active' }\n}\n\n// === Shared reducer helpers\n\n/**\n * Applies a single line-editing {@link KeyEvent} to a text buffer — the editing shared by input,\n * password, and editor. A printable key appends its character; `backspace` drops the last\n * character; `space` appends a space; ctrl-u clears the line; a key that edits nothing returns\n * `undefined`.\n *\n * @param value - The buffer the field holds so far\n * @param key - The decoded keypress to apply\n * @returns The new buffer, or `undefined` when the key does not edit the line, so the caller can\n *   leave the state untouched\n */\nexport function editLine(value: string, key: KeyEvent): string | undefined {\n\tif (key.ctrl && key.name === 'u') return ''\n\tif (key.name === 'backspace') return value.slice(0, -1)\n\tif (key.name === 'space') return `${value} `\n\t// A printable key that is not a control / navigation key — `name` is the literal character, and an\n\t// undecoded key carries none at all. Count CODE POINTS (not UTF-16 units) so an astral printable\n\t// (an emoji, a surrogate pair — `name.length` 2 but ONE code point) appends instead of being\n\t// dropped, while a multi-char control name (`up`, `return`) is still rejected.\n\tif (\n\t\t!key.ctrl &&\n\t\t!key.meta &&\n\t\tkey.name !== undefined &&\n\t\t[...key.name].length === 1 &&\n\t\tisPrintable(key.name)\n\t) {\n\t\treturn `${value}${key.sequence}`\n\t}\n\treturn undefined\n}\n\n// === Broker + bridge wiring helpers\n\n/**\n * Implements the default {@link import('./types.js').TimerHandler} — a thin host `setTimeout` / `clearTimeout`\n * wrapper that arms `callback` after `ms` and returns a {@link TimerCancelFunction}. The deadline seam\n * behind both the {@link import('./Prompt.js').Prompt} broker (its expiry) and the\n * {@link import('./PromptClient.js').PromptClient} (its reconnect backoff); a test injects a\n * deterministic timer instead, so neither entity touches real time.\n *\n * @param callback - The deadline callback to arm\n * @param ms - How long to wait before firing it, in milliseconds\n * @returns The {@link TimerCancelFunction} that clears the armed deadline\n */\nexport function defaultTimer(callback: () => void, ms: number): TimerCancelFunction {\n\tconst handle = setTimeout(callback, ms)\n\treturn () => clearTimeout(handle)\n}\n\n/**\n * Implements the default {@link import('./types.js').FetchHandler} — the global `fetch`, adapted to\n * the minimal injected shape the {@link import('./PromptClient.js').PromptClient} uses.\n *\n * @param input - The request URL\n * @param init - The request init the client sets — method, headers, body, and abort signal\n * @returns The host `fetch` promise for that request\n */\nexport function globalFetch(input: string, init?: FetchInit): Promise<Response> {\n\treturn fetch(input, init)\n}\n\n/**\n * Checks whether a caught value is an `AbortError` — the {@link import('./PromptClient.js').PromptClient}\n * distinguishes a deliberate `disconnect` / teardown (an aborted `fetch`) from a real fault, so it\n * exits its connect loop quietly instead of emitting `error` / reconnecting.\n *\n * @param error - The caught value to test\n * @returns True if the value is a host `Error` or `DOMException` named `AbortError`; false otherwise\n */\nexport function isAbortError(error: unknown): boolean {\n\treturn isError(error) && error.name === 'AbortError'\n}\n\n/**\n * Checks whether `url` is an insecure remote endpoint — a plain `http://` URL whose host is not a\n * loopback address. Pure string parsing (no `URL` global), so it stays total on malformed input;\n * the {@link import('./PromptClient.js').PromptClient} warns once when a `token` would cross such\n * an endpoint in cleartext.\n *\n * @remarks\n * A loopback host (`localhost`, `127.0.0.1`, `[::1]`) over `http://` is exempt (local\n * development has no network hop to eavesdrop on); every other `http://` host is insecure.\n * An `https://` URL (or any non-`http://` scheme) is never flagged.\n *\n * @param url - The candidate endpoint URL\n * @returns True if `url` is a non-loopback `http://` endpoint; false otherwise\n *\n * @example\n * ```ts\n * isInsecureRemote('http://example.com')     // true\n * isInsecureRemote('http://localhost:3000')  // false\n * isInsecureRemote('https://example.com')    // false\n * ```\n */\nexport function isInsecureRemote(url: string): boolean {\n\tconst prefix = 'http://'\n\tif (!url.startsWith(prefix)) return false\n\tconst rest = url.slice(prefix.length)\n\tconst hostEnd = rest.search(/[/?#]/)\n\tconst authority = hostEnd === -1 ? rest : rest.slice(0, hostEnd)\n\tconst host = authority.includes('@') ? authority.slice(authority.indexOf('@') + 1) : authority\n\tconst hostname = host.startsWith('[')\n\t\t? host.slice(0, host.indexOf(']') + 1)\n\t\t: (host.split(':')[0] ?? '')\n\treturn hostname !== 'localhost' && hostname !== '127.0.0.1' && hostname !== '[::1]'\n}\n\n// === Terminal manager wire seams (transport-neutral, no http dependency)\n\n/**\n * Serializes a parked {@link PendingForm} into a `pending` {@link WireEvent}, whose frame `id` is\n * the form's own id.\n *\n * @param form - The parked form's wire-safe record\n * @returns The `pending` frame — the JSON-stringified record as `data`, and the form's own `id`\n */\nexport function serializePending(form: PendingForm): WireEvent {\n\treturn { event: 'pending', data: JSON.stringify(form), id: form.id }\n}\n\n/**\n * Serializes a parked form's expiry or release into an `expire` {@link WireEvent}, whose `data` is\n * the JSON `{ id }` payload.\n *\n * @param id - The id of the parked form that expired or was released\n * @returns The `expire` frame, carrying the JSON-stringified `{ id }` payload as `data`\n */\nexport function serializeExpire(id: string): WireEvent {\n\treturn { event: 'expire', data: JSON.stringify({ id }) }\n}\n\n/**\n * Serializes the `destroy` {@link WireEvent} a broker or manager sends when it is going away, which\n * carries no payload.\n *\n * @returns The `destroy` frame, whose `data` is empty because the signal carries no payload\n */\nexport function serializeDestroy(): WireEvent {\n\treturn { event: 'destroy', data: '' }\n}\n","import type {\n\tAnswerError,\n\tParkedForm,\n\tParkRequest,\n\tPendingForm,\n\tPromptEventMap,\n\tPromptInterface,\n\tPromptOptions,\n\tTimerHandler,\n} from './types.js'\nimport type { Result } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { FieldError, FormInterface, FormResult, FormValues } from '@orkestrel/form'\nimport { DEFAULT_PROMPT_TIMEOUT_MS } from './constants.js'\nimport { TerminalError } from './errors.js'\nimport { defaultTimer } from './helpers.js'\nimport { attempt, isArray, isString } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { isFieldError, isFormError, serializeForm } from '@orkestrel/form'\n\n/**\n * Implements the headless form broker. It parks live forms, exposes their serialized schemas,\n * applies remote answers to the authoritative form, and abandons a parked form on timeout, release,\n * or teardown.\n *\n * @remarks\n * A parked record carries one call to `serializeForm`. A failed fill or submit leaves the record\n * parked for another answer. A successful submit settles the form once, emits `answer`, and removes\n * the record. Timeout, `stop`, and teardown abandon unsettled forms through their own `destroy`\n * method.\n *\n * @example\n * ```ts\n * const form = createForm({ fields: [{ control: 'text', name: 'name' }] })\n * const prompt = createPrompt()\n * const id = prompt.park(form)\n * prompt.answer(id, { name: 'Ada' })\n * await form.answer // { name: 'Ada' }\n * ```\n */\nexport class Prompt implements PromptInterface {\n\treadonly #timeout: number\n\treadonly #timer: TimerHandler\n\treadonly #cap: number | undefined\n\treadonly #parked = new Map<string, ParkedForm>()\n\treadonly #emitter: Emitter<PromptEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: PromptOptions) {\n\t\tthis.#timeout = options?.timeout ?? DEFAULT_PROMPT_TIMEOUT_MS\n\t\tthis.#timer = options?.timer ?? defaultTimer\n\t\tthis.#cap = options?.cap\n\t\tthis.#emitter = new Emitter({\n\t\t\t...(options?.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options?.error !== undefined ? { error: options.error } : {}),\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<PromptEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#parked.size\n\t}\n\n\tpending(): readonly PendingForm[]\n\tpending(id: string): PendingForm | undefined\n\tpending(id?: string): readonly PendingForm[] | PendingForm | undefined {\n\t\tif (id !== undefined) return this.#parked.get(id)?.pending\n\t\tconst forms: PendingForm[] = []\n\t\tfor (const parked of this.#parked.values()) forms.push(parked.pending)\n\t\treturn forms\n\t}\n\n\tpark(form: FormInterface, request?: ParkRequest): string {\n\t\tif (this.#destroyed) {\n\t\t\tform.destroy()\n\t\t\tthrow new TerminalError('EXPIRE', 'The broker has been destroyed')\n\t\t}\n\t\tif (this.#cap !== undefined && this.#parked.size >= this.#cap) {\n\t\t\tform.destroy()\n\t\t\tthrow new TerminalError('LIMIT', `The parked-form cap (${String(this.#cap)}) was reached`, {\n\t\t\t\tcap: this.#cap,\n\t\t\t})\n\t\t}\n\n\t\tconst id = crypto.randomUUID()\n\t\tconst pending: PendingForm = {\n\t\t\tid,\n\t\t\tschema: serializeForm(form.schema),\n\t\t\tstatus: 'pending',\n\t\t\ttime: Date.now(),\n\t\t\t...(request?.from !== undefined ? { from: request.from } : {}),\n\t\t\t...(request?.to !== undefined ? { to: request.to } : {}),\n\t\t}\n\t\tconst cancel = this.#timer(() => this.#expire(id), this.#timeout)\n\t\tthis.#parked.set(id, { form, pending, cancel })\n\t\tthis.#emitter.emit('pending', pending)\n\t\treturn id\n\t}\n\n\tanswer(id: string, values: FormValues): Result<FormValues, AnswerError> {\n\t\tconst outcome = attempt(() => this.#answer(id, values))\n\t\tif (outcome.success) return outcome.value\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\treason: 'rejected',\n\t\t\t\terrors: [{ field: 'form', message: 'The form rejected the answer' }],\n\t\t\t},\n\t\t}\n\t}\n\n\tstop(ids: readonly string[]): boolean\n\tstop(id: string): boolean\n\tstop(): void\n\tstop(ids?: string | readonly string[]): boolean | void {\n\t\tif (ids === undefined) {\n\t\t\tfor (const id of [...this.#parked.keys()]) this.#expire(id)\n\t\t\treturn\n\t\t}\n\t\tif (isArray(ids)) {\n\t\t\tlet stopped = true\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst parked = this.#parked.get(id)\n\t\t\t\tif (parked === undefined || parked.pending.status !== 'pending') stopped = false\n\t\t\t}\n\t\t\tfor (const id of ids) this.#expire(id)\n\t\t\treturn stopped\n\t\t}\n\t\treturn this.#expire(ids)\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tfor (const id of [...this.#parked.keys()]) this.#expire(id)\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#answer(id: string, values: FormValues): Result<FormValues, AnswerError> {\n\t\tconst parked = this.#parked.get(id)\n\t\tif (parked === undefined || parked.pending.status !== 'pending') {\n\t\t\treturn { success: false, error: { reason: 'unknown' } }\n\t\t}\n\n\t\tconst outcome = attempt(() => this.#submit(parked.form, values))\n\t\tif (!outcome.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { reason: 'rejected', errors: this.#errors(outcome.error, parked.form) },\n\t\t\t}\n\t\t}\n\t\tif (!outcome.value.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { reason: 'rejected', errors: outcome.value.error },\n\t\t\t}\n\t\t}\n\n\t\tparked.cancel()\n\t\tconst answered: ParkedForm = {\n\t\t\t...parked,\n\t\t\tpending: { ...parked.pending, status: 'answered' },\n\t\t}\n\t\tthis.#parked.set(id, answered)\n\t\tthis.#emitter.emit('answer', id, outcome.value.value)\n\t\tthis.#parked.delete(id)\n\t\treturn outcome.value\n\t}\n\n\t#submit(form: FormInterface, values: FormValues): FormResult {\n\t\tfor (const [field, value] of Object.entries(values)) {\n\t\t\tconst outcome = attempt(() => form.fill(field, value))\n\t\t\tif (!outcome.success) {\n\t\t\t\treturn { success: false, error: this.#errors(outcome.error, form, field) }\n\t\t\t}\n\t\t}\n\t\treturn form.submit()\n\t}\n\n\t#errors(error: unknown, form: FormInterface, field?: string): readonly FieldError[] {\n\t\tif (isFormError(error)) {\n\t\t\tif (isFieldError(error.context)) return [error.context]\n\t\t\tconst named = error.context?.field\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tfield: isString(named) ? named : this.#field(form, field),\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\t\treturn [\n\t\t\t{\n\t\t\t\tfield: this.#field(form, field),\n\t\t\t\tmessage: 'The form rejected the answer',\n\t\t\t},\n\t\t]\n\t}\n\n\t#field(form: FormInterface, field?: string): string {\n\t\treturn field ?? form.schema.fields[0]?.name ?? form.schema.name ?? 'form'\n\t}\n\n\t#expire(id: string): boolean {\n\t\tconst parked = this.#parked.get(id)\n\t\tif (parked === undefined || parked.pending.status !== 'pending') return false\n\t\tparked.cancel()\n\t\tconst expired: ParkedForm = {\n\t\t\t...parked,\n\t\t\tpending: { ...parked.pending, status: 'expired' },\n\t\t}\n\t\tthis.#parked.set(id, expired)\n\t\tparked.form.destroy()\n\t\tthis.#emitter.emit('expire', id)\n\t\tthis.#parked.delete(id)\n\t\treturn true\n\t}\n}\n","import type {\n\tFetchHandler,\n\tPromptClientEventMap,\n\tPromptClientInterface,\n\tPromptClientOptions,\n\tTimerCancelFunction,\n\tTimerHandler,\n} from './types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { FieldError, FormInterface, FormSchema, FormValues } from '@orkestrel/form'\nimport type { SSEEvent } from '@orkestrel/sse'\nimport {\n\tACCEPT_EVENT_STREAM,\n\tDEFAULT_RECONNECT_DELAY_MS,\n\tHEADER_TOKEN,\n\tSSE_BUFFER_LIMIT,\n\tSSE_EVENTS,\n} from './constants.js'\nimport {\n\tdefaultTimer,\n\tglobalFetch,\n\tisAbortError,\n\tisInsecureRemote,\n\tsanitizeDisplayText,\n\tsanitizeSchema,\n} from './helpers.js'\nimport { isPendingForm } from './validators.js'\nimport { arrayOf, isBoolean, isRecord, isString, parseJSON } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { createForm, isFieldError, parseForm } from '@orkestrel/form'\nimport { createSSEParser } from '@orkestrel/sse'\n\n/**\n * Implements the SSE form bridge. It ingests serialized forms from a remote broker without waiting\n * on a render, drives one form at a time through a local terminal, posts each answer back, and asks\n * again when the authoritative form refuses one.\n *\n * @remarks\n * - **Connect + reconnect.** {@link connect} opens the SSE stream and reconnects after a transport\n *   drop with the injected backoff unless reconnect is disabled, the client was destroyed, or\n *   {@link disconnect} deliberately stopped it.\n * - **Ingest + render.** Each `pending` envelope passes through `isPendingForm`, Form's `parseForm`,\n *   and terminal's `sanitizeSchema`, then enters a serial render queue. The SSE reader never awaits\n *   that queue, so `expire` and `destroy` remain live while a person is answering.\n * - **Safe local form.** The rendering copy omits every wire `pattern`, because Form compiles a\n *   pattern during local evaluation. The broker's parked form retains it and remains authoritative.\n * - **Refusal retry.** A structured `rejected` response seeds a new rendering form with the values\n *   the refused attempt submitted, applies every {@link FieldError} through `invalidate`, and asks\n *   again. No retry counter truncates the loop; acceptance, expiry, and the broker's own teardown\n *   are its bounds.\n * - **Replay safety.** A replayed id is skipped while it is queued, rendering, or posting. Once an\n *   attempt ends, a later delivery of that id may be rendered again.\n *\n * @example\n * ```ts\n * const client = createPromptClient({\n * \turl: 'http://localhost:3001/prompts',\n * \tterminal: createTerminal(),\n * })\n * await client.connect()\n * ```\n */\nexport class PromptClient implements PromptClientInterface {\n\treadonly url: string\n\treadonly #terminal: PromptClientOptions['terminal']\n\treadonly #token: string | undefined\n\treadonly #reconnect: boolean\n\treadonly #delay: number\n\treadonly #fetch: FetchHandler\n\treadonly #timer: TimerHandler\n\treadonly #emitter: Emitter<PromptClientEventMap>\n\t#controller: AbortController | undefined\n\t#backoff: TimerCancelFunction | undefined\n\t#wake: (() => void) | undefined\n\t#connecting = false\n\t#connected = false\n\t#destroyed = false\n\t#draining = false\n\t#warnedInsecureToken = false\n\treadonly #seen = new Set<string>()\n\treadonly #queue = new Map<string, FormSchema>()\n\t#active:\n\t\t| { readonly id: string; readonly form: FormInterface; readonly stopped: boolean }\n\t\t| undefined\n\n\tconstructor(options: PromptClientOptions) {\n\t\tthis.url = options.url\n\t\tthis.#terminal = options.terminal\n\t\tthis.#token = options.token\n\t\tthis.#reconnect = options.reconnect ?? true\n\t\tthis.#delay = options.delay ?? DEFAULT_RECONNECT_DELAY_MS\n\t\tthis.#fetch = options.fetch ?? globalFetch\n\t\tthis.#timer = options.timer ?? defaultTimer\n\t\tthis.#emitter = new Emitter({\n\t\t\t...(options.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options.error !== undefined ? { error: options.error } : {}),\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<PromptClientEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget connected(): boolean {\n\t\treturn this.#connected\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.#destroyed || this.#connecting) return\n\t\tthis.#connecting = true\n\t\twhile (this.#connecting && !this.#destroyed) {\n\t\t\ttry {\n\t\t\t\tawait this.#stream()\n\t\t\t} catch (error) {\n\t\t\t\tthis.#markDisconnected()\n\t\t\t\tif (this.#destroyed || isAbortError(error)) return\n\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t}\n\t\t\tif (!this.#reconnect || !this.#connecting || this.#destroyed) return\n\t\t\tawait this.#wait(this.#delay)\n\t\t}\n\t}\n\n\tdisconnect(): void {\n\t\tthis.#connecting = false\n\t\tthis.#controller?.abort()\n\t\tthis.#controller = undefined\n\t\tthis.#backoff?.()\n\t\tthis.#backoff = undefined\n\t\tconst wake = this.#wake\n\t\tthis.#wake = undefined\n\t\twake?.()\n\t\tthis.#markDisconnected()\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.disconnect()\n\t\tthis.#interrupt()\n\t\tthis.#emitter.destroy()\n\t}\n\n\tasync #stream(): Promise<void> {\n\t\tif (this.#token !== undefined && isInsecureRemote(this.url) && !this.#warnedInsecureToken) {\n\t\t\tthis.#warnedInsecureToken = true\n\t\t\tthis.#emitter.emit(\n\t\t\t\t'error',\n\t\t\t\tnew Error('auth token sent as cleartext over insecure http; use https'),\n\t\t\t)\n\t\t}\n\t\tconst controller = new AbortController()\n\t\tthis.#controller = controller\n\t\tconst response = await this.#fetch(this.url, {\n\t\t\theaders: this.#headers({ Accept: ACCEPT_EVENT_STREAM }),\n\t\t\tsignal: controller.signal,\n\t\t})\n\t\tif (!response.ok) throw new Error(`broker returned ${String(response.status)}`)\n\t\tconst body = response.body\n\t\tif (body === null) throw new Error('broker sent no stream')\n\n\t\tthis.#connected = true\n\t\tthis.#emitter.emit('connect')\n\n\t\tconst reader = body.getReader()\n\t\tconst decoder = new TextDecoder()\n\t\tconst parser = createSSEParser({ limit: SSE_BUFFER_LIMIT })\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst { done, value } = await reader.read()\n\t\t\t\tif (done) break\n\t\t\t\tfor (const event of parser.parse(decoder.decode(value, { stream: true }))) {\n\t\t\t\t\tthis.#handle(event)\n\t\t\t\t\tif (!this.#connecting) break\n\t\t\t\t}\n\t\t\t\tif (!this.#connecting) break\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock()\n\t\t}\n\t\tthis.#markDisconnected()\n\t}\n\n\t#handle(event: SSEEvent): void {\n\t\tif (event.event === SSE_EVENTS.pending) {\n\t\t\tconst parsed = parseJSON(event.data)\n\t\t\tif (!isPendingForm(parsed) || this.#seen.has(parsed.id)) return\n\t\t\tconst schema = parseForm(parsed.schema)\n\t\t\tif (schema === undefined) {\n\t\t\t\tthis.#emitter.emit(\n\t\t\t\t\t'error',\n\t\t\t\t\tnew Error(`broker sent an invalid form schema for ${parsed.id}`),\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#seen.add(parsed.id)\n\t\t\tthis.#queue.set(parsed.id, sanitizeSchema(schema))\n\t\t\tvoid this.#drain()\n\t\t\treturn\n\t\t}\n\t\tif (event.event === SSE_EVENTS.expire) {\n\t\t\tconst parsed = parseJSON(event.data)\n\t\t\tif (isRecord(parsed) && isString(parsed.id)) this.#expire(parsed.id)\n\t\t\treturn\n\t\t}\n\t\tif (event.event === SSE_EVENTS.destroy) {\n\t\t\tthis.disconnect()\n\t\t\tthis.#interrupt()\n\t\t}\n\t}\n\n\tasync #drain(): Promise<void> {\n\t\tif (this.#draining) return\n\t\tthis.#draining = true\n\t\ttry {\n\t\t\twhile (!this.#destroyed) {\n\t\t\t\tlet queued: readonly [string, FormSchema] | undefined\n\t\t\t\tfor (const entry of this.#queue) {\n\t\t\t\t\tqueued = entry\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif (queued === undefined) return\n\t\t\t\tconst [id, schema] = queued\n\t\t\t\tthis.#queue.delete(id)\n\t\t\t\ttry {\n\t\t\t\t\tawait this.#render(id, schema)\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst active = this.#active\n\t\t\t\t\tif (active?.id !== id || !active.stopped) this.#emitter.emit('error', error)\n\t\t\t\t} finally {\n\t\t\t\t\tconst active = this.#active\n\t\t\t\t\tif (active?.id === id) {\n\t\t\t\t\t\tactive.form.destroy()\n\t\t\t\t\t\tthis.#active = undefined\n\t\t\t\t\t}\n\t\t\t\t\tif (!this.#queue.has(id)) this.#seen.delete(id)\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#draining = false\n\t\t}\n\t}\n\n\tasync #render(id: string, schema: FormSchema): Promise<void> {\n\t\tlet values: FormValues | undefined\n\t\tlet errors: readonly FieldError[] = []\n\t\twhile (this.#seen.has(id) && !this.#destroyed) {\n\t\t\tconst form = this.#createRenderingForm(schema, values)\n\t\t\tthis.#active = { id, form, stopped: false }\n\t\t\tfor (const error of errors) form.invalidate(error.field, sanitizeDisplayText(error.message))\n\t\t\tconst submitted = await this.#terminal.ask(form)\n\t\t\tconst active = this.#active\n\t\t\tif (active?.id !== id || active.stopped) return\n\t\t\tconst rejected = await this.#post(id, submitted)\n\t\t\tconst posted = this.#active\n\t\t\tif (posted?.id !== id || posted.stopped || rejected === undefined) return\n\t\t\tvalues = submitted\n\t\t\terrors = rejected\n\t\t\tform.destroy()\n\t\t\tthis.#active = undefined\n\t\t}\n\t}\n\n\t#createRenderingForm(schema: FormSchema, values?: FormValues): FormInterface {\n\t\tconst fields = schema.fields.map((field) => {\n\t\t\tif (field.rule?.pattern === undefined) return field\n\t\t\tconst { pattern: _pattern, ...rule } = field.rule\n\t\t\treturn { ...field, rule }\n\t\t})\n\t\tconst form = createForm({ ...schema, fields }, values === undefined ? undefined : { values })\n\t\tvoid form.answer.catch(() => undefined)\n\t\treturn form\n\t}\n\n\tasync #post(id: string, values: FormValues): Promise<readonly FieldError[] | undefined> {\n\t\tconst response = await this.#fetch(this.url, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: this.#headers({ 'Content-Type': 'application/json' }),\n\t\t\tbody: JSON.stringify({ id, values }),\n\t\t})\n\t\tif (!response.ok) this.#emitter.emit('error', new Error(`broker rejected answer ${id}`))\n\t\tconst parsed = parseJSON(await response.text())\n\t\tif (!isRecord(parsed) || !isBoolean(parsed.success)) {\n\t\t\tthis.#emitter.emit('error', new Error(`broker returned an invalid answer result for ${id}`))\n\t\t\treturn undefined\n\t\t}\n\t\tif (parsed.success) return undefined\n\t\tconst error = parsed.error\n\t\tif (!isRecord(error) || !isString(error.reason)) {\n\t\t\tthis.#emitter.emit('error', new Error(`broker returned an invalid answer error for ${id}`))\n\t\t\treturn undefined\n\t\t}\n\t\tif (error.reason === 'unknown') return undefined\n\t\tif (error.reason === 'rejected' && arrayOf(isFieldError)(error.errors)) return error.errors\n\t\tthis.#emitter.emit('error', new Error(`broker returned an invalid answer refusal for ${id}`))\n\t\treturn undefined\n\t}\n\n\t#expire(id: string): void {\n\t\tconst active = this.#active\n\t\tif (active?.id === id) {\n\t\t\tthis.#active = { ...active, stopped: true }\n\t\t\tthis.#seen.delete(id)\n\t\t\tactive.form.destroy()\n\t\t} else if (this.#queue.delete(id)) this.#seen.delete(id)\n\t\tthis.#emitter.emit('expire', id)\n\t}\n\n\t#interrupt(): void {\n\t\tthis.#queue.clear()\n\t\tthis.#seen.clear()\n\t\tconst active = this.#active\n\t\tif (active === undefined) return\n\t\tthis.#active = { ...active, stopped: true }\n\t\tactive.form.destroy()\n\t}\n\n\t#markDisconnected(): void {\n\t\tif (!this.#connected) return\n\t\tthis.#connected = false\n\t\tthis.#emitter.emit('disconnect')\n\t}\n\n\t#headers(base: Record<string, string>): Record<string, string> {\n\t\tif (this.#token !== undefined) return { ...base, [HEADER_TOKEN]: this.#token }\n\t\treturn { ...base }\n\t}\n\n\t#wait(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst settle = this.#createSettler(resolve)\n\t\t\tthis.#wake = settle\n\t\t\tthis.#backoff = this.#timer(settle, ms)\n\t\t})\n\t}\n\n\t#createSettler(resolve: () => void): () => void {\n\t\treturn () => {\n\t\t\tthis.#backoff = undefined\n\t\t\tthis.#wake = undefined\n\t\t\tresolve()\n\t\t}\n\t}\n}\n","import type {\n\tPendingForm,\n\tPromptInterface,\n\tPromptOptions,\n\tTerminalAnswerError,\n\tTerminalManagerEventMap,\n\tTerminalManagerInterface,\n\tTerminalManagerOptions,\n\tTerminalSnapshot,\n\tTerminalStoreInterface,\n\tTimerHandler,\n} from './types.js'\nimport type { Result } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { FormInterface, FormValues } from '@orkestrel/form'\nimport { TerminalError } from './errors.js'\nimport { createPrompt } from './factories.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\n\n/**\n * Registers named {@link PromptInterface} brokers, one per endpoint, so several parties can `ask`\n * forms of each other by name with a `from` → `to` attribution edge on every parked form, and\n * refuses `DEADLOCK` on a transitive cycle across every in-flight ask.\n *\n * @remarks\n * - **Registry.** `add(name, options?)` mints (or, if `name` is already mounted, returns the\n *   existing broker unchanged — idempotent, never clobbers a live/parked endpoint). Every mounted\n *   broker's `pending` / `answer` / `expire` events are re-emitted on the manager, attributed by\n *   `name`.\n * - **`ask`.** The target must already be mounted through {@link add} — `ask` never auto-adds it;\n *   rejects `TARGET` for an unknown `to` (listing the known names). Rejects `DEADLOCK` when parking\n *   `from → to` would close a cycle over the current in-flight edge set (walked transitively);\n *   otherwise parks the caller's live form through the target's broker and returns that form's own\n *   `answer` promise. Edge cleanup never alters the value or rejection the caller observes.\n * - **Durable open / save.** `open(name)` restores an EMPTY broker from the `store` (parked\n *   Promises are process-bound and never resurrected); `save(name)` persists the endpoint's\n *   configured `timeout`.\n * - **Removal.** `remove` drops one endpoint, a batch (the array overload declared first), or every\n *   endpoint when called without an argument. It destroys each broker, which expires every form\n *   still parked on it. `destroy` is idempotent.\n *\n * @example\n * ```ts\n * const form = createForm({ fields: [{ control: 'text', name: 'name' }] })\n * const manager = new TerminalManager()\n * manager.add('agent')\n * const answer = manager.ask('user', 'agent', form)\n * manager.answer('agent', manager.pending('agent')[0].id, { name: 'Ada' })\n * await answer // { name: 'Ada' }\n * ```\n */\nexport class TerminalManager implements TerminalManagerInterface {\n\treadonly #terminals = new Map<string, PromptInterface>()\n\treadonly #config = new Map<string, PromptOptions>()\n\t// The handlers subscribed on a mounted broker's emitter — kept so `remove` can `off` them\n\t// explicitly (on top of the broker's own `destroy`, which already renders its emitter inert).\n\treadonly #listeners = new Map<\n\t\tstring,\n\t\t{\n\t\t\treadonly pending: (form: PendingForm) => void\n\t\t\treadonly answer: (id: string, values: FormValues) => void\n\t\t\treadonly expire: (id: string) => void\n\t\t}\n\t>()\n\t// In-flight `ask` edges, keyed by the parked form's id — the deadlock graph. `from` asked\n\t// `to`; cleanup on settle (answer / expire / destroy / remove) removes EXACTLY the edge that\n\t// call created.\n\treadonly #edges = new Map<string, { readonly from: string; readonly to: string }>()\n\treadonly #store: TerminalStoreInterface | undefined\n\treadonly #timeout: number | undefined\n\treadonly #timer: TimerHandler | undefined\n\treadonly #cap: number | undefined\n\treadonly #emitter: Emitter<TerminalManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: TerminalManagerOptions) {\n\t\tthis.#store = options?.store\n\t\tthis.#timeout = options?.timeout\n\t\tthis.#timer = options?.timer\n\t\tthis.#cap = options?.cap\n\t\tthis.#emitter = new Emitter({\n\t\t\t...(options?.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options?.error !== undefined ? { error: options.error } : {}),\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<TerminalManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#terminals.size\n\t}\n\n\t// === Accessors\n\n\tterminal(name: string): PromptInterface | undefined {\n\t\treturn this.#terminals.get(name)\n\t}\n\n\tterminals(): readonly PromptInterface[] {\n\t\treturn [...this.#terminals.values()]\n\t}\n\n\t// === Registry\n\n\tadd(name: string, options?: PromptOptions): PromptInterface {\n\t\tif (this.#destroyed) throw new TerminalError('DESTROYED', 'manager destroyed')\n\t\tconst existing = this.#terminals.get(name)\n\t\tif (existing !== undefined) return existing\n\t\tconst timeout = options?.timeout ?? this.#timeout\n\t\tconst timer = options?.timer ?? this.#timer\n\t\tconst cap = options?.cap ?? this.#cap\n\t\tconst promptOptions: PromptOptions = {\n\t\t\t...(options?.on !== undefined ? { on: options.on } : {}),\n\t\t\t...(options?.error !== undefined ? { error: options.error } : {}),\n\t\t\t...(timeout !== undefined ? { timeout } : {}),\n\t\t\t...(timer !== undefined ? { timer } : {}),\n\t\t\t...(cap !== undefined ? { cap } : {}),\n\t\t}\n\t\tconst broker = createPrompt(promptOptions)\n\t\tconst listeners = {\n\t\t\tpending: this.#createPendingListener(),\n\t\t\tanswer: this.#createAnswerListener(name),\n\t\t\texpire: this.#createExpireListener(name),\n\t\t}\n\t\tbroker.emitter.on('pending', listeners.pending)\n\t\tbroker.emitter.on('answer', listeners.answer)\n\t\tbroker.emitter.on('expire', listeners.expire)\n\t\tthis.#terminals.set(name, broker)\n\t\tthis.#config.set(name, { ...options })\n\t\tthis.#listeners.set(name, listeners)\n\t\treturn broker\n\t}\n\n\t// === Ask\n\n\task(from: string, to: string, form: FormInterface): Promise<FormValues> {\n\t\tconst broker = this.#terminals.get(to)\n\t\tif (broker === undefined) {\n\t\t\tconst known = [...this.#terminals.keys()]\n\t\t\treturn Promise.reject(\n\t\t\t\tnew TerminalError(\n\t\t\t\t\t'TARGET',\n\t\t\t\t\t`unknown terminal '${to}' (known: ${known.length > 0 ? known.join(', ') : 'none'})`,\n\t\t\t\t\t{ to, known },\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t\tconst cycle = this.#findCycle(from, to)\n\t\tif (cycle !== undefined) {\n\t\t\treturn Promise.reject(\n\t\t\t\tnew TerminalError(\n\t\t\t\t\t'DEADLOCK',\n\t\t\t\t\t`ask ${from} -> ${to} would deadlock: ${cycle.join(' -> ')}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tfrom,\n\t\t\t\t\t\tto,\n\t\t\t\t\t\tpath: cycle,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t\tconst id = broker.park(form, { from, to })\n\t\tif (broker.pending(id) !== undefined) {\n\t\t\tthis.#edges.set(id, { from, to })\n\t\t\tform.answer.then(this.#createEdgeClear(id), this.#createEdgeClear(id))\n\t\t}\n\t\treturn form.answer\n\t}\n\n\t// === Pending accessors\n\n\tpending(): readonly PendingForm[]\n\tpending(to: string): readonly PendingForm[]\n\tpending(to?: string): readonly PendingForm[] {\n\t\tif (to !== undefined) {\n\t\t\tconst broker = this.#terminals.get(to)\n\t\t\treturn broker === undefined ? [] : broker.pending()\n\t\t}\n\t\tconst result: PendingForm[] = []\n\t\tfor (const broker of this.#terminals.values()) result.push(...broker.pending())\n\t\treturn result\n\t}\n\n\t// === Answer\n\n\tanswer(to: string, id: string, values: FormValues): Result<FormValues, TerminalAnswerError> {\n\t\tconst broker = this.#terminals.get(to)\n\t\tif (broker === undefined) return { success: false, error: { reason: 'target' } }\n\t\tconst result = broker.answer(id, values)\n\t\tif (result.success) this.#edges.delete(id)\n\t\treturn result\n\t}\n\n\t// === Durable open / save\n\n\tasync open(name: string): Promise<PromptInterface | undefined> {\n\t\tif (this.#destroyed) throw new TerminalError('DESTROYED', 'manager destroyed')\n\t\tconst existing = this.#terminals.get(name)\n\t\tif (existing !== undefined) return existing\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(name)\n\t\tif (this.#destroyed) throw new TerminalError('DESTROYED', 'manager destroyed')\n\t\tif (snapshot === undefined) return undefined\n\t\treturn this.add(name, snapshot.timeout !== undefined ? { timeout: snapshot.timeout } : {})\n\t}\n\n\tasync save(name: string): Promise<boolean> {\n\t\tconst broker = this.#terminals.get(name)\n\t\tif (this.#store === undefined || broker === undefined) return false\n\t\tconst config = this.#config.get(name)\n\t\tconst snapshot: TerminalSnapshot = {\n\t\t\tid: name,\n\t\t\t...(config?.timeout !== undefined ? { timeout: config.timeout } : {}),\n\t\t}\n\t\tawait this.#store.set(snapshot)\n\t\treturn true\n\t}\n\n\t// === Removal (the array overload declared FIRST)\n\n\tremove(names: readonly string[]): boolean\n\tremove(name: string): boolean\n\tremove(): void\n\tremove(names?: string | readonly string[]): boolean | void {\n\t\tif (names === undefined) {\n\t\t\tfor (const name of [...this.#terminals.keys()]) this.#removeOne(name)\n\t\t\treturn\n\t\t}\n\t\tif (isArray(names)) {\n\t\t\tlet removed = true\n\t\t\tfor (const name of names) {\n\t\t\t\tif (!this.#removeOne(name)) removed = false\n\t\t\t}\n\t\t\treturn removed\n\t\t}\n\t\treturn this.#removeOne(names)\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.remove()\n\t\tthis.#edges.clear()\n\t\tthis.#emitter.destroy()\n\t}\n\n\t// === Private helpers\n\n\t#createPendingListener(): (form: PendingForm) => void {\n\t\treturn (form) => this.#emitter.emit('pending', form)\n\t}\n\n\t#createAnswerListener(name: string): (id: string, values: FormValues) => void {\n\t\treturn (id, values) => {\n\t\t\tthis.#edges.delete(id)\n\t\t\tthis.#emitter.emit('answer', name, id, values)\n\t\t}\n\t}\n\n\t#createExpireListener(name: string): (id: string) => void {\n\t\treturn (id) => {\n\t\t\tthis.#edges.delete(id)\n\t\t\tthis.#emitter.emit('expire', name, id)\n\t\t}\n\t}\n\n\t#createEdgeClear(id: string): () => void {\n\t\treturn () => {\n\t\t\tthis.#edges.delete(id)\n\t\t}\n\t}\n\n\t// Drop one endpoint: destroy its broker FIRST (its expire loop re-emits `expire` for every\n\t// still-parked form through the manager's listeners — still attached at this point, so\n\t// each settles on the manager emitter too), THEN unsubscribe the manager's listeners and\n\t// remove it from every registry map. `false` when `name` was not mounted.\n\t#removeOne(name: string): boolean {\n\t\tconst broker = this.#terminals.get(name)\n\t\tif (broker === undefined) return false\n\t\tbroker.destroy()\n\t\tconst listeners = this.#listeners.get(name)\n\t\tif (listeners !== undefined) {\n\t\t\tbroker.emitter.off('pending', listeners.pending)\n\t\t\tbroker.emitter.off('answer', listeners.answer)\n\t\t\tbroker.emitter.off('expire', listeners.expire)\n\t\t}\n\t\tthis.#terminals.delete(name)\n\t\tthis.#config.delete(name)\n\t\tthis.#listeners.delete(name)\n\t\tthis.#clearEdges(name)\n\t\treturn true\n\t}\n\n\t#clearEdges(to: string): void {\n\t\tfor (const [id, edge] of this.#edges) {\n\t\t\tif (edge.to === to) this.#edges.delete(id)\n\t\t}\n\t}\n\n\t// Walk the in-flight edge graph forward from `to`, looking for `from` — a hit means parking\n\t// `from -> to` would close a cycle. Returns the closing cycle path (`from` first and last),\n\t// or `undefined` when no cycle would form.\n\t#findCycle(from: string, to: string): readonly string[] | undefined {\n\t\tif (from === to) return [from, to]\n\t\tconst visited = new Set<string>([to])\n\t\tconst queue: Array<readonly string[]> = [[to]]\n\t\twhile (queue.length > 0) {\n\t\t\tconst path = queue.shift()\n\t\t\tif (path === undefined) break\n\t\t\tconst last = path[path.length - 1]\n\t\t\tif (last === undefined) continue\n\t\t\tfor (const edge of this.#edges.values()) {\n\t\t\t\tif (edge.from !== last) continue\n\t\t\t\tif (edge.to === from) return [from, ...path, from]\n\t\t\t\tif (visited.has(edge.to)) continue\n\t\t\t\tvisited.add(edge.to)\n\t\t\t\tqueue.push([...path, edge.to])\n\t\t\t}\n\t\t}\n\t\treturn undefined\n\t}\n}\n","import type { TerminalSnapshot, TerminalStoreInterface } from '../types.js'\n\n/**\n * Implements the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of\n * {@link TerminalSnapshot} records keyed by endpoint id, the default store\n * {@link import('../factories.js').createMemoryTerminalStore} builds and the exact twin of\n * {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore}. It carries no idle expiry and\n * no eviction.\n *\n * @remarks\n * A plain `Map<string, TerminalSnapshot>` — the snapshot is already pure, self-contained CONFIG-only\n * JSON, so the memory tier needs no encoding. There is NO idle-TTL and NO\n * eviction: a persisted config lives until an explicit `delete`. A durable backend (JSON / SQLite /\n * IndexedDB) swaps in through the SAME interface without touching the manager — its\n * driver-pluggable twin is {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore} (the\n * snapshot as one opaque JSON column).\n *\n * - **`get` resolves the persisted snapshot for an id**, or `undefined` if none is stored.\n * - **`set` inserts / replaces under the snapshot's OWN `id`** (no separate id param).\n * - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * The public surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and\n * {@link TerminalStoreInterface} carry the same methods. Hydration is a caller concern: `open` always\n * restores an EMPTY broker — parked Promises are process-bound and never resurrected.\n *\n * @example\n * ```ts\n * import { createMemoryTerminalStore } from '@orkestrel/terminal'\n *\n * const store = createMemoryTerminalStore()\n * await store.set({ id: 'shell', timeout: 5000 })   // persist a config\n * const snapshot = await store.get('shell')\n * await store.delete('shell')                       // drop it\n * ```\n */\nexport class MemoryTerminalStore implements TerminalStoreInterface {\n\treadonly #snapshots = new Map<string, TerminalSnapshot>()\n\n\t/**\n\t * Resolves the persisted snapshot for `id`.\n\t *\n\t * @param id - The endpoint name the snapshot is keyed by\n\t * @returns The stored snapshot, or `undefined` when none is held\n\t */\n\tget(id: string): Promise<TerminalSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\t/**\n\t * Inserts or replaces under the snapshot's OWN `id` (no separate id param).\n\t *\n\t * @param snapshot - The config snapshot to persist, carrying its own `id`\n\t * @returns A promise that settles once the snapshot is held\n\t */\n\tset(snapshot: TerminalSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The endpoint name to drop\n\t * @returns A promise that settles once the snapshot is gone\n\t */\n\tdelete(id: string): Promise<void> {\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type { TerminalSnapshot, TerminalSnapshotRow, TerminalStoreInterface } from '../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isTerminalSnapshot } from '../validators.js'\n\n/**\n * Implements a {@link TerminalStoreInterface} backed by one table of the `databases` layer — an\n * endpoint's durable config state is a row, so persistence reduces to keyed point-access (`get` /\n * `set` / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`\n * {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. A stored `snapshot` is narrowed\n * with {@link import('../validators.js').isTerminalSnapshot} on read.\n *\n * @remarks\n * The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,\n * JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /\n * IndexedDB backend swaps in WITHOUT touching the manager — the same seam as\n * {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. The driver defaults to memory\n * ({@link import('../factories.js').createDatabaseTerminalStore} passes `createMemoryDriver()`), so\n * it ALSO works in memory out of the box; you opt into the durable plumbing by passing a JSON /\n * SQLite / IndexedDB driver.\n *\n * The {@link TerminalSnapshot} is stored as ONE OPAQUE JSON COLUMN — the table is a row of\n * `{ id; snapshot }` ({@link TerminalSnapshotRow}). The snapshot is already a COMPLETE,\n * self-contained, pure-JSON CONFIG payload (no live broker state), so storing it whole is lossless\n * AND keeps the row type flat (`snapshot` reads back as `unknown`).\n *\n * - **`set(snapshot)` upserts under the snapshot's OWN `id`** (no separate id param) — it writes\n *   the row `{ id: snapshot.id, snapshot }`.\n * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to\n *   a {@link TerminalSnapshot} ({@link import('../validators.js').isTerminalSnapshot} — the total\n *   guard that narrows an untrusted storage read), or `undefined` if none is stored.\n * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * There is NO idle-TTL / eviction — a persisted config lives until an explicit `delete`. The public\n * surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and\n * {@link TerminalStoreInterface} carry the same methods. Hydration stays a caller concern: `open` always restores an EMPTY\n * broker — parked Promises are process-bound and never resurrected.\n *\n * @example\n * ```ts\n * import { createDatabaseTerminalStore } from '@orkestrel/terminal'\n * import { createMemoryDriver } from '@orkestrel/database'\n *\n * const store = createDatabaseTerminalStore(createMemoryDriver()) // a durable driver swaps in here\n * await store.set({ id: 'shell', timeout: 5000 })        // persist the config (one JSON column)\n * const snapshot = await store.get('shell')\n * await store.delete('shell')                            // drop it\n * ```\n */\nexport class DatabaseTerminalStore implements TerminalStoreInterface {\n\treadonly #table: TableInterface<TerminalSnapshotRow>\n\n\t/**\n\t * Wraps a table as a terminal store.\n\t *\n\t * @param table - The {@link TableInterface} holding the snapshots — its row is the\n\t *   {@link TerminalSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)\n\t */\n\tconstructor(table: TableInterface<TerminalSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\t/**\n\t * Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a\n\t * `TerminalSnapshot`.\n\t *\n\t * @param id - The endpoint name the row is keyed by\n\t * @returns The stored snapshot, or `undefined` when none is held or the column is off-shape\n\t */\n\tasync get(id: string): Promise<TerminalSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\t// The snapshot crosses back as an untrusted storage read (a structured clone / a JSON row),\n\t\t// so narrow the opaque JSON column with the boundary guard rather than a cast;\n\t\t// a malformed blob resolves `undefined`, never a broken config.\n\t\treturn isTerminalSnapshot(row.snapshot) ? row.snapshot : undefined\n\t}\n\n\t/**\n\t * Inserts or replaces under the snapshot's OWN `id` (no separate id param) — the row is\n\t * `{ id, snapshot }`.\n\t *\n\t * @param snapshot - The config snapshot to persist, carrying its own `id`\n\t * @returns A promise that settles once the row is written\n\t */\n\tasync set(snapshot: TerminalSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The endpoint name to drop\n\t * @returns A promise that settles once the row is gone\n\t */\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type {\n\tPromptClientInterface,\n\tPromptClientOptions,\n\tPromptInterface,\n\tPromptOptions,\n\tTerminalManagerInterface,\n\tTerminalManagerOptions,\n\tTerminalSnapshotRow,\n\tTerminalStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { Prompt } from './Prompt.js'\nimport { PromptClient } from './PromptClient.js'\nimport { TerminalManager } from './TerminalManager.js'\nimport { MemoryTerminalStore } from './stores/MemoryTerminalStore.js'\nimport { DatabaseTerminalStore } from './stores/DatabaseTerminalStore.js'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\n\n/**\n * Creates the headless {@link PromptInterface} broker. It parks live forms and applies remote\n * answers to the authoritative instances.\n *\n * @param options - See {@link PromptOptions}\n * @returns A {@link PromptInterface}\n *\n * @remarks\n * The caller awaits the parked form's own `answer`. Timeout, `stop`, or teardown destroys the form,\n * so that promise rejects with the Form package's `ABANDONED` error. Inject `options.timer` to\n * drive expiry without real time.\n *\n * @example\n * ```ts\n * import { createPrompt } from '@orkestrel/terminal'\n * import { createForm } from '@orkestrel/form'\n *\n * const prompt = createPrompt()\n * const form = createForm({ fields: [{ control: 'text', name: 'name' }] })\n * const id = prompt.park(form)\n * prompt.answer(id, { name: 'Ada' })\n * ```\n */\nexport function createPrompt(options?: PromptOptions): PromptInterface {\n\treturn new Prompt(options)\n}\n\n/**\n * Creates the SSE prompt {@link PromptClientInterface} bridge — it connects to a remote broker's\n * SSE endpoint, dispatches each received form to a local\n * {@link import('./types.js').TerminalInterface}, and POSTs the answer back. Universal — `fetch`\n * and SSE are web standards.\n *\n * @param options - See {@link PromptClientOptions} (`url` + `terminal` required)\n * @returns A {@link PromptClientInterface}\n *\n * @remarks\n * - **Connect + reconnect.** `await client.connect()` streams remote prompts until the stream\n *   ends; it reconnects with the `delay` backoff unless `reconnect` is `false` / the client was\n *   `destroy`ed. Inject `options.fetch` (a scripted `fetch`) and `options.timer` to drive it\n *   deterministically in tests — no real network.\n * - **Wire narrowing.** Every decoded prompt is guard-narrowed before dispatch (never an `as`).\n *\n * @example\n * ```ts\n * import { createPromptClient } from '@orkestrel/terminal'\n *\n * const client = createPromptClient({ url: 'http://host/prompts', terminal })\n * await client.connect()\n * ```\n */\nexport function createPromptClient(options: PromptClientOptions): PromptClientInterface {\n\treturn new PromptClient(options)\n}\n\n/**\n * Creates the multi-endpoint {@link TerminalManager} — a named registry of {@link PromptInterface}\n * brokers so several parties can `ask` forms of each other by name, with a transitive cycle check\n * that refuses `DEADLOCK` across every in-flight ask.\n *\n * @param options - See {@link TerminalManagerOptions}\n * @returns A {@link TerminalManager}\n *\n * @example\n * ```ts\n * import { createTerminalManager } from '@orkestrel/terminal'\n *\n * const manager = createTerminalManager()\n * manager.add('agent')\n * ```\n */\nexport function createTerminalManager(options?: TerminalManagerOptions): TerminalManagerInterface {\n\treturn new TerminalManager(options)\n}\n\n/**\n * Creates the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of endpoint\n * config snapshots, the default store backing a {@link TerminalManagerInterface}'s `open` / `save`.\n *\n * @returns A {@link TerminalStoreInterface}\n *\n * @example\n * ```ts\n * import { createMemoryTerminalStore } from '@orkestrel/terminal'\n *\n * const store = createMemoryTerminalStore()\n * ```\n */\nexport function createMemoryTerminalStore(): TerminalStoreInterface {\n\treturn new MemoryTerminalStore()\n}\n\n/**\n * Creates a {@link TerminalStoreInterface} backed by one table of the `databases` layer — the\n * driver-pluggable twin of {@link createMemoryTerminalStore}, storing each endpoint's config\n * snapshot as one opaque JSON column. The default driver is an in-memory `@orkestrel/database`\n * driver.\n *\n * @param driver - The {@link DriverInterface} backing the table (default an in-memory driver)\n * @returns A {@link TerminalStoreInterface}\n *\n * @example\n * ```ts\n * import { createDatabaseTerminalStore } from '@orkestrel/terminal'\n *\n * const store = createDatabaseTerminalStore() // in-memory by default\n * ```\n */\nexport function createDatabaseTerminalStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): TerminalStoreInterface {\n\t// The snapshot is stored as ONE OPAQUE JSON column (`rawShape`), so the row infers FLAT —\n\t// `{ id: string; snapshot: unknown }` = TerminalSnapshotRow.\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { terminals: columns } })\n\tconst table: TableInterface<TerminalSnapshotRow> = database.table('terminals')\n\treturn new DatabaseTerminalStore(table)\n}\n"],"mappings":"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"}