import { a as DecodedDirective, b as DirectiveClass, D as DirectiveHost, c as DirectiveFailure, d as DirectiveFailureWords, e as DirectiveRecordRef } from './directive-host-BLJvN-wO.js'; export { f as DirectiveApplyResult, g as DirectiveApplyState, h as DirectiveAskRequest, i as DirectiveCopyProps, j as DirectiveHostProvider, k as DirectiveHostProviderProps, l as DirectiveOpenItemOptions, m as DirectiveRecordProps, n as DirectiveScope, o as DirectiveScopeProvider, p as DirectiveShell, q as DirectiveValueRef, u as useDirectiveHost, r as useDirectiveScope } from './directive-host-BLJvN-wO.js'; import * as React from 'react'; import { ComponentType } from 'react'; /** * 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; export { ApplyDirectiveButton, CHANGE_VALUE_MAX, DirectiveChangeList, DirectiveFailure, DirectiveFailureWords, DirectiveFallbackCard, DirectiveHost, DirectiveProvisionalCard, DirectiveRecordRef, DirectiveRender, EMPTY_VALUE_WORD, NO_TITLE_WORD, SideEffectDirectiveCard, TARGETING_CLASSES, changesNothing, defaultFailureWords, describeChangeValue, directiveFieldLabel, directiveValueWord, failureWords, fieldLabel, getDirectiveRenderer, itemChanges, itemOwnName, itemRecordId, noteRecordChanged, provisionalDirectiveSlug, readsApplyLedger, recordFallbackName, recordRevision, registerDirectiveRenderer, resetDirectiveRenderers, useRecordRevision, useRecordValues }; export type { ApplyDirectiveButtonProps, ChangeValue, DirectiveApplyPhase, DirectiveFallbackCardProps, DirectiveProvisionalCardProps, DirectiveRenderProps, DirectiveRenderer, DirectiveRendererProps, DirectiveValueWord, ItemChange, ItemChangesOptions, RecordReader, RecordValues, RecordValuesStatus, SideEffectDirectiveCardProps };