/** * Central input validation for the TUI. * * EVERY external data source that crosses a trust boundary passes through * this module. Uses an **allow-list** approach: define the exact allowed * shape, types, ranges, and formats for each input; reject everything else. * * ── Trust boundaries ───────────────────────────────────────────────── * * Boundary | Source | Validator * ------------------|---------------------|-------------------------- * stdin | terminal emulator | validateStdinFragment() * paste | bracketed-paste | validatePasteContent() * AppProps | CLI host | validateAppProps() * Reducer Action | handleKey dispatch | validateAction() * Host callbacks | CLI/plugin return | validateCallbackReturn() * Mouse events | SGR protocol | validateMouseEvent() * Fleet telemetry | Director/FleetBus | validateFleetEntry() * Restore data | session JSONL | validateRestoreEntry() * * ── Rejection over coercion ────────────────────────────────────────── * * This module **rejects** invalid input rather than coercing it, for * three reasons: * * 1. **Coercion masks injection.** Trimming whitespace from a string * that contains an ANSI escape sequence leaves the sequence intact. * 2. **Semantic gap.** Coercing a value (e.g. clamping a PID to a valid * range) creates a gap between what was validated and what the * application actually uses — a future code path may use the raw * value, not the clamped one. * 3. **Predictable failure.** Silent data transformation makes security * debugging harder — rejection produces a clear error at the point * of violation; coercion produces subtly wrong behavior downstream. * * The single exception is **normalization before comparison**: trimming * whitespace from an enum label before comparing it to the allow-list * prevents trivial bypasses (e.g. `" off "` vs `"off"`). This is * NOT the same as coercing the input — the normalized comparison only * determines allow/deny; the caller receives the original value. * * ── Conventions ────────────────────────────────────────────────────── * * - Every `validate*` function returns `ValidationResult`: * `{ valid: true; value: T }` — the validated, ready-to-use value * `{ valid: false; error: string }` — a specific, actionable message * - Every error message follows the pattern: * `"{path}": {what went wrong} ({detail}).` * - Size limits are defined as module-level constants with doc comments. * - Enum/union allow-lists are defined as `const` arrays and kept in * ONE place so the allowed set is auditable. */ import type { ValidationResult } from './input-validation/result.js'; export { ALLOWED_ACTION_TYPES, type AllowedActionType, } from './input-validation/action-types.js'; export { ALLOWED_AUTONOMY_MODES, ALLOWED_CAPABILITY_FIELDS, ALLOWED_COLLAB_VERDICTS, ALLOWED_ENTRY_KINDS, ALLOWED_FLEET_CHAT_MODES, ALLOWED_FLEET_STATUSES, ALLOWED_KEY_EVENT_FIELDS, ALLOWED_MOUSE_BUTTONS, ALLOWED_MOUSE_KINDS, ALLOWED_PICKER_KINDS, ALLOWED_SCROLL_DIRS, ALLOWED_SDD_OPS, ALLOWED_SEND_MODES, TEXT_BEARING_ENTRY_KINDS, } from './input-validation/allow-lists.js'; export { MAX_ACTION_DEPTH, MAX_ACTION_STRING_FIELD, MAX_BATCHED_ACTIONS, MAX_ENTRY_TEXT_CHARS, MAX_FLEET_ENTRIES, MAX_HISTORY_ENTRIES, MAX_HOST_STRING_FIELD, MAX_INPUT_BUFFER_CHARS, MAX_PASTE_CHARS, MAX_PASTE_FRAGMENT_CHARS, MAX_PICKER_MATCHES, MAX_RECENT_MESSAGES, MAX_RECENT_TOOLS, } from './input-validation/limits.js'; export type { ValidationError, ValidationOk, ValidationResult, } from './input-validation/result.js'; export { validateFleetEntry, validateRestoreEntry } from './input-validation/state-entries.js'; export { validateKeyEventFields, validateMouseEvent, validatePasteContent, validateStdinFragment, } from './input-validation/terminal.js'; export declare function validateAction(action: { type: string; [key: string]: unknown; }): ValidationResult>; /** * Validate that an action dispatch is safe for the reducer. * This is a convenience wrapper used at the dispatch boundary. * Returns the original action untouched if valid, or throws with the * specific error message if invalid. * * In production, the caller can log the error and drop the action * instead of crashing — but for security boundaries, throwing is the * safe default because it prevents any partially-valid state from * reaching the reducer. */ export declare function ensureValidAction(action: { type: string; [key: string]: unknown; }): Record; /** * Safe dispatch wrapper: validates the action, then calls dispatch * only if validation passes. Returns true if dispatched, false if rejected * (with the error logged). */ export declare function safeDispatch(action: { type: string; [key: string]: unknown; }, dispatch: (action: Record) => void): boolean; /** * Normalize a string by trimming whitespace. * This is the ONLY normalization we do — and it's only used for * allow-list comparison, never for the returned value. */ export declare function normalizedEquals(a: string, b: string): boolean; //# sourceMappingURL=input-validation.d.ts.map