import { C as ComponentResolutionSource, a as ComponentResolution, b as ContentIrErrorReporter } from './component-resolution.types-CNArz3ZR.js'; export { c as ComponentLayerRef, d as ComponentLayerScope, e as ComponentOverlayInput, f as ComponentRole, g as ContentIrErrorReport, J as JsonObject, K as KindComponentLayerRow, h as KindComponentRow, S as SystemComponentEntry, i as consoleErrorReporter } from './component-resolution.types-CNArz3ZR.js'; import { C as ContentIrHost, K as KindRouteEnv, a as KindDefinitionSource, D as DecodedDirective, b as DirectiveClass, c as DirectiveHost, d as DirectiveFailure, e as DirectiveFailureWords, f as DirectiveRecordRef } from './route-8dfsihzb.js'; export { g as ContentIrRenderSeams, h as DB_KIND_COMPONENT_KEY, i as DIRECTIVE_BLOCK_TYPE, j as DirectiveApplyResult, k as DirectiveApplyState, l as DirectiveAskRequest, m as DirectiveCopyProps, n as DirectiveHostProvider, o as DirectiveHostProviderProps, p as DirectiveOpenItemOptions, q as DirectiveRecordProps, r as DirectiveScope, s as DirectiveScopeProvider, t as DirectiveShell, u as DirectiveValueRef, G as GENERIC_STRUCTURED_COMPONENT_KEY, v as GenericFallbackReason, I as IR_PROVISIONAL_KEY, w as IR_ROUTE_KEY, x as IrRenderBlock, y as IrRoutableBlock, z as IrRouteMarker, A as KindRouteBinding, B as KindRouteOptions, P as PartialRenderOptions, E as ProvisionalKindRender, S as StructuredValueRenderProps, F as SupersededKindRender, H as applyIrKindRoute, J as createKindRouteBinding, L as envelopeFromPartialKind, M as isPartialReadyKind, N as isProvisionalBlock, O as kindLookupSettled, Q as kindServerDataFromStoredValue, R as markKindPartialUnsafe, T as readIrRouteMarker, U as resetPartialUnsafeKinds, V as resetSourcelessDbRowReports, W as resolveAnnouncedKindLoading, X as resolveProvisionalKindRender, Y as resolveSupersededKindRender, Z as routeEnvOf, _ as useDirectiveHost, $ as useDirectiveScope } from './route-8dfsihzb.js'; import * as react from 'react'; import react__default, { ReactNode, ComponentType } from 'react'; export { ComponentResolver, ComponentResolverOptions, KIND_LOOKUP_BOUND_MS, KindComponentOverlayLoader, LAYER_COLUMNS, LayerDbRow, OVERLAY_ORGANIZATION_CHUNK, OVERLAY_RETRY_DELAYS_MS, OverlayEntry, OverlayLoaderPorts, OverlayTarget, OverlayViewer, OverlayViewerWatch, createOverlayViewerWatch, layerAudienceFilter, layerDbRowToLayerRow, rankLayerRows, readViewerLayerRows } from './resolver.js'; interface ContentIrRenderProviderProps { host: ContentIrHost; children: ReactNode; } declare function ContentIrRenderProvider({ host, children, }: ContentIrRenderProviderProps): react.JSX.Element; /** * The wired host, or null. For the rare consumer that can legitimately run * without a provider because it was handed its sources explicitly (see * `useContentIrKindVersion`). Everything else uses {@link useContentIrHost}. */ declare function useContentIrHostOrNull(): ContentIrHost | null; /** The wired host. Throws outside a provider β€” see the module doc. */ declare function useContentIrHost(): ContentIrHost; /** The wired host narrowed to what the pure route functions take. */ declare function useKindRouteEnv(): KindRouteEnv; /** * The two registries this hook watches. Passed explicitly by a host whose * render path sits BELOW no provider β€” matrx-frontend's block renderer runs * deep inside chat, workflow, and canvas trees that predate this package, and * threading a provider through all of them to read two counters would be the * tail wagging the dog. */ interface KindVersionSources { kinds: Pick; components: Pick; } /** * Subscribes the caller to registry changes FOR ONE KIND and returns that * kind's combined version. Pass null for blocks with no envelope kind β€” they * never repaint from registries (nothing to learn about them). * * `sources` defaults to the provider's host. Passing them explicitly is the * supported way to use this hook outside a provider. */ declare function useContentIrKindVersion(kind: string | null, sources?: KindVersionSources): number; declare function isRecordValue(value: unknown): value is Record; /** * True when `applyIrKindRoute` has a registered render path for this kind β€” a * compiled legacy bridge OR any ACTIVE resolver row (including db-sourced user * components, which route to `db_kind_component`). Mirrors the route's own * decision order; requires the resolver warm tier for db rows (see the warm * tick in {@link KindInstanceRender}). */ /** * Is there a render path for this kind that is NOT the generic key/value floor? * * 🚨 READ THIS BEFORE USING IT AS A HEALTH SIGNAL. It answers a narrow * question β€” "will a direct-object render mount something other than the * generic view?" β€” and it is the right question for the fallback decision it * was written for. It is the WRONG question for "does this kind work". * * It cannot see any of: whether the kind's schema loads, whether a streamed * payload is recognized from text, or what `applyIrKindRoute` returns for a * real envelope. On 2026-08-29 every one of ~221 kinds that had stopped * rendering in chat still answered `true` here, because their component rows * were fine β€” the recognition step ahead of the component was not. * * For "does this kind work", run the render paths * (`features/content-ir/render-paths`) and read the route's actual answer. */ declare function kindIsRoutable(kind: string, host: ContentIrHost): boolean; interface KindInstanceRenderProps { kind: string; /** The canonical instance value (a `kind_example.data` row, a form-emitted instance, a node output). */ value: unknown; /** Show the honest "no component registered" notice when unroutable. Default true. */ showRoutingNote?: boolean; /** * What to render when the routing decision lands on "no component exists for * this kind". The universal document view is the right answer almost * everywhere β€” it reads well and hides nothing. It is still the wrong answer * when the raw value is an internal ENVELOPE rather than content: an * `agent_result` dumped the verbatim prompt, the model id and the token bill * into the box a learner was waiting on. Passing a fallback lets that caller * show what the reader actually wants WITHOUT anyone second-guessing the * routing decision β€” this component stays the ONE place that decides whether * a kind has a component. * * Omitted β†’ the host's floor, exactly as before. */ unroutableFallback?: ReactNode; /** * Chrome, per THE WRAPPER LAW and the owner's no-cards ruling (2026-10-24: * "Avoid cards at all costs. Especially cards within other cards."): a shape * is never boxed by default. * - "flat" (default): normal padding only (`px-3 py-2`) β€” no border, no * background. The shape sits on the host surface, full width, off the walls. * - "bare": no padding either β€” for a host that already pads (a titled panel, * a dialog body, a chat message). * - "card": the deliberate opt-in bordered surface. Never inside another card. */ variant?: KindInstanceFrameVariant; className?: string; } type KindInstanceFrameVariant = "flat" | "card" | "bare"; /** * The frame classes per variant β€” exported so a guard can prove the DEFAULT * frame carries no border and no card background. */ declare const KIND_INSTANCE_FRAME_CLASS: Record; declare const DEFAULT_KIND_INSTANCE_FRAME: KindInstanceFrameVariant; declare function KindInstanceRender(props: KindInstanceRenderProps): react.JSX.Element; /** * The safety net + the "still arriving" affordance for a provisional kind * render (streaming partial kinds β€” see `route/partial-kind-route.ts` and * `common-docs/systems/architecture/content-ir/FEATURE.md`). * * TWO JOBS * -------- * 1. **Never let a component throw mid-stream.** A provisional value may be * missing required fields. The routed kind opted in to tolerating that * (every kind does β€” there is no opt-out), but that is a claim, not a proof β€” so a throw is * caught here, SCREAMS through the host's error reporter, drops the kind * back to withhold for the session (`markKindPartialUnsafe`), and falls back * to the kind's own loading skeleton. The user sees the pre-partial * behavior, not a broken message. * 2. **Say it is still arriving.** The user must be able to tell a live fill-in * from a finished render, and it must not read as an error. A quiet chip * rides the block's top edge β€” absolutely positioned and * `pointer-events-none`, so it costs the content no layout and cannot shift * the page when it disappears. It sits ON the border rather than inside the * block: a routed kind often renders its own chrome, and a chip inside the * box lands on top of those controls. * * No wrapper chrome: no border, no background, no padding. The kind component * already carries its own (THE WRAPPER LAW). */ interface ProvisionalKindBoundaryOwnProps { kind: string; /** Rendered instead of the children when the provisional render throws. */ fallback: ReactNode; children: ReactNode; /** * The value is FINAL (the block that streamed provisionally has settled). The host keeps this * boundary in place so the drawn component is the same element from its first provisional * frame through its final render (a streamed shape mounts once); a throw on a final value is not * a provisional failure, so it passes up to the host's own error boundary untouched. */ final?: boolean; } declare function ProvisionalKindBoundary(props: ProvisionalKindBoundaryOwnProps): react__default.JSX.Element; /** * The "still arriving" frame. `aria-busy` carries the same fact to assistive * tech that the chip carries visually. The chip's own rendering is a host seam * (`renderShimmer`) so an app with a shimmer primitive uses it and one without * still says the true thing, plainly. */ declare function ProvisionalKindFrame({ children, arriving, }: { children: ReactNode; /** * False once the value is final: the SAME frame element stays (so its child is never * re-parented β€” a streamed shape mounts once), it just stops saying "still arriving". */ arriving?: boolean; }): react__default.JSX.Element; interface GenericStructuredViewProps { /** The raw region source β€” the zero-loss floor when no envelope survived. */ content: string; /** Carries `__ir` (the parsed envelope) and `__ir_route` (the seam marker). */ metadata?: Record; /** * What to show while the region is still streaming. Hosts with a shimmer or * an icon set pass theirs; the default is the same sentence, plainly. */ streamingIndicator?: ReactNode; className?: string; } declare function GenericStructuredView({ content, metadata, streamingIndicator, className, }: GenericStructuredViewProps): react.JSX.Element; interface DelegatedOutputProps { output: unknown; /** The wrapper's `output_kind` β€” the node's DECLARATION, the fallback. */ declaredKind: string | null; /** * What to draw for a value with no kind at all, and as the unroutable * fallback. Hosts with a settled-output body (the same one their readout * uses β€” never a second reader) pass it; otherwise the floor draws it. * * A RENDER FUNCTION, not a node: the fallback needs the payload, and the only * component that has read it is this one. Handing back a static node would * force every host to re-read the wrapper itself β€” a second reader, which is * exactly what this family exists to prevent. */ fallback?: (output: unknown) => ReactNode; /** What to say when the step produced nothing. */ emptyLabel?: string; } /** * The delegation seam β€” the ONLY thing these components do with a payload. * * In-band `__kind` wins over the node's DECLARATION, the same law a run reducer * follows: the discriminator inside the value describes what we are actually * holding, so it is what routes. With no kind at all there is nothing to route * to, and the host's fallback (or the floor) shows what the step produced. */ declare function DelegatedOutput({ output, declaredKind, fallback, emptyLabel, }: DelegatedOutputProps): react.JSX.Element; interface NodeOutcomeViewProps { serverData?: unknown; /** Passed through to {@link DelegatedOutput}. */ fallback?: (output: unknown) => ReactNode; } /** THE renderer for the `node_outcome` runtime wrapper kind. */ declare function NodeOutcomeView({ serverData, fallback }: NodeOutcomeViewProps): react.JSX.Element | null; interface RunResultViewProps { serverData?: unknown; fallback?: (output: unknown) => ReactNode; } /** * THE renderer for the `run_result` runtime wrapper kind. * * One finished run: one `node_outcome` per TERMINAL node β€” each delegated to * {@link NodeOutcomeView}, which delegates the payload inside it to the data * kind's own component. Recursion all the way down; no payload is rendered * here, and no `final_text` is read here. * * The run's own `output` is rendered ONLY when the run declared no terminal * outcomes β€” otherwise it is the same content the outcomes already carry, and * showing both is the duplication the wrapper exists to prevent. */ declare function RunResultView({ serverData, fallback }: RunResultViewProps): react.JSX.Element | null; /** * Kind Directives β€” the renderer registry, and THE PREFIX TIER. * * A directive IS a kind instance, so the renderer for one is resolved from its * SLUG, in the same shape the kind component resolver uses: * * getDirectiveRenderer(directive) * β†’ an exact-slug renderer (directive_v1_action_plan_tree) * β†’ else the CLASS prefix rule (every directive_v1_reference_*) * β†’ else null (DirectiveRender's own tier: the * side-effect card, then the floor) * * THE PREFIX RULE is Arman's routing-language ruling made real: registering * `reference` once gives EVERY enrolled noun a renderer for free; a custom * renderer for one slug overrides it; a brand-new server noun renders with * ZERO client edits. Hosts register their bespoke renderers (reference chips, * plan trees) here; the package supplies the side-effect card and the floor. */ interface DirectiveRendererProps { /** The decoded two-key shell β€” slug, class, noun, items, position law. */ directive: DecodedDirective; } type DirectiveRenderer = ComponentType; /** * Register a renderer for a whole CLASS (the prefix rule), or for one exact * `(class, noun)` pair, which wins. `noun` is passed as a noun, never a * hand-typed slug: the slug is BUILT by the grammar, so a registration whose * slug could not be parsed back is unconstructable rather than unreachable. */ declare function registerDirectiveRenderer(directiveClass: DirectiveClass, renderer: DirectiveRenderer, noun?: string): void; /** The renderer for a slug: exact β†’ class prefix rule β†’ null. */ declare function getDirectiveRenderer(directive: Pick): DirectiveRenderer | null; /** Tests only. */ declare function resetDirectiveRenderers(): void; /** * What the Apply control knows about its block, for the rest of the card: * - `pending` β€” the ledger has not answered yet; * - `open` β€” nothing applied: rows compare against the record as it is now; * - `applied` β€” the change happened: rows draw it from `before` (the server's * record of what it replaced), never from a live re-read, which * now holds the NEW value. */ type DirectiveApplyPhase = { phase: "pending"; } | { phase: "open"; } | { phase: "applied"; before: ReadonlyArray | null> | null; }; /** Does this card read the ledger before offering Apply? (One rule, card and control.) */ declare function readsApplyLedger(host: { applyState?: unknown; confirm?: unknown; }, directive: DecodedDirective): boolean; interface ApplyDirectiveButtonProps { directive: DecodedDirective; label?: string; /** How many things this will write β€” shown during the wait so a long apply reads as work, not a frozen spinner. */ itemCount?: number; onApplied?: () => void; /** Told whenever what the control knows about its block changes. */ onPhase?: (phase: DirectiveApplyPhase) => void; /** * The block would change nothing (an update that sets no field). Apply stays * β€” validation offers, never blocks β€” but muted, with the reason beside it. */ nothingToChange?: boolean; } declare function ApplyDirectiveButton({ directive, label, itemCount, onApplied, onPhase, nothingToChange, }: ApplyDirectiveButtonProps): react.JSX.Element | null; /** * WHAT A DIRECTIVE ITEM WILL DO TO AN EXISTING RECORD β€” for the card, the * confirm dialog, and anything else that must say it before the click. * * WHY (reviewer, 2026-09-30): an Update card and a Delete card showed each item * as "Item" β€” they never named the record they would change, and an Update card * never said what it would change. The item-summary helpers name a thing to be * CREATED from its own fields; an update or delete item carries the TARGET's id * and, for an update, the NEW values β€” so its "title" field is the new title, * not the name of the record being changed. Naming the target is the host's * live lookup (`DirectiveHost.renderRecord`); what changes is right here. * * Law: common-docs/policies/no-dead-ends.md β€” the sentence * names what changes. */ /** Classes whose items point at an EXISTING record by `id`. */ declare const TARGETING_CLASSES: ReadonlySet; /** * How long a changed value may read before it is shortened. A value someone * must judge β€” a title, a status, a date β€” is always whole (G8A review: a 60 * cap plus CSS truncation cut "Review4 tasks…" on a phone); only a body of * prose longer than this is shortened, whole on hover and in View/Copy. */ declare const CHANGE_VALUE_MAX = 280; /** The id of the existing record an update/delete item targets, or null. */ declare function itemRecordId(item: Record): string | null; /** "due_date" β†’ "Due Date" β€” THE humanizer; underscores read as developer output. */ declare function fieldLabel(key: string): string; /** * THE ONE FIELD-LABEL RULE for a directive β€” card rows, card facts and the * host's confirm: the noun's title column reads "Title" whatever it is stored * as (a workbook's `workbook_name`, a note's `label`), every other field reads * through THE humanizer. A new workbook card said "workbook name" while its * confirm said "Title" (G8A review, 2026-10-02). */ declare function directiveFieldLabel(key: string, titleColumn: string | null | undefined): string; /** * The app's word for ONE stored value of ONE field β€” "incomplete" on a task * reads "Inbox", "high" reads "High". The host answers it for its pick-list * fields; null β†’ the value as stored. */ type DirectiveValueWord = (field: string, value: string) => string | null; /** * The name a NEW item carries, or null when it has none β€” the one rule the card * and a host's confirm share. `catalogItemTitle`'s last resort ("Item", "Item 2 of 3") * is a placeholder, never a name: a create with an empty title used to ask * "Create project Item?" and its card row read "Item" (G10B review, 2026-10-02). */ declare function itemOwnName(item: Record, titleColumn: string | null): string | null; /** What a nameless new item is called β€” said as such, never a placeholder name. */ declare const NO_TITLE_WORD = "No title"; /** How an empty value reads β€” before or after, on the card and in the confirm. */ declare const EMPTY_VALUE_WORD = "None"; /** * What a record is called when its name cannot be read: its TYPE ("Task"). * Never its id, in any slot β€” text, tooltip or screen-reader label. It used to * be "Task a8a00001", and a link to a record that no longer exists hovered * "Open Task a8a00001" (G10B review, 2026-10-02). The host says WHY the name is * missing (not found, no access) beside it. */ declare function recordFallbackName(nounLabel: string): string; /** One value as a row reads it: shortened, the whole of it, and whether it is empty. */ interface ChangeValue { value: string; full: string; clears: boolean; } interface ItemChange extends ChangeValue { key: string; /** "Due date". */ label: string; /** * What the field holds NOW, when the host could read the record β€” so an * update reads "old β†’ new", never just the new value (reviewer, 2026-10-02). * Absent when the current record is unknown. */ before?: ChangeValue; /** True when the record already holds exactly this value β€” nothing changes. */ same?: boolean; } /** One value, described for a change row (`value` shortened, `full` whole). */ declare function describeChangeValue(value: unknown, word?: (value: string) => string | null): ChangeValue; /** * Every field an UPDATE item sets, in the order the item carries them β€” ALL of * them, never a sample: a person approving an overwrite sees the whole of it. * * Pass `current` β€” the record as it is now (`DirectiveHost.readRecord`) β€” and * each change also carries what it REPLACES (`before`) and whether it changes * anything at all (`same`). A field the record does not carry gets no `before`. */ interface ItemChangesOptions { /** * The noun's title column (catalog `title_column` β€” `nounTitleColumn`). It is * labeled "Title" whatever it is called: a note's title is stored in * `label`, and the confirm said "Label" while the form said "Title" * (reviewer, 2026-10-02). The same rule the directive builder's form uses. */ titleColumn?: string | null; /** The app's word for a stored value (`DirectiveHost.valueLabel`, bound to the noun). */ valueWord?: DirectiveValueWord | null; } declare function itemChanges(item: Record, current?: Record | null, options?: ItemChangesOptions): ItemChange[]; /** * 🚨 AN UPDATE THAT WOULD CHANGE NOTHING SAYS SO (G11B review, 2026-10-07: the * confirm listed every field "(no change)", Apply stayed full-weight, and the * run ended "Updated task. Ran 2 times"). True when the item sets no field, or * when the record was read and EVERY field already holds its new value. A field * whose current value is unknown counts as a change β€” doubt never mutes Apply. * ONE rule for the card and the host's confirm. */ declare function changesNothing(changes: ReadonlyArray): boolean; interface SideEffectDirectiveCardProps { directive: DecodedDirective; } /** The host's value words for one record type, or null when it has none. */ declare function directiveValueWord(host: Pick, noun: string): DirectiveValueWord | null; /** * THE CHANGE LIST β€” every field an update sets, as "Label old β†’ new" when the * record's current value is known, "Label β†’ new" when it is not. ONE component * for the card row and the host's confirm dialog, so the two can never read * differently (reviewer, 2026-10-02: the confirm showed only the new value). * * 🚨 A VALUE SOMEONE MUST JUDGE IS NEVER CUT (G8A review, 2026-10-02): on a * phone the card is ~230px and the row read "Title Review… β†’ Review4 tas…". * Values wrap; below a 20rem container the label, the old value and the new * value stack, one per line. Measured on the list's own width (a container * query), so a narrow window panel on a desktop gets the same stacking. */ declare function DirectiveChangeList({ changes, className, }: { changes: ItemChange[]; className?: string; }): react.JSX.Element; declare function SideEffectDirectiveCard({ directive }: SideEffectDirectiveCardProps): react.JSX.Element; interface DirectiveFallbackCardProps { directive: DecodedDirective; /** Short, human explanation of why the rich renderer degraded. */ reason?: string; } declare function DirectiveFallbackCard({ directive, reason }: DirectiveFallbackCardProps): react.JSX.Element; /** The directive slug of a partial document, once its closing quote has arrived. */ declare function provisionalDirectiveSlug(content: string): string | null; interface DirectiveProvisionalCardProps { /** The partial fence body as received so far. */ content: string; /** * Whether the document may still be arriving. `false` means the stream is * over and the document never completed β€” the card says it was cut off. */ streaming: boolean; className?: string | undefined; } declare function DirectiveProvisionalCard({ content, streaming, className }: DirectiveProvisionalCardProps): react.JSX.Element; interface DirectiveRenderProps { /** The fence body (JSON string) or an already-parsed shell / value. */ content: unknown; className?: string; /** * Whether the document may still be arriving. A host that knows its stream * has ended passes `false`, so an undecodable directive head is shown as CUT * OFF rather than "writing…" forever. Omitted = it may still be arriving. */ streaming?: boolean; /** * The conversation this directive renders in (a chat message). Applies and * ledger reads key on it β€” the same namespace an agent proposal's Approve * uses β€” so one action can never apply twice through two doors. Omit in a * person's own content. Overrides any enclosing `DirectiveScopeProvider`. */ conversationId?: string | null; } declare function DirectiveRender({ conversationId, ...props }: DirectiveRenderProps): react.JSX.Element; /** * THE WORDS A FAILED APPLY SHOWS A PERSON. * * A card used to print the server's text as its sentence β€” e.g. * "unknown / non-writable noun 'task'. Writable: [...]" (G5 review, * 2026-10-02). A person needs WHAT failed and WHAT TO DO, in plain words; the * technical text is for whoever debugs it, behind a Details toggle. The host * may name a failure it recognizes (`DirectiveHost.explainFailure`); otherwise * these verb-aware defaults answer. */ /** The card's own words for a failure the host did not name. */ declare function defaultFailureWords(failure: DirectiveFailure): DirectiveFailureWords; /** The host's words when it names this failure, else the default. */ declare function failureWords(failure: DirectiveFailure, explain?: (failure: DirectiveFailure) => DirectiveFailureWords | null): DirectiveFailureWords; type RecordValuesStatus = "idle" | "loading" | "ready" | "unavailable"; interface RecordValues { /** The record's fields now, or null until (or unless) they are read. */ values: Record | null; status: RecordValuesStatus; } type RecordReader = (ref: DirectiveRecordRef) => Promise | null>; /** How many times this page has changed record `id` (0 = never). */ declare function recordRevision(id: string): number; /** * Record `id` just changed (an apply wrote it, or any other writer on the page). * Every `useRecordValues` naming it reads it again. */ declare function noteRecordChanged(id: string): void; /** The live revision of record `id`, re-rendering when it changes. */ declare function useRecordRevision(id: string): number; declare function useRecordValues(read: RecordReader | undefined, ref: DirectiveRecordRef | null): RecordValues; /** * The DB-component COMPILE CACHE β€” session-scoped, keyed per winning row * VERSION, with the loud-recovery policy built in. * * This was matrx-frontend's `dbKindComponentCache.ts` (316 lines of compile * caching + invalidation living in one host), absorbed per C22: cache * mechanics, key derivation, the scream-once latch, transform recovery, and * config narrowing are PACKAGE policy β€” every host was going to need exactly * these lines, bug for bug. What stays host-injected is exactly what is * host-shaped: * * - THE COMPILER ({@link DbKindComponentCompiler}). Compiling or sandboxing * user-authored component source is a security-shaped host decision β€” the * package never bundles Babel or an allowlist scope. matrx-frontend * injects its shared allowlist compiler (`compileSlotComponent`); a host * with no sandbox simply never constructs a cache. * - The default allowed-imports list (host scope registry). * - Where screams land ({@link ContentIrErrorReporter}) and where durable * incidents go ({@link DbKindComponentIncidentSink}). * - Invalidation TRIGGERS ({@link DbKindComponentCachePorts.registerInvalidation}): * the host wires its invalidation-registry keys (e.g. * `@ai-matrx/kit/invalidation` fired by name when an agent edits a * component row); the cache owns what invalidation MEANS. * * Contract (the db-row component contract, SHAPE_SYSTEM.md): * - `component_source` compiles to a React component receiving * `{ data, kind, config, runAction, itemState?, onResolve?, uiOptions? }` * where `data` is the kind instance value and `itemState` what actions * saved onto this item. * - `props_transform` (optional) compiles to a `(data) => data` function * applied to the value BEFORE it reaches the component. A throwing or * non-compiling transform screams and the untransformed value is used * (never a blank hole). * - `config.allowed_imports` (string[]) narrows the compile scope; absent, * the row gets the host's FULL registered allowlist. * * Cache key: (kind, platform, role, row.updated_at) β€” one compile per winning * row VERSION. A resolver refresh delivering an edited row (bumped * `updated_at`) re-keys and recompiles naturally; `invalidate` / * `invalidateAll` force-drop keys. Server edits never push to open clients β€” * the contract is refresh-on-view. */ /** * Settings the MOUNTING UI dictates to a kind component β€” the standard, * growing arg list every component honors (Arman, 2026-07-23). `selectionMode` * is the first: it tells a component whether the surface wants the user to * pick one value, many, or none (pure display). A component reads what it * understands and ignores the rest; absent = its own default (usually display). */ interface KindComponentUiOptions { selectionMode?: "single" | "multiple" | "none"; [key: string]: unknown; } /** * The return channel: how a kind component hands a chosen value back to the * surface that mounted it (a Kind Request). The mirror of `runAction` * (surface β†’ agent); this is component β†’ surface. Undefined in normal render * (chat/notes) β€” the component simply doesn't offer selection there. */ type ResolveKindValue = (value: unknown) => void; /** The envelope every kind action resolves to β€” a skip/failure is never a silent pass. */ type DbKindActionResult = { ok: true; result: unknown; } | { ok: false; error: string; }; /** * The action seam a compiled component receives: `runAction(key, input)` * triggers a registered platform capability (e.g. "trigger_agent"). Always * resolves to an `{ ok }` envelope, never throws β€” safe to call from imperfect * component code. This is the ONLY side-effect channel a sandboxed component * gets; it reaches no data directly. */ type RunDbKindAction = (key: string, input: unknown) => Promise; /** Props every compiled DB kind component receives. */ interface DbKindComponentRenderProps { /** The kind instance value β€” post-`props_transform` when one exists. */ data: unknown; /** The kind slug the value belongs to. */ kind: string; /** The resolver row's `config` object, verbatim (narrowed β€” see {@link DbKindComponentCache.config}). */ config: Record; /** The action seam β€” see {@link RunDbKindAction}. */ runAction: RunDbKindAction; /** * Present only when the component is mounted inside a Kind Request. Call it * with the user's chosen value to hand that value back to the requesting * surface (which resolves its promise). Undefined in normal render. */ onResolve?: ResolveKindValue; /** Settings the mounting surface dictates (e.g. `{ selectionMode: "single" }`). */ uiOptions?: KindComponentUiOptions; /** * This item's durable state: what `save_item_state` / `run_shortcut` with * `saveAs` wrote onto it (`{}` when nothing yet; survives reload). The host * adds `src` to every saved image ref (`{ file_id, mime_type, width, height }`) * so the component renders ``. */ itemState?: Record; } interface CompiledDbKindComponent { Component: react.ComponentType; /** Compiled `props_transform`, or null when the row declares none. */ transform: ((data: unknown) => unknown) | null; } type DbKindCompileResult = { ok: true; compiled: CompiledDbKindComponent; } | { ok: false; error: string; }; /** The failure modes a browser can observe on a DB kind component. */ type DbKindComponentIncidentType = /** `component_source` did not compile (or produced no component). */ "compile_error" /** The compiled component threw during render (error boundary caught it). */ | "render_throw" /** `props_transform` failed to compile or threw. */ | "transform_error"; /** * One durable render incident β€” the payload for whoever can actually FIX the * component. A host sink typically files it on the kind's own incident queue * (matrx-frontend: `content_ir.kind_component_incident` via RPC); without a * sink, a broken component seen only by ordinary users is invisible to its * author forever. `data` is the kind instance value β€” a privacy-conscious sink * reduces it to keys + types before it leaves the browser. */ interface DbKindComponentIncident { kind: string; errorType: DbKindComponentIncidentType; message: string; platform?: string; role?: string; componentKey?: string | null; componentUpdatedAt?: string | null; stack?: string | null; data?: unknown; } type DbKindComponentIncidentSink = (incident: DbKindComponentIncident) => void; /** * THE COMPILER PORT. Matches matrx-frontend's shared allowlist compiler * (`compileSlotComponent`) structurally: source in, `{ Component | error }` * out, never throws. The compiled component is generically typed β€” the cache * performs the single deliberate narrowing where the generic compiler meets * the kind prop contract. */ type DbKindComponentCompiler = (args: { code: string; allowedImports: string[]; }) => { Component: react.ComponentType> | null; error: string | null; }; interface DbKindComponentCachePorts { /** The host's sandbox compiler β€” see {@link DbKindComponentCompiler}. */ compile: DbKindComponentCompiler; /** The FULL registered allowlist a row without `config.allowed_imports` gets. */ defaultAllowedImports: () => string[]; /** Where screams land (every recovery path is loud). */ reportError: ContentIrErrorReporter; /** Durable incident sink β€” optional, but a host without one blinds authors. */ reportIncident?: DbKindComponentIncidentSink; /** Default `kind_component.platform` for this host (default "web"). */ platform?: string; /** * THE INVALIDATION REGISTRATION PORT. Called once at construction with the * cache's `invalidateAll`; the host registers it under its own invalidation * keys (e.g. `@ai-matrx/kit/invalidation`'s name-keyed registry, fired when * an agent's component write completes). The cache owns the mechanics β€” * what gets dropped, the scream-latch reset; the host owns only WHEN. */ registerInvalidation?: (invalidateAll: () => void) => void; } interface DbKindComponentCache { /** * Compile (once per resolver key per row version) a db-source resolution's * `component_source` + optional `props_transform`. Synchronous β€” the caller * (a lazily-loaded Impl) already paid the compiler chunk. */ getOrCompile(kind: string, resolution: ComponentResolution, platform?: string, role?: string): DbKindCompileResult; /** * Apply the row's transform to the kind value. Loud on throw, never fatal β€” * the untransformed value comes back so content is never hidden. */ applyPropsTransform(kind: string, compiled: CompiledDbKindComponent, value: unknown): unknown; /** * THE CONFIG BOUNDARY. `ComponentResolution.config` is typed * `Record` β€” deliberately agnostic about a host's JSONB * interior. This narrows at runtime (plain object β†’ itself; anything else β†’ * scream + empty config) rather than asserting: a row whose `config` is not * an object is a malformed `kind_component` row, and the component still * renders rather than crashing. */ config(config: unknown, kind: string): Record; /** Drop a (kind, platform, role) key family (authoring surfaces call after editing a row). */ invalidate(kind: string, platform?: string, role?: string): void; /** Drop everything β€” the invalidation-port payload. */ invalidateAll(): void; } /** * A routed lazy warm row owns a real body, but the per-kind cold fetch has not * landed it yet. This is loading, not a compile failure. */ declare function isDbKindComponentBodyPending(resolution: ComponentResolution): boolean; /** Build the session cache. One per host app β€” construct it in the wiring module. */ declare function createDbKindComponentCache(ports: DbKindComponentCachePorts): DbKindComponentCache; /** * DbKindComponentErrorBoundary β€” the DEFAULT error boundary around a compiled * DB kind component (absorbed from matrx-frontend per the C23 retrofit; the * package previously shipped "no error capture by design", which left every * host to rebuild this class). * * A user-authored component that throws during render must never crash the * surface (chat, notes, admin preview). The boundary catches, renders the * fallback (the kind's generic structured viewer β€” the R6 disposition, never * a blank hole), and SCREAMS: a recovery firing means a real bug got past * authoring. * * `resetSignal` (the component's `updated_at`) un-latches the boundary when a * NEW component version arrives: an author who fixes a throwing component must * see the fix on the next re-render, not stay stuck on the fallback until a * full unmount. Without this the error state is sticky for the whole session β€” * the "broke, then magically fixed itself minutes later" class. React error * boundaries never self-clear, so a version change is the only safe signal * (`hasError` alone can't tell a fixed version from the same broken one). * * `onCaught` is the scream seam: a host binds its structured render-error * capture + durable incident filing (matrx-frontend files a `render_throw` * incident so the component's author learns). Bound to nothing, the default is * an honest console scream β€” never silence. */ interface DbKindComponentErrorBoundaryProps { kind: string; /** The resolved component's `updated_at`; a change means a new version. */ resetSignal: string | null; fallback: react.ReactNode; children: react.ReactNode; /** * Where the catch lands. A host binds structured capture + incident filing * here; the default screams to the console. NOTE for hosts whose console * adapter persists `console.error`: bind this (which replaces the default) * rather than mirroring the capture through the console twice. */ onCaught?: (error: Error, info: { componentStack: string | null; }) => void; } interface State { hasError: boolean; /** * The `resetSignal` seen on the LAST render β€” tracked every render (not just * on error) so that at throw time it already holds the version that threw. * `getDerivedStateFromError` cannot read props, so this is how the boundary * knows which version to un-latch away from. */ signalAtLastRender: string | null; } declare class DbKindComponentErrorBoundary extends react.Component { constructor(props: DbKindComponentErrorBoundaryProps); static getDerivedStateFromError(): Partial; static getDerivedStateFromProps(props: DbKindComponentErrorBoundaryProps, state: State): State | null; componentDidCatch(error: Error, errorInfo: react.ErrorInfo): void; render(): react.ReactNode; } export { ApplyDirectiveButton, CHANGE_VALUE_MAX, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, DEFAULT_KIND_INSTANCE_FRAME, DbKindComponentErrorBoundary, DelegatedOutput, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, DirectiveHost, DirectiveProvisionalCard, DirectiveRecordRef, DirectiveRender, EMPTY_VALUE_WORD, GenericStructuredView, KIND_INSTANCE_FRAME_CLASS, KindDefinitionSource, KindInstanceRender, KindRouteEnv, NO_TITLE_WORD, NodeOutcomeView, ProvisionalKindBoundary, ProvisionalKindFrame, RunResultView, SideEffectDirectiveCard, TARGETING_CLASSES, changesNothing, createDbKindComponentCache, defaultFailureWords, describeChangeValue, directiveFieldLabel, directiveValueWord, failureWords, fieldLabel, getDirectiveRenderer, isDbKindComponentBodyPending, isRecordValue, itemChanges, itemOwnName, itemRecordId, kindIsRoutable, noteRecordChanged, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, recordRevision, registerDirectiveRenderer, resetDirectiveRenderers, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv, useRecordRevision, useRecordValues }; export type { ApplyDirectiveButtonProps, ChangeValue, CompiledDbKindComponent, ContentIrRenderProviderProps, DbKindActionResult, DbKindCompileResult, DbKindComponentCache, DbKindComponentCachePorts, DbKindComponentCompiler, DbKindComponentErrorBoundaryProps, DbKindComponentIncident, DbKindComponentIncidentSink, DbKindComponentIncidentType, DbKindComponentRenderProps, DelegatedOutputProps, DirectiveApplyPhase, DirectiveFallbackCardProps, DirectiveProvisionalCardProps, DirectiveRenderProps, DirectiveRenderer, DirectiveRendererProps, DirectiveValueWord, GenericStructuredViewProps, ItemChange, ItemChangesOptions, KindComponentUiOptions, KindInstanceFrameVariant, KindInstanceRenderProps, KindVersionSources, NodeOutcomeViewProps, RecordReader, RecordValues, RecordValuesStatus, ResolveKindValue, RunDbKindAction, RunResultViewProps, SideEffectDirectiveCardProps };