@orkestrel/terminal 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,32 @@
1
- import { CheckboxField } from '@orkestrel/form';
2
- import { ConfirmField } from '@orkestrel/form';
3
- import { DriverInterface } from '@orkestrel/database';
4
- import { EditorField } from '@orkestrel/form';
5
- import { EmitterErrorHandler } from '@orkestrel/emitter';
6
- import { EmitterHooks } from '@orkestrel/emitter';
7
- import { EmitterInterface } from '@orkestrel/emitter';
8
- import { FieldChoice } from '@orkestrel/form';
9
- import { FieldError } from '@orkestrel/form';
10
- import { FormInterface } from '@orkestrel/form';
11
- import { FormSchema } from '@orkestrel/form';
12
- import { FormValues } from '@orkestrel/form';
13
- import { Guard } from '@orkestrel/contract';
14
- import { JSONRecord } from '@orkestrel/contract';
15
- import { PasswordField } from '@orkestrel/form';
16
- import { Result } from '@orkestrel/contract';
17
- import { SelectField } from '@orkestrel/form';
18
- import { Style } from '@orkestrel/console';
19
- import { StylerInterface } from '@orkestrel/console';
20
- import { TableInterface } from '@orkestrel/database';
21
- import { TextField } from '@orkestrel/form';
22
-
23
- /** The `Accept` header value that opens the broker's SSE stream. */
1
+ import type { CheckboxField } from '@orkestrel/form';
2
+ import type { ConfirmField } from '@orkestrel/form';
3
+ import type { DriverInterface } from '@orkestrel/database';
4
+ import type { EditorField } from '@orkestrel/form';
5
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
6
+ import type { EmitterHooks } from '@orkestrel/emitter';
7
+ import type { EmitterInterface } from '@orkestrel/emitter';
8
+ import type { FieldChoice } from '@orkestrel/form';
9
+ import type { FieldError } from '@orkestrel/form';
10
+ import type { FormInterface } from '@orkestrel/form';
11
+ import type { FormSchema } from '@orkestrel/form';
12
+ import type { FormValues } from '@orkestrel/form';
13
+ import type { Guard } from '@orkestrel/contract';
14
+ import type { JSONRecord } from '@orkestrel/contract';
15
+ import type { PasswordField } from '@orkestrel/form';
16
+ import type { Result } from '@orkestrel/contract';
17
+ import type { SelectField } from '@orkestrel/form';
18
+ import type { Style } from '@orkestrel/console';
19
+ import type { StylerInterface } from '@orkestrel/console';
20
+ import type { TableInterface } from '@orkestrel/database';
21
+ import type { TextField } from '@orkestrel/form';
22
+
23
+ /** Names the `Accept` header value that opens the broker's SSE stream — `text/event-stream`. */
24
24
  export declare const ACCEPT_EVENT_STREAM = "text/event-stream";
25
25
 
26
26
  /**
27
- * Why {@link PromptInterface.answer} refused. Names its axis with `reason`.
27
+ * Explains why {@link PromptInterface.answer} refused — `unknown` for an id no form is parked
28
+ * under, `rejected` for values the authoritative form itself refused, carrying the `FieldError`
29
+ * list it reported. Names its axis with `reason`.
28
30
  *
29
31
  * @remarks
30
32
  * - `unknown` — no form is parked under that id, or the one that was has already settled.
@@ -41,42 +43,55 @@ export declare type AnswerError = {
41
43
  readonly errors: readonly FieldError[];
42
44
  };
43
45
 
44
- /** Backspace (BS, U+0008) — Ctrl+H / some terminals' Backspace. */
46
+ /** Names the backspace byte (BS, U+0008) — Ctrl+H / some terminals' Backspace. */
45
47
  export declare const BACKSPACE: string;
46
48
 
47
49
  /**
48
- * Advance a checkbox prompt by one {@link KeyEvent} — the pure
49
- * `(state, key) → PromptStep<readonly string[]>` reducer. `up` / `down` (and `k` / `j`) move the
50
- * focus (wrapping); `space` toggles the focused index in the checked set; return submits the
51
- * checked values in choice order; ctrl-c cancels. The form applies selection-count rules.
52
- */
53
- export declare function checkboxReduce(state: ReturnType<typeof createCheckboxState>, key: KeyEvent): PromptStep<readonly string[], ReturnType<typeof createCheckboxState>>;
54
-
55
- /** Render a checkbox-field key state as a multi-line styled view. */
56
- export declare function checkboxView(state: ReturnType<typeof createCheckboxState>): string;
57
-
58
- /**
59
- * Advance a confirm prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<boolean>`
60
- * reducer. `y` / `Y` submits `true`, `n` / `N` submits `false`, return on an empty line submits
61
- * the `default`, ctrl-c cancels; any other key is ignored (stays active).
62
- */
63
- export declare function confirmReduce(state: ReturnType<typeof createConfirmState>, key: KeyEvent): PromptStep<boolean, ReturnType<typeof createConfirmState>>;
50
+ * Represents the immutable state a checkbox field's reducer carries — the select state plus the ticked set.
51
+ *
52
+ * @remarks
53
+ * - `message` — the sanitized label the header renders.
54
+ * - `choices` — the choices the list offers, in declared order.
55
+ * - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
56
+ * - `focused` — the index the cursor sits on.
57
+ * - `checked` — the ticked indices, in the order they were ticked; the reducer sorts them into
58
+ * choice order when it submits.
59
+ */
60
+ export declare interface CheckboxState {
61
+ readonly message: string;
62
+ readonly choices: readonly FieldChoice[];
63
+ readonly styler: StylerInterface;
64
+ readonly theme: PromptTheme;
65
+ readonly focused: number;
66
+ readonly checked: readonly number[];
67
+ }
64
68
 
65
69
  /**
66
- * Render a confirm-field key state as a styled view. The selected role paints the default letter.
67
- */
68
- export declare function confirmView(state: ReturnType<typeof createConfirmState>): string;
70
+ * Represents the immutable state a confirm field's reducer carries. It holds no typed value, because the
71
+ * answer is the key itself.
72
+ *
73
+ * @remarks
74
+ * - `message` — the sanitized label the header renders.
75
+ * - `default` — the answer a bare return submits, and the letter the view capitalizes.
76
+ * - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
77
+ */
78
+ export declare interface ConfirmState {
79
+ readonly message: string;
80
+ readonly default: boolean;
81
+ readonly styler: StylerInterface;
82
+ readonly theme: PromptTheme;
83
+ }
69
84
 
70
85
  /**
71
- * The control BYTE (or CRLF pair) → key descriptor table {@link import('./helpers.js').parseKey}
72
- * consults for the one-byte keys and the two-byte CRLF Enter chunk. Each entry carries the
73
- * canonical `name` and whether it is a `ctrl` combination. The source of truth for that decode;
74
- * frozen.
86
+ * Holds the control byte (or CRLF pair) to key descriptor table
87
+ * {@link import('./helpers.js').parseKey} consults for the one-byte keys and the two-byte CRLF
88
+ * Enter chunk. Each entry carries the canonical `name` and whether it is a `ctrl` combination. The
89
+ * source of truth for that decode; frozen.
75
90
  *
76
91
  * @remarks
77
92
  * `return` / `newline` / `return + newline` all map to `return` (one canonical Enter name) — a
78
93
  * terminal or a paste can deliver Enter as `\r`, `\n`, or the `\r\n` pair in one chunk;
79
- * `delete` / `backspace` both map to `backspace` (the two Backspace bytes); the Ctrl combos
94
+ * `delete` / `backspace` both map to `backspace` (the Backspace bytes); the Ctrl combos
80
95
  * (`c` / `d` / `u` / `a` / `e`) carry `ctrl: true` so a reducer can match
81
96
  * `key.ctrl && key.name === 'c'`. `escape` / `tab` / `space` are plain named keys.
82
97
  */
@@ -86,48 +101,39 @@ export declare const CONTROL_NAMES: Readonly<Record<string, {
86
101
  }>>;
87
102
 
88
103
  /**
89
- * Build the initial checkbox-field key state.
104
+ * Builds the initial checkbox-field reducer state — the offered choices, with every value in the
105
+ * field's `default` list pre-checked.
90
106
  *
91
107
  * @param field - The checkbox field to render
92
108
  * @param styler - The styler used to render the view
93
109
  * @param theme - The optional terminal theme
94
110
  * @returns The initial immutable key state
95
111
  */
96
- export declare function createCheckboxState(field: CheckboxField, styler?: StylerInterface, theme?: PromptThemeOptions): {
97
- message: string;
98
- choices: FieldChoice[];
99
- styler: StylerInterface;
100
- theme: PromptTheme;
101
- focused: number;
102
- checked: readonly number[];
103
- };
112
+ export declare function createCheckboxState(field: CheckboxField, styler?: StylerInterface, theme?: PromptThemeOptions): CheckboxState;
104
113
 
105
114
  /**
106
- * Build the initial confirm-field key state.
115
+ * Builds the initial confirm-field reducer state — the sanitized label and the declared default
116
+ * answer.
107
117
  *
108
118
  * @param field - The confirm field to render
109
119
  * @param styler - The styler used to render the view
110
120
  * @param theme - The optional terminal theme
111
121
  * @returns The initial immutable key state
112
122
  */
113
- export declare function createConfirmState(field: ConfirmField, styler?: StylerInterface, theme?: PromptThemeOptions): {
114
- message: string;
115
- default: boolean;
116
- styler: StylerInterface;
117
- theme: PromptTheme;
118
- };
123
+ export declare function createConfirmState(field: ConfirmField, styler?: StylerInterface, theme?: PromptThemeOptions): ConfirmState;
119
124
 
120
125
  /**
121
- * Create a {@link TerminalStoreInterface} backed by one table of the `databases` layer — the
126
+ * Creates a {@link TerminalStoreInterface} backed by one table of the `databases` layer — the
122
127
  * driver-pluggable twin of {@link createMemoryTerminalStore}, storing each endpoint's config
123
- * snapshot as one opaque JSON column.
128
+ * snapshot as one opaque JSON column. The default driver is an in-memory `@orkestrel/database`
129
+ * driver.
124
130
  *
125
131
  * @param driver - The {@link DriverInterface} backing the table (default an in-memory driver)
126
132
  * @returns A {@link TerminalStoreInterface}
127
133
  *
128
134
  * @example
129
135
  * ```ts
130
- * import { createDatabaseTerminalStore } from '@src/core'
136
+ * import { createDatabaseTerminalStore } from '@orkestrel/terminal'
131
137
  *
132
138
  * const store = createDatabaseTerminalStore() // in-memory by default
133
139
  * ```
@@ -135,47 +141,36 @@ export declare function createConfirmState(field: ConfirmField, styler?: StylerI
135
141
  export declare function createDatabaseTerminalStore(driver?: DriverInterface): TerminalStoreInterface;
136
142
 
137
143
  /**
138
- * Build the initial editor-field key state.
144
+ * Builds the initial editor-field reducer state — the committed lines empty, and the declared
145
+ * default held for a finish with nothing typed.
139
146
  *
140
147
  * @param field - The editor field to render
141
148
  * @param styler - The styler used to render the view
142
149
  * @param theme - The optional terminal theme
143
150
  * @returns The initial immutable key state
144
151
  */
145
- export declare function createEditorState(field: EditorField, styler?: StylerInterface, theme?: PromptThemeOptions): {
146
- message: string;
147
- default: string;
148
- styler: StylerInterface;
149
- theme: PromptTheme;
150
- lines: readonly string[];
151
- current: string;
152
- };
152
+ export declare function createEditorState(field: EditorField, styler?: StylerInterface, theme?: PromptThemeOptions): EditorState;
153
153
 
154
154
  /**
155
- * Build the initial text-field key state.
155
+ * Builds the initial text-field reducer state — the sanitized label, the declared default, the
156
+ * styler, and the resolved theme.
156
157
  *
157
158
  * @param field - The text field to render
158
159
  * @param styler - The styler used to render the view
159
160
  * @param theme - The optional terminal theme
160
161
  * @returns The initial immutable key state
161
162
  */
162
- export declare function createInputState(field: TextField, styler?: StylerInterface, theme?: PromptThemeOptions): {
163
- message: string;
164
- default: string;
165
- styler: StylerInterface;
166
- theme: PromptTheme;
167
- value: string;
168
- };
163
+ export declare function createInputState(field: TextField, styler?: StylerInterface, theme?: PromptThemeOptions): InputState;
169
164
 
170
165
  /**
171
- * Create the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of endpoint
166
+ * Creates the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of endpoint
172
167
  * config snapshots, the default store backing a {@link TerminalManagerInterface}'s `open` / `save`.
173
168
  *
174
169
  * @returns A {@link TerminalStoreInterface}
175
170
  *
176
171
  * @example
177
172
  * ```ts
178
- * import { createMemoryTerminalStore } from '@src/core'
173
+ * import { createMemoryTerminalStore } from '@orkestrel/terminal'
179
174
  *
180
175
  * const store = createMemoryTerminalStore()
181
176
  * ```
@@ -183,23 +178,18 @@ export declare function createInputState(field: TextField, styler?: StylerInterf
183
178
  export declare function createMemoryTerminalStore(): TerminalStoreInterface;
184
179
 
185
180
  /**
186
- * Build the initial password-field key state.
181
+ * Builds the initial password-field reducer state — the text-field state, plus the mask glyph each
182
+ * typed character renders as.
187
183
  *
188
184
  * @param field - The password field to render
189
185
  * @param styler - The styler used to render the view
190
186
  * @param theme - The optional terminal theme
191
187
  * @returns The initial immutable key state
192
188
  */
