import { type DashboardResult, type ComposedView, type EvalOptions } from './dashboard.js'; import type { CompiledDefinition, Finding, Inventory, IR } from './types.js'; /** The kind names the engine ships. A closed set, so an unknown spelling is * a refusal (`surface-unknown`) with did-you-mean — the same rule every * closed vocabulary in the engine follows. */ export declare const SURFACE_KIND_NAMES: readonly ["dashboard", "report", "form"]; export type SurfaceKindName = typeof SURFACE_KIND_NAMES[number]; /** * The routing-grade probe (E32 t4 review): what a CLI gate needs to know * before bouncing a file to another command. `null` means the text is not * YAML at all — the gate must NOT bounce then, because "declares surface: * dashboard" would be a false statement about a file that declares nothing * parseable; it falls through to the surface evaluator the user actually * invoked, whose refusal wording owns the syntax error (evaluateDashboard's * line-and-caret, evaluateReport's report-worded translation). `declared` * distinguishes a written `surface:` key from the absence-means-dashboard * default, so a bounce message never claims a file "declares" a kind the * author never typed. An unknown kind is the one mistake refused HERE * (surface-unknown): routing a typo to either evaluator would bury it under * that evaluator's unrelated complaints. */ export declare function surfaceKindProbe(yamlText: string): { kind: SurfaceKindName; declared: boolean; } | null; /** * Which surface kind `yamlText` declares. Defaults to 'dashboard' — on an * absent key, on a non-mapping document, and on YAML that does not parse: * broken syntax must be reported by the surface evaluator that owns the * file's refusal wording, not pre-empted here with a worse one. CLI routing * gates want surfaceKindProbe instead: this collapsed answer cannot tell * "declares dashboard" from "does not parse", and bouncing on it produced a * factually false message (E32 t4 review). */ export declare function surfaceKindOf(yamlText: string): SurfaceKindName; /** One report section, evaluated: its heading, its markdown notes verbatim * (the render layer owns turning them into HTML), and the vids of the views * placed in it, in authored order. */ export interface ReportSection { label?: string; notes?: string; vids: string[]; } export interface ReportResult { title: string; subtitle?: string; /** the declared snapshot date, normalized — ABSENT when none was declared * or the declaration was malformed (warn `report-date`): the render layer * falls back to the render date, which the evaluator cannot know */ date?: string; sections: ReportSection[]; /** every placed view, evaluated, in first-mention order — ids ARE the vids * the sections reference. The §2 vid policy: a parameter-free named * reference keys under its own name (the payload-equivalence proof with * the dashboard depends on it — same id, same widget-id prefixes, same * bytes), while an overridden reference (label:/with:) and an inline * widget entry mint `sec-v` ('~'-suffixed when a library file is * literally named like a mint, so the two namespaces can never collide — * see mintVid). Reports mint no anonymous nav vids — there is no attach() * counter here at all. */ views: ComposedView[]; theme?: DashboardResult['theme']; /** the report's animation ceiling — its DEFAULT is off (§1.4): a report is * a print-shaped document, and motion is opt-in there, not opt-out */ motion?: 'full' | 'reduced' | 'off'; } /** * Evaluate a report surface file (§1.4). Refusals are the author's own * grammar mistakes — no/empty `sections:` (surface-sections-empty), any * PlacementError, a placed for_each view — while everything about whether a * NAME resolves stays the warn-level view-* family with a stub substituted, * the same two-channel doctrine every surface keeps. */ export declare function evaluateReport(yamlText: string, ir: IR, inventory: Inventory | null, findings: Finding[], opts?: EvalOptions): ReportResult; export interface FormResult { title: string; subtitle?: string; /** the lead-in prose, markdown, VERBATIM — the render layer turns it into * HTML (the report's notes precedent) */ intro?: string; /** the target: op_record's PK needs a node, so `document:` is required and * must name a document this vault actually has */ document: string; block: string; /** the declared APPEND form on that block — the only write this page makes */ action: string; /** the submit button's word (default: the form's own label) */ submit: string; after: { /** `{id}`/`{uuid}` are the ONLY variables, substituted from the write's * own answer by the client */ message: string; /** how the new record's address is shown: a link into the KB, the id as * plain text, or nothing. FAIL-CLOSED downstream, twice (design §5 item * 6): no home URL degrades link → text, no record in the answer degrades * either one → none */ address: 'link' | 'text' | 'none'; /** offer a "file another" reset. Undeclared is false — an intake that * never said so does not invite a second submission */ again: boolean; }; theme?: DashboardResult['theme']; motion?: 'full' | 'reduced' | 'off'; } /** * Evaluate a form surface file (§2.3). Every refusal is a DashboardError (the * one surface refusal type every kind throws) so a host renders the same * failure envelope for a broken intake as for a broken report. * * `def` is a required argument, not an EvalOptions field: a form surface is * ONLY meaningful against a definition (its block, its action and the fields * it draws all live there), so an optional one would only buy the ability to * evaluate nothing. */ export declare function evaluateForm(yamlText: string, ir: IR, def: CompiledDefinition, findings: Finding[]): FormResult;