/** * The asset id shape. Base32-lower, matching the server's `^lib_[a-z2-7]{16}$` * exactly. * * The alphabet is the house convention across this API (f3 sessions {32}, f4 * uploads {26}, preview host labels, publish keys) and it excludes 0/1/8/9 so an * id read off a terminal carries no visually ambiguous characters. 16 chars is * 80 bits, which is what makes the key pattern unguessable, one of the four * counters to an agent inventing a URL. * * The CLI briefly accepted hex as well, because every EXAMPLE id written into * the design record was hex and contradicted the record's own regex. User ruling * 2026-08-23: the regex is authoritative and the examples were wrong. Matching * the server exactly is what keeps a client-side reject and a server-side * `unknown[]` from ever disagreeing. */ export declare const LIB_ID_RE: RegExp; export declare function isLibraryId(s: string): boolean; /** * An asset record as the API emits it. Only `id` and `url` are structurally * required; everything else is optional BECAUSE THE WIRE SAYS SO, not as a * convenience: * • `kind` may be ABSENT — a real state (unclassifiable), never "" and never * "unknown". Coercing absence to a string would invent a classification. * • `text_in_image` is omitted when not confidently read, never "". * • `retired` rides fetch and batch but NOT search (a search never returns a * retired asset), so its absence is normal rather than a defect. */ export interface AssetRecord { id: string; url: string; kind?: "prop" | "frame"; width?: number; height?: number; aspect?: string; has_alpha?: boolean; bytes?: number; format?: string; subject?: string; style?: string[]; palette?: string[]; render?: string; view?: string; description?: string; usage_hint?: string; text_in_image?: string; occupies_canvas?: number; retired?: boolean; } export interface Gap { tag: string; message: string; } export interface SearchResponse { query?: string; /** The corpus the answer came from. Absent on an older API — the header line degrades away. */ revision?: string; resultCount: number; results: AssetRecord[]; gaps: Gap[]; } export interface BatchResponse { resolved: AssetRecord[]; /** Verbatim echoes of unresolvable inputs. Disjoint from `resolved`. */ unknown: string[]; } /** * Parse one asset record. * * `kind` is admitted ONLY as "prop" or "frame". Anything else — including "" and * "unknown" — parses to ABSENT rather than being passed through, because a record * whose kind is the literal string "unknown" would render as a real classification * on the line an agent uses to decide whether the asset is usable at all. * * Returns undefined when `id`/`url` are missing: a record with no URL is not a * usable result, and dropping it is better than rendering an entry whose payload * line is blank. */ export declare function parseAssetRecord(raw: unknown): AssetRecord | undefined; /** * Parse the search envelope. * * `resultCount` is taken from the wire when present and otherwise derived from the * array, so a truncated envelope still renders a truthful count rather than 0 — * and 0 is the one value that must never be invented, because zero results is a * meaningful product answer (the honest-empty path) rather than an absence. */ export declare function parseSearchResponse(raw: unknown): SearchResponse; /** * Parse the batch envelope. `unknown[]` entries are echoed VERBATIM by the server * and are kept as raw strings — they are the caller's own input coming back, which * is what lets an agent diff against what it sent without parsing our prose. */ export declare function parseBatchResponse(raw: unknown): BatchResponse; /** A single record from `GET /library/assets/{id}` — the same record shape, unwrapped. */ export declare function parseFetchResponse(raw: unknown): AssetRecord | undefined;