import { z } from "zod"; import { type JsonSchema } from "@vendoai/core"; /** 01-core §14 */ export interface StandardSchema { "~standard": { validate(value: unknown): unknown; }; } /** 01-core §14 (amended 2026-07-18): one optional props schema per entry; * the model-facing JSON Schema is derived internally by the composition — * hosts never hand-write it (`propsJsonSchema` is removed). Schema-less * entries are legal: the model infers props and validation is permissive. */ export interface RegisteredComponent { name: string; description: string; propsSchema?: StandardSchema; examples?: string[]; } /** 01-core §14 */ export type ComponentCatalog = ReadonlyArray; /** 01-core §14 (2026-07-18 amendment) — name-keyed registry form. The same * object serves both sides: the server reads the data fields, * reads the component references. The composition normalizes registry → * catalog entry by entry: key → `name`, `props` → `propsSchema`, `component` * dropped (the server MUST IGNORE it — never touched, never executed). */ export interface ComponentRegistryEntry { /** Host component reference for the client side; ignored server-side. */ component: unknown; description: string; /** The ONE optional props schema — same StandardSchema, same derivation. */ props?: StandardSchema; examples?: string[]; } /** 01-core §14 — keys are component names (PascalCase). */ export type ComponentRegistry = Record; /** The composition's internal normalized catalog entry (01 §14 amendment): * `propsJsonSchema` here is DERIVED — from the entry's single zod schema at * normalization time, or loaded verbatim from catalog@1's disk `propsSchema` * field — never hand-written by hosts. It drives both the generation prompt * and generated-props validation (04 §1). */ export interface NormalizedCatalogEntry extends RegisteredComponent { propsJsonSchema?: JsonSchema; } /** The normalized internal catalog the composition hands to the apps block. */ export type NormalizedCatalog = ReadonlyArray; /** One face `vendo sync` resolved to a real file and inlined into * `.vendo/fonts.css`. Metadata ONLY — never the bytes: theme.json is a bundle * import and rides the `?vendoTheme=` query string, so a base64 face here * would blow past every proxy's request-line limit. */ export interface VendoThemeFont { family: string; weight: string; style: string; source: "next/font" | "public" | "google" | (string & {}); } /** 01-core §14. The shape only: `./theme.js` owns the defaults, the merge, and * the one mapping onto `--vendo-*` CSS variables that every surface renders * through. * * `density`, `motion` and `typography.fonts[].source` carry a `| (string & {})` * arm so a `.vendo/theme.json` import — whose strings every bundler widens to * `string` — assigns to `theme` with NO cast, while the real values still * autocomplete. The widening is the TS surface only: `vendoThemeSchema` below * stays strict for the on-disk file, and `./theme.js` renders anything else as * the default (`comfortable` / `full`). */ export interface VendoTheme { colors: { background: string; surface: string; text: string; muted: string; accent: string; accentText: string; danger: string; border: string; success?: string; warning?: string; info?: string; surfaceRaised?: string; }; typography: { fontFamily: string; headingFamily?: string; monoFamily?: string; baseSize: string; weightNormal?: string; weightEmphasis?: string; letterSpacing?: string; lineHeightBody?: string; lineHeightHeading?: string; /** What `.vendo/fonts.css` holds, for a reader that has the theme but not * the sheet. Emitted by sync; nothing renders off it. */ fonts?: VendoThemeFont[]; }; radius: { small: string; medium: string; large: string; }; shadow?: { small: string; medium: string; large: string; }; density: "compact" | "comfortable" | (string & {}); motion: "full" | "reduced" | (string & {}); borderWidth?: string; /** Categorical chart series, in order; beyond six a chart reads the ramp * `chartPaletteFor` derives from the accent. */ chartPalette?: string[]; motionDuration?: string; motionEasing?: string; } /** 01-core §14. Every field added after the original eight-color shape is * OPTIONAL: a failed parse discards the WHOLE theme file, so a required addition * would blank the brand of every host whose theme predates it. */ export declare const vendoThemeSchema: z.ZodObject<{ colors: z.ZodObject<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">>; typography: z.ZodObject<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">>; radius: z.ZodObject<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>; shadow: z.ZodOptional, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>>; density: z.ZodEnum<["compact", "comfortable"]>; motion: z.ZodEnum<["full", "reduced"]>; borderWidth: z.ZodOptional; chartPalette: z.ZodOptional, string[], string[]>>; motionDuration: z.ZodOptional; motionEasing: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ colors: z.ZodObject<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">>; typography: z.ZodObject<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">>; radius: z.ZodObject<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>; shadow: z.ZodOptional, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>>; density: z.ZodEnum<["compact", "comfortable"]>; motion: z.ZodEnum<["full", "reduced"]>; borderWidth: z.ZodOptional; chartPalette: z.ZodOptional, string[], string[]>>; motionDuration: z.ZodOptional; motionEasing: z.ZodOptional; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ colors: z.ZodObject<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ background: z.ZodString; surface: z.ZodString; text: z.ZodString; muted: z.ZodString; accent: z.ZodString; accentText: z.ZodString; danger: z.ZodString; border: z.ZodString; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; surfaceRaised: z.ZodOptional; }, z.ZodTypeAny, "passthrough">>; typography: z.ZodObject<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ fontFamily: z.ZodString; headingFamily: z.ZodOptional; monoFamily: z.ZodOptional; baseSize: z.ZodString; weightNormal: z.ZodOptional; weightEmphasis: z.ZodOptional; letterSpacing: z.ZodOptional; lineHeightBody: z.ZodOptional; lineHeightHeading: z.ZodOptional; fonts: z.ZodOptional; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ family: z.ZodString; weight: z.ZodString; style: z.ZodString; source: z.ZodEnum<["next/font", "public", "google"]>; }, z.ZodTypeAny, "passthrough">>, "many">>; }, z.ZodTypeAny, "passthrough">>; radius: z.ZodObject<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, "passthrough", z.ZodTypeAny, z.objectOutputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>; shadow: z.ZodOptional, z.objectInputType<{ small: z.ZodString; medium: z.ZodString; large: z.ZodString; }, z.ZodTypeAny, "passthrough">>>; density: z.ZodEnum<["compact", "comfortable"]>; motion: z.ZodEnum<["full", "reduced"]>; borderWidth: z.ZodOptional; chartPalette: z.ZodOptional, string[], string[]>>; motionDuration: z.ZodOptional; motionEasing: z.ZodOptional; }, z.ZodTypeAny, "passthrough">>; /** One page of the host product a generated view may send someone to. The * `description` is what picks between them — the agent reads it, never the path. */ export interface VendoRoute { path: string; description: string; } /** The host's route registry, keyed by the NAME generated UI links to. Paths are * the host's own; a link names a key, so nothing generated authors a URL. */ export type VendoRouteMap = Record; /** A resolved navigation — what a host's `onNavigate` is handed. `path` is the * REGISTERED path with the link's params substituted and URL-encoded. */ export interface VendoNavigation { to: string; path: string; params?: Record; } export declare const vendoRouteSchema: z.ZodObject<{ path: z.ZodString; description: z.ZodString; }, "strip", z.ZodTypeAny, { path: string; description: string; }, { path: string; description: string; }>; export declare const vendoRouteMapSchema: z.ZodRecord>; /** The parameters a registered path takes. * * ONE definition, because THREE readers must agree about it and they break in a * correlated way when they drift: this file's resolver, the gauntlet's routes * check (`facts.ts` `routeIssues`), and the briefing's ROUTES section. A path whose * parameters are read differently by any two of them is a link that resolves * and is refused, or is accepted and goes nowhere. */ export declare const vendoRouteParams: (path: string) => string[]; /** The colon-led segments this resolver cannot fill — `:slug.html`, `:id-2`. * * The exact COMPLEMENT of {@link vendoRouteParams} over colon-led segments, from * the same `PARAM_SEGMENT`: every segment starting with `:` is either a * parameter or named here, never both and never neither. That is what makes * "supported" and "refused" agree by construction instead of by two authors * keeping two rules in step — and the gap between them is precisely where * `/posts/:slug.html` fell, reported as taking NO parameters while the resolver * handed back a path still carrying `:slug.html`. Nothing could fill it, so the * link died quietly, and the floor and the briefing read it the same wrong way. * * A host hears about this at registration (`createVendo`), never at render. */ export declare const unsupportedRouteParams: (path: string) => string[]; /** Resolve a link target against the registry. A name the host never registered * — or one whose path has `:params` the link left unfilled — resolves to * `undefined`: an unknown route is REFUSED here rather than passed through, so * the only strings that can become an href are the host's own. */ export declare function resolveVendoRoute(routes: VendoRouteMap, to: string, params?: Record): VendoNavigation | undefined; /** How this host's brand FEELS, in one line, for the thinker that does not * render. Its companion — the host component list this used to render beside the * theme — is gone: `renderBriefingPack` renders that list for the rung that * actually writes a screen, and two renderings of one config key is what the * briefing pack exists to prevent. The theme half is NOT a second copy of * anything: the pack hands the screen agent the tokens VERBATIM, and this is a * sentence. It is also the one observable that says the theme surface resolved * at all (server.test.ts's profile/profileDir/disk seam). */ export declare const themeSummary: (theme?: VendoTheme) => string | undefined; //# sourceMappingURL=catalog.d.ts.map