/** * Catalog builder — turns the component graph into an A2UI v1.0-shaped * catalog document (#1887, strategy §4.2 in docs/GENERATIVE-UI-STRATEGY.md). * * A catalog is what a *renderer* or a *composer* reads: every node an agent * may name, its props as JSON Schema, its slots as child lists, and the Eddie * tag each node maps to. It is generated from `.eddie-brain/components.json` * on every `eddie-brain init`, so it cannot drift from source, and it is * covered by the CI graph-freshness gate like the rest of the graph. * * Shape follows `specification/v1_0/json/catalog_definition.json` in * a2ui-project/a2ui: `catalogId`, `protocolVersion`, `instructions`, and a * `components` map whose values are JSON Schema objects carrying the * `allowedParents` / `allowedChildren` / `metadata.extensions` fields that * v1.0 added. Two rules from that spec shape everything here: * * - **Node names are UAX #31 identifiers.** `ed-r-stat-card` is not a legal * component name (hyphens fail `XID_Continue`), so nodes are `StatCard` * and the tag lives in `metadata.extensions.eddie_tag`. * - **`Surface` is reserved** as the root parent; a profile's composition * nodes declare `allowedParents: ["Surface"]`. * * Three Eddie-level fields (`profile`, `contractComplete`, `eddieVersion`) * sit at the catalog root. `catalog_definition.json` declares * `additionalProperties: false` there, so a validator that checks the root * strictly will flag them; A2UI's own `assemble_catalog.py` does not (it * checks the document is a valid Draft 2020-12 schema). They stay at the * root because the approved spec names them there and consumers need * `contractComplete` before they trust containment. Revisit when v1.0 * finalizes (Q4 2026) and offers a catalog-level extension slot. * * Deterministic on purpose: no timestamps. `eddieVersion` is the provenance. * A timestamp would make every `init` a git diff and break the freshness * gate (the same trap `metadata.json` fell into before it was gitignored). */ import type { AntiPattern, ComponentEntry, PropertyEntry, SlotEntry } from '../types.js'; /** A2UI v1.0 `common_types.json` — the child-reference schema every node uses. */ export declare const A2UI_COMMON_TYPES = "https://a2ui.org/specification/v1_0/common_types.json"; export declare const A2UI_CHILD_LIST = "https://a2ui.org/specification/v1_0/common_types.json#/$defs/ChildList"; /** Where the catalog is published (strategy §4.2). */ export declare const CATALOG_ID = "https://ds.bradfrost.com/catalog/eddie/v1"; export declare const CATALOG_PROTOCOL_VERSION = "1.0"; /** The ASCII subset of a UAX #31 identifier — every node, prop, slot and extension key must match. */ export declare const IDENTIFIER_RE: RegExp; /** Longest description carried per node or prop; the full text stays in `eddie_get_component`. */ export declare const DESCRIPTION_MAX = 240; /** Minimal JSON Schema surface this builder emits. */ export interface JsonSchema { type?: string | string[]; const?: unknown; enum?: unknown[]; default?: unknown; description?: string; items?: JsonSchema; properties?: Record; required?: string[]; additionalProperties?: boolean; $ref?: string; $comment?: string; } /** Everything the catalog knows about a node beyond its JSON Schema. Keys are UAX #31 identifiers. */ export interface EddieExtensions { /** The Eddie custom-element tag this node renders as, or the root tag of a composition's expansion. */ eddie_tag: string; /** `primitive` maps 1:1 to a tag; `composition` expands into several (strategy §4.2); `text` is the built-in text node. */ eddie_kind: 'primitive' | 'composition' | 'text'; eddie_package?: string; eddie_atomicLevel?: string; eddie_category?: string; eddie_projectScope?: string; eddie_recipeKind?: string; /** The `