193
- export declare function createPasswordState(field: PasswordField, styler?: StylerInterface, theme?: PromptThemeOptions): {
194
- message: string;
195
- mask: string;
196
- styler: StylerInterface;
197
- theme: PromptTheme;
198
- value: string;
199
- };
189
+ export declare function createPasswordState(field: PasswordField, styler?: StylerInterface, theme?: PromptThemeOptions): PasswordState;
200
190
 
201
191
  /**
202
- * Create the headless {@link PromptInterface} broker. It parks live forms and applies remote
192
+ * Creates the headless {@link PromptInterface} broker. It parks live forms and applies remote
203
193
  * answers to the authoritative instances.
204
194
  *
205
195
  * @param options - See {@link PromptOptions}
@@ -212,7 +202,7 @@ export declare function createPasswordState(field: PasswordField, styler?: Style
212
202
  *
213
203
  * @example
214
204
  * ```ts
215
- * import { createPrompt } from '@src/core'
205
+ * import { createPrompt } from '@orkestrel/terminal'
216
206
  * import { createForm } from '@orkestrel/form'
217
207
  *
218
208
  * const prompt = createPrompt()
@@ -224,9 +214,10 @@ export declare function createPasswordState(field: PasswordField, styler?: Style
224
214
  export declare function createPrompt(options?: PromptOptions): PromptInterface;
225
215
 
226
216
  /**
227
- * Create the SSE prompt {@link PromptClientInterface} BRIDGE — it connects to a remote broker's SSE
228
- * endpoint, dispatches each received form to a local {@link import('./types.js').TerminalInterface},
229
- * and POSTs the answer back. Universal — `fetch` / SSE are web-standard.
217
+ * Creates the SSE prompt {@link PromptClientInterface} bridge — it connects to a remote broker's
218
+ * SSE endpoint, dispatches each received form to a local
219
+ * {@link import('./types.js').TerminalInterface}, and POSTs the answer back. Universal — `fetch`
220
+ * and SSE are web standards.
230
221
  *
231
222
  * @param options - See {@link PromptClientOptions} (`url` + `terminal` required)
232
223
  * @returns A {@link PromptClientInterface}
@@ -236,11 +227,11 @@ export declare function createPrompt(options?: PromptOptions): PromptInterface;
236
227
  * ends; it reconnects with the `delay` backoff unless `reconnect` is `false` / the client was
237
228
  * `destroy`ed. Inject `options.fetch` (a scripted `fetch`) and `options.timer` to drive it
238
229
  * deterministically in tests — no real network.
239
- * - **§14 wire narrowing.** Every decoded prompt is guard-narrowed before dispatch (never an `as`).
230
+ * - **Wire narrowing.** Every decoded prompt is guard-narrowed before dispatch (never an `as`).
240
231
  *
241
232
  * @example
242
233
  * ```ts
243
- * import { createPromptClient } from '@src/core'
234
+ * import { createPromptClient } from '@orkestrel/terminal'
244
235
  *
245
236
  * const client = createPromptClient({ url: 'http://host/prompts', terminal })
246
237
  * await client.connect()
@@ -249,7 +240,7 @@ export declare function createPrompt(options?: PromptOptions): PromptInterface;
249
240
  export declare function createPromptClient(options: PromptClientOptions): PromptClientInterface;
250
241
 
251
242
  /**
252
- * Build a complete {@link PromptTheme} by merging a partial one over
243
+ * Builds a complete {@link PromptTheme} by merging a partial one over
253
244
  * {@link DEFAULT_PROMPT_THEME}, leaf by leaf — each supplied icon replaces that glyph, each
254
245
  * supplied role replaces that {@link Style}, and everything else keeps its default. Each supplied
255
246
  * style is snapshotted through the console module's own
@@ -271,32 +262,27 @@ export declare function createPromptClient(options: PromptClientOptions): Prompt
271
262
  export declare function createPromptTheme(options?: PromptThemeOptions): PromptTheme;
272
263
 
273
264
  /**
274
- * Build the initial select-field key state.
265
+ * Builds the initial select-field reducer state — the offered choices, with the focus pre-placed on
266
+ * the declared default.
275
267
  *
276
268
  * @param field - The select field to render
277
269
  * @param styler - The styler used to render the view
278
270
  * @param theme - The optional terminal theme
279
271
  * @returns The initial immutable key state
280
272
  */
281
- export declare function createSelectState(field: SelectField, styler?: StylerInterface, theme?: PromptThemeOptions): {
282
- message: string;
283
- choices: FieldChoice[];
284
- styler: StylerInterface;
285
- theme: PromptTheme;
286
- focused: number;
287
- };
273
+ export declare function createSelectState(field: SelectField, styler?: StylerInterface, theme?: PromptThemeOptions): SelectState;
288
274
 
289
275
  /**
290
- * Create the multi-endpoint {@link TerminalManager} — a named registry of
291
- * {@link PromptInterface} brokers so several parties can `ask` prompts of each other by name,
292
- * with a transitive DEADLOCK check across every in-flight ask.
276
+ * Creates the multi-endpoint {@link TerminalManager} — a named registry of {@link PromptInterface}
277
+ * brokers so several parties can `ask` forms of each other by name, with a transitive cycle check
278
+ * that refuses `DEADLOCK` across every in-flight ask.
293
279
  *
294
280
  * @param options - See {@link TerminalManagerOptions}
295
281
  * @returns A {@link TerminalManager}
296
282
  *
297
283
  * @example
298
284
  * ```ts
299
- * import { createTerminalManager } from '@src/core'
285
+ * import { createTerminalManager } from '@orkestrel/terminal'
300
286
  *
301
287
  * const manager = createTerminalManager()
302
288
  * manager.add('agent')
@@ -304,33 +290,34 @@ export declare function createSelectState(field: SelectField, styler?: StylerInt
304
290
  */
305
291
  export declare function createTerminalManager(options?: TerminalManagerOptions): TerminalManagerInterface;
306
292
 
307
- /** Ctrl+A (SOH, U+0001) — move to start of line. */
293
+ /** Names the Ctrl+A byte (SOH, U+0001) — move to start of line. */
308
294
  export declare const CTRL_A: string;
309
295
 
310
- /** Ctrl+C (ETX, U+0003) — interrupt / cancel. */
296
+ /** Names the Ctrl+C byte (ETX, U+0003) — interrupt / cancel. */
311
297
  export declare const CTRL_C: string;
312
298
 
313
- /** Ctrl+D (EOT, U+0004) — end-of-transmission / finish (the editor's commit key). */
299
+ /** Names the Ctrl+D byte (EOT, U+0004) — end-of-transmission / finish (the editor's commit key). */
314
300
  export declare const CTRL_D: string;
315
301
 
316
- /** Ctrl+E (ENQ, U+0005) — move to end of line. */
302
+ /** Names the Ctrl+E byte (ENQ, U+0005) — move to end of line. */
317
303
  export declare const CTRL_E: string;
318
304
 
319
- /** Ctrl+U (NAK, U+0015) — clear the current line. */
305
+ /** Names the Ctrl+U byte (NAK, U+0015) — clear the current line. */
320
306
  export declare const CTRL_U: string;
321
307
 
322
308
  /**
323
- * A {@link TerminalStoreInterface} backed by one table of the `databases` layer — an endpoint's
324
- * durable CONFIG state IS a row, so persistence reduces to keyed point-access (`get` / `set` /
325
- * `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
326
- * {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}.
309
+ * Implements a {@link TerminalStoreInterface} backed by one table of the `databases` layer — an
310
+ * endpoint's durable config state is a row, so persistence reduces to keyed point-access (`get` /
311
+ * `set` / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
312
+ * {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. A stored `snapshot` is narrowed
313
+ * with {@link import('../validators.js').isTerminalSnapshot} on read.
327
314
  *
328
315
  * @remarks
329
316
  * The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,
330
317
  * JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /
331
318
  * IndexedDB backend swaps in WITHOUT touching the manager — the same seam as
332
319
  * {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. The driver defaults to memory
333
- * ({@link import('./factories.js').createDatabaseTerminalStore} passes `createMemoryDriver()`), so
320
+ * ({@link import('../factories.js').createDatabaseTerminalStore} passes `createMemoryDriver()`), so
334
321
  * it ALSO works in memory out of the box; you opt into the durable plumbing by passing a JSON /
335
322
  * SQLite / IndexedDB driver.
336
323
  *
@@ -342,18 +329,19 @@ export declare const CTRL_U: string;
342
329
  * - **`set(snapshot)` upserts under the snapshot's OWN `id`** (no separate id param) — it writes
343
330
  * the row `{ id: snapshot.id, snapshot }`.
344
331
  * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
345
- * a {@link TerminalSnapshot} ({@link import('./validators.js').isTerminalSnapshot} — the AGENTS §14
346
- * boundary narrow for an untrusted storage read), or `undefined` if none is stored.
332
+ * a {@link TerminalSnapshot} ({@link import('../validators.js').isTerminalSnapshot} — the total
333
+ * guard that narrows an untrusted storage read), or `undefined` if none is stored.
347
334
  * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
348
335
  *
349
336
  * There is NO idle-TTL / eviction — a persisted config lives until an explicit `delete`. The public
350
- * surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method bijection with
351
- * {@link TerminalStoreInterface}). Hydration stays a caller concern: `open` always restores an EMPTY
337
+ * surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and
338
+ * {@link TerminalStoreInterface} carry the same methods. Hydration stays a caller concern: `open` always restores an EMPTY
352
339
  * broker — parked Promises are process-bound and never resurrected.
353
340
  *
354
341
  * @example
355
342
  * ```ts
356
- * import { createDatabaseTerminalStore, createMemoryDriver } from '@src/core'
343
+ * import { createDatabaseTerminalStore } from '@orkestrel/terminal'
344
+ * import { createMemoryDriver } from '@orkestrel/database'
357
345
  *
358
346
  * const store = createDatabaseTerminalStore(createMemoryDriver()) // a durable driver swaps in here
359
347
  * await store.set({ id: 'shell', timeout: 5000 }) // persist the config (one JSON column)
@@ -364,25 +352,42 @@ export declare const CTRL_U: string;
364
352
  export declare class DatabaseTerminalStore implements TerminalStoreInterface {
365
353
  #private;
366
354
  /**
367
- * Wrap a table as a terminal store.
355
+ * Wraps a table as a terminal store.
368
356
  *
369
357
  * @param table - The {@link TableInterface} holding the snapshots — its row is the
370
358
  * {@link TerminalSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
371
359
  */
372
360
  constructor(table: TableInterface<TerminalSnapshotRow>);
373
- /** Resolve the persisted snapshot for `id`, narrowing the opaque JSON column back to a `TerminalSnapshot`. */
361
+ /**
362
+ * Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a
363
+ * `TerminalSnapshot`.
364
+ *
365
+ * @param id - The endpoint name the row is keyed by
366
+ * @returns The stored snapshot, or `undefined` when none is held or the column is off-shape
367
+ */
374
368
  get(id: string): Promise<TerminalSnapshot | undefined>;
375
- /** Insert or replace under the snapshot's OWN `id` (no separate id param) — the row is `{ id, snapshot }`. */
369
+ /**
370
+ * Inserts or replaces under the snapshot's OWN `id` (no separate id param) — the row is
371
+ * `{ id, snapshot }`.
372
+ *
373
+ * @param snapshot - The config snapshot to persist, carrying its own `id`
374
+ * @returns A promise that settles once the row is written
375
+ */
376
376
  set(snapshot: TerminalSnapshot): Promise<void>;
377
- /** Drop a snapshot by id; an absent id is a no-op (no throw). */
377
+ /**
378
+ * Drops a snapshot by id; an absent id is a no-op (no throw).
379
+ *
380
+ * @param id - The endpoint name to drop
381
+ * @returns A promise that settles once the row is gone
382
+ */
378
383
  delete(id: string): Promise<void>;
379
384
  }
380
385
 
381
- /** The default mask glyph {@link import('./helpers.js').createPasswordState} uses — `*`. */
386
+ /** Names the default mask glyph {@link import('./helpers.js').createPasswordState} uses — `*`. */
382
387
  export declare const DEFAULT_MASK = "*";
383
388
 
384
389
  /**
385
- * The {@link import('./types.js').PromptTheme} every prompt renders with unless its options supply
390
+ * Holds the {@link import('./types.js').PromptTheme} every prompt renders with unless its options supply
386
391
  * another — the glyph set assembled from {@link PROMPT_ICONS} plus the console
387
392
  * {@link import('@orkestrel/console').STATUS_ICONS} `success` / `error` marks, and the console
388
393
  * {@link import('@orkestrel/console').Style} each role is painted with. Deeply frozen through the
@@ -398,60 +403,70 @@ export declare const DEFAULT_MASK = "*";
398
403
  */
399
404
  export declare const DEFAULT_PROMPT_THEME: PromptTheme;
400
405
 
401
- /** How long (ms) the {@link import('./types.js').PromptInterface} broker parks an unanswered prompt before it expires — 5 minutes. */
406
+ /** Holds how long (ms) the {@link import('./types.js').PromptInterface} broker parks an unanswered form before it expires — 5 minutes. */
402
407
  export declare const DEFAULT_PROMPT_TIMEOUT_MS = 300000;
403
408
 
404
- /** How long (ms) the {@link import('./types.js').PromptClientInterface} waits before each reconnect attempt — 2 seconds. */
409
+ /** Holds how long (ms) the {@link import('./types.js').PromptClientInterface} waits before each reconnect attempt — 2 seconds. */
405
410
  export declare const DEFAULT_RECONNECT_DELAY_MS = 2000;
406
411
 
407
412
  /**
408
- * The default {@link import('./types.js').TimerHandler} — a thin host `setTimeout` / `clearTimeout`
409
- * wrapper that arms `callback` after `ms` and returns a {@link TimerCancel}. The deadline seam
413
+ * Implements the default {@link import('./types.js').TimerHandler} — a thin host `setTimeout` / `clearTimeout`
414
+ * wrapper that arms `callback` after `ms` and returns a {@link TimerCancelFunction}. The deadline seam
410
415
  * behind both the {@link import('./Prompt.js').Prompt} broker (its expiry) and the
411
416
  * {@link import('./PromptClient.js').PromptClient} (its reconnect backoff); a test injects a
412
417
  * deterministic timer instead, so neither entity touches real time.
418
+ *
419
+ * @param callback - The deadline callback to arm
420
+ * @param ms - How long to wait before firing it, in milliseconds
421
+ * @returns The {@link TimerCancelFunction} that clears the armed deadline
413
422
  */
414
- export declare function defaultTimer(callback: () => void, ms: number): TimerCancel;
423
+ export declare function defaultTimer(callback: () => void, ms: number): TimerCancelFunction;
415
424
 
416
- /** Delete (DEL, U+007F) — the usual Backspace byte on a Unix TTY. */
425
+ /** Names the delete byte (DEL, U+007F) — the usual Backspace byte on a Unix TTY. */
417
426
  export declare const DELETE: string;
418
427
 
419
428
  /**
420
- * Apply a single line-editing {@link KeyEvent} to a text buffer — the editing shared by input /
421
- * password / editor. A printable key appends its character; `backspace` drops the last character;
422
- * `space` appends a space; ctrl-u clears the line. Returns the new buffer, or `undefined` when the
423
- * key does not edit the line (so the caller can leave the state untouched).
429
+ * Applies a single line-editing {@link KeyEvent} to a text buffer — the editing shared by input,
430
+ * password, and editor. A printable key appends its character; `backspace` drops the last
431
+ * character; `space` appends a space; ctrl-u clears the line; a key that edits nothing returns
432
+ * `undefined`.
433
+ *
434
+ * @param value - The buffer the field holds so far
435
+ * @param key - The decoded keypress to apply
436
+ * @returns The new buffer, or `undefined` when the key does not edit the line, so the caller can
437
+ * leave the state untouched
424
438
  */
425
439
  export declare function editLine(value: string, key: KeyEvent): string | undefined;
426
440
 
427
441
  /**
428
- * Advance an editor prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
429
- * reducer. Printable characters extend the current line; backspace shrinks it; return commits the
430
- * current line and starts a fresh one; ctrl-d FINISHES (joining all lines, falling back to the
431
- * default when empty); ctrl-c cancels. The form validates the candidate after the driver fills it.
432
- */
433
- export declare function editorReduce(state: ReturnType<typeof createEditorState>, key: KeyEvent): PromptStep<string, ReturnType<typeof createEditorState>>;
434
-
435
- /**
436
- * Render an editor-field key state as a multi-line styled view with its finish hint.
437
- */
438
- export declare function editorView(state: ReturnType<typeof createEditorState>): string;
439
-
440
- /** The styled error line (`✖ message`) a form driver appends for a field failure. */
441
- export declare function errorLine(styler: StylerInterface, theme: PromptTheme, message: string): string;
442
-
443
- /** Escape (ESC, U+001B) — the lone byte, and the lead byte of every CSI / SS3 sequence. */
444
- export declare const ESCAPE: string;
442
+ * Represents the immutable state an editor field's reducer carries — the committed lines and the line still
443
+ * being typed, kept apart so a return commits one without ending the field.
444
+ *
445
+ * @remarks
446
+ * - `message` — the sanitized label the header renders.
447
+ * - `default` — the text an empty finish falls back to.
448
+ * - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
449
+ * - `lines` — the lines already committed with a return.
450
+ * - `current` — the line in progress.
451
+ */
452
+ export declare interface EditorState {
453
+ readonly message: string;
454
+ readonly default: string;
455
+ readonly styler: StylerInterface;
456
+ readonly theme: PromptTheme;
457
+ readonly lines: readonly string[];
458
+ readonly current: string;
459
+ }
445
460
 
446
461
  /**
447
- * A minimal `fetch` — the subset of the global `fetch` a {@link PromptClientInterface} uses: open
462
+ * Represents a minimal `fetch` — the subset of the global `fetch` a {@link PromptClientInterface} uses: open
448
463
  * the SSE stream, POST an answer. Injected so a test drives the client with a scripted `Response`
449
464
  * instead of a real network.
450
465
  */
451
466
  export declare type FetchHandler = (input: string, init?: FetchInit) => Promise<Response>;
452
467
 
453
468
  /**
454
- * The request init a {@link PromptClientInterface} passes to its {@link FetchHandler} — the
469
+ * Represents the request init a {@link PromptClientInterface} passes to its {@link FetchHandler} — the
455
470
  * `RequestInit` fields it actually sets.
456
471
  */
457
472
  export declare interface FetchInit {
@@ -461,44 +476,58 @@ export declare interface FetchInit {
461
476
  readonly signal?: AbortSignal;
462
477
  }
463
478
 
464
- /** The default {@link import('./types.js').FetchHandler} — the global `fetch`, adapted to the minimal injected shape the {@link import('./PromptClient.js').PromptClient} uses. */
465
- export declare function globalFetch(input: string, init?: FetchInit): Promise<Response>;
466
-
467
- /** The auth-token request header the {@link import('./types.js').PromptClientInterface} sends. */
468
- export declare const HEADER_TOKEN = "x-orkestrel-token";
469
-
470
479
  /**
471
- * Render a prompt header followed by a key hint painted with the `hint` role, or the header alone
472
- * when no hint is supplied.
480
+ * Implements the default {@link import('./types.js').FetchHandler} — the global `fetch`, adapted to
481
+ * the minimal injected shape the {@link import('./PromptClient.js').PromptClient} uses.
473
482
  *
474
- * @param styler - The console styler that renders each role
475
- * @param theme - The resolved prompt theme
476
- * @param message - The prompt's question text
477
- * @param hint - The optional key hint to append
478
- * @returns The rendered header with the optional hint
483
+ * @param input - The request URL
484
+ * @param init - The request init the client sets — method, headers, body, and abort signal
485
+ * @returns The host `fetch` promise for that request
479
486
  */
480
- export declare function hintedHeader(styler: StylerInterface, theme: PromptTheme, message: string, hint?: string): string;
487
+ export declare function globalFetch(input: string, init?: FetchInit): Promise<Response>;
481
488
 
482
489
  /**
483
- * Advance an input prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
484
- * reducer. Printable characters extend the value; backspace shrinks it; ctrl-u clears it; ctrl-c
485
- * cancels; return produces the candidate value, with an empty line falling back to the default.
490
+ * Names the auth-token request header the {@link import('./types.js').PromptClientInterface} sends
491
+ * when a `token` is configured — `x-orkestrel-token`.
486
492
  */
487
- export declare function inputReduce(state: ReturnType<typeof createInputState>, key: KeyEvent): PromptStep<string, ReturnType<typeof createInputState>>;
493
+ export declare const HEADER_TOKEN = "x-orkestrel-token";
488
494
 
489
- /** Render a text-field key state as a styled view. */
490
- export declare function inputView(state: ReturnType<typeof createInputState>): string;
495
+ /**
496
+ * Represents the immutable state a text field's reducer carries — built by
497
+ * {@link import('./helpers.js').createInputState}, rendered by
498
+ * {@link import('./helpers.js').renderInputView}, and advanced by
499
+ * {@link import('./helpers.js').reduceInput}.
500
+ *
501
+ * @remarks
502
+ * - `message` — the sanitized label the header renders.
503
+ * - `default` — the declared default a bare return submits.
504
+ * - `styler` — the console styler every role is painted through.
505
+ * - `theme` — the resolved {@link PromptTheme}.
506
+ * - `value` — the characters typed so far.
507
+ */
508
+ export declare interface InputState {
509
+ readonly message: string;
510
+ readonly default: string;
511
+ readonly styler: StylerInterface;
512
+ readonly theme: PromptTheme;
513
+ readonly value: string;
514
+ }
491
515
 
492
516
  /**
493
- * Whether a caught value is an `AbortError` — the {@link import('./PromptClient.js').PromptClient}
517
+ * Checks whether a caught value is an `AbortError` — the {@link import('./PromptClient.js').PromptClient}
494
518
  * distinguishes a deliberate `disconnect` / teardown (an aborted `fetch`) from a real fault, so it
495
519
  * exits its connect loop quietly instead of emitting `error` / reconnecting.
520
+ *
521
+ * @param error - The caught value to test
522
+ * @returns True if the value is a host `Error` or `DOMException` named `AbortError`; false otherwise
496
523
  */
497
524
  export declare function isAbortError(error: unknown): boolean;
498
525
 
499
526
  /**
500
- * Whether `url` is an INSECURE remote endpoint — a plain `http://` URL whose host is NOT a
501
- * loopback address. Pure string parsing (no `URL` global), so it stays total on malformed input.
527
+ * Checks whether `url` is an insecure remote endpoint — a plain `http://` URL whose host is not a
528
+ * loopback address. Pure string parsing (no `URL` global), so it stays total on malformed input;
529
+ * the {@link import('./PromptClient.js').PromptClient} warns once when a `token` would cross such
530
+ * an endpoint in cleartext.
502
531
  *
503
532
  * @remarks
504
533
  * A loopback host (`localhost`, `127.0.0.1`, `[::1]`) over `http://` is exempt (local
@@ -506,7 +535,7 @@ export declare function isAbortError(error: unknown): boolean;
506
535
  * An `https://` URL (or any non-`http://` scheme) is never flagged.
507
536
  *
508
537
  * @param url - The candidate endpoint URL
509
- * @returns `true` when `url` is a non-loopback `http://` endpoint
538
+ * @returns True if `url` is a non-loopback `http://` endpoint; false otherwise
510
539
  *
511
540
  * @example
512
541
  * ```ts
@@ -518,28 +547,40 @@ export declare function isAbortError(error: unknown): boolean;
518
547
  export declare function isInsecureRemote(url: string): boolean;
519
548
 
520
549
  /**
521
- * Narrow an unknown wire value to a {@link PendingForm} envelope.
550
+ * Narrows an unknown wire value to a {@link PendingForm} envelope — the envelope alone, because the
551
+ * form package's `parseForm` owns the schema payload.
522
552
  *
523
553
  * @remarks
524
554
  * This guard checks the transport record and proves only that `schema` is a record. The Form
525
555
  * package's `parseForm` owns the schema payload and its semantic audit.
526
556
  *
527
557
  * @param value - The decoded wire value to inspect
528
- * @returns Whether the value is a complete pending-form envelope
558
+ * @returns True if the value is a complete pending-form envelope; false otherwise
529
559
  */
530
560
  export declare function isPendingForm(value: unknown): value is PendingForm;
531
561
 
532
- /** Narrow an unknown value to a {@link PendingFormStatus}. */
562
+ /**
563
+ * Narrows an unknown value to a {@link PendingFormStatus}.
564
+ *
565
+ * @param value - The candidate ticket status
566
+ * @returns True if the value is one of the declared ticket statuses; false otherwise
567
+ */
533
568
  export declare const isPendingFormStatus: Guard<PendingFormStatus>;
534
569
 
535
- /** Whether a single character is a printable (non-control) character — used by {@link parseKey}'s char fallback. */
570
+ /**
571
+ * Checks whether a single character is printable — the fallback test {@link parseKey} applies after
572
+ * the control bytes and the escape sequences, so the C0 controls and DEL are excluded.
573
+ *
574
+ * @param character - The single character to test
575
+ * @returns True if the character is at or above space and is not DEL; false otherwise
576
+ */
536
577
  export declare function isPrintable(character: string): boolean;
537
578
 
538
579
  /**
539
- * Narrow an unknown caught value to a {@link TerminalError}.
580
+ * Narrows an unknown caught value to a {@link TerminalError}, so a caller can branch on its `code`.
540
581
  *
541
582
  * @param value - The value to test (typically a `catch` binding or a rejected prompt call)
542
- * @returns `true` when `value` is a {@link TerminalError}
583
+ * @returns True if `value` is a {@link TerminalError}; false otherwise
543
584
  *
544
585
  * @example
545
586
  * ```ts
@@ -554,30 +595,34 @@ export declare function isPrintable(character: string): boolean;
554
595
  */
555
596
  export declare function isTerminalError(value: unknown): value is TerminalError;
556
597
 
557
- /** Narrow an unknown value to a {@link TerminalSnapshot}. */
598
+ /**
599
+ * Narrows an unknown value to a {@link TerminalSnapshot} — a non-empty `id` and an optional numeric
600
+ * `timeout`, the read boundary a store applies to an untrusted persisted row.
601
+ *
602
+ * @param value - The candidate snapshot read back from storage
603
+ * @returns True if the value carries a non-empty `id` and an optional numeric `timeout`; false otherwise
604
+ */
558
605
  export declare const isTerminalSnapshot: Guard<TerminalSnapshot>;
559
606
 
560
607
  /**
561
- * Narrow an unknown value to a transport-neutral {@link WireEvent}.
608
+ * Narrows an unknown value to a transport-neutral {@link WireEvent} — the guard a consumer's own
609
+ * transport applies to an inbound frame.
562
610
  *
563
611
  * @param value - The candidate wire event
564
- * @returns Whether the value carries an event name, serialized data, and an optional id
612
+ * @returns True if the value carries an event name, serialized data, and an optional id; false otherwise
565
613
  */
566
614
  export declare const isWireEvent: Guard<WireEvent>;
567
615
 
568
616
  /**
569
- * The Control Sequence Introducer lead (`ESC[`) for the navigation keys — the prefix of the
570
- * arrow / home / end / delete sequences {@link SEQUENCE_NAMES} is keyed by. Named `KEY_CSI`
571
- * (not `CSI`) so it never collides with the console module's SGR `CSI` (both barrel through
572
- * `@src/core`).
617
+ * Names the Single Shift Three lead (`ESCO`) — the alternate arrow-key prefix some terminals emit
618
+ * (`ESC O A`). Built from the console module's own {@link import('@orkestrel/console').ESC}; the
619
+ * navigation keys' CSI lead is that module's {@link import('@orkestrel/console').CSI}, which this
620
+ * package reuses rather than redeclaring.
573
621
  */
574
- export declare const KEY_CSI: string;
575
-
576
- /** The Single Shift Three lead (`ESCO`) — the alternate arrow-key prefix some terminals emit (`ESC O A`). */
577
622
  export declare const KEY_SS3: string;
578
623
 
579
624
  /**
580
- * One decoded keypress — the TTY-agnostic representation of a single key, the output of
625
+ * Represents one decoded keypress — the TTY-agnostic representation of a single key, the output of
581
626
  * {@link import('./helpers.js').parseKey}. A driver reads `name` and the modifier flags to decide
582
627
  * its transition; `sequence` is preserved so a printable character round-trips and an unknown
583
628
  * escape is never lost.
@@ -586,15 +631,15 @@ export declare const KEY_SS3: string;
586
631
  * - `name` — the canonical key name: a control or navigation key (`return`, `backspace`, `tab`,
587
632
  * `escape`, `up` / `down` / `left` / `right`, `space`, `home`, `end`, `delete`), a named ctrl
588
633
  * combo (`c` with `ctrl` true for ctrl-c, likewise `d` / `u` / `a` / `e`), or the printable
589
- * character itself (`'a'`, `'7'`, `'?'`). An unrecognized sequence yields `name: ''`; the decoder
590
- * is total and never throws.
634
+ * character itself (`'a'`, `'7'`, `'?'`). An unrecognized sequence carries NO `name` — absence,
635
+ * never an empty string — and the decoder stays total and never throws.
591
636
  * - `sequence` — the exact input bytes as a string (a `Uint8Array` is decoded UTF-8). The driver
592
637
  * writes this verbatim for a printable key.
593
638
  * - `ctrl` / `meta` / `shift` — the modifier flags. `ctrl` is true for a C0 control byte, `meta`
594
639
  * for an ESC-prefixed (Alt) sequence, `shift` for an uppercase-letter printable.
595
640
  */
596
641
  export declare interface KeyEvent {
597
- readonly name: string;
642
+ readonly name?: string;
598
643
  readonly sequence: string;
599
644
  readonly ctrl: boolean;
600
645
  readonly meta: boolean;
@@ -602,14 +647,15 @@ export declare interface KeyEvent {
602
647
  }
603
648
 
604
649
  /**
605
- * The in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of
606
- * {@link TerminalSnapshot}s keyed by endpoint id, the DEFAULT store
607
- * {@link import('./factories.js').createMemoryTerminalStore} builds. The EXACT twin of
608
- * {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore}.
650
+ * Implements the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of
651
+ * {@link TerminalSnapshot} records keyed by endpoint id, the default store
652
+ * {@link import('../factories.js').createMemoryTerminalStore} builds and the exact twin of
653
+ * {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore}. It carries no idle expiry and
654
+ * no eviction.
609
655
  *
610
656
  * @remarks
611
- * A plain `Map<string, TerminalSnapshot>` (AGENTS §21 — the snapshot is already pure, self-contained
612
- * CONFIG-only JSON, so no encoding is needed for the memory tier). There is NO idle-TTL and NO
657
+ * A plain `Map<string, TerminalSnapshot>` — the snapshot is already pure, self-contained CONFIG-only
658
+ * JSON, so the memory tier needs no encoding. There is NO idle-TTL and NO
613
659
  * eviction: a persisted config lives until an explicit `delete`. A durable backend (JSON / SQLite /
614
660
  * IndexedDB) swaps in through the SAME interface without touching the manager — its
615
661
  * driver-pluggable twin is {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore} (the
@@ -619,13 +665,13 @@ export declare interface KeyEvent {
619
665
  * - **`set` inserts / replaces under the snapshot's OWN `id`** (no separate id param).
620
666
  * - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).
621
667
  *
622
- * The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
623
- * bijection with {@link TerminalStoreInterface}). Hydration is a caller concern: `open` always
668
+ * The public surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and
669
+ * {@link TerminalStoreInterface} carry the same methods. Hydration is a caller concern: `open` always
624
670
  * restores an EMPTY broker — parked Promises are process-bound and never resurrected.
625
671
  *
626
672
  * @example
627
673
  * ```ts
628
- * import { createMemoryTerminalStore } from '@src/core'
674
+ * import { createMemoryTerminalStore } from '@orkestrel/terminal'
629
675
  *
630
676
  * const store = createMemoryTerminalStore()
631
677
  * await store.set({ id: 'shell', timeout: 5000 }) // persist a config
@@ -635,36 +681,55 @@ export declare interface KeyEvent {
635
681
  */
636
682
  export declare class MemoryTerminalStore implements TerminalStoreInterface {
637
683
  #private;
684
+ /**
685
+ * Resolves the persisted snapshot for `id`.
686
+ *
687
+ * @param id - The endpoint name the snapshot is keyed by
688
+ * @returns The stored snapshot, or `undefined` when none is held
689
+ */
638
690
  get(id: string): Promise<TerminalSnapshot | undefined>;
691
+ /**
692
+ * Inserts or replaces under the snapshot's OWN `id` (no separate id param).
693
+ *
694
+ * @param snapshot - The config snapshot to persist, carrying its own `id`
695
+ * @returns A promise that settles once the snapshot is held
696
+ */
639
697
  set(snapshot: TerminalSnapshot): Promise<void>;
698
+ /**
699
+ * Drops a snapshot by id; an absent id is a no-op (no throw).
700
+ *
701
+ * @param id - The endpoint name to drop
702
+ * @returns A promise that settles once the snapshot is gone
703
+ */
640
704
  delete(id: string): Promise<void>;
641
705
  }
642
706
 
643
- /** Line feed (`\n`, U+000A) — Enter on some terminals / pasted input. */
707
+ /** Names the line feed byte (`\n`, U+000A) — Enter on some terminals / pasted input. */
644
708
  export declare const NEWLINE: string;
645
709
 
646
710
  /**
647
- * One parked form's runtime state inside the broker — the live form, the wire-safe record the
711
+ * Represents one parked form's runtime state inside the broker — the live form, the wire-safe record the
648
712
  * broker exposes, and the cancel for its expiry timer.
649
713
  *
650
714
  * @remarks
651
- * `form` is the AUTHORITATIVE form the caller parked, not a copy: an answer fills and submits this
715
+ * `form` is the authoritative form the caller parked, not a copy: an answer fills and submits this
652
716
  * one, so a `custom` rule that never crossed the wire still decides. Expiry destroys it, which
653
717
  * abandons it and settles the caller's promise through the form's own lifecycle. `pending` is the
654
718
  * wire record, whose `status` tracks the ticket.
655
719
  */
656
- export declare interface Parked {
720
+ export declare interface ParkedForm {
657
721
  readonly form: FormInterface;
722
+ /** Lists every parked record (`pending()`), or looks one up by id (`pending(id)`). */
658
723
  readonly pending: PendingForm;
659
- readonly cancel: TimerCancel;
724
+ readonly cancel: TimerCancelFunction;
660
725
  }
661
726
 
662
727
  /**
663
- * The parking envelope — everything the broker needs about a park that the form itself does not
728
+ * Represents the parking envelope — everything the broker needs about a park that the form itself does not
664
729
  * say.
665
730
  *
666
731
  * @remarks
667
- * `from` and `to` are the attribution edge, set ONLY by a {@link TerminalManagerInterface}: which
732
+ * `from` and `to` are the attribution edge, set only by a {@link TerminalManagerInterface}: which
668
733
  * endpoint asked, which endpoint must answer. A direct broker caller passes no request at all.
669
734
  */
670
735
  export declare interface ParkRequest {
@@ -673,24 +738,24 @@ export declare interface ParkRequest {
673
738
  }
674
739
 
675
740
  /**
676
- * Decode one keypress's bytes into a {@link KeyEvent} — total, never throws. A `Uint8Array` is
677
- * read as UTF-8; the resulting string is matched against the known control bytes and the CRLF
678
- * pair ({@link CONTROL_NAMES}) and escape sequences ({@link SEQUENCE_NAMES}), falling back to a
679
- * single printable character. An unrecognized sequence yields `name: ''` with the raw `sequence`
741
+ * Decodes one keypress's bytes into a {@link KeyEvent} — total, never throws. A `Uint8Array` is
742
+ * read as UTF-8; the resulting string is matched against the known control bytes and the CRLF pair
743
+ * ({@link CONTROL_NAMES}) and escape sequences ({@link SEQUENCE_NAMES}), falling back to a single
744
+ * printable character. An unrecognized sequence carries no `name`, with the raw `sequence`
680
745
  * preserved.
681
746
  *
682
747
  * @remarks
683
748
  * - **Single control byte.** A one-character control input (`return` / `backspace` / `tab` /
684
749
  * `escape` / `space`, or a Ctrl combo `c` / `d` / `u` / `a` / `e`), or the two-byte `\r\n`
685
750
  * CRLF pair, is looked up in {@link CONTROL_NAMES}, carrying its `ctrl` flag.
686
- * - **Escape sequence.** A multi-byte ESC sequence (`up` / `down` / `left` / `right` in BOTH the
751
+ * - **Escape sequence.** A multi-byte ESC sequence (`up` / `down` / `left` / `right` in both the
687
752
  * `ESC[A` and `ESCOA` forms, plus `home` / `end` / `delete`) is looked up in
688
753
  * {@link SEQUENCE_NAMES} and flagged `meta`.
689
754
  * - **Printable character.** A single printable character becomes `name` = that character, with
690
755
  * `shift` set when it is an uppercase letter. A multi-code-point printable (an emoji, a pasted
691
756
  * run) keeps its first code point as the name and the whole input as `sequence`.
692
- * - **Unknown.** Anything else (an unrecognized escape, an empty input) yields `name: ''` —
693
- * total, so the driver never crashes on a stray byte.
757
+ * - **Unknown.** Anything else (an unrecognized escape, an empty input) yields an event with NO
758
+ * `name` — absence, never an empty string — total, so the driver never crashes on a stray byte.
694
759
  *
695
760
  * @param input - The raw keypress bytes, as a string or `Uint8Array`
696
761
  * @returns The decoded {@link KeyEvent}
@@ -707,18 +772,26 @@ export declare interface ParkRequest {
707
772
  export declare function parseKey(input: string | Uint8Array): KeyEvent;
708
773
 
709
774
  /**
710
- * Advance a password prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
711
- * reducer. Identical line-editing to {@link inputReduce} (printable extends, backspace shrinks,
712
- * ctrl-u clears, ctrl-c cancels) but the view masks the value. Return produces the candidate value.
713
- */
714
- export declare function passwordReduce(state: ReturnType<typeof createPasswordState>, key: KeyEvent): PromptStep<string, ReturnType<typeof createPasswordState>>;
715
-
716
- /** Render a password-field key state as a styled view. */
717
- export declare function passwordView(state: ReturnType<typeof createPasswordState>): string;
775
+ * Represents the immutable state a password field's reducer carries — the text state with the mask glyph in
776
+ * place of a default, because a secret is never seeded from the schema.
777
+ *
778
+ * @remarks
779
+ * - `message` — the sanitized label the header renders.
780
+ * - `mask` — the glyph each typed character renders as.
781
+ * - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
782
+ * - `value` — the characters typed so far, rendered only as the mask repeated.
783
+ */
784
+ export declare interface PasswordState {
785
+ readonly message: string;
786
+ readonly mask: string;
787
+ readonly styler: StylerInterface;
788
+ readonly theme: PromptTheme;
789
+ readonly value: string;
790
+ }
718
791
 
719
792
  /**
720
- * One form PARKED by the broker — an id-keyed, wire-safe record of a live form awaiting a remote
721
- * answer. The value a `pending` listener receives and the broker serializes over SSE to a
793
+ * Represents one form parked by the broker — an id-keyed, wire-safe record of a live form awaiting
794
+ * a remote answer. The value a `pending` listener receives and the broker serializes over SSE to a
722
795
  * {@link PromptClientInterface}.
723
796
  *
724
797
  * @remarks
@@ -743,9 +816,9 @@ export declare interface PendingForm {
743
816
  }
744
817
 
745
818
  /**
746
- * The lifecycle status of a parked {@link PendingForm} — where the TICKET stands, which is not
747
- * where the form stands. A ticket is `pending` until somebody answers it; the form it carries has
748
- * its own status, and the two are separate facts about separate entities.
819
+ * Names the lifecycle status of a parked {@link PendingForm} — where the ticket stands, which is
820
+ * not where the form stands. A ticket is `pending` until somebody answers it; the form it carries
821
+ * has its own status, and each is a separate fact about a separate entity.
749
822
  *
750
823
  * @remarks
751
824
  * - `pending` — parked, awaiting {@link PromptInterface.answer}.
@@ -755,8 +828,9 @@ export declare interface PendingForm {
755
828
  export declare type PendingFormStatus = 'pending' | 'answered' | 'expired';
756
829
 
757
830
  /**
758
- * The headless form broker. It parks live forms, exposes their serialized schemas, and applies
759
- * remote answers to the authoritative form.
831
+ * Implements the headless form broker. It parks live forms, exposes their serialized schemas,
832
+ * applies remote answers to the authoritative form, and abandons a parked form on timeout, release,
833
+ * or teardown.
760
834
  *
761
835
  * @remarks
762
836
  * A parked record carries one call to `serializeForm`. A failed fill or submit leaves the record
@@ -789,8 +863,9 @@ export declare class Prompt implements PromptInterface {
789
863
  }
790
864
 
791
865
  /**
792
- * The six default glyphs {@link DEFAULT_PROMPT_THEME} assembles its `icons` from. Read only when
793
- * the default theme is assembled; a view reads its resolved theme and never this constant. Frozen.
866
+ * Holds the terminal-owned glyphs {@link DEFAULT_PROMPT_THEME} assembles its `icons` from, beside
867
+ * the console module's own success and error marks. Read only when the default theme is assembled;
868
+ * a view reads its resolved theme and never this constant. Frozen.
794
869
  *
795
870
  * @remarks
796
871
  * - `question` — the leading mark on a prompt's message line.
@@ -808,15 +883,16 @@ export declare const PROMPT_ICONS: Readonly<{
808
883
  }>;
809
884
 
810
885
  /**
811
- * Every {@link import('./types.js').PromptRole}, in one frozen list — the role axis's source of
886
+ * Holds every {@link import('./types.js').PromptRole}, in one frozen list — the role axis's source of
812
887
  * truth. {@link import('./helpers.js').createPromptTheme} walks it to merge a partial theme, and
813
888
  * a consumer building a complete role map reads it rather than retyping every name.
814
889
  */
815
890
  export declare const PROMPT_ROLES: readonly PromptRole[];
816
891
 
817
892
  /**
818
- * The SSE form bridge. It ingests serialized forms from a remote broker, renders them through a
819
- * local terminal, and posts answers back without blocking the event stream.
893
+ * Implements the SSE form bridge. It ingests serialized forms from a remote broker without waiting
894
+ * on a render, drives one form at a time through a local terminal, posts each answer back, and asks
895
+ * again when the authoritative form refuses one.
820
896
  *
821
897
  * @remarks
822
898
  * - **Connect + reconnect.** {@link connect} opens the SSE stream and reconnects after a transport
@@ -824,12 +900,13 @@ export declare const PROMPT_ROLES: readonly PromptRole[];
824
900
  * {@link disconnect} deliberately stopped it.
825
901
  * - **Ingest + render.** Each `pending` envelope passes through `isPendingForm`, Form's `parseForm`,
826
902
  * and terminal's `sanitizeSchema`, then enters a serial render queue. The SSE reader never awaits
827
- * that queue, so `expire` and `shutdown` remain live while a person is answering.
903
+ * that queue, so `expire` and `destroy` remain live while a person is answering.
828
904
  * - **Safe local form.** The rendering copy omits every wire `pattern`, because Form compiles a
829
905
  * pattern during local evaluation. The broker's parked form retains it and remains authoritative.
830
906
  * - **Refusal retry.** A structured `rejected` response seeds a new rendering form with the values
831
- * just submitted, applies every {@link FieldError} through `invalidate`, and asks again. No retry
832
- * counter truncates the loop; acceptance, expiry, and shutdown are its bounds.
907
+ * the refused attempt submitted, applies every {@link FieldError} through `invalidate`, and asks
908
+ * again. No retry counter truncates the loop; acceptance, expiry, and the broker's own teardown
909
+ * are its bounds.
833
910
  * - **Replay safety.** A replayed id is skipped while it is queued, rendering, or posting. Once an
834
911
  * attempt ends, a later delivery of that id may be rendered again.
835
912
  *
@@ -854,7 +931,7 @@ export declare class PromptClient implements PromptClientInterface {
854
931
  }
855
932
 
856
933
  /**
857
- * The client's event map — lean, errors `unknown`, no listener-error event.
934
+ * Declares the client's event map — lean, errors `unknown`, no listener-error event.
858
935
  *
859
936
  * @remarks
860
937
  * - `connect` — the SSE stream opened.
@@ -872,10 +949,10 @@ export declare type PromptClientEventMap = {
872
949
  };
873
950
 
874
951
  /**
875
- * The SSE form BRIDGE — the client-side counterpart to {@link PromptInterface}. It receives
876
- * serialized {@link PendingForm} records from a remote broker, rebuilds each schema locally, drives
877
- * it through a {@link TerminalInterface}, and POSTs the answer back, so a human at this machine
878
- * answers forms a broker parked elsewhere.
952
+ * Declares the SSE form bridge — the client-side counterpart to {@link PromptInterface}. It
953
+ * receives serialized {@link PendingForm} records from a remote broker, rebuilds each schema
954
+ * locally, drives it through a {@link TerminalInterface}, and POSTs the answer back, so a human at
955
+ * this machine answers forms a broker parked elsewhere.
879
956
  *
880
957
  * @remarks
881
958
  * - **Connect.** {@link connect} opens the SSE stream through the injected `fetch` and resolves
@@ -888,25 +965,40 @@ export declare type PromptClientEventMap = {
888
965
  * the wire is never executed locally. The authoritative form decides.
889
966
  * - **Refusal retries.** A rejected answer comes back with the parked form's own errors; the client
890
967
  * applies them to the local form and asks again until the answer is accepted or the form expires.
891
- * - **`connected`** reflects whether the stream is currently open.
968
+ * - **`connected`** reflects whether the stream is open.
892
969
  */
893
970
  export declare interface PromptClientInterface {
971
+ /** Holds the typed emitter every client event is published on. */
894
972
  readonly emitter: EmitterInterface<PromptClientEventMap>;
973
+ /** Holds the remote broker's SSE endpoint this client reads from and answers to. */
895
974
  readonly url: string;
975
+ /** Reports whether the SSE stream is open. */
896
976
  readonly connected: boolean;
977
+ /**
978
+ * Opens the stream and pumps it, queueing each received form for the local terminal; reconnects
979
+ * on the `delay` backoff.
980
+ */
897
981
  connect(): Promise<void>;
982
+ /**
983
+ * Stops the current connection and the reconnect loop. An active local render continues, and a
984
+ * later `connect()` can restart the stream.
985
+ */
898
986
  disconnect(): void;
987
+ /**
988
+ * Tears the client down permanently — disconnects, drops the queue, abandons the active local
989
+ * form, and destroys the emitter.
990
+ */
899
991
  destroy(): void;
900
992
  }
901
993
 
902
994
  /**
903
- * Options for {@link import('./factories.js').createPromptClient} and the
995
+ * Configures {@link import('./factories.js').createPromptClient} and the
904
996
  * {@link PromptClientInterface}.
905
997
  *
906
998
  * @remarks
907
999
  * - `url` — the remote broker's SSE endpoint. A GET opens the stream; answers POST back to it.
908
- * - `terminal` — the LOCAL {@link TerminalInterface} each remote form is driven through, so a human
909
- * at THIS machine answers a form parked elsewhere.
1000
+ * - `terminal` — the local {@link TerminalInterface} each remote form is driven through, so a human
1001
+ * at this machine answers a form parked elsewhere.
910
1002
  * - `token` — an optional auth token, sent as the {@link import('./constants.js').HEADER_TOKEN}
911
1003
  * header on every request.
912
1004
  * - `reconnect` — whether to reconnect after the stream drops, default true.
@@ -931,7 +1023,7 @@ export declare interface PromptClientOptions {
931
1023
  }
932
1024
 
933
1025
  /**
934
- * The broker's event map — lean, errors `unknown`, no listener-error event.
1026
+ * Declares the broker's event map — lean, errors `unknown`, no listener-error event.
935
1027
  *
936
1028
  * @remarks
937
1029
  * - `pending` — a form was parked; a transport forwards the wire record to remote clients.
@@ -940,15 +1032,15 @@ export declare interface PromptClientOptions {
940
1032
  */
941
1033
  export declare type PromptEventMap = {
942
1034
  readonly pending: readonly [form: PendingForm];
1035
+ /**
1036
+ * Reports an accepted answer, carrying the parked form id and settled values.
1037
+ */
943
1038
  readonly answer: readonly [id: string, values: FormValues];
944
1039
  readonly expire: readonly [id: string];
945
1040
  };
946
1041
 
947
- /** The styled prompt-message header (`? message`) — the leading line every active prompt view shares, themed by the `question` + `message` roles. */
948
- export declare function promptHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
949
-
950
1042
  /**
951
- * One glyph slot a rendered field draws — the icon axis of a {@link PromptTheme}. A named value
1043
+ * Names one glyph slot a rendered field draws — the icon axis of a {@link PromptTheme}. A named value
952
1044
  * set, not a toggle, so it stays a union.
953
1045
  *
954
1046
  * @remarks
@@ -961,16 +1053,16 @@ export declare function promptHeader(styler: StylerInterface, theme: PromptTheme
961
1053
  export declare type PromptIcon = 'question' | 'pointer' | 'dot' | 'selected' | 'checked' | 'unchecked' | 'success' | 'error';
962
1054
 
963
1055
  /**
964
- * The headless form BROKER — parks a live form until somebody elsewhere answers it. The headless
965
- * arm of the local-TTY / headless / remote trio: there is no terminal here, so a transport forwards
966
- * each `pending` record to whoever can answer, and {@link answer} drives the parked form to
967
- * settlement.
1056
+ * Declares the headless form broker — parks a live form until somebody elsewhere answers it. The
1057
+ * headless arm of the local-TTY, headless, and remote trio: there is no terminal here, so a
1058
+ * transport forwards each `pending` record to whoever can answer, and {@link answer} drives the
1059
+ * parked form to settlement.
968
1060
  *
969
1061
  * @remarks
970
1062
  * - **The form is the unit.** {@link park} takes a live form, mints an id, emits `pending`, and
971
1063
  * returns the id. It wraps no promise, because the caller already holds one: the form's own
972
1064
  * `answer`.
973
- * - **The parked form is authoritative.** {@link answer} fills and submits THAT form, so every rule
1065
+ * - **The parked form is authoritative.** {@link answer} fills and submits that form, so every rule
974
1066
  * it carries decides, including a `custom` validator the wire dropped. A refusal returns the
975
1067
  * form's own errors and leaves the form parked.
976
1068
  * - **Timeout abandons.** An unanswered form is destroyed after `timeout` ms; `expire` fires and
@@ -991,20 +1083,39 @@ export declare type PromptIcon = 'question' | 'pointer' | 'dot' | 'selected' | '
991
1083
  * ```
992
1084
  */
993
1085
  export declare interface PromptInterface {
1086
+ /** Holds the typed emitter every broker event is published on. */
994
1087
  readonly emitter: EmitterInterface<PromptEventMap>;
1088
+ /** Reports how many forms this broker holds parked. */
995
1089
  readonly count: number;
1090
+ /**
1091
+ * Parks a live form, mints its id, emits `pending`, and arms the expiry deadline. Returns the id;
1092
+ * the caller already holds the promise.
1093
+ */
996
1094
  park(form: FormInterface, request?: ParkRequest): string;
1095
+ /** Lists every parked record (`pending()`), or looks one up by id (`pending(id)`). */
997
1096
  pending(): readonly PendingForm[];
998
1097
  pending(id: string): PendingForm | undefined;
1098
+ /**
1099
+ * Fills and submits the authoritative parked form. Accepted, it settles and the record is
1100
+ * dropped; refused, the form stays parked.
1101
+ */
999
1102
  answer(id: string, values: FormValues): Result<FormValues, AnswerError>;
1103
+ /**
1104
+ * Releases a batch (`stop(ids)`, the array overload declared first), one id, or every parked
1105
+ * form. The broker stays usable.
1106
+ */
1000
1107
  stop(ids: readonly string[]): boolean;
1001
1108
  stop(id: string): boolean;
1002
1109
  stop(): void;
1110
+ /**
1111
+ * Tears the broker down — abandons every parked form, cancels every deadline, then destroys the
1112
+ * emitter. Idempotent.
1113
+ */
1003
1114
  destroy(): void;
1004
1115
  }
1005
1116
 
1006
1117
  /**
1007
- * Options for {@link import('./factories.js').createPrompt} and every {@link PromptInterface}
1118
+ * Configures {@link import('./factories.js').createPrompt} and every {@link PromptInterface}
1008
1119
  * broker, including one a {@link TerminalManagerInterface} mounts per endpoint.
1009
1120
  *
1010
1121
  * @remarks
@@ -1028,9 +1139,9 @@ export declare interface PromptOptions {
1028
1139
  }
1029
1140
 
1030
1141
  /**
1031
- * One styling slot a rendered field paints through — the semantic axis of a {@link PromptTheme}. A
1032
- * role says what a fragment MEANS; the theme decides what that meaning looks like, so a consumer
1033
- * re-maps styled output by naming roles rather than reimplementing a renderer.
1142
+ * Names one styling slot a rendered field paints through — the semantic axis of a
1143
+ * {@link PromptTheme}. A role says what a fragment means; the theme decides what that meaning looks
1144
+ * like, so a consumer re-maps styled output by naming roles rather than reimplementing a renderer.
1034
1145
  *
1035
1146
  * @remarks
1036
1147
  * - `question` — the leading mark on an active field's line.
@@ -1051,16 +1162,17 @@ export declare interface PromptOptions {
1051
1162
  export declare type PromptRole = 'question' | 'pointer' | 'message' | 'content' | 'success' | 'error' | 'selected' | 'focus' | 'hint' | 'muted' | 'description';
1052
1163
 
1053
1164
  /**
1054
- * Where one field's reducer stands after a key. `active`: keep asking, because the key was
1165
+ * Names where one field's reducer stands after a key. `active`: keep asking, because the key was
1055
1166
  * consumed or the answer was refused. `submit`: the field resolved with its `value`. `cancel`: the
1056
1167
  * user aborted with ctrl-c. Names its axis, never `kind`.
1057
1168
  */
1058
1169
  export declare type PromptStatus = 'active' | 'submit' | 'cancel';
1059
1170
 
1060
1171
  /**
1061
- * The result of one reducer step — the next `state`, the rendered `view`, the `status`, and, on
1062
- * `submit`, the resolved `value`. The whole contract between a pure reducer and the impure driver:
1063
- * the driver applies the next `state`, writes the `view`, and reads `value` on `submit`.
1172
+ * Represents the result of one reducer step — the next `state`, the rendered `view`, the `status`,
1173
+ * and, on `submit` alone, the candidate `value`. The whole contract between a pure reducer and the
1174
+ * impure driver: the driver applies the next `state`, writes the `view`, and reads `value` on
1175
+ * `submit`.
1064
1176
  *
1065
1177
  * @typeParam T - The value this field resolves to, as its control admits it.
1066
1178
  * @typeParam S - The reducer's concrete state shape, carried directly so `state` stays precisely
@@ -1071,7 +1183,7 @@ export declare type PromptStatus = 'active' | 'submit' | 'cancel';
1071
1183
  * is the final state.
1072
1184
  * - `view` — the styled string to render now, possibly multi-line. On a refused `submit` it carries
1073
1185
  * the failure; the driver re-renders it each step.
1074
- * - `value` — present ONLY on a `submit` step.
1186
+ * - `value` — present only on a `submit` step.
1075
1187
  */
1076
1188
  export declare interface PromptStep<T, S> {
1077
1189
  readonly state: S;
@@ -1081,9 +1193,9 @@ export declare interface PromptStep<T, S> {
1081
1193
  }
1082
1194
 
1083
1195
  /**
1084
- * A resolved PRESENTATION — the glyph for every {@link PromptIcon} and the console {@link Style}
1085
- * for every {@link PromptRole}. Plain JSON data with no functions, so it crosses the wire with the
1086
- * form it decorates. Built by {@link import('./helpers.js').createPromptTheme}.
1196
+ * Represents a resolved presentation — the glyph for every {@link PromptIcon} and the console
1197
+ * {@link Style} for every {@link PromptRole}. Plain JSON data with no functions, so it crosses the
1198
+ * wire with the form it decorates. Built by {@link import('./helpers.js').createPromptTheme}.
1087
1199
  *
1088
1200
  * @remarks
1089
1201
  * A role's value is the console module's own {@link Style} — the one style model the whole console
@@ -1098,8 +1210,8 @@ export declare interface PromptTheme {
1098
1210
  }
1099
1211
 
1100
1212
  /**
1101
- * The PARTIAL {@link PromptTheme} an option bag carries — every icon and every role is optional,
1102
- * and {@link import('./helpers.js').createPromptTheme} merges what is supplied over
1213
+ * Represents the partial {@link PromptTheme} an option bag carries — every icon and every role is
1214
+ * optional, and {@link import('./helpers.js').createPromptTheme} merges what is supplied over
1103
1215
  * {@link import('./constants.js').DEFAULT_PROMPT_THEME} leaf by leaf. Supplying one icon or one
1104
1216
  * role leaves every other slot at its default.
1105
1217
  */
@@ -1108,11 +1220,179 @@ export declare interface PromptThemeOptions {
1108
1220
  readonly roles?: Readonly<Partial<Record<PromptRole, Style>>>;
1109
1221
  }
1110
1222
 
1111
- /** Carriage return (`\r`, U+000D) — Enter on most terminals. */
1223
+ /**
1224
+ * Advances a checkbox prompt by one {@link KeyEvent} — the pure
1225
+ * `(state, key) → PromptStep<readonly string[]>` reducer. `up` / `down` (and `k` / `j`) move the
1226
+ * focus (wrapping); `space` toggles the focused index in the checked set; return submits the
1227
+ * checked values in choice order; ctrl-c cancels. The form applies selection-count rules.
1228
+ *
1229
+ * @param state - The checkbox field's current reducer state
1230
+ * @param key - The decoded keypress to apply
1231
+ * @returns The next step — the state, the rendered view, the status, and the ticked values on submit
1232
+ */
1233
+ export declare function reduceCheckbox(state: CheckboxState, key: KeyEvent): PromptStep<readonly string[], CheckboxState>;
1234
+
1235
+ /**
1236
+ * Advances a confirm prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<boolean>`
1237
+ * reducer. `y` / `Y` submits `true`, `n` / `N` submits `false`, return on an empty line submits
1238
+ * the `default`, ctrl-c cancels; any other key is ignored (stays active).
1239
+ *
1240
+ * @param state - The confirm field's current reducer state
1241
+ * @param key - The decoded keypress to apply
1242
+ * @returns The next step — the state, the rendered view, the status, and the answer on submit
1243
+ */
1244
+ export declare function reduceConfirm(state: ConfirmState, key: KeyEvent): PromptStep<boolean, ConfirmState>;
1245
+
1246
+ /**
1247
+ * Advances an editor prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
1248
+ * reducer. Printable characters extend the current line; backspace shrinks it; return commits the
1249
+ * current line and starts a fresh one; ctrl-d finishes, joining every line and falling back to the
1250
+ * default when empty; ctrl-c cancels. The form validates the candidate after the driver fills it.
1251
+ *
1252
+ * @param state - The editor field's current reducer state
1253
+ * @param key - The decoded keypress to apply
1254
+ * @returns The next step — the state, the rendered view, the status, and the joined text on submit
1255
+ */
1256
+ export declare function reduceEditor(state: EditorState, key: KeyEvent): PromptStep<string, EditorState>;
1257
+
1258
+ /**
1259
+ * Advances an input prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
1260
+ * reducer. Printable characters extend the value; backspace shrinks it; ctrl-u clears it; ctrl-c
1261
+ * cancels; return produces the candidate value, with an empty line falling back to the default.
1262
+ *
1263
+ * @param state - The text field's current reducer state
1264
+ * @param key - The decoded keypress to apply
1265
+ * @returns The next step — the new state, the rendered view, the status, and the value on submit
1266
+ */
1267
+ export declare function reduceInput(state: InputState, key: KeyEvent): PromptStep<string, InputState>;
1268
+
1269
+ /**
1270
+ * Advances a password prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
1271
+ * reducer. Identical line-editing to {@link reduceInput} (printable extends, backspace shrinks,
1272
+ * ctrl-u clears, ctrl-c cancels) but the view masks the value. Return produces the candidate value.
1273
+ *
1274
+ * @param state - The password field's current reducer state
1275
+ * @param key - The decoded keypress to apply
1276
+ * @returns The next step — the new state, the masked view, the status, and the value on submit
1277
+ */
1278
+ export declare function reducePassword(state: PasswordState, key: KeyEvent): PromptStep<string, PasswordState>;
1279
+
1280
+ /**
1281
+ * Advances a select prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
1282
+ * reducer. `up` / `down` (and `k` / `j`) move the focus, wrapping at the ends; return submits the
1283
+ * focused choice's `value`; ctrl-c cancels. An empty choice list can never submit (a higher layer
1284
+ * guards against it); any other key is ignored.
1285
+ *
1286
+ * @param state - The select field's current reducer state
1287
+ * @param key - The decoded keypress to apply
1288
+ * @returns The next step — the state, the rendered view, the status, and the chosen value on submit
1289
+ */
1290
+ export declare function reduceSelect(state: SelectState, key: KeyEvent): PromptStep<string, SelectState>;
1291
+
1292
+ /**
1293
+ * Renders a checkbox-field reducer state as a multi-line styled view — one box per choice, and the
1294
+ * selected count beneath them.
1295
+ *
1296
+ * @param state - The checkbox field's current reducer state
1297
+ * @returns The rendered view — the header, one box per choice, and the selected count
1298
+ */
1299
+ export declare function renderCheckboxView(state: CheckboxState): string;
1300
+
1301
+ /**
1302
+ * Renders a confirm-field reducer state as a styled view — the header and the yes/no group, with
1303
+ * the default letter capitalized and painted by the `selected` role.
1304
+ *
1305
+ * @param state - The confirm field's current reducer state
1306
+ * @returns The rendered view — the header and the yes/no group with the default capitalized
1307
+ */
1308
+ export declare function renderConfirmView(state: ConfirmState): string;
1309
+
1310
+ /**
1311
+ * Renders an editor-field reducer state as a multi-line styled view — the finish hint, the
1312
+ * committed lines, and the line in progress.
1313
+ *
1314
+ * @param state - The editor field's current reducer state
1315
+ * @returns The rendered view — the hinted header, the committed lines, and the line in progress
1316
+ */
1317
+ export declare function renderEditorView(state: EditorState): string;
1318
+
1319
+ /**
1320
+ * Renders the styled failure line (`✖ message`) a form driver writes for each refused field before
1321
+ * it asks that field again.
1322
+ *
1323
+ * @param styler - The console styler that renders each role
1324
+ * @param theme - The resolved prompt theme
1325
+ * @param message - The failure text, normally the field's label and the reason
1326
+ * @returns The rendered failure line
1327
+ */
1328
+ export declare function renderErrorLine(styler: StylerInterface, theme: PromptTheme, message: string): string;
1329
+
1330
+ /**
1331
+ * Renders a question header followed by a key hint painted with the `hint` role, or the header
1332
+ * alone when no hint is supplied.
1333
+ *
1334
+ * @param styler - The console styler that renders each role
1335
+ * @param theme - The resolved prompt theme
1336
+ * @param message - The prompt's question text
1337
+ * @param hint - The optional key hint to append
1338
+ * @returns The rendered header with the optional hint
1339
+ */
1340
+ export declare function renderHintedHeader(styler: StylerInterface, theme: PromptTheme, message: string, hint?: string): string;
1341
+
1342
+ /**
1343
+ * Renders a text-field reducer state as a styled view — the header, the pointer, and the typed
1344
+ * value, or the default shown as a hint while nothing is typed.
1345
+ *
1346
+ * @param state - The text field's current reducer state
1347
+ * @returns The rendered single-line view — header, pointer, and the typed value or the default
1348
+ */
1349
+ export declare function renderInputView(state: InputState): string;
1350
+
1351
+ /**
1352
+ * Renders a password-field reducer state as a styled view, with the value replaced by the mask
1353
+ * repeated so the secret is never echoed.
1354
+ *
1355
+ * @param state - The password field's current reducer state
1356
+ * @returns The rendered view, with the mask repeated in place of the typed value
1357
+ */
1358
+ export declare function renderPasswordView(state: PasswordState): string;
1359
+
1360
+ /**
1361
+ * Renders the styled question header (`? message`) — the leading line every active prompt view
1362
+ * shares, themed by the `question` + `message` roles.
1363
+ *
1364
+ * @param styler - The console styler that renders each role
1365
+ * @param theme - The resolved prompt theme
1366
+ * @param message - The prompt's question text
1367
+ * @returns The rendered question header
1368
+ */
1369
+ export declare function renderPromptHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
1370
+
1371
+ /**
1372
+ * Renders a select-field reducer state as a multi-line styled view — one row per choice, with the
1373
+ * focused row marked and its help shown.
1374
+ *
1375
+ * @param state - The select field's current reducer state
1376
+ * @returns The rendered view — the header, then one row per choice with the focused row marked
1377
+ */
1378
+ export declare function renderSelectView(state: SelectState): string;
1379
+
1380
+ /**
1381
+ * Renders the styled submit line (`✔ message`) — the committed header an interactive prompt shows
1382
+ * after it resolves, themed by the `success` + `message` roles.
1383
+ *
1384
+ * @param styler - The console styler that renders each role
1385
+ * @param theme - The resolved prompt theme
1386
+ * @param message - The settled prompt's question text
1387
+ * @returns The rendered committed header
1388
+ */
1389
+ export declare function renderSubmitHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
1390
+
1391
+ /** Names the carriage return byte (`\r`, U+000D) — Enter on most terminals. */
1112
1392
  export declare const RETURN: string;
1113
1393
 
1114
1394
  /**
1115
- * Sanitize text for one single-line display slot. Composes console's ANSI {@link strip} and C0
1395
+ * Sanitizes text for one single-line display slot. Composes console's ANSI {@link strip} and C0
1116
1396
  * {@link stripControls} passes with removal of tab, line feed, and carriage return.
1117
1397
  *
1118
1398
  * @param text - The text to sanitize for a glyph or hint slot
@@ -1126,7 +1406,8 @@ export declare const RETURN: string;
1126
1406
  export declare function sanitizeDisplayText(text: string): string;
1127
1407
 
1128
1408
  /**
1129
- * Sanitize every terminal-readable string in a parsed form schema.
1409
+ * Sanitizes every terminal-readable string in a parsed form schema, keeping every identity and
1410
+ * answer string verbatim and dropping field metadata.
1130
1411
  *
1131
1412
  * @remarks
1132
1413
  * Display strings pass through {@link sanitizeDisplayText}: labels, help, placeholders, masks,
@@ -1148,7 +1429,7 @@ export declare function sanitizeDisplayText(text: string): string;
1148
1429
  export declare function sanitizeSchema(schema: FormSchema): FormSchema;
1149
1430
 
1150
1431
  /**
1151
- * Sanitize every glyph a wire-supplied {@link PromptThemeOptions} carries for a single-line display
1432
+ * Sanitizes every glyph a wire-supplied {@link PromptThemeOptions} carries for a single-line display
1152
1433
  * slot. Only the icons need it: a role is guard-narrowed to a console {@link Style}, whose colors
1153
1434
  * and attributes are fixed name sets, so no role can carry a byte a terminal would act on.
1154
1435
  *
@@ -1158,21 +1439,29 @@ export declare function sanitizeSchema(schema: FormSchema): FormSchema;
1158
1439
  export declare function sanitizeThemeIcons(theme: PromptThemeOptions): PromptThemeOptions;
1159
1440
 
1160
1441
  /**
1161
- * Advance a select prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
1162
- * reducer. `up` / `down` (and `k` / `j`) move the focus, WRAPPING at the ends; return submits the
1163
- * focused choice's `value`; ctrl-c cancels. An empty choice list can never submit (a higher layer
1164
- * guards against it); any other key is ignored.
1165
- */
1166
- export declare function selectReduce(state: ReturnType<typeof createSelectState>, key: KeyEvent): PromptStep<string, ReturnType<typeof createSelectState>>;
1167
-
1168
- /** Render a select-field key state as a multi-line styled view. */
1169
- export declare function selectView(state: ReturnType<typeof createSelectState>): string;
1442
+ * Represents the immutable state a select field's reducer carries — the choices the list offers and
1443
+ * the index the cursor sits on.
1444
+ *
1445
+ * @remarks
1446
+ * - `message` — the sanitized label the header renders.
1447
+ * - `choices` — the choices the list offers, in declared order.
1448
+ * - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
1449
+ * - `focused` — the index the cursor sits on, pre-placed on the declared default.
1450
+ */
1451
+ export declare interface SelectState {
1452
+ readonly message: string;
1453
+ readonly choices: readonly FieldChoice[];
1454
+ readonly styler: StylerInterface;
1455
+ readonly theme: PromptTheme;
1456
+ readonly focused: number;
1457
+ }
1170
1458
 
1171
1459
  /**
1172
- * The exact escape SEQUENCE → canonical key NAME table {@link import('./helpers.js').parseKey}
1173
- * consults for the navigation / editing keys. Covers BOTH the CSI form (`ESC[A`…) and the SS3
1174
- * form (`ESCOA`…) of the four arrows, plus the `home` / `end` / `delete` CSI sequences (with
1175
- * their numeric-tilde variants). The source of truth for the multi-byte key decode; frozen.
1460
+ * Holds the exact escape sequence to canonical key name table
1461
+ * {@link import('./helpers.js').parseKey} consults for the navigation and editing keys. Covers the
1462
+ * CSI form (`ESC[A`…) and the SS3 form (`ESCOA`…) of the arrows, plus the `home` / `end` / `delete`
1463
+ * CSI sequences with their numeric-tilde variants. The source of truth for the multi-byte key
1464
+ * decode; frozen.
1176
1465
  *
1177
1466
  * @remarks
1178
1467
  * Terminals disagree on these: a cursor key is `ESC[A` (normal) or `ESCOA` (application mode),
@@ -1182,20 +1471,37 @@ export declare function selectView(state: ReturnType<typeof createSelectState>):
1182
1471
  */
1183
1472
  export declare const SEQUENCE_NAMES: Readonly<Record<string, string>>;
1184
1473
 
1185
- /** Serialize a parked prompt's expiry or release into a {@link WireEvent} — event `'expire'`, `data` the JSON-stringified `{ id }` payload. */
1474
+ /**
1475
+ * Serializes the `destroy` {@link WireEvent} a broker or manager sends when it is going away, which
1476
+ * carries no payload.
1477
+ *
1478
+ * @returns The `destroy` frame, whose `data` is empty because the signal carries no payload
1479
+ */
1480
+ export declare function serializeDestroy(): WireEvent;
1481
+
1482
+ /**
1483
+ * Serializes a parked form's expiry or release into an `expire` {@link WireEvent}, whose `data` is
1484
+ * the JSON `{ id }` payload.
1485
+ *
1486
+ * @param id - The id of the parked form that expired or was released
1487
+ * @returns The `expire` frame, carrying the JSON-stringified `{ id }` payload as `data`
1488
+ */
1186
1489
  export declare function serializeExpire(id: string): WireEvent;
1187
1490
 
1188
- /** Serialize a parked {@link PendingForm} into a {@link WireEvent}. */
1491
+ /**
1492
+ * Serializes a parked {@link PendingForm} into a `pending` {@link WireEvent}, whose frame `id` is
1493
+ * the form's own id.
1494
+ *
1495
+ * @param form - The parked form's wire-safe record
1496
+ * @returns The `pending` frame — the JSON-stringified record as `data`, and the form's own `id`
1497
+ */
1189
1498
  export declare function serializePending(form: PendingForm): WireEvent;
1190
1499
 
1191
- /** The {@link WireEvent} a broker/manager sends when it is going away — event `'shutdown'`, no payload. */
1192
- export declare function serializeShutdown(): WireEvent;
1193
-
1194
- /** Space (U+0020). */
1500
+ /** Names the space byte (U+0020). */
1195
1501
  export declare const SPACE = " ";
1196
1502
 
1197
1503
  /**
1198
- * The maximum number of characters the {@link import('./types.js').PromptClientInterface} lets its
1504
+ * Sets the maximum number of characters the {@link import('./types.js').PromptClientInterface} lets its
1199
1505
  * SSE parser buffer before treating the stream as hostile — 1 MiB, comfortably above any
1200
1506
  * legitimate prompt payload. Passed as the `limit` to `createSSEParser` so an unterminated
1201
1507
  * or oversized `data:` field cannot grow the buffer without bound (a memory-exhaustion guard).
@@ -1203,37 +1509,36 @@ export declare const SPACE = " ";
1203
1509
  export declare const SSE_BUFFER_LIMIT = 1048576;
1204
1510
 
1205
1511
  /**
1206
- * The SSE `event:` names the broker emits and the {@link import('./types.js').PromptClientInterface}
1207
- * dispatches on. Frozen; the source of truth for the wire event vocabulary.
1512
+ * Holds the SSE `event:` names the broker emits and the
1513
+ * {@link import('./types.js').PromptClientInterface} dispatches on — `pending`, `expire`, and
1514
+ * `destroy`. Frozen; the source of truth for the wire event vocabulary.
1208
1515
  *
1209
1516
  * @remarks
1210
1517
  * - `pending` — a serialized {@link import('./types.js').PendingForm} to dispatch and answer.
1211
- * - `expire` — an `{ id }` payload: the broker expired or released a parked prompt (the client drops it).
1212
- * - `shutdown` — the broker is going away; the client disconnects (no auto-reconnect) but stays reusable.
1518
+ * - `expire` — an `{ id }` payload: the broker expired or released a parked form (the client drops it).
1519
+ * - `destroy` — the broker is going away; the client disconnects (no auto-reconnect) but stays reusable.
1213
1520
  */
1214
1521
  export declare const SSE_EVENTS: Readonly<{
1215
1522
  pending: "pending";
1216
1523
  expire: "expire";
1217
- shutdown: "shutdown";
1524
+ destroy: "destroy";
1218
1525
  }>;
1219
1526
 
1220
- /** The styled submit line (`✔ message`) — the committed header an interactive prompt shows once resolved, themed by the `success` + `message` roles. */
1221
- export declare function submitHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
1222
-
1223
- /** Tab (`\t`, U+0009). */
1527
+ /** Names the tab byte (`\t`, U+0009). */
1224
1528
  export declare const TAB: string;
1225
1529
 
1226
1530
  /**
1227
- * Why a {@link TerminalManagerInterface.answer} call refused — an {@link AnswerError} from the
1228
- * endpoint's own broker, or `terminal` when no endpoint is mounted under that name. One
1229
- * discriminant, `reason`, across both.
1531
+ * Explains why a {@link TerminalManagerInterface.answer} call refused — an {@link AnswerError} from the
1532
+ * endpoint's own broker, or `target` when no endpoint is mounted under that name. That is the same
1533
+ * condition {@link TerminalErrorCode}'s `TARGET` names for {@link TerminalManagerInterface.ask}, so
1534
+ * one word carries it on both doors. One discriminant, `reason`, across every member.
1230
1535
  */
1231
1536
  export declare type TerminalAnswerError = AnswerError | {
1232
- readonly reason: 'terminal';
1537
+ readonly reason: 'target';
1233
1538
  };
1234
1539
 
1235
1540
  /**
1236
- * The error the terminal surfaces for its own refusals: parking on a destroyed or full broker, an
1541
+ * Represents the error the terminal surfaces for its own refusals: parking on a destroyed or full broker, an
1237
1542
  * unusable driver stream, a manager routing fault, or a ctrl-c cancellation. A parked form's own
1238
1543
  * lifecycle failures reject through the form's `answer` with the form package's error, never with
1239
1544
  * this one.
@@ -1244,15 +1549,22 @@ export declare type TerminalAnswerError = AnswerError | {
1244
1549
  * a caught value with {@link isTerminalError} and branch on `error.code`.
1245
1550
  */
1246
1551
  export declare class TerminalError extends Error {
1247
- /** The machine-readable condition — see {@link TerminalErrorCode}. */
1552
+ /** Holds the machine-readable condition — see {@link TerminalErrorCode}. */
1248
1553
  readonly code: TerminalErrorCode;
1249
- /** An optional context bag naming the offending values — see the class {@link TerminalError remarks}. */
1554
+ /** Holds an optional context bag naming the offending values — see the class {@link TerminalError remarks}. */
1250
1555
  readonly context?: Readonly<Record<string, unknown>>;
1556
+ /**
1557
+ * Builds one terminal refusal.
1558
+ *
1559
+ * @param code - The machine-readable {@link TerminalErrorCode} a caller branches on
1560
+ * @param message - The human-readable reason
1561
+ * @param context - The optional bag naming the offending values — see the class {@link TerminalError remarks}
1562
+ */
1251
1563
  constructor(code: TerminalErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
1252
1564
  }
1253
1565
 
1254
1566
  /**
1255
- * The machine-readable condition carried by a {@link import('./errors.js').TerminalError} — the
1567
+ * Names the machine-readable condition carried by a {@link import('./errors.js').TerminalError} — the
1256
1568
  * axis a `catch` branches on. Names its axis (the failure condition), never `kind`.
1257
1569
  *
1258
1570
  * @remarks
@@ -1275,15 +1587,15 @@ export declare class TerminalError extends Error {
1275
1587
  export declare type TerminalErrorCode = 'EXPIRE' | 'CANCEL' | 'DRIVER' | 'DEADLOCK' | 'TARGET' | 'LIMIT' | 'DESTROYED';
1276
1588
 
1277
1589
  /**
1278
- * The contract for asking a form of a human at a keyboard — one method, because a form is one
1279
- * question however many fields it holds. The server `Terminal` implements it against a real TTY;
1280
- * a {@link PromptClientInterface} holds one to answer forms parked elsewhere.
1590
+ * Declares the contract for asking a form of a human at a keyboard — `ask` and nothing beside it,
1591
+ * because a form is one question however many fields it holds. The server `Terminal` implements it
1592
+ * against a real TTY; a {@link PromptClientInterface} holds one to answer forms parked elsewhere.
1281
1593
  *
1282
1594
  * @remarks
1283
1595
  * `ask` drives the form the caller passes: it walks the schema's fields in order, binds each
1284
1596
  * keystroke through the form's own `fill`, submits, and returns the settled values. The returned
1285
1597
  * promise is the form's `answer`, so a caller holding the form can await either one. Ctrl-c at an
1286
- * interactive driver is the one exception: it rejects THIS promise with a `TerminalError` coded
1598
+ * interactive driver is the one exception: it rejects this promise with a `TerminalError` coded
1287
1599
  * `CANCEL` and leaves the form `editing`, so the form's own `answer` stays pending for its owner.
1288
1600
  *
1289
1601
  * A driver never owns the form's lifetime. To interrupt an active walk, destroy the form: it
@@ -1291,29 +1603,32 @@ export declare type TerminalErrorCode = 'EXPIRE' | 'CANCEL' | 'DRIVER' | 'DEADLO
1291
1603
  * is the only cancellation channel, which is why this contract needs no second method.
1292
1604
  */
1293
1605
  export declare interface TerminalInterface {
1606
+ /**
1607
+ * Walks the given form to settlement and resolves its values. The Contract section names the
1608
+ * ctrl-c exception.
1609
+ */
1294
1610
  ask(form: FormInterface): Promise<FormValues>;
1295
1611
  }
1296
1612
 
1297
1613
  /**
1298
- * The multi-endpoint terminal MANAGER — a registry of named {@link PromptInterface} brokers (one
1299
- * per endpoint), so several parties can `ask` forms of each other by NAME with a `from` → `to`
1300
- * attribution edge on every parked form, and a transitive DEADLOCK check across all in-flight
1301
- * asks.
1614
+ * Registers named {@link PromptInterface} brokers, one per endpoint, so several parties can `ask`
1615
+ * forms of each other by name with a `from` → `to` attribution edge on every parked form, and
1616
+ * refuses `DEADLOCK` on a transitive cycle across every in-flight ask.
1302
1617
  *
1303
1618
  * @remarks
1304
1619
  * - **Registry.** `add(name, options?)` mints (or, if `name` is already mounted, returns the
1305
- * EXISTING broker UNCHANGED — idempotent, never clobbers a live/parked endpoint). Every mounted
1620
+ * existing broker unchanged — idempotent, never clobbers a live/parked endpoint). Every mounted
1306
1621
  * broker's `pending` / `answer` / `expire` events are re-emitted on the manager, attributed by
1307
1622
  * `name`.
1308
- * - **`ask`.** The target must already be mounted via {@link add} — `ask` never auto-adds it;
1623
+ * - **`ask`.** The target must already be mounted through {@link add} — `ask` never auto-adds it;
1309
1624
  * rejects `TARGET` for an unknown `to` (listing the known names). Rejects `DEADLOCK` when parking
1310
- * `from → to` would close a cycle over the CURRENT in-flight edge set (walked transitively);
1625
+ * `from → to` would close a cycle over the current in-flight edge set (walked transitively);
1311
1626
  * otherwise parks the caller's live form through the target's broker and returns that form's own
1312
1627
  * `answer` promise. Edge cleanup never alters the value or rejection the caller observes.
1313
1628
  * - **Durable open / save.** `open(name)` restores an EMPTY broker from the `store` (parked
1314
1629
  * Promises are process-bound and never resurrected); `save(name)` persists the endpoint's
1315
1630
  * configured `timeout`.
1316
- * - **Removal.** `remove` drops one endpoint, a batch (§9.2, array overload FIRST), or every
1631
+ * - **Removal.** `remove` drops one endpoint, a batch (the array overload declared first), or every
1317
1632
  * endpoint when called without an argument. It destroys each broker, which expires every form
1318
1633
  * still parked on it. `destroy` is idempotent.
1319
1634
  *
@@ -1333,7 +1648,7 @@ export declare class TerminalManager implements TerminalManagerInterface {
1333
1648
  get emitter(): EmitterInterface<TerminalManagerEventMap>;
1334
1649
  get count(): number;
1335
1650
  terminal(name: string): PromptInterface | undefined;
1336
- terminals(): readonly string[];
1651
+ terminals(): readonly PromptInterface[];
1337
1652
  add(name: string, options?: PromptOptions): PromptInterface;
1338
1653
  ask(from: string, to: string, form: FormInterface): Promise<FormValues>;
1339
1654
  pending(): readonly PendingForm[];
@@ -1348,8 +1663,8 @@ export declare class TerminalManager implements TerminalManagerInterface {
1348
1663
  }
1349
1664
 
1350
1665
  /**
1351
- * The manager's event map — the name-attributed re-emission of every mounted broker's events, so a
1352
- * caller subscribes once for ALL endpoints instead of once per broker.
1666
+ * Declares the manager's event map — the name-attributed re-emission of every mounted broker's
1667
+ * events, so a caller subscribes once for every endpoint instead of once per broker.
1353
1668
  *
1354
1669
  * @remarks
1355
1670
  * - `pending` — an endpoint parked a form; the record itself carries `from` and `to`.
@@ -1363,47 +1678,81 @@ export declare type TerminalManagerEventMap = {
1363
1678
  };
1364
1679
 
1365
1680
  /**
1366
- * The multi-endpoint terminal MANAGER — a registry of named {@link PromptInterface} brokers, one
1367
- * per endpoint, so several parties (agents, tools, humans) can ask forms of each other BY NAME,
1368
- * attributed with a `from` → `to` edge on every parked record.
1681
+ * Declares a registry of named {@link PromptInterface} brokers, one per endpoint, so several
1682
+ * parties (agents, tools, humans) can ask forms of each other by name, attributed with a `from` →
1683
+ * `to` edge on every parked record.
1369
1684
  *
1370
1685
  * @remarks
1371
1686
  * - **Accessors.** `terminal(name)` looks up one endpoint's broker; `terminals()` lists every
1372
- * mounted endpoint name.
1687
+ * mounted broker, in insertion order. `terminals()` returns brokers, not keys; a name is an
1688
+ * argument the `terminal`, `add`, `ask`, `pending`, `answer`, `open`, `save`, and `remove`
1689
+ * methods take.
1373
1690
  * - **`add`** mints, or returns, the broker for `name`. Idempotent; it never clobbers a live
1374
1691
  * endpoint.
1375
- * - **`ask`** is the attributed convenience: it parks `form` from `from` to `to`, adding `to` if it
1376
- * is absent, and resolves with the settled values.
1692
+ * - **`ask`** is the attributed convenience: it parks `form` from `from` to `to` and resolves with
1693
+ * the settled values. It never mounts `to` — an unmounted target rejects with a
1694
+ * {@link import('./errors.js').TerminalError} coded `TARGET`, so `add` the endpoint first.
1377
1695
  * - **`pending()`** lists every endpoint's parked records; `pending(to)` scopes to one endpoint.
1378
1696
  * - **`answer`** routes to the named endpoint's broker.
1379
1697
  * - **`open`** restores, or returns the live, broker for `name` from the `store`.
1380
1698
  * - **`save`** persists an endpoint's config snapshot; false when there is no store, or `name` is
1381
1699
  * unknown.
1382
- * - **Batch `remove`.** The array overload is declared FIRST: `remove(names)` removes each listed
1383
- * endpoint and reports whether any named terminal was removed; `remove(name)` removes one;
1700
+ * - **Batch `remove`.** The array overload is declared first: `remove(names)` removes every listed
1701
+ * endpoint and reports true only when all of them were mounted; `remove(name)` removes one;
1384
1702
  * `remove()` removes every endpoint without destroying the manager.
1385
1703
  * - **`destroy`** tears down every broker, then the manager's own emitter.
1386
1704
  */
1387
1705
  export declare interface TerminalManagerInterface {
1706
+ /**
1707
+ * Holds the typed emitter every mounted broker's events are re-published on, attributed by name.
1708
+ */
1388
1709
  readonly emitter: EmitterInterface<TerminalManagerEventMap>;
1710
+ /** Reports how many endpoints are mounted. */
1389
1711
  readonly count: number;
1712
+ /** Looks up one endpoint's broker by name. */
1390
1713
  terminal(name: string): PromptInterface | undefined;
1391
- terminals(): readonly string[];
1714
+ /** Lists every mounted broker, in insertion order. */
1715
+ terminals(): readonly PromptInterface[];
1716
+ /**
1717
+ * Mints, or returns unchanged, the broker for `name`. Idempotent; it never clobbers a live
1718
+ * endpoint.
1719
+ */
1392
1720
  add(name: string, options?: PromptOptions): PromptInterface;
1721
+ /**
1722
+ * Parks `form` from `from` to `to` and resolves with the settled values. Rejects `TARGET` or
1723
+ * `DEADLOCK`.
1724
+ */
1393
1725
  ask(from: string, to: string, form: FormInterface): Promise<FormValues>;
1726
+ /**
1727
+ * Lists every endpoint's parked records (`pending()`), or scopes to one endpoint (`pending(to)`).
1728
+ */
1394
1729
  pending(): readonly PendingForm[];
1395
1730
  pending(to: string): readonly PendingForm[];
1731
+ /**
1732
+ * Routes an answer to the named endpoint's broker; `{ reason: 'target' }` when no endpoint
1733
+ * carries that name.
1734
+ */
1396
1735
  answer(to: string, id: string, values: FormValues): Result<FormValues, TerminalAnswerError>;
1736
+ /**
1737
+ * Returns the live broker for `name`, or restores an empty one from the `store`. Parked forms are
1738
+ * never resurrected.
1739
+ */
1397
1740
  open(name: string): Promise<PromptInterface | undefined>;
1741
+ /** Persists an endpoint's config snapshot; false with no store, or an unknown name. */
1398
1742
  save(name: string): Promise<boolean>;
1743
+ /**
1744
+ * Removes a batch (`remove(names)`, the array overload declared first, true only when every name
1745
+ * was mounted), one endpoint, or every endpoint.
1746
+ */
1399
1747
  remove(names: readonly string[]): boolean;
1400
1748
  remove(name: string): boolean;
1401
1749
  remove(): void;
1750
+ /** Tears down every broker, then the manager's own emitter. */
1402
1751
  destroy(): void;
1403
1752
  }
1404
1753
 
1405
1754
  /**
1406
- * Options for {@link import('./factories.js').createTerminalManager} and the
1755
+ * Configures {@link import('./factories.js').createTerminalManager} and the
1407
1756
  * {@link TerminalManagerInterface}.
1408
1757
  *
1409
1758
  * @remarks
@@ -1422,9 +1771,9 @@ export declare interface TerminalManagerOptions {
1422
1771
  }
1423
1772
 
1424
1773
  /**
1425
- * One endpoint's persisted CONFIG snapshot — `id` is the endpoint name and `timeout` its configured
1426
- * default. Parked forms are process-bound and are never resurrected, so `open` always restores an
1427
- * EMPTY broker.
1774
+ * Represents one endpoint's persisted config snapshot — `id` is the endpoint name and `timeout` its
1775
+ * configured default. Parked forms are process-bound and are never resurrected, so `open` always
1776
+ * restores an empty broker.
1428
1777
  */
1429
1778
  export declare interface TerminalSnapshot {
1430
1779
  readonly id: string;
@@ -1432,9 +1781,9 @@ export declare interface TerminalSnapshot {
1432
1781
  }
1433
1782
 
1434
1783
  /**
1435
- * One opaque persisted row — the shape a `TableInterface<TerminalSnapshotRow>`-backed store reads
1436
- * and writes. `snapshot` is narrowed with {@link import('./validators.js').isTerminalSnapshot} on
1437
- * read.
1784
+ * Represents one opaque persisted row — the shape a table-backed store reads and writes. The store
1785
+ * is a `TableInterface<TerminalSnapshotRow>`, and `snapshot` is narrowed with
1786
+ * {@link import('./validators.js').isTerminalSnapshot} on read.
1438
1787
  */
1439
1788
  export declare interface TerminalSnapshotRow {
1440
1789
  readonly id: string;
@@ -1442,35 +1791,45 @@ export declare interface TerminalSnapshotRow {
1442
1791
  }
1443
1792
 
1444
1793
  /**
1445
- * The point-access persistence seam for a {@link TerminalManagerInterface}'s endpoint configs.
1794
+ * Declares the point-access persistence seam for a {@link TerminalManagerInterface}'s endpoint configs.
1446
1795
  * Every primitive is async; deleting an absent id is a no-op.
1447
1796
  */
1448
1797
  export declare interface TerminalStoreInterface {
1798
+ /** Resolves the snapshot stored for `id`, or `undefined` when none is. */
1449
1799
  get(id: string): Promise<TerminalSnapshot | undefined>;
1800
+ /** Inserts or replaces under the snapshot's own `id`; there is no id argument. */
1450
1801
  set(snapshot: TerminalSnapshot): Promise<void>;
1802
+ /** Drops a snapshot by id. An absent id is a no-op, never a throw. */
1451
1803
  delete(id: string): Promise<void>;
1452
1804
  }
1453
1805
 
1454
- /** Cancel a pending {@link TimerHandler} deadline — idempotent, safe to call after the timer fired. */
1455
- export declare type TimerCancel = () => void;
1806
+ /** Cancels a pending {@link TimerHandler} deadline — idempotent, safe to call after the timer fired. */
1807
+ export declare type TimerCancelFunction = () => void;
1456
1808
 
1457
1809
  /**
1458
- * One injected timer — arms a deadline `callback` to fire after `ms`, returning a
1459
- * {@link TimerCancel} that cancels it. The broker's timeout seam: the default wraps the host
1810
+ * Represents one injected timer — arms a deadline `callback` to fire after `ms`, returning a
1811
+ * {@link TimerCancelFunction} that cancels it. The broker's timeout seam: the default wraps the host
1460
1812
  * `setTimeout` and `clearTimeout`; a test injects a deterministic timer that captures the callback
1461
1813
  * and fires it on demand, with no real time and no global patching.
1462
1814
  */
1463
- declare type TimerHandler_2 = (callback: () => void, ms: number) => TimerCancel;
1815
+ declare type TimerHandler_2 = (callback: () => void, ms: number) => TimerCancelFunction;
1464
1816
  export { TimerHandler_2 as TimerHandler }
1465
1817
 
1466
- /** Toggle `index` in a readonly index list — copy-on-write, returning the new sorted-by-insertion list. */
1818
+ /**
1819
+ * Toggles `index` in a readonly index list — copy-on-write, returning the new sorted-by-insertion
1820
+ * list; the primitive {@link reduceCheckbox} calls.
1821
+ *
1822
+ * @param indices - The ticked indices, in tick order
1823
+ * @param index - The index to add when absent, or drop when present
1824
+ * @returns A new list carrying the toggled membership; the input is never mutated
1825
+ */
1467
1826
  export declare function toggleIndex(indices: readonly number[], index: number): readonly number[];
1468
1827
 
1469
1828
  /**
1470
- * One SSE-shaped wire frame — the `event` name, its already-stringified `data` payload, and an
1829
+ * Represents one SSE-shaped wire frame — the `event` name, its already-stringified `data` payload, and an
1471
1830
  * optional `id`. The transport-neutral shape {@link import('./helpers.js').serializePending},
1472
1831
  * {@link import('./helpers.js').serializeExpire}, and
1473
- * {@link import('./helpers.js').serializeShutdown} build, with no `http` dependency.
1832
+ * {@link import('./helpers.js').serializeDestroy} build, with no `http` dependency.
1474
1833
  */
1475
1834
  export declare interface WireEvent {
1476
1835
  readonly event: string;