@ai-matrx/records-ui 0.6.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/host.tsx","../src/names.ts","../src/PersonPicker.tsx","../src/editors.tsx","../src/parity.ts","../src/RelationPicker.tsx","../src/gridEditing.tsx","../src/Refusal.tsx","../src/values.tsx","../src/Grid.tsx","../src/ExportMenu.tsx","../src/ImportWizard.tsx","../src/CustomFieldsSection.tsx","../src/RecordForm.tsx","../src/systemTable.ts","../src/FieldEditor.tsx","../src/TableSettings.tsx","../src/Peek.tsx","../src/views.ts","../src/ViewSwitcher.tsx","../src/ViewBar.tsx","../src/seedOnce.ts","../src/ProposalRow.tsx","../src/ActionInbox.tsx","../src/HistoryPanel.tsx","../src/CommentThread.tsx","../src/forms.ts","../src/FormBuilder.tsx","../src/FormRunner.tsx","../src/charts.ts","../src/docs.ts","../src/DocTemplate.tsx","../src/DocRender.tsx","../src/SignBlock.tsx","../src/NotifyRuleEditor.tsx","../src/ChartBlock.tsx","../src/DashboardCanvas.tsx","../src/RecordChat.tsx","../src/EnrichPanel.tsx","../src/ChecklistRunner.tsx","../src/BookingSlots.tsx","../src/CaptureSheet.tsx","../src/PortalShell.tsx","../src/PublicViewPage.tsx","../src/EmbedFrame.tsx","../src/RecordsMount.tsx","../src/TablesHome.tsx","../src/createTable.ts","../src/TablePage.tsx"],"sourcesContent":["// src/index.ts — @ai-matrx/records-ui\n//\n// The canonical screens of the AI Matrx record store. Every component here\n// reads and writes ONLY through @ai-matrx/records, renders through\n// @ai-matrx/design-system's own primitives and data table, and carries\n// @ai-matrx/alchemy's menu where a person would reach for one.\n//\n// There is no bespoke per-feature record UI in this platform: a feature that\n// needs a grid, a form, a picker or a peek mounts one of these.\n\nexport {\n RecordsUiProvider,\n useRecordsUi,\n useTableRights,\n NO_RIGHTS,\n NO_UPLOAD_REASON,\n NO_SAVED_VIEWS_REASON,\n NO_MEMBERS_REASON,\n} from \"./host\";\nexport type { RecordsUiHost, TableRights, OrganizationMember } from \"./host\";\nexport { humanize, fieldName, tableName, recordName, rowName } from \"./names\";\nexport { PersonPicker, memberName, personRecordForMember } from \"./PersonPicker\";\nexport type { PersonPickerProps } from \"./PersonPicker\";\nexport { GridCell, useGridEditing, fieldIsEditable } from \"./gridEditing\";\nexport type { GridEditing, CellAddress, CellState, CellRefusal } from \"./gridEditing\";\nexport { RefusalNotice, RefusalLine } from \"./Refusal\";\nexport { Grid, columnForField } from \"./Grid\";\nexport type { GridProps } from \"./Grid\";\nexport { ExportMenu } from \"./ExportMenu\";\nexport type { ExportMenuProps } from \"./ExportMenu\";\nexport { ImportWizard } from \"./ImportWizard\";\nexport type { ImportWizardProps } from \"./ImportWizard\";\nexport { CustomFieldsSection } from \"./CustomFieldsSection\";\nexport type { CustomFieldsSectionProps } from \"./CustomFieldsSection\";\nexport { FieldEditor } from \"./FieldEditor\";\nexport type { FieldEditorProps } from \"./FieldEditor\";\nexport { TableSettings } from \"./TableSettings\";\nexport type { TableSettingsProps, FieldProposalRow } from \"./TableSettings\";\nexport { Peek } from \"./Peek\";\nexport type { PeekProps } from \"./Peek\";\nexport { RecordForm } from \"./RecordForm\";\nexport type { RecordFormProps } from \"./RecordForm\";\nexport { RelationPicker } from \"./RelationPicker\";\nexport type { RelationPickerProps } from \"./RelationPicker\";\nexport { FieldControl, FieldLabel, RecordChip } from \"./editors\";\nexport type { FieldEditorControlProps } from \"./editors\";\nexport { renderValue, scalarText, envelopeFor, ProvenanceBadge } from \"./values\";\nexport { editorKindFor, fieldTypeLabel, PARITY_LABEL, PARITY_MADE_OF } from \"./parity\";\nexport type { EditorKind } from \"./parity\";\nexport { ensureSystemTable, useSystemTable } from \"./systemTable\";\nexport type { SystemTableSpec, SystemFieldSpec, UseSystemTableState } from \"./systemTable\";\nexport {\n VIEW_LAYOUTS,\n VIEW_TABLE,\n LAYOUT_LABEL,\n LAYOUT_NEEDS,\n LAYOUT_FIELD_KIND,\n LAYOUT_NO_FIELD,\n viewDocument,\n viewFromRecord,\n viewPatchDocument,\n} from \"./views\";\nexport type { SavedView, SavedViewSpec, ViewLayout, ViewSort } from \"./views\";\nexport { ViewSwitcher, useViewRecords } from \"./ViewSwitcher\";\nexport type { ViewSwitcherProps } from \"./ViewSwitcher\";\nexport { ViewBar } from \"./ViewBar\";\nexport type { ViewBarProps } from \"./ViewBar\";\nexport { ProposalRow } from \"./ProposalRow\";\nexport type { ProposalRowProps, ProposedChange, ProposalOutcome } from \"./ProposalRow\";\nexport { ActionInbox, ACTION_KINDS, ACTION_TABLE, actionDocument } from \"./ActionInbox\";\nexport type { ActionInboxProps, ActionKind, QueuedAction, QueuedActionSpec } from \"./ActionInbox\";\nexport { HistoryPanel } from \"./HistoryPanel\";\nexport type { HistoryPanelProps } from \"./HistoryPanel\";\nexport { CommentThread, COMMENT_TABLE } from \"./CommentThread\";\nexport {\n FORM_FLOWS,\n FORM_TABLE,\n formDocument,\n formFromRecord,\n submissionStamp,\n} from \"./forms\";\nexport type { FormFlow, FormQuestionSpec, FormSpec, FormTheme, SavedForm } from \"./forms\";\nexport { FormBuilder } from \"./FormBuilder\";\nexport type { FormBuilderProps } from \"./FormBuilder\";\nexport {\n CHART_KINDS,\n CHART_KIND_LABEL,\n CHART_NEEDS,\n DASHBOARD_TABLE,\n SERIES_COLORS,\n dashboardDocument,\n dashboardFromRecord,\n groupLabel,\n} from \"./charts\";\nexport type { ChartKind, ChartSpec, DashboardSpec, SavedDashboard } from \"./charts\";\nexport { bodyFromKeys, bodyForReading, fieldToken, isSignatureField } from \"./docs\";\nexport type { DocTemplateSpec } from \"./docs\";\nexport { DocTemplate } from \"./DocTemplate\";\nexport type { DocTemplateProps } from \"./DocTemplate\";\nexport { DocRender } from \"./DocRender\";\nexport type { DocRenderProps } from \"./DocRender\";\nexport { SignBlock } from \"./SignBlock\";\nexport type { SignBlockProps } from \"./SignBlock\";\nexport { NotifyRuleEditor } from \"./NotifyRuleEditor\";\nexport type { NotifyRuleEditorProps, NotifyRuleSpec } from \"./NotifyRuleEditor\";\nexport { ChartBlock } from \"./ChartBlock\";\nexport type { ChartBlockProps } from \"./ChartBlock\";\nexport { DashboardCanvas } from \"./DashboardCanvas\";\nexport type { DashboardCanvasProps } from \"./DashboardCanvas\";\nexport { FormRunner } from \"./FormRunner\";\nexport type { FormRunnerProps } from \"./FormRunner\";\nexport type { CommentThreadProps } from \"./CommentThread\";\nexport { RecordChat, NO_CHAT_REASON } from \"./RecordChat\";\nexport type { RecordChatProps, RecordChatContext, RecordChatEntry, RecordChatWithheld } from \"./RecordChat\";\nexport { EnrichPanel, NO_ENRICH_REASON } from \"./EnrichPanel\";\nexport type { EnrichPanelProps, EnrichAsk, EnrichOutcome } from \"./EnrichPanel\";\nexport { ChecklistRunner, CHECKLIST_TABLE } from \"./ChecklistRunner\";\nexport type { ChecklistRunnerProps, ChecklistSpec, ChecklistStepSpec } from \"./ChecklistRunner\";\nexport { BookingSlots } from \"./BookingSlots\";\nexport type { BookingSlotsProps } from \"./BookingSlots\";\nexport { CaptureSheet, CAPTURE_MODES, IN_MEMORY_QUEUE_REASON } from \"./CaptureSheet\";\nexport type { CaptureSheetProps, CaptureMode } from \"./CaptureSheet\";\nexport { PortalShell } from \"./PortalShell\";\nexport type { PortalShellProps } from \"./PortalShell\";\nexport { PublicViewPage } from \"./PublicViewPage\";\nexport type { PublicViewPageProps } from \"./PublicViewPage\";\nexport { EmbedFrame, useEmbedHandshake } from \"./EmbedFrame\";\nexport type { EmbedFrameProps } from \"./EmbedFrame\";\nexport type { CaptureQueuePort, PendingCapture } from \"./host\";\n\n// The two page assemblies a host route mounts, and the provider pair they need.\nexport { RecordsMount, storeDecidesRights, personActor, recordsDataSource, STORE_DECIDES_REASON, KERNEL_REASON } from \"./RecordsMount\";\nexport type { RecordsMountProps } from \"./RecordsMount\";\nexport { TablesHome, TABLE_LANES, LANE_TITLE, LANE_EMPTY, laneFor } from \"./TablesHome\";\nexport type { TablesHomeProps, TableLane } from \"./TablesHome\";\nexport { TablePage, TABLE_NOT_REACHABLE, DEFAULT_VIEW_NAME } from \"./TablePage\";\nexport type { TablePageProps } from \"./TablePage\";\nexport { declareTable, addFields, tokenFor, DEFAULT_FIELDS } from \"./createTable\";\nexport type { NewTableSpec, NewFieldSpec, DeclareResult } from \"./createTable\";\n","\"use client\";\n\n// src/host.tsx — @ai-matrx/records-ui\n//\n// THE ONE BINDING POINT. A host mounts `<RecordsUiProvider>` once, inside\n// `<RecordsProvider>` from @ai-matrx/records, and every component in this\n// package reads what it needs from here. There is no module-level state: two\n// organizations in two tabs must never share one.\n//\n// WHAT A HOST BINDS, AND WHAT HAPPENS WHEN IT DOES NOT\n// ----------------------------------------------------\n// `rights` answers \"may this person administer this table?\" — the question the\n// \"+\" add-field affordance turns on (SCR-2 / SCR-4). It is a PORT and not a\n// guess, and its default answer is `false` WITH A REASON, so the control is\n// ABSENT rather than disabled, and the reason is available to anyone who asks\n// why. A disabled-looking control that nobody can explain is the screen lying.\n\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport type { Table, Uuid } from \"@ai-matrx/records\";\nimport type { RecordChatContext } from \"./RecordChat\";\nimport type { EnrichAsk, EnrichOutcome } from \"./EnrichPanel\";\n\n/** What a person may do to one table. The words are the store's, not ours. */\nexport interface TableRights {\n /** SCR-2: holders of `admin` on the table see the \"+\" and the settings panel. */\n admin: boolean;\n /** SCR-18: `commenter` and no higher right. */\n comment: boolean;\n /** May write records at all. */\n write: boolean;\n /**\n * Why this answer, in a sentence a person can read. Never empty: a right that\n * is false without a reason is the silent failure this package refuses.\n */\n reason: string;\n}\n\nexport const NO_RIGHTS: TableRights = {\n admin: false,\n comment: false,\n write: false,\n reason:\n \"No rights port is bound, so this screen assumes nothing. Bind `rights` on <RecordsUiProvider> \" +\n \"with your host's answer to 'may this person administer this table?'. Until then every \" +\n \"administering control is ABSENT rather than shown-and-dead.\",\n};\n\nexport interface RecordsUiHost {\n /** Answer the rights question for one table. Synchronous: a screen renders now. */\n rights?: (table: Table) => TableRights;\n /** Where a record's own page lives, when the host has one. A peek is used when it does not. */\n hrefForRecord?: (args: { table: Table; recordId: Uuid }) => string | undefined;\n /** The host's own link element, so routing stays the host's business. */\n Link?: (props: { href: string; children: ReactNode; className?: string }) => ReactNode;\n /** Toasts. Absent means the screen shows the sentence inline instead — never silence. */\n notify?: { success: (message: string) => void; error: (message: string) => void };\n /** Density for every table this package renders. */\n density?: \"condensed\" | \"normal\" | \"spacious\";\n /**\n * OPTIONAL. Where a file a person attached actually goes. A File is a record\n * in the kernel File Table (REC-31), but the BYTES are the host's file\n * service, not this package's business — so this is a port.\n *\n * Unbound, an attachment question does NOT draw a file chooser that quietly\n * loses the file: it says, in one sentence, that no file store is bound and\n * names this port. Absent or honest, never dead.\n */\n upload?: (file: File) => Promise<{ ok: true; fileId: Uuid } | { ok: false; reason: string }>;\n /**\n * OPTIONAL. The organization's saved views as `platform.saved_view` holds\n * them — which is what a subscription points at (DOOR-18). The record store\n * has NO door onto that table, because it is the platform's and not the\n * store's, so this is a port rather than a read this package invents.\n *\n * Unbound, `NotifyRuleEditor` shows the subscriptions that exist and says, in\n * one sentence, that it cannot offer a view to subscribe to. It never renders\n * an empty picker that looks like \"you have no views\".\n */\n savedViews?: () => Promise<Array<{ id: Uuid; name: string }>>;\n /**\n * OPTIONAL. WHO IS IN THIS ORGANIZATION (FLD-11 `member`).\n *\n * A person field must offer PEOPLE. Who the people are is the platform's\n * answer — organization membership lives in `iam`, not in the record store —\n * and the store has no door onto it, so this is a port rather than a read\n * this package invents. `PersonPicker` resolves whoever is picked to their\n * record in the kernel Person Table, which is what the Field actually stores.\n *\n * Unbound, a person question is ABSENT with `NO_MEMBERS_REASON`. It never\n * falls back to listing the kernel Person Table's contents: that Table also\n * holds the Homes this package writes, and offering \"Comments Home\" as a\n * person is exactly what this port exists to stop.\n */\n members?: () => Promise<OrganizationMember[]>;\n /**\n * OPTIONAL. THE HOST'S OWN CHAT SURFACE (SCR-26).\n *\n * This package ships no chat UI, on purpose: AI Matrx has exactly one, it\n * lives in matrx-frontend (`AgentConversationColumn`), and it reads that app's\n * Redux store — so a second one here would drift within a month and a package\n * that imported the first would stop being a package. `RecordChat` therefore\n * builds the CONTEXT (the record, through the read door, with the masked\n * fields named) and hands it to this port.\n *\n * Unbound, the panel is ABSENT with that reason, never a composer that goes\n * nowhere.\n */\n chat?: (context: RecordChatContext) => ReactNode;\n /**\n * OPTIONAL. THE SERVER'S `records` TOOL (SCR-27).\n *\n * An AI fill must be written with actor `agent` on behalf of the person, and\n * only the server can honestly say that — a browser stamping itself `agent`\n * is a browser claiming to be one. So `EnrichPanel` asks here, and the host\n * calls the server's own `records` tool (`action: \"record_write\"`), which\n * stamps `_actor` and `_on_behalf_of` itself.\n *\n * Unbound, no Fill control is drawn at all and the reason names this port.\n */\n enrich?: (ask: EnrichAsk) => Promise<EnrichOutcome>;\n /**\n * OPTIONAL. WHERE AN OFFLINE CAPTURE WAITS (SCR-30).\n *\n * `CaptureSheet` mints the id for a capture BEFORE it tries to send it, so a\n * phone with no signal has already decided what the write will be called.\n * Where that queue physically lives is the host's business — IndexedDB in a\n * browser, a file in a desktop app — so it is a port. Unbound, the sheet\n * keeps its queue in memory for the life of the page AND SAYS SO, because a\n * queue that silently died with the tab is the failure this exists to avoid.\n */\n captureQueue?: CaptureQueuePort;\n}\n\n/** One member of the organization, in the words a person reads. */\nexport interface OrganizationMember {\n /** The platform's user id. This is what a Person record carries as `user_id`. */\n userId: string;\n /** Their display name, when the platform has one. */\n name?: string | null;\n email?: string | null;\n avatarUrl?: string | null;\n}\n\n/** The durable half of offline capture: read the queue, write it, that is all. */\nexport interface CaptureQueuePort {\n load: () => Promise<PendingCapture[]>;\n save: (pending: PendingCapture[]) => Promise<void>;\n}\n\n/** One capture waiting to be written, with the id the CLIENT minted for it. */\nexport interface PendingCapture {\n /**\n * The client key. Minted offline, before the first attempt, and never\n * re-minted on retry — that is exactly what lets the store's replay ledger\n * tell a retry from a second capture.\n */\n clientKey: string;\n tableId: Uuid;\n payload: Record<string, unknown>;\n capturedAt: string;\n device: string;\n /** How many times sending has been tried, and what the store last said. */\n attempts: number;\n lastRefusal?: string | null;\n}\n\n/** The sentence the notify editor shows when no saved-view port is bound. */\nexport const NO_SAVED_VIEWS_REASON =\n \"No saved-view port is bound, so there is nothing here to subscribe to. A subscription points at a \" +\n \"`platform.saved_view`, which the record store has no door onto — bind `savedViews` on \" +\n \"<RecordsUiProvider> with your host's own list and the picker appears.\";\n\n/** The sentence a person question shows when no membership port is bound. */\nexport const NO_MEMBERS_REASON =\n \"No membership port is bound, so this question cannot offer anybody. A person field points at the \" +\n \"kernel Person Table, and who is in this organization is the platform's answer rather than the \" +\n \"record store's — bind `members` on <RecordsUiProvider> with your host's own roster and the picker \" +\n \"appears.\";\n\n/** The sentence an attachment question shows when no file store is bound. */\nexport const NO_UPLOAD_REASON =\n \"No file store is bound, so this question cannot take a file. Bind `upload` on \" +\n \"<RecordsUiProvider> with your host's file service and the chooser appears.\";\n\nconst HostContext = createContext<RecordsUiHost | null>(null);\n\nexport function RecordsUiProvider({ value, children }: { value: RecordsUiHost; children: ReactNode }) {\n const bound = useMemo(() => value, [value]);\n return <HostContext.Provider value={bound}>{children}</HostContext.Provider>;\n}\n\nexport function useRecordsUi(): RecordsUiHost {\n return useContext(HostContext) ?? {};\n}\n\n/** The rights for one table — `NO_RIGHTS`, with its reason, when nothing is bound. */\nexport function useTableRights(table: Table | null | undefined): TableRights {\n const host = useRecordsUi();\n return useMemo(() => {\n if (!table) return NO_RIGHTS;\n if (!host.rights) return NO_RIGHTS;\n return host.rights(table);\n }, [host, table]);\n}\n","// src/names.ts — @ai-matrx/records-ui\n//\n// WHAT A PERSON READS, NEVER WHAT THE MACHINE STORES.\n//\n// Measured on the real screens (independent verdict, 19 September): a table row\n// read `Saved views · 9 fields · records_ui_view`, a relation cell read a bare\n// `8f2c…` identifier, a header read `stage` because the Field's label was\n// blank, and the type word on a column tooltip read `long_text`. Airtable,\n// Notion and Linear never show a person an internal name; the verdict called\n// this one of the three things a first-time user feels within a minute.\n//\n// So every place this package prints something a person reads goes through one\n// of these three functions. They are deliberately dumb: they choose the best\n// human string that IS AVAILABLE and, when none is, say what the thing is\n// rather than printing the token. No screen in this package formats a name of\n// its own any more.\n\nimport type { Field, ReadRow, RecordDocument, Table } from \"@ai-matrx/records\";\n\n/**\n * A token (`records_ui_view`, `long_text`, `v78_widget2`) as a person would\n * write it. Used ONLY as a last resort, when the thing carries no label at all\n * — a raw token on a screen is the defect, and a humanised token is the least\n * bad honest answer, because it still names the same thing.\n */\nexport function humanize(token: string): string {\n const words = token\n .replace(/[_\\-.]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .trim();\n if (words === \"\") return token;\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** The name of one Field, as a header, a form label or a peek's term. */\nexport function fieldName(field: Field): string {\n const label = (field.label ?? \"\").trim();\n if (label !== \"\") return label;\n const name = (field.name ?? \"\").trim();\n if (name !== \"\") return name;\n return humanize(field.key);\n}\n\n/** The name of one Table, as a card, a heading or a breadcrumb. */\nexport function tableName(table: Table): string {\n const name = (table.name ?? \"\").trim();\n if (name !== \"\") return name;\n const singular = (table.label_singular ?? \"\").trim();\n if (singular !== \"\") return singular;\n return humanize(table.slug ?? \"\");\n}\n\n/**\n * The name of one RECORD, for a chip, a card, a relation cell or a peek title.\n *\n * `titleKey` is the Table's own `title_field` when the caller knows the Table —\n * that is the store's answer to \"what makes this record a chip\" (REC-2) — and\n * the conventional keys are tried after it. A record with nothing readable is\n * NOT shown as a truncated uuid: it says it has no name yet, because \"8f2c1b0a\"\n * tells a person nothing and looks like a bug.\n */\nexport function recordName(\n document: RecordDocument | undefined,\n titleKey?: string | null,\n fallback = \"Untitled\",\n): string {\n const data = (document ?? {}) as Record<string, unknown>;\n const keys = [titleKey, \"title\", \"name\", \"label\", \"full_name\", \"subject\", \"summary\"].filter(\n (key): key is string => typeof key === \"string\" && key !== \"\",\n );\n for (const key of keys) {\n const value = data[key];\n if (typeof value === \"string\" && value.trim() !== \"\") return value.trim();\n if (typeof value === \"number\") return String(value);\n }\n return fallback;\n}\n\n/** The same question for a row the read door returned. */\nexport function rowName(row: ReadRow | undefined, titleKey?: string | null, fallback = \"Untitled\"): string {\n return recordName(row?.document, titleKey, fallback);\n}\n","\"use client\";\n\n// src/PersonPicker.tsx — @ai-matrx/records-ui · FLD-11 (`member`)\n//\n// PICKING A PERSON MEANS PICKING A PERSON.\n//\n// What it replaced, measured on the real screen (independent verdict, 19\n// September): the \"Owner\" field — which the settings panel itself calls a\n// Person field — offered \"Comments Home\", \"Saved views Home\" and \"V78 Home\".\n// Those are not people. They are the Home records this package writes into the\n// kernel Person Table so that its own Tables have somewhere to live (REC-1),\n// and the generic relation picker was listing the Table's contents, which is\n// exactly right for a relation and exactly wrong for a person.\n//\n// SO A PERSON FIELD ASKS A DIFFERENT QUESTION. The list is the ORGANIZATION'S\n// MEMBERS — who those are is the platform's answer and not the record store's,\n// so it arrives through the `members` port on the host, the same way saved\n// views and file uploads do. The record store has no door onto organization\n// membership and this package does not invent one.\n//\n// WHAT IS STORED IS STILL A RECORD ID, because a member field is a relation to\n// the kernel Person Table and the store's foreign key is real. So picking a\n// member resolves that member to their Person record — by the `user_id` the\n// record carries — and writes one when the organization has not got one yet.\n// That write is the same `record_write` everything else in this package uses;\n// there is no second storage path, and a Home (a Person record with no\n// `user_id`) is never offered and never picked.\n//\n// Unbound port: the control is ABSENT with its reason, never a dead box and\n// never a list of the wrong things.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { Field, ReadRow, RecordsError, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport {\n BasicInput,\n Button,\n Popover,\n PopoverContent,\n PopoverTrigger,\n ScrollArea,\n cn,\n} from \"@ai-matrx/design-system\";\n\nimport { RecordChip } from \"./editors\";\nimport { useRecordsUi, type OrganizationMember } from \"./host\";\nimport { NO_MEMBERS_REASON } from \"./host\";\nimport { fieldName } from \"./names\";\n\nexport interface PersonPickerProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n className?: string | undefined;\n}\n\n/** A Person record in the kernel Table, as this picker needs to read it. */\ninterface PersonRecord {\n id: Uuid;\n userId: string | null;\n name: string;\n}\n\nfunction personFromRow(row: ReadRow): PersonRecord {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const userId = data[\"user_id\"];\n return {\n id: row.id,\n userId: typeof userId === \"string\" && userId !== \"\" ? userId : null,\n name: String(data[\"full_name\"] ?? data[\"name\"] ?? data[\"email\"] ?? \"\").trim(),\n };\n}\n\n/** The member's own name, as a person reads it. Never a uuid. */\nexport function memberName(member: OrganizationMember): string {\n const display = (member.name ?? \"\").trim();\n if (display !== \"\") return display;\n const email = (member.email ?? \"\").trim();\n if (email !== \"\") return email;\n return \"A member with no name set\";\n}\n\n/**\n * Find (or write) the kernel Person record for one member. Exported because\n * an agent filling a person field server-side needs exactly the same answer,\n * and two implementations of \"which record is this person\" is two answers.\n */\nexport async function personRecordForMember(\n client: RecordsClient,\n personTableId: Uuid,\n people: PersonRecord[],\n member: OrganizationMember,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const held = people.find((p) => p.userId === member.userId);\n if (held) return { ok: true, data: held.id };\n const written = await client.recordWrite({\n table_id: personTableId,\n data: {\n user_id: member.userId,\n full_name: memberName(member),\n ...(member.email ? { email: member.email } : {}),\n },\n });\n return written;\n}\n\nexport function PersonPicker({ field, value, onChange, disabled, id, className }: PersonPickerProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const [members, setMembers] = useState<OrganizationMember[] | null>(null);\n const [people, setPeople] = useState<PersonRecord[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [search, setSearch] = useState(\"\");\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const membersPort = host.members;\n const personTable = field.relation_target;\n\n const picked = useMemo<string[]>(\n () => (Array.isArray(value) ? value.map(String) : value === null || value === undefined ? [] : [String(value)]),\n [value],\n );\n\n const load = useCallback(async () => {\n if (!membersPort) return;\n const [roster, records] = await Promise.all([\n membersPort(),\n personTable ? client.list({ table_id: personTable, limit: 500 }) : Promise.resolve(null),\n ]);\n setMembers(roster);\n if (records && !records.ok) {\n setError(records.error.message);\n return;\n }\n setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);\n }, [membersPort, client, personTable]);\n\n useEffect(() => {\n if (!open) return;\n void load();\n }, [open, load]);\n\n // The names of the records that are already picked, whether or not the list\n // has been opened — a chip that read `8f2c1b0a` is the defect this closes.\n useEffect(() => {\n if (picked.length === 0 || !personTable || people.length > 0) return;\n let cancelled = false;\n void client.list({ table_id: personTable, limit: 500 }).then((result) => {\n if (cancelled || !result.ok) return;\n setPeople(result.data.rows.map(personFromRow).filter((p) => p.userId !== null));\n });\n return () => {\n cancelled = true;\n };\n }, [client, personTable, picked.length, people.length]);\n\n if (!membersPort) {\n // ABSENT AND HONEST. A person question with nobody to offer is not a box\n // that silently does nothing — it names the port that fills it.\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{NO_MEMBERS_REASON}</p>;\n }\n\n if (!personTable) {\n return (\n <p className={cn(\"text-xs text-muted-foreground\", className)}>\n {fieldName(field)} is a person field, but it does not say which Table the people are\n records of yet, so there is nothing to pick from. A table admin sets its target in the field\n editor.\n </p>\n );\n }\n\n const nameOfRecord = (recordId: string) => {\n const person = people.find((p) => p.id === recordId);\n if (!person) return \"Loading…\";\n if (person.name !== \"\") return person.name;\n const member = (members ?? []).find((m) => m.userId === person.userId);\n return member ? memberName(member) : \"A member with no name set\";\n };\n\n const pick = async (member: OrganizationMember) => {\n setBusy(true);\n setError(null);\n const resolved = await personRecordForMember(client, personTable, people, member);\n setBusy(false);\n if (!resolved.ok) {\n setError(resolved.error.message);\n return;\n }\n // Keep the newly written record so the chip can be named at once.\n if (!people.some((p) => p.id === resolved.data)) {\n setPeople((held) => [...held, { id: resolved.data, userId: member.userId, name: memberName(member) }]);\n }\n if (!field.multi) {\n onChange(picked[0] === resolved.data ? null : resolved.data);\n setOpen(false);\n return;\n }\n const next = new Set(picked);\n if (next.has(resolved.data)) next.delete(resolved.data);\n else next.add(resolved.data);\n onChange(next.size === 0 ? null : [...next]);\n };\n\n const drop = (recordId: string) => {\n const next = picked.filter((id) => id !== recordId);\n onChange(next.length === 0 ? null : field.multi ? next : (next[0] ?? null));\n };\n\n const visible = (members ?? []).filter((member) =>\n search.trim() === \"\" ? true : memberName(member).toLowerCase().includes(search.trim().toLowerCase()),\n );\n const pickedUserIds = new Set(\n picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean),\n );\n\n return (\n <div className={cn(\"flex flex-wrap items-center gap-1\", className)}>\n {picked.map((recordId) => (\n <RecordChip\n key={recordId}\n title={nameOfRecord(recordId)}\n {...(disabled ? {} : { onRemove: () => drop(recordId) })}\n />\n ))}\n {disabled ? null : (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n aria-label={`Pick a person for ${fieldName(field)}`}\n >\n {picked.length === 0 ? \"Pick a person\" : \"Change\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-64 p-1\" align=\"start\">\n <BasicInput\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search people\"\n className=\"mb-1 h-7 text-xs\"\n />\n {error ? <p className=\"p-2 text-xs text-destructive\">{error}</p> : null}\n {members === null ? <p className=\"p-2 text-xs text-muted-foreground\">Reading the members…</p> : null}\n <ScrollArea className=\"max-h-56\">\n <ul>\n {visible.map((member) => (\n <li key={member.userId}>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void pick(member)}\n className={cn(\n \"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted\",\n pickedUserIds.has(member.userId) ? \"bg-accent text-accent-foreground\" : \"\",\n )}\n >\n {memberName(member)}\n {member.email && member.email !== memberName(member) ? (\n <span className=\"ml-1 opacity-60\">{member.email}</span>\n ) : null}\n </button>\n </li>\n ))}\n </ul>\n {members !== null && visible.length === 0 ? (\n <p className=\"p-2 text-xs text-muted-foreground\">\n {members.length === 0\n ? \"This organization has no other members yet, so there is nobody to assign.\"\n : \"Nobody in this organization matches.\"}\n </p>\n ) : null}\n </ScrollArea>\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/editors.tsx — @ai-matrx/records-ui\n//\n// ONE EDITOR PER PARITY TYPE, and every one of them is a design-system\n// primitive. There is no bespoke input in this package and no per-feature\n// editor anywhere in the platform: a Field decides which of these is drawn,\n// from what the STORE stores about it (behaviour + modifiers + format + unit +\n// relation target), never from the value it happens to hold.\n//\n// FLD-9: a Formula is worked out by the system. Its editor is not a disabled\n// text box — it is the value with the sentence the store itself would say if\n// you tried to type into it.\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { Field, RecordDocument, StoredRecord, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n BasicTextarea,\n Badge,\n Button,\n Checkbox,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { editorKindFor } from \"./parity\";\nimport { fieldName, recordName } from \"./names\";\nimport { RelationPicker } from \"./RelationPicker\";\nimport { PersonPicker } from \"./PersonPicker\";\n\nexport interface FieldEditorControlProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n}\n\n/** The label row every editor shares: one line, the label, the unit, the required mark. */\nexport function FieldLabel({ field, htmlFor, children }: { field: Field; htmlFor: string; children?: ReactNode }) {\n return (\n <div className=\"flex items-baseline gap-1.5\">\n <Label htmlFor={htmlFor} className=\"text-xs font-medium\">\n {fieldName(field)}\n </Label>\n {field.required ? <span className=\"text-xs text-destructive\">required</span> : null}\n {field.unit ? <span className=\"text-xs text-muted-foreground\">{field.unit}</span> : null}\n {children}\n </div>\n );\n}\n\nexport function FieldControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const kind = editorKindFor(field);\n const inputId = id ?? `field-${field.key}`;\n\n switch (kind) {\n case \"formula\":\n case \"lookup\":\n case \"rollup\":\n return (\n <div className=\"rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground\">\n {/* The store's own sentence for typing into a computed field. */}\n {value === null || value === undefined ? \"—\" : String(value)}\n <span className=\"ml-2 italic\">\n {fieldName(field)} is worked out by the system, so it cannot be typed in\n </span>\n </div>\n );\n case \"json\":\n return <JsonControl field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"long_text\":\n return (\n <BasicTextarea\n id={inputId}\n rows={3}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"number\":\n case \"currency\":\n case \"percent\":\n return (\n <BasicInput\n id={inputId}\n type=\"number\"\n inputMode=\"decimal\"\n className=\"tabular-nums\"\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n />\n );\n case \"datetime\":\n return (\n <BasicInput\n id={inputId}\n type={field.format === \"datetime\" ? \"datetime-local\" : \"date\"}\n value={value === null || value === undefined ? \"\" : String(value).slice(0, field.format === \"datetime\" ? 16 : 10)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"email\":\n case \"phone\":\n case \"url\":\n return (\n <BasicInput\n id={inputId}\n type={kind === \"email\" ? \"email\" : kind === \"phone\" ? \"tel\" : \"url\"}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"select\":\n case \"multi_select\":\n return <OptionControl field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"member\":\n // A person field asks who is in the organization, never what is in a\n // Table — see PersonPicker's header for the screen that made this split.\n return <PersonPicker field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"relation\":\n case \"attachment\":\n return <RelationPicker field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n default:\n if (typeof value === \"boolean\" || field.config?.[\"kind\"] === \"boolean\") {\n return (\n <Checkbox\n id={inputId}\n checked={value === true}\n disabled={disabled}\n onCheckedChange={(next) => onChange(next === true)}\n />\n );\n }\n return (\n <BasicInput\n id={inputId}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n }\n}\n\n/**\n * A document-shaped value, edited as the text it is. It is parsed on every\n * keystroke and the PARSE FAILURE IS SHOWN — a box that silently handed the\n * store unparseable text and let it answer `22P02 invalid input syntax` is a\n * refusal the person could have been spared half a second earlier.\n */\nfunction JsonControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const initial = value === null || value === undefined ? \"\" : typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n const [text, setText] = useState(initial);\n const [broken, setBroken] = useState<string | null>(null);\n return (\n <div className=\"flex flex-col gap-1\">\n <BasicTextarea\n id={id}\n rows={4}\n className=\"font-mono text-[11px]\"\n value={text}\n disabled={disabled}\n onChange={(e) => {\n const next = e.target.value;\n setText(next);\n if (next.trim() === \"\") {\n setBroken(null);\n onChange(null);\n return;\n }\n try {\n onChange(JSON.parse(next));\n setBroken(null);\n } catch (thrown) {\n setBroken(thrown instanceof Error ? thrown.message : String(thrown));\n }\n }}\n />\n {broken ? (\n <p className=\"text-xs text-destructive\">\n {fieldName(field)} is not readable as structured data yet: {broken}\n </p>\n ) : null}\n </div>\n );\n}\n\n/**\n * FLD-5 / FLD-6. A list field stores the ID OF AN OPTION RECORD, because every\n * pick-list is already a Table. The options are read through the store's own\n * `custom.field_options` door, which resolves the options Table from the\n * Field's config — this component never has to know which Table that is.\n */\nfunction OptionControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const client = useRecordsClient();\n const [options, setOptions] = useState<StoredRecord[] | null>(null);\n const [refusal, setRefusal] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void client.fieldOptions({ field_id: field.id }).then((result) => {\n if (cancelled) return;\n if (result.ok) setOptions(result.data ?? []);\n else setRefusal(result.error.message);\n });\n return () => {\n cancelled = true;\n };\n }, [client, field.id]);\n\n if (refusal) return <p className=\"text-xs text-destructive\">{refusal}</p>;\n if (!options) return <p className=\"text-xs text-muted-foreground\">Reading this field&apos;s choices…</p>;\n if (options.length === 0) {\n // Two different facts, and a person acts on them differently: a choice\n // field whose Table is empty, and a choice field that names no Table at\n // all. One blank control for both is the silent failure.\n return (\n <p className=\"text-xs text-muted-foreground\">\n {field.options_table_id\n ? `${fieldName(field)} takes its choices from a Table that has no records yet — add the choices there and they appear here.`\n : `${fieldName(field)} does not name the Table its choices come from yet, so there is nothing to choose. A table admin sets it in the field editor.`}\n </p>\n );\n }\n\n const titleOf = (option: StoredRecord) =>\n recordName(option.data as RecordDocument | undefined, null, \"Unnamed choice\");\n\n if (field.multi) {\n const picked = new Set((Array.isArray(value) ? value : []).map(String));\n return (\n <div className=\"flex flex-wrap gap-1\">\n {options.map((option) => (\n <Button\n key={option.id}\n type=\"button\"\n size=\"sm\"\n variant={picked.has(option.id) ? \"default\" : \"outline\"}\n disabled={disabled}\n onClick={() => {\n const next = new Set(picked);\n if (next.has(option.id)) next.delete(option.id);\n else next.add(option.id);\n onChange(next.size === 0 ? null : [...next]);\n }}\n >\n {titleOf(option)}\n </Button>\n ))}\n </div>\n );\n }\n\n return (\n <Select\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled ?? false}\n onValueChange={(next) => onChange(next === \"\" ? null : next)}\n >\n <SelectTrigger id={id} size=\"sm\">\n <SelectValue placeholder=\"Choose\" />\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {titleOf(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\n/** The chip a picked record shows as — REC-2's \"a record is a chip\" in one place. */\nexport function RecordChip({\n title,\n onRemove,\n className,\n}: {\n title: string;\n onRemove?: (() => void) | undefined;\n className?: string | undefined;\n}) {\n return (\n <Badge variant=\"secondary\" className={cn(\"gap-1 text-[11px]\", className)}>\n {title}\n {onRemove ? (\n <button type=\"button\" onClick={onRemove} aria-label={`Remove ${title}`} className=\"opacity-60 hover:opacity-100\">\n ×\n </button>\n ) : null}\n </Badge>\n );\n}\n\nexport type { Uuid };\n","// src/parity.ts — @ai-matrx/records-ui\n//\n// FLD-11, the parity floor. A Field stores a BEHAVIOUR (one of five) plus\n// modifiers, unit and format; a person picked one of THIRTEEN parity types in\n// the UI. This resolves the second from the first, using the same facts the\n// store's own `custom.parity_field_types()` describes — which is generated into\n// `@ai-matrx/records` and imported here, never retyped.\n//\n// Nothing in this file decides policy. It decides which editor to draw.\n\nimport { KERNEL_TABLES, PARITY_FIELD_TYPES, type Field, type ParityFieldType } from \"@ai-matrx/records\";\nimport { humanize } from \"./names\";\n\n/** The kernel ids come from the store's own kernel rows, never from a literal here. */\nconst kernelId = (name: string): string =>\n KERNEL_TABLES.find((t) => t.name === name)?.id ?? \"\";\nconst KERNEL_FILE_TABLE = kernelId(\"File\");\nconst KERNEL_PERSON_TABLE = kernelId(\"Person\");\n\nexport const PARITY_LABEL: Record<ParityFieldType, string> = {\n attachment: \"Attachment\",\n currency: \"Currency\",\n datetime: \"Date\",\n email: \"Email\",\n formula: \"Formula\",\n lookup: \"Lookup\",\n member: \"Person\",\n multi_select: \"Multi-select\",\n percent: \"Percent\",\n phone: \"Phone\",\n rollup: \"Rollup\",\n select: \"Select\",\n url: \"Link\",\n};\n\n/** The \"made of\" sentence the store itself publishes, for the field editor's help text. */\nexport const PARITY_MADE_OF: Record<string, string> = Object.fromEntries(\n PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of]),\n);\n\n/** Plain text and plain number are behaviours with no parity type of their own. */\nexport type EditorKind =\n | ParityFieldType\n | \"relation\"\n | \"text\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"json\"\n | \"long_text\";\n\n/**\n * Which editor one Field wants. Reads the Field's own declaration only — the\n * behaviour, the modifiers, the format, the relation target and the config —\n * because those are what the store stores, and a screen that guessed from a\n * value would draw a different editor for an empty record.\n */\nexport function editorKindFor(field: Field): EditorKind {\n const format = (field.format ?? \"\").toLowerCase();\n const config = field.config ?? {};\n switch (field.type) {\n case \"text\":\n if (format === \"email\") return \"email\";\n if (format === \"phone\") return \"phone\";\n if (format === \"url\") return \"url\";\n // FLD-1: a document-shaped value is a `text` behaviour carrying a format.\n // It gets its own editor because a person typing JSON into a one-line box\n // and getting `22P02` back is the failure this resolves ahead of time.\n if (format === \"json\" || config[\"json\"] === true) return \"json\";\n if (format === \"long\" || config[\"multiline\"] === true) return \"long_text\";\n return \"text\";\n case \"range\": {\n const kind = String(config[\"kind\"] ?? \"number\");\n if (kind === \"date\" || kind === \"datetime\") return \"datetime\";\n if (format === \"currency\" || (field.unit ?? \"\").length > 1) return \"currency\";\n if (format === \"percent\" || field.unit === \"%\") return \"percent\";\n return \"number\";\n }\n case \"list\":\n return field.multi ? \"multi_select\" : \"select\";\n case \"relation\":\n return relationEditor(field);\n case \"formula\": {\n const via = config[\"via\"];\n if (via && config[\"agg\"]) return \"rollup\";\n if (via) return \"lookup\";\n return \"formula\";\n }\n default:\n return \"text\";\n }\n}\n\n/**\n * REC-31 / FLD-11: a relation is an `attachment` when it points at the kernel\n * File Table and a `member` when it points at the kernel Person Table. Every\n * other relation is drawn by the generic picker, which is what `\"relation\"`\n * means here — the one primitive SCR-N-2 says must exist.\n */\nfunction relationEditor(field: Field): EditorKind {\n const parity = String(field.config?.[\"parity\"] ?? \"\");\n if (parity === \"attachment\" || parity === \"member\") return parity;\n if (field.relation_target === KERNEL_FILE_TABLE) return \"attachment\";\n if (field.relation_target === KERNEL_PERSON_TABLE) return \"member\";\n return \"relation\" as EditorKind;\n}\n\n/** The type word a person sees in a header or a settings row. */\nexport function fieldTypeLabel(field: Field): string {\n const kind = editorKindFor(field);\n const known = (PARITY_LABEL as Record<string, string>)[kind];\n if (known) return field.multi && kind !== \"multi_select\" ? `${known} (many)` : known;\n const plain: Record<string, string> = {\n text: \"Text\",\n long_text: \"Long text\",\n number: \"Number\",\n boolean: \"Yes / no\",\n date: \"Date\",\n json: \"Structured data\",\n relation: \"Link to a record\",\n };\n // Never a raw token on a screen: an editor kind this table has not named is\n // still written the way a person writes it.\n return plain[kind] ?? humanize(kind);\n}\n","\"use client\";\n\n// src/RelationPicker.tsx — @ai-matrx/records-ui · SCR-N-2\n//\n// THE ONE GENERIC RELATION PICKER. Before it, every relation-shaped field in\n// the product had a type-specific picker (image, file, url, scope) and a plain\n// `relation` field was not editable at all.\n//\n// It reads the target Table's records through the read door, shows each one as\n// its own chip (REC-2: the title field is what makes a record a chip), and\n// respects `relation_max` by saying the number rather than silently dropping a\n// pick.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { Field, ReadRow } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n Button,\n Popover,\n PopoverContent,\n PopoverTrigger,\n ScrollArea,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { RecordChip } from \"./editors\";\nimport { fieldName, rowName } from \"./names\";\n\nexport interface RelationPickerProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n className?: string | undefined;\n}\n\nexport function RelationPicker({ field, value, onChange, disabled, id, className }: RelationPickerProps) {\n const client = useRecordsClient();\n const [rows, setRows] = useState<ReadRow[] | null>(null);\n const [refusal, setRefusal] = useState<string | null>(null);\n const [search, setSearch] = useState(\"\");\n const [open, setOpen] = useState(false);\n\n const picked = useMemo<string[]>(\n () => (Array.isArray(value) ? value.map(String) : value === null || value === undefined ? [] : [String(value)]),\n [value],\n );\n\n useEffect(() => {\n if (!open || rows || !field.relation_target) return;\n let cancelled = false;\n void client.list({ table_id: field.relation_target, limit: 200 }).then((result) => {\n if (cancelled) return;\n if (result.ok) setRows(result.data.rows);\n else setRefusal(result.error.message);\n });\n return () => {\n cancelled = true;\n };\n }, [client, field.relation_target, open, rows]);\n\n if (!field.relation_target) {\n // Absent, and honest about why: a relation with no declared target is a\n // Field the store has not finished, not a picker that \"has no options\".\n return (\n <p className=\"text-xs text-muted-foreground\">\n {fieldName(field)} points at records, but it does not say which Table yet, so there is nothing to pick\n from. A table admin sets its target in the field editor.\n </p>\n );\n }\n\n const byId = new Map((rows ?? []).map((row) => [row.id, row]));\n // A chip carries the record's NAME. Before `names.ts`, a relation whose\n // target had not loaded yet drew `8f2c1b0a` — a bare identifier, which the\n // verdict of 19 September counted among the three things a first-time user\n // feels within a minute.\n const titleOf = (recordId: string) => rowName(byId.get(recordId), null, \"Loading…\");\n const full = field.multi && field.relation_max !== null && picked.length >= field.relation_max;\n\n const toggle = (recordId: string) => {\n if (!field.multi) {\n onChange(picked[0] === recordId ? null : recordId);\n setOpen(false);\n return;\n }\n const next = new Set(picked);\n if (next.has(recordId)) next.delete(recordId);\n else if (!full) next.add(recordId);\n onChange(next.size === 0 ? null : [...next]);\n };\n\n const visible = (rows ?? []).filter((row) =>\n search.trim() === \"\" ? true : titleOf(row.id).toLowerCase().includes(search.trim().toLowerCase()),\n );\n\n return (\n <div className={cn(\"flex flex-wrap items-center gap-1\", className)}>\n {picked.map((recordId) => (\n <RecordChip\n key={recordId}\n title={titleOf(recordId)}\n {...(disabled ? {} : { onRemove: () => toggle(recordId) })}\n />\n ))}\n {disabled ? null : (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button id={id} type=\"button\" size=\"sm\" variant=\"outline\" aria-label={`Pick for ${fieldName(field)}`}>\n {picked.length === 0 ? \"Pick\" : \"Change\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-64 p-1\" align=\"start\">\n <BasicInput\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search\"\n className=\"mb-1 h-7 text-xs\"\n />\n {refusal ? <p className=\"p-2 text-xs text-destructive\">{refusal}</p> : null}\n {!rows && !refusal ? <p className=\"p-2 text-xs text-muted-foreground\">Reading…</p> : null}\n {full ? (\n <p className=\"p-2 text-xs text-muted-foreground\">\n {fieldName(field)} can point at {field.relation_max} at most. Remove one to add another.\n </p>\n ) : null}\n <ScrollArea className=\"max-h-56\">\n <ul>\n {visible.map((row) => (\n <li key={row.id}>\n <button\n type=\"button\"\n onClick={() => toggle(row.id)}\n className={cn(\n \"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted\",\n picked.includes(row.id) ? \"bg-accent text-accent-foreground\" : \"\",\n )}\n >\n {titleOf(row.id)}\n </button>\n </li>\n ))}\n </ul>\n {rows && visible.length === 0 ? (\n <p className=\"p-2 text-xs text-muted-foreground\">Nothing in that table matches.</p>\n ) : null}\n </ScrollArea>\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/gridEditing.tsx — @ai-matrx/records-ui · SCR-1 / REC-9\n//\n// EDITING A RECORD WHERE IT IS SHOWN.\n//\n// Until this file existed, the grid was a read-only window: double-clicking a\n// cell opened a panel of raw JSON with no control, no Save and no Delete, and\n// the only way to write anything was the whole \"New record\" form. The\n// independent verdict of 19 September put it first of three: \"In Airtable you\n// click a cell and type. Here a cell opens a read-only window of programming\n// text… Every other gap is downstream of this one.\"\n//\n// WHAT THIS IS, AND WHAT IT DELIBERATELY IS NOT\n// ---------------------------------------------\n// `@ai-matrx/design-system`'s data table HAS an inline editor\n// (`EditableTableCell`) and this package does not use it here, for one reason\n// that is not taste: that editor speaks six value shapes (string, number,\n// boolean, select, tags, date) and collects edits into a draft map that a\n// floating Save pill persists. A Field in this store is one of THIRTEEN parity\n// types — a relation, a person, a file, a multi-choice whose options are the\n// records of another Table, a json document, a formula that cannot be typed\n// into at all — and every one of them already has exactly one editor in this\n// package (`FieldControl`, itself built from design-system primitives). Two\n// editing models on one screen is the fork the inventory law forbids, so the\n// cell hosts the ONE editor a Field already has, and the write goes through the\n// ONE write door with the version the person started from.\n//\n// THE CONCURRENCY STORY, WHICH IS THE WHOLE POINT OF REC-9\n// -------------------------------------------------------\n// The read door answers documents, never versions. So the FIRST time a person\n// edits a given record in this session, the version is read for that one record\n// (`custom.io_revisions`) and remembered. Every save from then on carries it,\n// and the store — not this screen — decides whether somebody else got there\n// first. When it did, the store raises `PT409` with the other person's value in\n// the detail, and the cell shows THAT: their value, beside the value being\n// written, with a Retry that re-reads the version and writes again, and a\n// \"Keep theirs\" that drops the edit. Nothing is silently overwritten and\n// nothing is silently lost.\n//\n// OPTIMISTIC, BUT NEVER DISHONEST: the typed value is shown the instant it is\n// committed, and it is REMOVED again the moment the store refuses. A cell that\n// kept showing a value the store rejected is the lie this package exists to\n// prevent.\n\nimport { useCallback, useMemo, useRef, useState, type FocusEvent } from \"react\";\nimport type { Field, ReadRow, RecordsError, Uuid } from \"@ai-matrx/records\";\nimport type { WriteConflict } from \"@ai-matrx/records\";\nimport { asWriteConflict, type RecordsClient } from \"@ai-matrx/records/core\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport { Button, cn } from \"@ai-matrx/design-system\";\n\nimport { FieldControl } from \"./editors\";\nimport { RefusalLine } from \"./Refusal\";\nimport { editorKindFor } from \"./parity\";\nimport { fieldName } from \"./names\";\nimport { renderValue } from \"./values\";\n\n/** Which cell is open. A grid opens exactly one at a time, like every other grid. */\nexport interface CellAddress {\n rowId: Uuid;\n key: string;\n}\n\n/** What one cell is doing right now, so nothing about it is guessed by a caller. */\nexport type CellState = \"clean\" | \"saving\" | \"refused\";\n\nexport interface CellRefusal {\n error: RecordsError;\n /** Present when the store said `PT409`: the other person's value, from the store. */\n conflict: WriteConflict | null;\n /** The value that was being written, so Retry can write it again. */\n attempted: unknown;\n}\n\n/**\n * FLD-9. A computed Field is not editable and never will be — the store works\n * it out. Saying so here, once, keeps every caller from re-deciding it.\n */\nexport function fieldIsEditable(field: Field): boolean {\n const kind = editorKindFor(field);\n return kind !== \"formula\" && kind !== \"lookup\" && kind !== \"rollup\";\n}\n\nexport interface GridEditing {\n /** The value to DRAW for one cell — the optimistic one when there is one. */\n valueFor: (row: ReadRow, field: Field) => unknown;\n editing: CellAddress | null;\n stateOf: (rowId: Uuid, key: string) => CellState;\n refusalOf: (rowId: Uuid, key: string) => CellRefusal | null;\n begin: (address: CellAddress) => void;\n cancel: () => void;\n /** Commit the open cell. `move` opens the next/previous editable cell after it. */\n commit: (value: unknown, move?: \"next\" | \"previous\" | null) => void;\n /** Write the attempted value again, after re-reading the version. */\n retry: (rowId: Uuid, key: string) => void;\n /** Drop the edit and show what the other person wrote. */\n keepTheirs: (rowId: Uuid, key: string) => void;\n /** Soft delete, through the store's own door. Answers the store's refusal, or null. */\n remove: (rowId: Uuid) => Promise<RecordsError | null>;\n /** Write an empty record and open its first editable cell. */\n addRecord: () => Promise<RecordsError | null>;\n /** The last refusal from a delete or an add, for the grid to print. */\n rowError: RecordsError | null;\n clearRowError: () => void;\n busy: boolean;\n}\n\ninterface Options {\n tableId: Uuid;\n fields: Field[];\n rows: ReadRow[];\n /** Re-read the page once the store has accepted something. */\n reload: () => void;\n /** May this person write records at all? A read-only grid opens no editor. */\n canWrite: boolean;\n}\n\n/**\n * THE VERSION THE PERSON STARTED FROM, read once per record per session.\n *\n * Not read for the page: a list of two hundred records would be two hundred\n * extra door calls for a person who is going to edit one cell. Not guessed\n * either — `null` means \"we never read one\", and the save then carries no\n * expected version and is the store's ordinary last-writer-wins write, exactly\n * as the store defines it.\n */\nasync function versionOf(\n client: RecordsClient,\n cache: Map<string, number>,\n recordId: Uuid,\n): Promise<number | null> {\n const held = cache.get(recordId);\n if (held !== undefined) return held;\n const answered = await client.revisions({ record_id: recordId });\n if (!answered.ok) return null;\n const newest = answered.data.reduce<number | null>(\n (best, row) => (best === null || row.version > best ? row.version : best),\n null,\n );\n if (newest !== null) cache.set(recordId, newest);\n return newest;\n}\n\nexport function useGridEditing({ tableId, fields, rows, reload, canWrite }: Options): GridEditing {\n const client = useRecordsClient();\n const [editing, setEditing] = useState<CellAddress | null>(null);\n const [optimistic, setOptimistic] = useState<Record<string, unknown>>({});\n const [saving, setSaving] = useState<Record<string, true>>({});\n const [refusals, setRefusals] = useState<Record<string, CellRefusal>>({});\n const [rowError, setRowError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const versions = useRef(new Map<string, number>());\n\n const editable = useMemo(() => fields.filter(fieldIsEditable), [fields]);\n const order = useMemo(() => editable.map((f) => f.key), [editable]);\n const rowIds = useMemo(() => rows.map((r) => r.id), [rows]);\n\n const cellKey = (rowId: Uuid, key: string) => `${rowId}::${key}`;\n\n const valueFor = useCallback(\n (row: ReadRow, field: Field) => {\n const held = optimistic[cellKey(row.id, field.key)];\n return held === undefined ? row.document?.[field.key] : held;\n },\n [optimistic],\n );\n\n const stateOf = useCallback(\n (rowId: Uuid, key: string): CellState => {\n const id = cellKey(rowId, key);\n if (saving[id]) return \"saving\";\n if (refusals[id]) return \"refused\";\n return \"clean\";\n },\n [saving, refusals],\n );\n\n const refusalOf = useCallback(\n (rowId: Uuid, key: string) => refusals[cellKey(rowId, key)] ?? null,\n [refusals],\n );\n\n const begin = useCallback(\n (address: CellAddress) => {\n if (!canWrite) return;\n setEditing(address);\n // The version this edit starts from, read once for this record.\n void versionOf(client, versions.current, address.rowId);\n },\n [canWrite, client],\n );\n\n const cancel = useCallback(() => setEditing(null), []);\n\n /** One write of one Field of one record, with whatever version we hold. */\n const writeCell = useCallback(\n async (rowId: Uuid, key: string, value: unknown) => {\n const id = cellKey(rowId, key);\n setOptimistic((held) => ({ ...held, [id]: value }));\n setSaving((held) => ({ ...held, [id]: true }));\n setRefusals((held) => {\n if (!held[id]) return held;\n const next = { ...held };\n delete next[id];\n return next;\n });\n\n const version = await versionOf(client, versions.current, rowId);\n const written = await client.recordUpdate({\n record_id: rowId,\n patch: { [key]: value },\n ...(version === null ? {} : { expectedVersion: version }),\n });\n\n setSaving((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n\n if (written.ok) {\n // The store's own new version, so the NEXT edit of this record carries it.\n versions.current.set(rowId, written.data);\n reload();\n return;\n }\n\n // Refused: the optimistic value comes straight back off the screen, and\n // the store's own sentence goes on it.\n setOptimistic((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n // A stale write means the version we hold is wrong; forget it so the\n // retry reads the current one rather than repeating the same refusal.\n if (written.error.code === \"stale_write\") versions.current.delete(rowId);\n setRefusals((held) => ({\n ...held,\n [id]: {\n error: written.error,\n conflict: asWriteConflict(written.error, rowId),\n attempted: value,\n },\n }));\n },\n [client, reload],\n );\n\n const commit = useCallback(\n (value: unknown, move: \"next\" | \"previous\" | null = null) => {\n const open = editing;\n if (!open) return;\n const row = rows.find((r) => r.id === open.rowId);\n const unchanged = row !== undefined && sameValue(row.document?.[open.key], value);\n if (!unchanged) void writeCell(open.rowId, open.key, value);\n\n if (!move) {\n setEditing(null);\n return;\n }\n const next = step(open, order, rowIds, move);\n setEditing(next);\n if (next) void versionOf(client, versions.current, next.rowId);\n },\n [editing, rows, writeCell, order, rowIds, client],\n );\n\n const retry = useCallback(\n (rowId: Uuid, key: string) => {\n const held = refusals[cellKey(rowId, key)];\n if (!held) return;\n void writeCell(rowId, key, held.attempted);\n },\n [refusals, writeCell],\n );\n\n const keepTheirs = useCallback(\n (rowId: Uuid, key: string) => {\n const id = cellKey(rowId, key);\n versions.current.delete(rowId);\n setRefusals((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n setOptimistic((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n reload();\n },\n [reload],\n );\n\n const remove = useCallback(\n async (rowId: Uuid) => {\n setBusy(true);\n setRowError(null);\n const done = await client.recordDelete({ record_id: rowId });\n setBusy(false);\n if (done.ok) {\n versions.current.delete(rowId);\n reload();\n return null;\n }\n setRowError(done.error);\n return done.error;\n },\n [client, reload],\n );\n\n const addRecord = useCallback(async () => {\n setBusy(true);\n setRowError(null);\n // AIRTABLE'S GESTURE: a new row appears and you type into it. The store\n // decides whether an empty record is allowed — a Table with a required\n // Field refuses, in its own words, and the grid offers the whole form.\n const written = await client.recordWrite({ table_id: tableId, data: {} });\n setBusy(false);\n if (!written.ok) {\n setRowError(written.error);\n return written.error;\n }\n reload();\n const first = order[0];\n if (first) setEditing({ rowId: written.data, key: first });\n return null;\n }, [client, tableId, reload, order]);\n\n return {\n valueFor,\n editing,\n stateOf,\n refusalOf,\n begin,\n cancel,\n commit,\n retry,\n keepTheirs,\n remove,\n addRecord,\n rowError,\n clearRowError: () => setRowError(null),\n busy,\n };\n}\n\n/** Tab order: across the row, then on to the next row. Stops at the ends. */\nfunction step(\n from: CellAddress,\n order: string[],\n rowIds: Uuid[],\n move: \"next\" | \"previous\",\n): CellAddress | null {\n const column = order.indexOf(from.key);\n const row = rowIds.indexOf(from.rowId);\n if (column < 0 || row < 0) return null;\n const delta = move === \"next\" ? 1 : -1;\n let nextColumn = column + delta;\n let nextRow = row;\n if (nextColumn >= order.length) {\n nextColumn = 0;\n nextRow += 1;\n } else if (nextColumn < 0) {\n nextColumn = order.length - 1;\n nextRow -= 1;\n }\n const key = order[nextColumn];\n const rowId = rowIds[nextRow];\n if (key === undefined || rowId === undefined) return null;\n return { rowId, key };\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (left === null || left === undefined) return right === null || right === undefined || right === \"\";\n if (right === null || right === undefined) return left === \"\";\n if (typeof left === \"object\" || typeof right === \"object\") {\n try {\n return JSON.stringify(left) === JSON.stringify(right);\n } catch {\n return false;\n }\n }\n return false;\n}\n\n/**\n * ONE CELL. Read, until somebody asks to change it; then the Field's own\n * editor, in place, with the keys a person expects from a grid.\n *\n * `data-matrx-cell-control` is the data table's own opt-out from whole-row\n * click, so opening a cell never also opens the record panel behind it.\n */\nexport function GridCell({\n field,\n row,\n editing,\n canWrite,\n}: {\n field: Field;\n row: ReadRow;\n editing: GridEditing;\n canWrite: boolean;\n}) {\n const open = editing.editing?.rowId === row.id && editing.editing.key === field.key;\n const value = editing.valueFor(row, field);\n const state = editing.stateOf(row.id, field.key);\n const refusal = editing.refusalOf(row.id, field.key);\n const editable = canWrite && fieldIsEditable(field);\n\n if (open) {\n return (\n <OpenCell\n field={field}\n value={value}\n onCommit={(next, move) => editing.commit(next, move)}\n onCancel={editing.cancel}\n />\n );\n }\n\n return (\n <span data-matrx-cell-control=\"\" className=\"flex min-w-0 flex-col gap-0.5\">\n <span\n role={editable ? \"button\" : undefined}\n tabIndex={editable ? 0 : undefined}\n aria-label={editable ? `Edit ${fieldName(field)}` : undefined}\n title={editable ? `${fieldName(field)} — press Enter to edit` : undefined}\n className={cn(\n \"block min-w-0 truncate rounded px-1 py-0.5\",\n editable ? \"cursor-text hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\" : \"\",\n state === \"saving\" ? \"opacity-60\" : \"\",\n state === \"refused\" ? \"ring-1 ring-destructive\" : \"\",\n )}\n onClick={editable ? () => editing.begin({ rowId: row.id, key: field.key }) : undefined}\n onKeyDown={\n editable\n ? (event) => {\n if (event.key === \"Enter\" || event.key === \"F2\") {\n event.preventDefault();\n editing.begin({ rowId: row.id, key: field.key });\n }\n }\n : undefined\n }\n >\n {renderValue(field, value, row.document)}\n </span>\n\n {state === \"saving\" ? <span className=\"px-1 text-[10px] text-muted-foreground\">Saving…</span> : null}\n\n {refusal ? (\n <span className=\"flex flex-col gap-0.5 rounded border border-destructive/40 p-1\">\n <RefusalLine error={refusal.error} />\n {refusal.conflict ? (\n <span className=\"text-[11px]\">\n {/* The other person's value, as the store sent it. */}\n Theirs: <strong>{formatTheirs(refusal.conflict, field.key)}</strong>\n </span>\n ) : null}\n <span className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"outline\" onClick={() => editing.retry(row.id, field.key)}>\n Try again\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => editing.keepTheirs(row.id, field.key)}>\n Keep theirs\n </Button>\n </span>\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction formatTheirs(conflict: WriteConflict, key: string): string {\n const theirs = conflict.contested_fields?.[key];\n if (theirs === null || theirs === undefined || theirs === \"\") return \"(empty)\";\n return typeof theirs === \"object\" ? JSON.stringify(theirs) : String(theirs);\n}\n\n/**\n * WHICH EDITORS CLOSE THEMSELVES ON BLUR, AND WHY THE OTHERS MUST NOT.\n *\n * A typed box (text, number, date, email, url, phone) is finished when you look\n * away, exactly as a spreadsheet is. A PICKER is not: a select, a relation\n * picker and a person picker all open a Radix popover, which is portalled OUT\n * of this cell, so \"focus left the cell\" fires the instant the list opens.\n * Committing there would save the old value and shut the list a person just\n * asked for. So pickers carry an explicit Save and Cancel, and the keys work on\n * both.\n */\nfunction closesOnBlur(field: Field): boolean {\n switch (editorKindFor(field)) {\n case \"select\":\n case \"multi_select\":\n case \"relation\":\n case \"member\":\n case \"attachment\":\n return false;\n default:\n return true;\n }\n}\n\n/**\n * The open cell. Enter commits, Escape cancels, Tab commits and opens the next\n * one — the three keys every grid in the world binds, so nobody has to be told.\n * A long-text Field takes Enter for a newline and commits on Ctrl/Cmd+Enter,\n * because the alternative is a text box you cannot put a paragraph in.\n */\nfunction OpenCell({\n field,\n value,\n onCommit,\n onCancel,\n}: {\n field: Field;\n value: unknown;\n onCommit: (value: unknown, move: \"next\" | \"previous\" | null) => void;\n onCancel: () => void;\n}) {\n const [draft, setDraft] = useState<unknown>(value);\n const multiline = editorKindFor(field) === \"long_text\";\n const blurCommits = closesOnBlur(field);\n\n const blur = blurCommits\n ? {\n onBlur: (event: FocusEvent<HTMLSpanElement>) => {\n // Leaving the cell altogether commits, exactly as a spreadsheet does.\n // Moving between the editor's own parts does not.\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n onCommit(draft, null);\n },\n }\n : {};\n\n return (\n <span\n data-matrx-cell-control=\"\"\n className=\"flex min-w-[10rem] flex-col gap-1\"\n ref={(node) => {\n if (!node) return;\n const control = node.querySelector<HTMLElement>(\"input, textarea, [role='combobox'], button\");\n if (control && document.activeElement !== control) control.focus();\n }}\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n onCancel();\n return;\n }\n if (event.key === \"Tab\") {\n event.preventDefault();\n event.stopPropagation();\n onCommit(draft, event.shiftKey ? \"previous\" : \"next\");\n return;\n }\n if (event.key === \"Enter\" && (!multiline || event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n event.stopPropagation();\n onCommit(draft, null);\n }\n }}\n {...blur}\n >\n <FieldControl field={field} value={draft} onChange={setDraft} id={`cell-${field.id}`} />\n {blurCommits ? (\n <span className=\"text-[10px] text-muted-foreground\">\n {multiline ? \"⌘⏎ saves · Esc cancels · Tab next\" : \"⏎ saves · Esc cancels · Tab next\"}\n </span>\n ) : (\n <span className=\"flex items-center gap-1\">\n <Button size=\"sm\" onClick={() => onCommit(draft, null)}>\n Save\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n </span>\n )}\n </span>\n );\n}\n","\"use client\";\n\n// src/Refusal.tsx — @ai-matrx/records-ui\n//\n// THE ONE PLACE A REFUSAL IS SHOWN, and it shows the STORE'S OWN SENTENCE.\n// Nothing in this package writes its own copy for something the store already\n// explained: \"Someone else changed this record while you were working on it\" was\n// written to be read by the person who hit it.\n//\n// Every component here renders this when a call comes back `{ok:false}`. A\n// component that rendered an empty list instead would be the lie the whole\n// record package exists to prevent.\n\nimport type { ReactNode } from \"react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Alert, AlertDescription, AlertTitle, cn } from \"@ai-matrx/design-system\";\n\nconst TITLE: Record<string, string> = {\n stale_write: \"Someone else wrote first\",\n door: \"The store did not open this door\",\n door_absent: \"That door does not exist yet\",\n refused_by_rule: \"The store refused this\",\n invalid_argument: \"The store refused this\",\n not_found: \"Not there any more\",\n missing_reference: \"That points somewhere it cannot\",\n already_exists: \"That already exists\",\n not_supported: \"The store does not do that\",\n store_limit: \"The store hit a limit\",\n store_not_served: \"The store is not being served\",\n internal: \"The store said something this package does not recognise\",\n};\n\nexport function RefusalNotice({\n error,\n className,\n actions,\n}: {\n error: RecordsError;\n className?: string | undefined;\n actions?: ReactNode | undefined;\n}) {\n return (\n <Alert\n variant=\"destructive\"\n className={cn(\"text-xs\", className)}\n {...(error.sqlstate ? { title: `The store's code for this was ${error.sqlstate}` } : {})}\n >\n <AlertTitle className=\"text-xs font-medium\">{TITLE[error.code] ?? \"The store refused this\"}</AlertTitle>\n <AlertDescription className=\"space-y-1 text-xs\">\n {/* The store's own words, verbatim. */}\n <p>{error.message}</p>\n {error.hint ? <p className=\"opacity-80\">{error.hint}</p> : null}\n {/* The store's CODE is a fact for whoever has to debug it, not a\n sentence for the person reading the refusal — printing `42501` in\n the body made the screen read like a stack trace (verdict, 19\n September). It stays, on the notice, where an engineer can find it. */}\n {error.sqlstate ? (\n <p className=\"sr-only\" data-sqlstate={error.sqlstate}>\n The store&apos;s code for this was {error.sqlstate}.\n </p>\n ) : null}\n {actions}\n </AlertDescription>\n </Alert>\n );\n}\n\n/** A small inline one, for a cell or a field where a block would break the layout. */\nexport function RefusalLine({ error, className }: { error: RecordsError; className?: string | undefined }) {\n return (\n <p className={cn(\"text-xs text-destructive\", className)} title={error.hint ?? undefined}>\n {error.message}\n </p>\n );\n}\n","\"use client\";\n\n// src/values.tsx — @ai-matrx/records-ui\n//\n// HOW A VALUE IS SHOWN, one function, used by the grid cell, the peek, the\n// custom-fields section and the form's read state alike. Per SCR it is never\n// per-feature: every surface that shows a Value in this platform shows it the\n// same way, because the way is a property of the Field, not of the screen.\n//\n// VAL-2: a blank is never unexplained. When the record's envelope says why a\n// value is missing, the reason is what is shown — \"never asked\" and \"refused\"\n// are different facts and a person acts on them differently.\n\nimport type { Field, RecordDocument, ValueEnvelope } from \"@ai-matrx/records\";\nimport { Badge, cn } from \"@ai-matrx/design-system\";\nimport { editorKindFor } from \"./parity\";\n\n/** The envelope for one key, when the document carries one. */\nexport function envelopeFor(document: RecordDocument | undefined, key: string): ValueEnvelope | undefined {\n const block = document?._values as Record<string, ValueEnvelope> | undefined;\n return block?.[key];\n}\n\nconst ABSENCE_WORDS: Record<string, string> = {\n \"never asked\": \"never asked\",\n none: \"none\",\n refused: \"refused\",\n conflicting: \"conflicting\",\n};\n\nexport function renderValue(field: Field, value: unknown, document?: RecordDocument) {\n const envelope = envelopeFor(document, field.key);\n if (envelope?.absent) {\n return (\n <span className=\"text-xs italic text-muted-foreground\" title={`VAL-2: ${envelope.absent}`}>\n {ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent)}\n </span>\n );\n }\n if (value === null || value === undefined || value === \"\") {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n const kind = editorKindFor(field);\n if (Array.isArray(value)) {\n return (\n <span className=\"flex flex-wrap gap-1\">\n {value.map((item, i) => (\n <Badge key={`${String(item)}-${i}`} variant=\"secondary\" className=\"text-[11px]\">\n {scalarText(field, item)}\n </Badge>\n ))}\n </span>\n );\n }\n if (kind === \"url\" && typeof value === \"string\") {\n return (\n <a className=\"truncate text-primary underline-offset-2 hover:underline\" href={value} target=\"_blank\" rel=\"noreferrer\">\n {value}\n </a>\n );\n }\n if (kind === \"email\" && typeof value === \"string\") {\n return (\n <a className=\"truncate text-primary underline-offset-2 hover:underline\" href={`mailto:${value}`}>\n {value}\n </a>\n );\n }\n if (typeof value === \"boolean\") {\n return <span>{value ? \"Yes\" : \"No\"}</span>;\n }\n return <span className={cn(\"truncate\", kind === \"number\" || kind === \"currency\" || kind === \"percent\" ? \"tabular-nums\" : \"\")}>{scalarText(field, value)}</span>;\n}\n\n/** The text of one scalar, with the Field's UNIT and FORMAT applied — FLD-N-1 says both change the MEANING. */\nexport function scalarText(field: Field, value: unknown): string {\n if (value === null || value === undefined) return \"—\";\n const kind = editorKindFor(field);\n if (typeof value === \"number\") {\n if (kind === \"percent\") return `${value}%`;\n if (kind === \"currency\" && field.unit) return `${field.unit}${value.toLocaleString()}`;\n return field.unit ? `${value.toLocaleString()} ${field.unit}` : value.toLocaleString();\n }\n if (kind === \"datetime\" && typeof value === \"string\") {\n const at = new Date(value);\n if (!Number.isNaN(at.getTime())) {\n return field.format === \"datetime\" ? at.toLocaleString() : at.toLocaleDateString();\n }\n }\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The provenance badge a value carries when the store interned a source for it (SCR-27). */\nexport function ProvenanceBadge({ document, fieldKey }: { document: RecordDocument | undefined; fieldKey: string }) {\n const envelope = envelopeFor(document, fieldKey);\n if (!envelope?.src) return null;\n const sources = document?._sources as Record<string, Record<string, unknown>> | undefined;\n const source = sources?.[envelope.src];\n const label = source ? Object.values(source).map(String).join(\" · \") : envelope.src;\n return (\n <Badge variant=\"outline\" className=\"text-[10px] font-normal\" title={`Written by ${envelope.actor ?? \"?\"}${envelope.at ? ` at ${envelope.at}` : \"\"}`}>\n {label}\n </Badge>\n );\n}\n","\"use client\";\n\n// src/Grid.tsx — @ai-matrx/records-ui · SCR-1, SCR-2, SCR-4, SCR-31\n//\n// A custom table opens as a grid: RECORDS ARE ROWS, FIELDS ARE COLUMNS, AND A\n// CELL IS WHERE YOU CHANGE IT.\n//\n// It is the canonical `MatrxDataTable` — not a table this package drew. The\n// columns are built from the Table's own Field records, the rows are the\n// records the read door returned, and the \"+\" at the end of the column headers\n// is present for a holder of `admin` on the table and ABSENT — never disabled,\n// never greyed — for everybody else (SCR-4).\n//\n// EDITING IS HERE, NOT IN A PANEL SOMEWHERE ELSE (`gridEditing.tsx`). Click a\n// cell, or focus it and press Enter, and the Field's own editor opens in place;\n// Enter saves, Escape cancels, Tab saves and opens the next one. The save goes\n// through the one write door carrying the version the person started from, so\n// the STORE decides whether somebody else got there first — and when it did,\n// the cell shows their value with a Try again beside it. A row is deleted from\n// its own row menu, with the consequence named before the delete, and a new\n// record is one button that puts you straight into the first cell.\n//\n// Every refusal is the store's own sentence (`RefusalNotice`). A grid that\n// rendered \"no records\" because the door refused is the defect this package\n// exists to prevent, so the empty state and the refusal are different things\n// and both are shown.\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport {\n useFields,\n useRecords,\n useTable,\n type Field,\n type ReadRow,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport { MatrxDataTable } from \"@ai-matrx/design-system/data-table\";\nimport type { MatrxColumnDef } from \"@ai-matrx/design-system/data-table/types\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { editorKindFor, fieldTypeLabel } from \"./parity\";\nimport { fieldName, tableName } from \"./names\";\nimport { renderValue } from \"./values\";\nimport { GridCell, useGridEditing, type GridEditing } from \"./gridEditing\";\n\nexport interface GridProps {\n tableId: Uuid;\n /** Rows per page. The table's own pagination handles the rest. */\n pageSize?: number | undefined;\n /** Opened when a row is clicked. A host that has a record page passes its own. */\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n /** SCR-2. Called when an admin clicks the \"+\" at the end of the headers. */\n onAddField?: (() => void) | undefined;\n /**\n * The host's whole-record form. Offered BY NAME when the store refuses an\n * empty record — a Table with a required Field cannot be added to one cell at\n * a time, and saying so beats a button that fails.\n */\n onNewRecordForm?: (() => void) | undefined;\n /** Extra toolbar content — the view switcher, the export menu, the view bar. */\n toolbarActions?: ReactNode | undefined;\n /** Editing in place is on by default; a read-only surface (a portal) turns it off. */\n editable?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport function Grid({\n tableId,\n pageSize = 50,\n onOpenRecord,\n onAddField,\n onNewRecordForm,\n toolbarActions,\n editable = true,\n className,\n}: GridProps) {\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [page, setPage] = useState(0);\n const records = useRecords(tableId, { pageSize, page });\n const rights = useTableRights(table.data);\n const canWrite = Boolean(editable) && rights.write;\n\n const rows = useMemo(() => records.data?.rows ?? [], [records.data]);\n const editing = useGridEditing({\n tableId,\n fields: fields.data ?? [],\n rows,\n reload: records.reload,\n canWrite,\n });\n\n const columns = useMemo<MatrxColumnDef<ReadRow>[]>(\n () => (fields.data ?? []).map((field) => columnForField(field, canWrite ? editing : null)),\n [fields.data, canWrite, editing],\n );\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n\n const loading = table.loading || fields.loading;\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* SCR-N-4 / the one-row header rule: the table's name, its row count and\n its controls on ONE line. No repeated name, no subtitle restating it. */}\n <div className=\"flex items-center gap-2\">\n <h2 className=\"truncate text-sm font-medium\">\n {table.data ? tableName(table.data) : <Skeleton className=\"h-4 w-32\" />}\n </h2>\n {records.data?.total !== null && records.data?.total !== undefined ? (\n <span className=\"text-xs text-muted-foreground\">{records.data.total}</span>\n ) : null}\n <div className=\"ml-auto flex items-center gap-1\">{toolbarActions}</div>\n </div>\n\n {records.error ? <RefusalNotice error={records.error} /> : null}\n\n {/* A delete or an add the store refused, in the store's own sentence, with\n the one control that can still get the person what they asked for. */}\n {editing.rowError ? (\n <RefusalNotice\n error={editing.rowError}\n actions={\n <div className=\"mt-1 flex gap-1\">\n {onNewRecordForm ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n editing.clearRowError();\n onNewRecordForm();\n }}\n >\n Fill it in on the full form\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={editing.clearRowError}>\n Dismiss\n </Button>\n </div>\n }\n />\n ) : null}\n\n {!records.live ? (\n // Nothing fails silently: a list that stopped updating says so.\n <p className=\"text-xs text-muted-foreground\">{records.liveReason}</p>\n ) : null}\n\n <MatrxDataTable<ReadRow>\n data={rows}\n columns={columns}\n getRowId={(row) => row.id}\n isLoading={loading || records.loading}\n density={host.density ?? \"condensed\"}\n tableId={`records-grid-${tableId}`}\n stickyHeader\n pageSize={pageSize}\n {...(onOpenRecord ? { onRowOpen: (row: ReadRow) => onOpenRecord(row.id) } : {})}\n {...(canWrite\n ? {\n rowActions: (row: ReadRow) => (\n <DeleteRecordButton\n row={row}\n retentionDays={table.data?.retention_days ?? null}\n onDelete={() => editing.remove(row.id)}\n />\n ),\n }\n : {})}\n emptyState={{\n title: \"No records yet\",\n description: rights.write\n ? \"Add the first one and it appears here.\"\n : \"Nothing has been written to this table.\",\n }}\n toolbar={{\n search: true,\n searchPlaceholder: \"Search records\",\n // SCR-2 / SCR-4: PRESENT for an admin, ABSENT for everyone else.\n // There is no third state: this package ships no disabled variant of\n // these controls, so a member cannot be shown a dead one by mistake.\n actions: (\n <>\n {canWrite ? (\n <Button size=\"sm\" disabled={editing.busy} onClick={() => void editing.addRecord()}>\n {editing.busy ? \"Adding…\" : \"New record\"}\n </Button>\n ) : null}\n {rights.admin && onAddField ? <AddFieldButton onClick={onAddField} /> : null}\n </>\n ),\n }}\n />\n\n <Pager\n page={page}\n pageSize={pageSize}\n total={records.data?.total ?? null}\n rows={rows.length}\n onPage={setPage}\n />\n </div>\n );\n}\n\n/**\n * SCR-2. The \"+\" at the far right of the column headers. It exists only for a\n * holder of `admin`: the caller above decides, and there is no disabled variant\n * of this button anywhere in the package.\n */\nfunction AddFieldButton({ onClick }: { onClick: () => void }) {\n return (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onClick}\n aria-label=\"Add a field\"\n title=\"Add a field to this table\"\n >\n +\n </Button>\n );\n}\n\n/**\n * DELETING NAMES THE CONSEQUENCE BEFORE IT HAPPENS. One press asks; the second\n * one does it. The sentence is the store's own truth about this Table — a soft\n * delete that stays reversible for the Table's own retention window (REC-23),\n * or, when the Table declares none, the plain fact that it can be restored.\n */\nfunction DeleteRecordButton({\n row,\n retentionDays,\n onDelete,\n}: {\n row: ReadRow;\n retentionDays: number | null;\n onDelete: () => Promise<unknown>;\n}) {\n const [asking, setAsking] = useState(false);\n if (!asking) {\n return (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Delete this record\"\n title=\"Delete this record\"\n onClick={() => setAsking(true)}\n >\n Delete\n </Button>\n );\n }\n return (\n <span className=\"flex items-center gap-1 text-[11px]\">\n <span className=\"text-muted-foreground\">\n {retentionDays\n ? `Removes it from the table. Restorable for ${retentionDays} days.`\n : \"Removes it from the table. It can be restored from the record's history.\"}\n </span>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => {\n setAsking(false);\n void onDelete();\n }}\n >\n Delete\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setAsking(false)}>\n Keep\n </Button>\n <span className=\"sr-only\">{row.id}</span>\n </span>\n );\n}\n\nfunction Pager({\n page,\n pageSize,\n total,\n rows,\n onPage,\n}: {\n page: number;\n pageSize: number;\n total: number | null;\n rows: number;\n onPage: (page: number) => void;\n}) {\n const from = page * pageSize;\n const last = total === null ? rows < pageSize : from + rows >= total;\n if (page === 0 && last) return null;\n return (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <Button size=\"sm\" variant=\"ghost\" disabled={page === 0} onClick={() => onPage(page - 1)}>\n Previous\n </Button>\n <span>\n {from + 1}–{from + rows}\n {total === null ? \"\" : ` of ${total}`}\n </span>\n <Button size=\"sm\" variant=\"ghost\" disabled={last} onClick={() => onPage(page + 1)}>\n Next\n </Button>\n </div>\n );\n}\n\n/**\n * One Field becomes one column. The header is the Field's own NAME — never its\n * key (`names.ts`) — and the cell is the value, rendered by its parity type and\n * editable in place when an editing session is passed.\n */\nexport function columnForField(field: Field, editing?: GridEditing | null): MatrxColumnDef<ReadRow> {\n const name = fieldName(field);\n return {\n id: field.key,\n header: name,\n label: name,\n accessorFn: (row) => row.document?.[field.key],\n sortable: true,\n filter: editorKindFor(field) === \"select\" || editorKindFor(field) === \"multi_select\" ? \"select\" : \"auto\",\n cell: (row) =>\n editing ? (\n <GridCell field={field} row={row} editing={editing} canWrite />\n ) : (\n renderValue(field, row.document?.[field.key], row.document)\n ),\n headerClassName: \"whitespace-nowrap\",\n // The type is in the header's tooltip rather than a second header row: one\n // row of headers, always — and it is the parity type's own WORD, not a\n // token (`Long text`, never `long_text`).\n className: \"align-top\",\n ...({ title: fieldTypeLabel(field) } as Record<string, unknown>),\n };\n}\n","\"use client\";\n\n// src/ExportMenu.tsx — @ai-matrx/records-ui · SCR-31\n//\n// ANY VIEW EXPORTS AS CSV OR XLSX, CARRYING EXACTLY THE COLUMNS AND ROWS THE\n// READING PRINCIPAL MAY SEE — which is not a filter this component applies. The\n// rows it exports are the rows the READ DOOR returned, and the columns are the\n// Fields the store said APPLY. There is no wider read anywhere in this file, so\n// an export can never contain something the screen did not.\n//\n// The bytes are `@ai-matrx/records`' own `exportCsv` / `exportXlsx`, so an\n// export from a screen and an export from a script are the same file.\n\nimport { useState } from \"react\";\nimport { useFields, useRecords, type Field, type ReadRow, type ReadValue, type Uuid } from \"@ai-matrx/records/react\";\nimport { exportCsv, exportXlsx, type ExportRow } from \"@ai-matrx/records/core\";\nimport { AlchemyMenu } from \"@ai-matrx/alchemy/react\";\nimport { Button, cn } from \"@ai-matrx/design-system\";\nimport { RefusalLine } from \"./Refusal\";\n\nexport interface ExportMenuProps {\n tableId: Uuid;\n /** The rows on screen. Absent means \"this table's first page\", read the same way. */\n rows?: ReadRow[] | undefined;\n /** What the file is called. The table's name by default. */\n label?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * The rows, in the package's own `ExportRow` shape — the value AND its envelope,\n * so the exported cell can carry the store's own absence WORD instead of a blank\n * (VAL-2: \"never asked\" and \"refused\" are different facts, and the file says\n * which).\n */\nfunction toRows(fields: Field[], records: ReadRow[]): ExportRow[] {\n return records.map((record) => {\n const document = record.document ?? {};\n const envelopes = (document[\"_values\"] ?? {}) as Record<string, { absent?: string | null }>;\n const row: ExportRow = {};\n for (const field of fields) {\n const envelope = envelopes[field.key];\n row[field.key] = {\n field_key: field.key,\n value: document[field.key] ?? null,\n absent_reason: (envelope?.absent ?? null) as ReadValue[\"absent_reason\"],\n } as ReadValue;\n }\n return row;\n });\n}\n\nfunction download(name: string, mime: string, bytes: BlobPart) {\n const url = URL.createObjectURL(new Blob([bytes], { type: mime }));\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = name;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\nexport function ExportMenu({ tableId, rows, label, className }: ExportMenuProps) {\n const fields = useFields(tableId);\n const page = useRecords(tableId, { pageSize: 500 });\n const [failure, setFailure] = useState<string | null>(null);\n\n const records = rows ?? page.data?.rows ?? [];\n const name = label ?? \"records\";\n\n if (fields.error) return <RefusalLine error={fields.error} className={className} />;\n if (!rows && page.error) return <RefusalLine error={page.error} className={className} />;\n if (!fields.data || (!rows && !page.data)) {\n // The columns ARE the Fields and the rows are the read door's answer, so\n // there is no export to offer until both have arrived. A button that\n // produced a headerless or rowless file would be worse than a moment's wait.\n return <span className={cn(\"text-xs text-muted-foreground\", className)}>Reading this table…</span>;\n }\n\n const exported = () => toRows(fields.data ?? [], records);\n\n return (\n <div className={cn(\"flex items-center gap-1\", className)}>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => download(`${name}.csv`, \"text/csv;charset=utf-8\", exportCsv(fields.data ?? [], exported()))}\n >\n CSV\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n try {\n void exportXlsx(fields.data ?? [], exported(), name).then((bytes) =>\n download(\n `${name}.xlsx`,\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n bytes as unknown as BlobPart,\n ),\n );\n } catch (thrown) {\n // Nothing fails silently: say what broke and what to do instead.\n setFailure(\n `The spreadsheet could not be written (${thrown instanceof Error ? thrown.message : String(thrown)}). ` +\n `The CSV beside this button carries the same rows.`,\n );\n }\n }}\n >\n XLSX\n </Button>\n {/* The same menu every other surface on the platform carries. */}\n <AlchemyMenu\n label={name}\n sourceId={`records:${tableId}`}\n size=\"xs\"\n json={() => records.map((r) => r.document)}\n human={() => exportCsv(fields.data ?? [], exported())}\n />\n {failure ? <p className=\"text-xs text-destructive\">{failure}</p> : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/ImportWizard.tsx — @ai-matrx/records-ui · SCR-10, SCR-N-7\n//\n// MAP A FILE'S COLUMNS ONTO FIELDS, PREVIEW THE ROWS IT WILL WRITE, AND OFFER\n// ANY UNMAPPED COLUMN AS A FIELD PROPOSAL.\n//\n// The parsing and the matching are `@ai-matrx/records`' own `importCsv` /\n// `importXlsx`, so a file imported from a screen and a file imported from a\n// script land identically. An unmapped column is NEVER dropped quietly: it is\n// listed, and \"add this as a field\" sits beside it under the same right as the\n// grid's \"+\" (SCR-N-7) — absent, not disabled, for anybody else.\n//\n// Every row is written through the ONE write door, one at a time, and a row the\n// store refuses keeps its own refusal beside it. A partial import that pretended\n// to be a whole one is the failure this screen exists to make impossible.\n\nimport { useState } from \"react\";\nimport { useFields, useRecordMutation, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport { importCsv, importXlsx, type ParsedImport } from \"@ai-matrx/records/core\";\nimport { Badge, Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldName } from \"./names\";\n\nexport interface ImportWizardProps {\n tableId: Uuid;\n /** SCR-N-7: what \"add this as a field\" does. Absent means the offer is not made. */\n onProposeField?: ((header: string) => void) | undefined;\n onDone?: ((written: number) => void) | undefined;\n className?: string | undefined;\n}\n\ninterface RowOutcome {\n index: number;\n recordId: string | null;\n refusal: string | null;\n}\n\nexport function ImportWizard({ tableId, onProposeField, onDone, className }: ImportWizardProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const mutation = useRecordMutation();\n const [parsed, setParsed] = useState<ParsedImport | null>(null);\n const [outcomes, setOutcomes] = useState<RowOutcome[]>([]);\n const [reading, setReading] = useState<string | null>(null);\n\n const take = async (file: File) => {\n setReading(null);\n setOutcomes([]);\n try {\n const declared = fields.data ?? [];\n const result = file.name.toLowerCase().endsWith(\".xlsx\")\n ? await importXlsx(declared, await file.arrayBuffer())\n : importCsv(declared, await file.text());\n setParsed(result);\n } catch (thrown) {\n setReading(`That file could not be read: ${thrown instanceof Error ? thrown.message : String(thrown)}`);\n }\n };\n\n const write = async () => {\n if (!parsed) return;\n const done: RowOutcome[] = [];\n for (const [index, row] of parsed.rows.entries()) {\n const id = await mutation.write({ table_id: tableId, data: row });\n done.push({ index, recordId: id, refusal: id ? null : (mutation.error?.message ?? \"The store refused this row.\") });\n setOutcomes([...done]);\n }\n onDone?.(done.filter((d) => d.recordId).length);\n };\n\n const written = outcomes.filter((o) => o.recordId).length;\n const refused = outcomes.filter((o) => !o.recordId).length;\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Import</span>\n <span className=\"text-muted-foreground\">{table.data?.name}</span>\n {/* A file cannot be mapped before the store has said which Fields\n apply, so the chooser waits rather than matching against nothing and\n reporting every column as unmapped. It ALSO waits for the Table\n itself: the rights that decide whether \"add this as a field\" is\n offered are read from the Table, and a chooser that opened first\n could show an admin a mapping with the offer missing — a control\n silently absent for the one person who may use it. Both answers, or\n no chooser.\n (Found by the suite under load, 2026-09-18: the Fields arrived\n before the Table and the offer was not there.) */}\n {fields.data && table.data ? (\n <input\n type=\"file\"\n accept=\".csv,.xlsx\"\n aria-label=\"Choose a file to import\"\n className=\"ml-auto text-xs\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void take(file);\n }}\n />\n ) : (\n <span className=\"ml-auto text-muted-foreground\">\n {fields.data ? \"Reading this table…\" : \"Reading this table's fields…\"}\n </span>\n )}\n </div>\n\n {reading ? <p className=\"text-destructive\">{reading}</p> : null}\n\n {parsed ? (\n <>\n {/* The mapping, column by column, with nothing hidden. */}\n <ul className=\"flex flex-wrap gap-1\">\n {parsed.columns.map((column) => (\n <li key={column.header}>\n <Badge variant={column.field ? \"secondary\" : \"outline\"} className=\"gap-1 text-[11px] font-normal\">\n {column.header}\n <span className=\"opacity-60\">→</span>\n {column.field ? (\n column.field.label || column.field.key\n ) : (\n <span className=\"text-destructive\">no field</span>\n )}\n {/* SCR-N-7, and it is gated by the SAME right as the grid's \"+\". */}\n {!column.field && rights.admin && onProposeField ? (\n <button\n type=\"button\"\n className=\"underline underline-offset-2\"\n onClick={() => onProposeField(column.header)}\n >\n add as a field\n </button>\n ) : null}\n </Badge>\n </li>\n ))}\n </ul>\n\n {parsed.unmapped.length > 0 ? (\n <p className=\"text-muted-foreground\">\n {parsed.unmapped.length} column{parsed.unmapped.length === 1 ? \"\" : \"s\"} match no Field and{\" \"}\n {rights.admin && onProposeField\n ? \"can be added as fields above.\"\n : \"will not be written. Nothing is dropped quietly: the columns are listed above.\"}\n </p>\n ) : null}\n\n <Separator />\n\n {/* The preview: exactly the rows the write door will be handed. */}\n <p className=\"text-muted-foreground\">\n {parsed.rows.length} row{parsed.rows.length === 1 ? \"\" : \"s\"} to write\n </p>\n <div className=\"max-h-56 overflow-auto rounded border\">\n <table className=\"w-full\">\n <thead className=\"sticky top-0 bg-muted\">\n <tr>\n {(fields.data ?? []).map((field) => (\n <th key={field.id} className=\"px-2 py-1 text-left font-medium\">\n {fieldName(field)}\n </th>\n ))}\n <th className=\"px-2 py-1 text-left font-medium\">Result</th>\n </tr>\n </thead>\n <tbody>\n {parsed.rows.slice(0, 50).map((row, index) => {\n const outcome = outcomes.find((o) => o.index === index);\n return (\n <tr key={index} className=\"border-t\">\n {(fields.data ?? []).map((field) => (\n <td key={field.id} className=\"max-w-40 truncate px-2 py-1\">\n {row[field.key] ?? \"\"}\n </td>\n ))}\n <td className=\"px-2 py-1\">\n {outcome?.recordId ? (\n <span className=\"text-muted-foreground\">written</span>\n ) : outcome?.refusal ? (\n // The store's own sentence, on the row it refused.\n <span className=\"text-destructive\">{outcome.refusal}</span>\n ) : null}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {mutation.error && outcomes.length === 0 ? <RefusalNotice error={mutation.error} /> : null}\n\n <div className=\"flex items-center gap-2\">\n <Button size=\"sm\" disabled={mutation.saving || !rights.write} onClick={() => void write()}>\n {mutation.saving ? \"Writing…\" : `Write ${parsed.rows.length} rows`}\n </Button>\n {outcomes.length > 0 ? (\n <span className=\"text-muted-foreground\">\n {written} written{refused > 0 ? `, ${refused} refused — each one says why on its row` : \"\"}\n </span>\n ) : null}\n </div>\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/CustomFieldsSection.tsx — @ai-matrx/records-ui · SCR-12\n//\n// THE ONE LINE A STANDARD ENTITY PAGE ADDS.\n//\n// <CustomFieldsSection entityToken=\"agent\" recordId={agent.id} />\n//\n// A standard entity's page grows its organization's custom Fields in one\n// section, resolved from the Field records, WITH NO PER-ENTITY CODE. That is the\n// whole point: nobody writes a section per entity, and an organization that adds\n// a field to Agents sees it on every Agent page the same afternoon.\n//\n// FLD-8 / REC-34: a Field that extends a standard entity carries\n// `entity_definition_id`, and only entity and detail table types carry custom\n// fields at all. When a token carries none, this renders NOTHING — an empty\n// titled box on every page in the product would be worse than silence, and the\n// section says so in its own docs rather than on the screen.\n\nimport { useMemo, useState } from \"react\";\nimport { useFields, useRecord, useTable, useTables, type Uuid } from \"@ai-matrx/records/react\";\nimport { Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalLine } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { ProvenanceBadge, renderValue } from \"./values\";\nimport { fieldName } from \"./names\";\n\nexport interface CustomFieldsSectionProps {\n /**\n * The Table the Fields extend. For a standard entity this is the Table record\n * that stands for that entity — the host passes it, because which entity a\n * page is showing is the page's own fact.\n *\n * A page that knows the entity's TOKEN rather than its id passes `entityToken`\n * instead, and this section resolves it: an entity page must not have to run\n * a lookup of its own to add one line.\n */\n tableId?: Uuid | undefined;\n /** The entity's registered token (REC-33), e.g. `party`. Resolved to its Table. */\n entityToken?: string | undefined;\n recordId: Uuid;\n /** The heading. One row, no subtitle restating it. */\n title?: string | undefined;\n className?: string | undefined;\n}\n\nexport function CustomFieldsSection({\n tableId,\n entityToken,\n recordId,\n title = \"Custom fields\",\n className,\n}: CustomFieldsSectionProps) {\n // A token is resolved through the same `tableList` door everything else uses.\n // A token this organization's store does not know is NOT an error a person\n // must act on — it means the entity has no Table here yet, and the section is\n // absent exactly as it is when the Table has no custom Fields.\n const all = useTables();\n const resolved = useMemo<Uuid | null>(() => {\n if (tableId) return tableId;\n if (!entityToken) return null;\n return all.data?.find((t) => t.slug === entityToken)?.id ?? null;\n }, [tableId, entityToken, all.data]);\n\n return resolved ? (\n <ResolvedCustomFields\n tableId={resolved}\n recordId={recordId}\n title={title}\n className={className}\n />\n ) : null;\n}\n\nfunction ResolvedCustomFields({\n tableId,\n recordId,\n title,\n className,\n}: {\n tableId: Uuid;\n recordId: Uuid;\n title: string;\n className?: string | undefined;\n}) {\n const fields = useFields(tableId);\n const record = useRecord(recordId);\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [editing, setEditing] = useState(false);\n\n // FLD-8: a Field that EXTENDS a standard entity is one whose\n // `entity_definition_id` names that entity's Table. That is the whole test —\n // there is no per-entity list of \"which fields are custom\" anywhere.\n const custom = useMemo(\n () => (fields.data ?? []).filter((field) => field.entity_definition_id === tableId),\n [fields.data, tableId],\n );\n\n // Nothing to grow: render nothing at all rather than an empty titled box.\n if (!fields.loading && custom.length === 0) return null;\n if (fields.error) return <RefusalLine error={fields.error} className={className} />;\n\n const document = record.data?.document;\n\n return (\n <section className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">{title}</h3>\n <span className=\"text-muted-foreground\">{custom.length}</span>\n {rights.write ? (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto\" onClick={() => setEditing((e) => !e)}>\n {editing ? \"Done\" : \"Edit\"}\n </Button>\n ) : null}\n </div>\n <Separator />\n {editing ? (\n <RecordForm\n tableId={tableId}\n recordId={recordId}\n onSaved={() => {\n setEditing(false);\n record.reload();\n }}\n />\n ) : (\n <dl className=\"grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5\">\n {custom.map((field) => (\n <div key={field.id} className=\"contents\">\n <dt className=\"flex items-baseline gap-1 truncate text-muted-foreground\">\n {fieldName(field)}\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </dt>\n <dd className=\"min-w-0\">{renderValue(field, document?.[field.key], document)}</dd>\n </div>\n ))}\n </dl>\n )}\n </section>\n );\n}\n","\"use client\";\n\n// src/RecordForm.tsx — @ai-matrx/records-ui · SCR-N-1\n//\n// THE GENERIC CREATE / EDIT FORM, RESOLVED FROM THE FIELD RECORDS. Before it,\n// every create and edit form in the product was hand-written per feature, which\n// is why a custom table could not open a record at all.\n//\n// Two honest halves:\n// · BEFORE the write, the mirror (`predictWriteRefusals`) says what the store\n// is about to refuse, in the store's own sentence. It is not validation —\n// the store validates — it just says it half a second earlier.\n// · AFTER the write, whatever the store said is shown verbatim, including the\n// conflict object when somebody else wrote first.\n//\n// It never blocks a save on its own opinion: the mirror's sentences are shown,\n// and the write is still attempted, because the store is the one that decides.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport {\n useFields,\n useRecord,\n useRecordMutation,\n type Field,\n type RecordDocument,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport { predictWriteRefusals } from \"@ai-matrx/records/core\";\nimport { Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { FieldControl, FieldLabel } from \"./editors\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { ProvenanceBadge } from \"./values\";\nimport { useRecordVersion } from \"./systemTable\";\n\nexport interface RecordFormProps {\n tableId: Uuid;\n /** Absent means \"create\". Present means \"edit that record\". */\n recordId?: Uuid | undefined;\n /** FLD-10: which Fields apply is the store's decision, and it takes the record type. */\n recordType?: string | undefined;\n onSaved?: ((recordId: Uuid) => void) | undefined;\n onCancel?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function RecordForm({\n tableId,\n recordId,\n recordType,\n onSaved,\n onCancel,\n className,\n}: RecordFormProps) {\n const host = useRecordsUi();\n const fields = useFields(tableId, recordType);\n const existing = useRecord(recordId ?? null);\n const mutation = useRecordMutation();\n const [draft, setDraft] = useState<Record<string, unknown>>({});\n const [touched, setTouched] = useState(false);\n // REC-9: the version this form LOADED, so a second writer is TOLD rather than\n // overwritten. The read door answers documents, never versions.\n const loadedVersion = useRecordVersion(recordId ?? null);\n\n // The record's own document is the starting draft. A form that started empty\n // over an existing record would silently propose blanking every field.\n useEffect(() => {\n const document = existing.data?.document;\n if (document) setDraft({ ...document });\n }, [existing.data?.record_id, loadedVersion]);\n\n const document = useMemo<RecordDocument>(() => {\n const out: RecordDocument = {};\n for (const [key, value] of Object.entries(draft)) {\n if (key.startsWith(\"_\")) continue;\n if (value !== undefined) out[key] = value;\n }\n return out;\n }, [draft]);\n\n const predicted = useMemo(\n () => (fields.data ? predictWriteRefusals({ fields: fields.data, document, ...(recordType ? { recordType } : {}) }) : []),\n [fields.data, document, recordType],\n );\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (existing.error) return <RefusalNotice error={existing.error} className={className} />;\n\n const save = async () => {\n setTouched(true);\n if (recordId) {\n const version = loadedVersion;\n const moved = await mutation.update({\n record_id: recordId,\n patch: document,\n ...(version === null ? {} : { expectedVersion: version }),\n });\n if (moved !== null) {\n host.notify?.success(\"Saved\");\n existing.reload();\n onSaved?.(recordId);\n }\n return;\n }\n const written = await mutation.write({ table_id: tableId, data: document });\n if (written) {\n host.notify?.success(\"Saved\");\n onSaved?.(written);\n }\n };\n\n return (\n <form\n className={cn(\"flex min-w-0 flex-col gap-3\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n void save();\n }}\n >\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {(fields.data ?? []).map((field) => (\n <FieldRow\n key={field.id}\n field={field}\n value={draft[field.key]}\n document={existing.data?.document}\n problems={touched ? predicted.filter((p) => p.field_key === field.key) : []}\n onChange={(value) => setDraft((d) => ({ ...d, [field.key]: value }))}\n />\n ))}\n </div>\n\n {/* A refusal with no field of its own — a size or envelope refusal. */}\n {touched\n ? predicted\n .filter((p) => !p.field_key)\n .map((p) => (\n <p key={p.message} className=\"text-xs text-destructive\">\n {p.message}\n </p>\n ))\n : null}\n\n {mutation.error ? (\n <RefusalNotice\n error={mutation.error}\n {...(mutation.conflict\n ? {\n actions: (\n <div className=\"mt-1 space-y-1\">\n {/* The conflict, field by field, as the store sent it. */}\n {Object.entries(mutation.conflict.contested_fields).map(([key, theirs]) => (\n <p key={key} className=\"font-mono text-[11px]\">\n {key}: yours {JSON.stringify(draft[key])} · theirs {JSON.stringify(theirs)}\n </p>\n ))}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n existing.reload();\n mutation.clearConflict();\n }}\n >\n Take theirs and start again\n </Button>\n </div>\n ),\n }\n : {})}\n />\n ) : null}\n\n <Separator />\n <div className=\"flex items-center gap-2\">\n <Button type=\"submit\" size=\"sm\" disabled={mutation.saving}>\n {mutation.saving ? \"Saving…\" : recordId ? \"Save\" : \"Create\"}\n </Button>\n {onCancel ? (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n ) : null}\n </div>\n </form>\n );\n}\n\nfunction FieldRow({\n field,\n value,\n document,\n problems,\n onChange,\n}: {\n field: Field;\n value: unknown;\n document: RecordDocument | undefined;\n problems: Array<{ message: string }>;\n onChange: (value: unknown) => void;\n}) {\n const id = `field-${field.id}`;\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <FieldLabel field={field} htmlFor={id}>\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </FieldLabel>\n <FieldControl field={field} value={value} onChange={onChange} id={id} />\n {problems.map((problem) => (\n <p key={problem.message} className=\"text-xs text-destructive\">\n {problem.message}\n </p>\n ))}\n </div>\n );\n}\n","\"use client\";\n\n// src/systemTable.ts — @ai-matrx/records-ui\n//\n// THE PACKAGE'S OWN TABLES, MADE THE WAY EVERY OTHER TABLE IS MADE.\n//\n// A saved view, a queued action, a comment and a form are all RECORDS. They are\n// not a second storage system bolted onto the side of the record store, and\n// they are not rows this package writes into `platform.*` behind the store's\n// back — the data source port this package's client speaks has no insert on it\n// at all, on purpose. So each of them is an ordinary Table in the organization's\n// own store, declared once, through the store's own doors:\n//\n// 1. REC-1 — a Table has to live somewhere, and a Home is an ordinary record\n// in the person kernel, so a Home is written first (`record_write`).\n// 2. `table_declare` declares the Table under that Home.\n// 3. Each Field is a record in the field kernel carrying the new Table's id.\n//\n// That is exactly the sequence the store forced on us: declaring a Table with\n// no Home is refused by `custom._table_shape_guard` with \"a table has to live\n// somewhere - give it a home\". Nothing here works around a guard; it obeys one.\n//\n// WHAT THIS BUYS: a saved view is readable, exportable, historied, commentable\n// and agent-writable by every other component in this package, for free,\n// because it is a record like any other. An agent can write a whole view — or a\n// whole form — with one `record_write`.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport type { RecordsError, Uuid } from \"@ai-matrx/records\";\n\n/** One Field of a package-owned Table, in the store's own words. */\nexport interface SystemFieldSpec {\n key: string;\n label: string;\n /** FLD-1: one of the five behaviours. `text` covers the json-ish ones too. */\n type: \"text\" | \"range\" | \"list\" | \"relation\" | \"formula\";\n sort: number;\n required?: boolean;\n multi?: boolean;\n config?: Record<string, unknown>;\n}\n\nexport interface SystemTableSpec {\n /** The token this Table is addressed by. Every package table starts `records_ui_`. */\n slug: string;\n name: string;\n labelSingular: string;\n labelPlural: string;\n titleField: string;\n fields: SystemFieldSpec[];\n}\n\n/**\n * One in-flight declaration per (organization, slug), so two components that\n * mount at the same moment do not declare the same Table twice. Keyed by the\n * organization, never global: two organizations in two tabs never share one.\n */\nconst inFlight = new Map<string, Promise<Uuid>>();\n\n/** Find this organization's copy of a package-owned Table, declaring it the first time. */\nexport async function ensureSystemTable(\n client: RecordsClient,\n spec: SystemTableSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const cacheKey = `${client.config.organizationId}:${spec.slug}`;\n const running = inFlight.get(cacheKey);\n if (running) {\n try {\n return { ok: true, data: await running };\n } catch {\n inFlight.delete(cacheKey);\n }\n }\n\n const tables = await client.tableList();\n if (!tables.ok) return tables;\n const found = tables.data.find((t) => t.slug === spec.slug);\n if (found) {\n // A PACKAGE TABLE GROWS. A later version of this package declares a Field\n // the organization's copy was made without, and an organization that got\n // its copy first would otherwise be the one where the new Field silently\n // does not exist. So every load reconciles: the Fields in the spec that\n // the Table has not got are added, through the same two writes a Field is\n // always made with. Nothing is ever renamed or removed here.\n const grown = await addMissingFields(client, spec, found.id);\n if (!grown.ok) return grown;\n // A PACKAGE TABLE ALSO CHANGES SHAPE. Adding what is missing is only half\n // of level: a Field the organization already holds can carry a DIFFERENT\n // behaviour from the one this version of the package declares, and then\n // every write of that Field is refused by the store for a reason the\n // person cannot act on. See `reconcileFieldShapes`.\n const levelled = await reconcileFieldShapes(client, spec, found.id);\n if (!levelled.ok) return levelled;\n return { ok: true, data: found.id };\n }\n\n let settle: (id: Uuid) => void = () => undefined;\n let fail: (reason: unknown) => void = () => undefined;\n const pending = new Promise<Uuid>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n // The refusal is RETURNED, below, as this package's never-throw envelope.\n // Without this the same refusal is also an unhandled promise rejection on\n // every host that never happened to have a second caller waiting here — a\n // red console (and, under a test runner, a failed run) for a refusal that\n // was in fact reported properly.\n pending.catch(() => undefined);\n inFlight.set(cacheKey, pending);\n\n const declared = await declare(client, spec);\n if (declared.ok) settle(declared.data);\n else {\n fail(declared.error);\n inFlight.delete(cacheKey);\n }\n return declared;\n}\n\n/**\n * The Fields of `spec` the organization's copy of this Table has not got yet,\n * added the way a Field is always added: the Table's own declaration first\n * (REC-1 — the Table declares its fields), then the definition in the field\n * kernel. Idempotent, and a no-op for a Table that is already level.\n */\nasync function addMissingFields(\n client: RecordsClient,\n spec: SystemTableSpec,\n tableId: Uuid,\n): Promise<{ ok: true; data: true } | { ok: false; error: RecordsError }> {\n const held = await client.fields({ table_id: tableId });\n if (!held.ok) return held;\n const have = new Set(held.data.map((f) => f.key));\n const missing = spec.fields.filter((f) => !have.has(f.key));\n if (missing.length === 0) return { ok: true, data: true };\n\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n const declaration = [...held.data.map((f) => ({ name: f.key })), ...missing.map((f) => ({ name: f.key }))];\n const redeclared = await client.recordUpdate({ record_id: tableId, patch: { fields: declaration } });\n if (!redeclared.ok) return redeclared;\n\n for (const field of missing) {\n const written = await client.recordWrite({\n table_id: fieldKernel.data,\n data: fieldDocument(field, tableId),\n });\n if (!written.ok) return written;\n }\n return { ok: true, data: true };\n}\n\n/**\n * THE FIELD THAT CHANGED BEHAVIOUR UNDER AN ORGANIZATION THAT ALREADY HAD ONE.\n *\n * Found live on 2026-09-19: `ActionInbox` could not record an outcome in one\n * organization, because that organization's copy of `records_ui_action` held\n * `status` as a `relation` while this package declares it `text`. Every write\n * of an outcome was refused `22P02 invalid input syntax for type uuid: \"open\"`\n * — the store was right, the package was the one out of date, and\n * `addMissingFields` never looked at a Field it already had.\n *\n * So the reconciliation is two questions, not one: which Fields are MISSING,\n * and which Fields are THERE WITH THE WRONG SHAPE. Shape here means exactly the\n * two properties that decide what a value is made of and therefore what the\n * store will accept — the behaviour (FLD-1) and whether it is multi (FLD-2).\n *\n * WHAT IS DELIBERATELY NOT RECONCILED: label, sort, required, config. Those are\n * presentation and policy, an organization may legitimately have moved them,\n * and none of them can make a write fail. Nothing is ever renamed or removed\n * here — this only ever moves a Field back onto the behaviour the package's own\n * components write against.\n */\nasync function reconcileFieldShapes(\n client: RecordsClient,\n spec: SystemTableSpec,\n tableId: Uuid,\n): Promise<{ ok: true; data: true } | { ok: false; error: RecordsError }> {\n const held = await client.fields({ table_id: tableId });\n if (!held.ok) return held;\n const byKey = new Map(held.data.map((f) => [f.key, f]));\n\n for (const field of spec.fields) {\n const have = byKey.get(field.key);\n if (!have) continue; // `addMissingFields` owns that half and already ran.\n const patch: Record<string, unknown> = {};\n if (have.type !== field.type) patch.type = field.type;\n if (have.multi !== (field.multi ?? false)) patch.multi = field.multi ?? false;\n if (Object.keys(patch).length === 0) continue;\n\n // The Field definition is an ordinary record in the field kernel, so it is\n // levelled through the ordinary write door — never a second storage path.\n const written = await client.recordUpdate({ record_id: have.id, patch });\n // A Field this package cannot level is a Table whose writes will keep being\n // refused, so the refusal is reported rather than swallowed.\n if (!written.ok) return written;\n }\n return { ok: true, data: true };\n}\n\n/** One Field record's document — the same one whether it is declared with the Table or added later. */\nfunction fieldDocument(field: SystemFieldSpec, tableId: Uuid): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: field.type,\n sort: field.sort,\n required: field.required ?? false,\n multi: field.multi ?? false,\n dated: false,\n rules: [],\n config: field.config ?? {},\n source: \"manual\",\n depends_on: [],\n sensitivity: \"internal\",\n source_config: {},\n context_policy: \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n };\n}\n\nasync function declare(\n client: RecordsClient,\n spec: SystemTableSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const personKernel = await client.personKernelId();\n if (!personKernel.ok) return personKernel;\n\n const home = await client.recordWrite({\n table_id: personKernel.data,\n data: { name: `${spec.name} Home` },\n });\n if (!home.ok) return home;\n\n const table = await client.tableDeclare({\n homeId: home.data,\n spec: {\n name: spec.name,\n slug: spec.slug,\n type: \"entity\",\n label_singular: spec.labelSingular,\n label_plural: spec.labelPlural,\n display: \"list\",\n weight: \"light\",\n ordered: false,\n row_order: \"manual\",\n title_field: spec.titleField,\n retention_days: 365,\n // AGT-1: the whole point is that an agent writes a view or a form in one\n // call, so a package-owned Table is agent-writable by declaration.\n agent_writable: true,\n default_sort: [{ field: spec.titleField, direction: \"asc\" }],\n fields: spec.fields.map((f) => ({ name: f.key })),\n },\n });\n if (!table.ok) return table;\n\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n for (const field of spec.fields) {\n const written = await client.recordWrite({\n table_id: fieldKernel.data,\n data: fieldDocument(field, table.data),\n });\n // A Field the store refused is a Table that would quietly lose a column, so\n // it is reported rather than skipped.\n if (!written.ok) return written;\n }\n\n return { ok: true, data: table.data };\n}\n\nexport interface UseSystemTableState {\n tableId: Uuid | null;\n loading: boolean;\n error: RecordsError | null;\n}\n\n/** The hook every package-owned component opens with. */\nexport function useSystemTable(spec: SystemTableSpec): UseSystemTableState {\n const client = useRecordsClient();\n const [state, setState] = useState<UseSystemTableState>({ tableId: null, loading: true, error: null });\n const slug = spec.slug;\n const stable = useMemo(() => spec, [slug]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n let cancelled = false;\n setState({ tableId: null, loading: true, error: null });\n void ensureSystemTable(client, stable).then((result) => {\n if (cancelled) return;\n setState(\n result.ok\n ? { tableId: result.data, loading: false, error: null }\n : { tableId: null, loading: false, error: result.error },\n );\n });\n return () => {\n cancelled = true;\n };\n }, [client, stable]);\n\n return state;\n}\n\n/**\n * THE VERSION OF THE ONE RECORD BEING EDITED.\n *\n * The read door (`custom.read_records`) answers documents, never versions —\n * deliberately, because a version is a fact about the row and not about what\n * this reader may see. A screen that saves optimistically still needs the\n * version it LOADED, so it reads it here, for the one record it is editing and\n * never for a list, through `custom.io_revisions`.\n *\n * `null` is an honest answer: the save then carries no expected version and is\n * the store's ordinary last-writer-wins write. It is never a guess.\n */\nexport function useRecordVersion(recordId: Uuid | null | undefined): number | null {\n const client = useRecordsClient();\n const [version, setVersion] = useState<number | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setVersion(null);\n if (!recordId) return;\n void client.revisions({ record_id: recordId }).then((answered) => {\n if (cancelled || !answered.ok) return;\n const newest = answered.data.reduce<number | null>(\n (held, row) => (held === null || row.version > held ? row.version : held),\n null,\n );\n setVersion(newest);\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId]);\n\n return version;\n}\n","\"use client\";\n\n// src/FieldEditor.tsx — @ai-matrx/records-ui · SCR-9\n//\n// ONE FIELD'S TYPE, OPTIONS, VALIDATION RULE AND SENSITIVITY, FROM THE SAME\n// PANEL THAT CREATED IT.\n//\n// The thirteen types a person picks are the store's own parity types, read from\n// `PARITY_FIELD_TYPES` — generated from `custom.parity_field_types()`, never a\n// list typed here. Each one carries the store's own \"made of\" sentence, so the\n// person choosing sees what the platform will actually store.\n//\n// FLD-1/2/3 are kept separate on this panel exactly as the store keeps them: a\n// BEHAVIOUR, then modifiers, then Rules. A constraint is never a behaviour, and\n// this panel has no place to type one as if it were.\n\nimport { useMemo, useState } from \"react\";\nimport {\n KERNEL_TABLES,\n PARITY_FIELD_TYPES,\n type Field,\n type FieldRule,\n type ParityFieldType,\n type Uuid,\n} from \"@ai-matrx/records\";\nimport { useRecordMutation, useTable } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n Button,\n Checkbox,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Separator,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { PARITY_LABEL, PARITY_MADE_OF, editorKindFor } from \"./parity\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldName } from \"./names\";\n\nconst RULE_KINDS: FieldRule[\"kind\"][] = [\n \"min\",\n \"max\",\n \"length\",\n \"pattern\",\n \"equals_field\",\n \"differs_from_field\",\n];\n\nconst SENSITIVITIES = [\"public\", \"internal\", \"restricted\", \"secret\"] as const;\n\nexport interface FieldEditorProps {\n tableId: Uuid;\n /** The Field being edited. Absent means a new one. */\n field?: Field | undefined;\n onSaved?: (() => void) | undefined;\n onCancel?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function FieldEditor({ tableId, field, onSaved, onCancel, className }: FieldEditorProps) {\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const mutation = useRecordMutation();\n const [draft, setDraft] = useState<Record<string, unknown>>(() => ({\n key: field?.key ?? \"\",\n label: field?.label ?? \"\",\n type: field?.type ?? \"text\",\n multi: field?.multi ?? false,\n dated: field?.dated ?? false,\n required: field?.required ?? false,\n format: field?.format ?? null,\n unit: field?.unit ?? null,\n config: field?.config ?? {},\n rules: field?.rules ?? [],\n sensitivity: field?.sensitivity ?? \"internal\",\n relation_target: field?.relation_target ?? null,\n sort: field?.sort ?? 100,\n source: field?.source ?? \"manual\",\n applies_to_types: field?.applies_to_types ?? [],\n context_policy: field?.context_policy ?? \"include\",\n depends_on: [],\n source_config: {},\n entity_definition_id: tableId,\n }));\n\n const parity = useMemo<ParityFieldType | \"text\" | \"number\" | \"long_text\">(\n () => editorKindFor({ ...(field ?? {}), ...draft } as Field) as ParityFieldType,\n [draft, field],\n );\n\n // SCR-4: a person who does not administer the table never sees this panel.\n if (!rights.admin) {\n return (\n <p className={cn(\"text-xs text-muted-foreground\", className)}>\n {/* Honest, not dead: the reason, in a sentence. */}\n {rights.reason}\n </p>\n );\n }\n\n const set = (patch: Record<string, unknown>) => setDraft((d) => ({ ...d, ...patch }));\n\n /** The parity type a person picks decides behaviour + format + unit together. */\n const pickParity = (next: string) => {\n const row = PARITY_FIELD_TYPES.find((p) => p.parity_type === next);\n if (!row) {\n set({ type: next === \"long_text\" ? \"text\" : next === \"number\" ? \"range\" : \"text\", format: null, config: {} });\n return;\n }\n const patch: Record<string, unknown> = { type: row.behavior, config: { ...(draft[\"config\"] as object) } };\n if ([\"email\", \"phone\", \"url\", \"currency\", \"percent\", \"datetime\"].includes(next)) patch[\"format\"] = next;\n if (next === \"percent\") patch[\"unit\"] = \"%\";\n if (next === \"datetime\") patch[\"config\"] = { kind: \"date\" };\n if (next === \"multi_select\") patch[\"multi\"] = true;\n if (next === \"select\") patch[\"multi\"] = false;\n if (next === \"member\" || next === \"attachment\") {\n patch[\"config\"] = { ...(draft[\"config\"] as object), parity: next };\n }\n set(patch);\n };\n\n const save = async () => {\n // A Field is a Record (REC-25), so it is written through the one write door\n // like everything else — there is no field-specific write path.\n const written = field\n ? await mutation.update({ record_id: field.id, patch: draft })\n : await mutation.write({ table_id: FIELD_KERNEL, data: draft });\n if (written !== null) onSaved?.();\n };\n\n const rules = (draft[\"rules\"] as FieldRule[]) ?? [];\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-3 text-xs\", className)}>\n {/* One row of header: what this is, and nothing restating it. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{field ? `Field · ${fieldName(field)}` : \"New field\"}</span>\n <span className=\"ml-auto text-muted-foreground\">{table.data?.name}</span>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Label</Label>\n <BasicInput value={String(draft[\"label\"] ?? \"\")} onChange={(e) => set({ label: e.target.value })} />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Key</Label>\n <BasicInput\n value={String(draft[\"key\"] ?? \"\")}\n disabled={Boolean(field)}\n onChange={(e) => set({ key: e.target.value })}\n />\n </label>\n\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Type</Label>\n <Select value={String(parity)} onValueChange={pickParity}>\n <SelectTrigger size=\"sm\" aria-label=\"Field type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"text\">Text</SelectItem>\n <SelectItem value=\"long_text\">Long text</SelectItem>\n <SelectItem value=\"number\">Number</SelectItem>\n {PARITY_FIELD_TYPES.map((row) => (\n <SelectItem key={row.parity_type} value={row.parity_type}>\n {/* The label, and under it the store's own sentence about what\n this type is MADE OF — the person choosing sees what the\n platform will actually store, not just a word. */}\n <span className=\"flex flex-col\">\n <span>{PARITY_LABEL[row.parity_type]}</span>\n <span className=\"text-[11px] text-muted-foreground\">{row.made_of}</span>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {/* The store's own sentence about what this type is MADE OF. */}\n <p className=\"text-[11px] text-muted-foreground\">{PARITY_MADE_OF[String(parity)] ?? \"\"}</p>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Sensitivity</Label>\n <Select value={String(draft[\"sensitivity\"] ?? \"internal\")} onValueChange={(v) => set({ sensitivity: v })}>\n <SelectTrigger size=\"sm\" aria-label=\"Sensitivity\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSITIVITIES.map((word) => (\n <SelectItem key={word} value={word}>\n {word}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[11px] text-muted-foreground\">\n AGT-7: a ceiling a merge field's delivery can never widen.\n </p>\n </div>\n </div>\n\n {/* FLD-2: modifiers, and they are NOT a second behaviour. */}\n <div className=\"flex flex-wrap items-center gap-4\">\n <label className=\"flex items-center gap-1.5\">\n <Checkbox checked={draft[\"multi\"] === true} onCheckedChange={(v) => set({ multi: v === true })} />\n Holds many values\n </label>\n <label className=\"flex items-center gap-1.5\">\n <Checkbox checked={draft[\"dated\"] === true} onCheckedChange={(v) => set({ dated: v === true })} />\n Values carry their own dates\n </label>\n <label className=\"flex items-center gap-1.5\">\n <Checkbox checked={draft[\"required\"] === true} onCheckedChange={(v) => set({ required: v === true })} />\n Required\n </label>\n </div>\n\n <Separator />\n\n {/* FLD-3: a constraint is a RULE attached to the Field, never a behaviour. */}\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Validation</span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"ml-auto\"\n onClick={() => set({ rules: [...rules, { kind: \"min\", value: 0 }] })}\n >\n Add a rule\n </Button>\n </div>\n {rules.length === 0 ? (\n <p className=\"text-muted-foreground\">No rules. The store will accept any value this type allows.</p>\n ) : null}\n {rules.map((rule, index) => (\n <div key={`${rule.kind}-${index}`} className=\"flex items-center gap-1\">\n <Select\n value={rule.kind}\n onValueChange={(kind) =>\n set({ rules: rules.map((r, i) => (i === index ? { ...r, kind: kind as FieldRule[\"kind\"] } : r)) })\n }\n >\n <SelectTrigger size=\"sm\" className=\"w-44\" aria-label={`Rule ${index + 1} kind`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RULE_KINDS.map((kind) => (\n <SelectItem key={kind} value={kind}>\n {kind}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <BasicInput\n className=\"h-8\"\n value={String(rule.value ?? \"\")}\n aria-label={`Rule ${index + 1} value`}\n onChange={(e) =>\n set({ rules: rules.map((r, i) => (i === index ? { ...r, value: e.target.value } : r)) })\n }\n />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Remove rule ${index + 1}`}\n onClick={() => set({ rules: rules.filter((_, i) => i !== index) })}\n >\n ×\n </Button>\n </div>\n ))}\n </div>\n\n {mutation.error ? <RefusalNotice error={mutation.error} /> : null}\n\n <div className=\"flex items-center gap-2\">\n <Button size=\"sm\" disabled={mutation.saving} onClick={() => void save()}>\n {mutation.saving ? \"Saving…\" : field ? \"Save field\" : \"Add field\"}\n </Button>\n {onCancel ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n ) : null}\n </div>\n </div>\n );\n}\n\n/**\n * The kernel Field Table — a Field record lives in it, like every other record.\n * The id comes from the store's own kernel rows (generated), never a literal.\n */\nconst FIELD_KERNEL = KERNEL_TABLES.find((t) => t.name === \"Field\")!.id;\n","\"use client\";\n\n// src/TableSettings.tsx — @ai-matrx/records-ui · SCR-3, SCR-4, SCR-5\n//\n// EVERY FIELD OF ONE TABLE, TO RENAME, REORDER, RETYPE AND DELETE, FROM ONE\n// PANEL — and the agent's pending field proposals in the SAME list, with the\n// same accept and reject on each (SCR-5), because a proposal is a field that\n// has not been agreed to yet, not a different kind of thing in a different\n// place.\n//\n// The panel does not exist at all for somebody who does not administer the\n// table (SCR-4). There is no read-only variant: what it would show, the grid\n// already shows.\n\nimport { useState } from \"react\";\nimport { useFields, useRecordMutation, useTable, type Field, type Uuid } from \"@ai-matrx/records/react\";\nimport { Badge, Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { FieldEditor } from \"./FieldEditor\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldTypeLabel } from \"./parity\";\nimport { fieldName } from \"./names\";\n\nexport interface FieldProposalRow {\n id: string;\n /** What the agent proposed, in the Field shape the store would store. */\n field: Partial<Field> & { key: string; label?: string };\n why: string;\n proposed_by: string;\n}\n\nexport interface TableSettingsProps {\n tableId: Uuid;\n /**\n * SCR-5. Pending field proposals. The door that lists them\n * (`custom.field_propose`) does not exist yet — `@ai-matrx/records` answers\n * `door_absent` by name for it — so a host passes what it has, and when it\n * has nothing the section says so rather than pretending there is nothing to\n * approve.\n */\n proposals?: FieldProposalRow[] | undefined;\n onAcceptProposal?: ((proposal: FieldProposalRow) => void) | undefined;\n onRejectProposal?: ((proposal: FieldProposalRow) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TableSettings({\n tableId,\n proposals,\n onAcceptProposal,\n onRejectProposal,\n className,\n}: TableSettingsProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const mutation = useRecordMutation();\n const [editing, setEditing] = useState<Field | \"new\" | null>(null);\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (!rights.admin) return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n\n const rows = [...(fields.data ?? [])].sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));\n\n const move = async (field: Field, direction: -1 | 1) => {\n const index = rows.findIndex((r) => r.id === field.id);\n const swap = rows[index + direction];\n if (!swap) return;\n // The order is the Field's own `sort`, so reordering is two ordinary writes\n // through the one write door, not a table-level layout blob.\n await mutation.update({ record_id: field.id, patch: { sort: swap.sort ?? index + direction } });\n await mutation.update({ record_id: swap.id, patch: { sort: field.sort ?? index } });\n fields.reload();\n };\n\n const remove = async (field: Field) => {\n // REC-23: soft, and reversible while the table keeps its history.\n await mutation.remove({ record_id: field.id });\n fields.reload();\n };\n\n if (editing) {\n return (\n <FieldEditor\n tableId={tableId}\n {...(editing === \"new\" ? {} : { field: editing })}\n onSaved={() => {\n setEditing(null);\n fields.reload();\n }}\n onCancel={() => setEditing(null)}\n className={className}\n />\n );\n }\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Fields</span>\n <span className=\"text-muted-foreground\">{rows.length}</span>\n <Button size=\"sm\" variant=\"outline\" className=\"ml-auto\" onClick={() => setEditing(\"new\")}>\n Add a field\n </Button>\n </div>\n\n {mutation.error ? <RefusalNotice error={mutation.error} /> : null}\n\n <ul className=\"divide-y rounded border\">\n {rows.map((field, index) => (\n <li key={field.id} className=\"flex items-center gap-2 px-2 py-1.5\">\n <span className=\"min-w-0 flex-1 truncate\">{fieldName(field)}</span>\n <Badge variant=\"outline\" className=\"text-[10px] font-normal\">\n {fieldTypeLabel(field)}\n </Badge>\n {field.required ? <span className=\"text-[10px] text-destructive\">required</span> : null}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Move ${fieldName(field)} up`}\n disabled={index === 0}\n onClick={() => void move(field, -1)}\n >\n ↑\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Move ${fieldName(field)} down`}\n disabled={index === rows.length - 1}\n onClick={() => void move(field, 1)}\n >\n ↓\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setEditing(field)}>\n Edit\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"text-destructive\"\n aria-label={`Delete ${fieldName(field)}`}\n onClick={() => void remove(field)}\n >\n Delete\n </Button>\n </li>\n ))}\n {rows.length === 0 ? <li className=\"px-2 py-2 text-muted-foreground\">This table has no fields yet.</li> : null}\n </ul>\n\n <Separator />\n\n {/* SCR-5: proposals are fields in the same list, with the same two verbs. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Proposed</span>\n <span className=\"text-muted-foreground\">{proposals?.length ?? 0}</span>\n </div>\n {proposals === undefined ? (\n <p className=\"text-muted-foreground\">\n Nothing is listing proposals here yet: the store has no `custom.field_propose` door, so this panel would be\n inventing an empty queue. When the door lands, its rows appear in this list with the same accept and reject.\n </p>\n ) : proposals.length === 0 ? (\n <p className=\"text-muted-foreground\">No field is waiting for a decision.</p>\n ) : (\n <ul className=\"divide-y rounded border\">\n {proposals.map((proposal) => (\n <li key={proposal.id} className=\"flex items-center gap-2 px-2 py-1.5\">\n <span className=\"min-w-0 flex-1 truncate\">{proposal.field.label || proposal.field.key}</span>\n <span className=\"min-w-0 flex-1 truncate text-muted-foreground\">{proposal.why}</span>\n <Badge variant=\"secondary\" className=\"text-[10px] font-normal\">\n {proposal.proposed_by}\n </Badge>\n <Button size=\"sm\" variant=\"outline\" onClick={() => onAcceptProposal?.(proposal)}>\n Accept\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => onRejectProposal?.(proposal)}>\n Reject\n </Button>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/Peek.tsx — @ai-matrx/records-ui · SCR-N-3\n//\n// THE GENERIC PEEK, DRIVEN BY THE FIELD RECORDS. There is no per-table peek in\n// this platform: before this, 21 hand-written peeks covered 19 registered\n// catalogue keys and every custom table — 100% of them — fell to \"Peek — coming\n// soon\".\n//\n// It reads the record through the read door, shows every applicable Field's\n// value the way that Field says to show it, and flips to the same\n// `RecordForm` for editing. It carries the Alchemy menu, so everything a person\n// can copy, hand to an agent or export from a record is in the one place it is\n// everywhere else on the platform.\n\nimport { useState } from \"react\";\nimport { useFields, useRecord, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport { AlchemyMenu } from \"@ai-matrx/alchemy/react\";\nimport { Button, Separator, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { ProvenanceBadge, renderValue } from \"./values\";\nimport { fieldName, recordName } from \"./names\";\n\nexport interface PeekProps {\n tableId: Uuid;\n recordId: Uuid;\n onClose?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function Peek({ tableId, recordId, onClose, className }: PeekProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const record = useRecord(recordId, true);\n const rights = useTableRights(table.data);\n const host = useRecordsUi();\n const [editing, setEditing] = useState(false);\n\n if (record.error) return <RefusalNotice error={record.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n\n const document = record.data?.document;\n // REC-2: the Table's own title field is what makes a record a chip. A record\n // with nothing readable says so — a truncated uuid tells a person nothing and\n // reads like a bug (`names.ts`).\n const title = document ? recordName(document, table.data?.title_field) : \"\";\n const href = host.hrefForRecord && table.data ? host.hrefForRecord({ table: table.data, recordId }) : undefined;\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n {/* ONE row of header: the title, the controls. Nothing repeats the name. */}\n <div className=\"flex items-center gap-2\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {record.loading && !document ? <Skeleton className=\"h-4 w-40\" /> : title}\n </h3>\n <AlchemyMenu\n label={title || \"Record\"}\n sourceId={`record:${recordId}`}\n size=\"xs\"\n human={() =>\n (fields.data ?? [])\n .map((field) => `${fieldName(field)}: ${String(document?.[field.key] ?? \"\")}`)\n .join(\"\\n\")\n }\n json={() => document ?? {}}\n />\n {href ? (\n <a className=\"text-primary underline-offset-2 hover:underline\" href={href}>\n Open\n </a>\n ) : null}\n {rights.write ? (\n <Button size=\"sm\" variant={editing ? \"ghost\" : \"outline\"} onClick={() => setEditing((e) => !e)}>\n {editing ? \"Stop editing\" : \"Edit\"}\n </Button>\n ) : null}\n {onClose ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={onClose} aria-label=\"Close\">\n ×\n </Button>\n ) : null}\n </div>\n\n <Separator />\n\n {editing ? (\n <RecordForm\n tableId={tableId}\n recordId={recordId}\n onSaved={() => {\n setEditing(false);\n record.reload();\n }}\n onCancel={() => setEditing(false)}\n />\n ) : (\n <dl className=\"grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5\">\n {(fields.data ?? []).map((field) => (\n <div key={field.id} className=\"contents\">\n <dt className=\"flex items-baseline gap-1 truncate text-muted-foreground\">\n {fieldName(field)}\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </dt>\n <dd className=\"min-w-0\">{renderValue(field, document?.[field.key], document)}</dd>\n </div>\n ))}\n </dl>\n )}\n\n {/* FLD-9: what the system worked out, and where it came from. */}\n {record.data?.computed?.length ? (\n <>\n <Separator />\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">Worked out by the system</span>\n {record.data.computed.map((row, i) => (\n <p key={i} className=\"text-muted-foreground\">\n {JSON.stringify(row)}\n </p>\n ))}\n </div>\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/views.ts — @ai-matrx/records-ui · SCR-6, SCR-7, SCR-N-6\n//\n// A SAVED VIEW IS ONE RECORD, and that record owns its layout and REFERENCES\n// its membership rule.\n//\n// The split matters. A view does not carry a filter predicate of its own that a\n// screen re-implements in JavaScript: it names a Rule, and the STORE answers\n// who is in it (`custom.rule_members`). So the same view means the same thing\n// to a grid, to an export, to an agent and to the server. What the view owns\n// itself is presentation — which of the four layouts, which Field the kanban\n// columns come from, which Field the calendar reads, which Field the gallery\n// shows — because that is not data, it is how this person wants to look at it.\n//\n// The whole view is also a plain declarative object (`SavedViewSpec`), which is\n// what makes \"an agent writes the view in 45 seconds\" true: one `record_write`\n// of one document, and the person only tweaks.\n\nimport type { ReadRow, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** The four ways one saved view can be looked at (SCR-6). */\nexport const VIEW_LAYOUTS = [\"grid\", \"kanban\", \"calendar\", \"gallery\"] as const;\nexport type ViewLayout = (typeof VIEW_LAYOUTS)[number];\n\nexport const LAYOUT_LABEL: Record<ViewLayout, string> = {\n grid: \"Grid\",\n kanban: \"Kanban\",\n calendar: \"Calendar\",\n gallery: \"Gallery\",\n};\n\n/**\n * What each layout needs before it can draw anything, in one sentence a screen\n * prints. A layout that is missing its Field says so instead of rendering an\n * empty board that looks like \"no records\".\n */\nexport const LAYOUT_NEEDS: Record<ViewLayout, string | null> = {\n grid: null,\n kanban: \"A kanban board needs a Field to make its columns from — pick one and the board appears.\",\n calendar: \"A calendar needs a date Field to place records on — pick one and the month appears.\",\n gallery: null,\n};\n\n/** One sort clause. The Field's key and a direction; nothing else is a sort. */\nexport interface ViewSort {\n field: string;\n direction: \"asc\" | \"desc\";\n}\n\n/**\n * THE DECLARATIVE SPEC. An agent writes this whole object; a person tweaks it.\n * Every builder component in this package takes one of these as a prop.\n */\nexport interface SavedViewSpec {\n name: string;\n /** The Table this view looks at. */\n subject: Uuid;\n layout: ViewLayout;\n /** Kanban: the Field whose value becomes a column. */\n groupField?: string | null;\n /** Calendar: the Field that places a record in the month. */\n dateField?: string | null;\n /** Gallery: the Field shown large on the card. */\n imageField?: string | null;\n sorts?: ViewSort[];\n /**\n * The membership Rule. The STORE decides who is in this view; this is a\n * reference to its Rule record, never a predicate this package evaluates.\n */\n ruleId?: Uuid | null;\n isDefault?: boolean;\n}\n\n/** A saved view as it comes back out of the store, with its record's own id. */\nexport interface SavedView extends SavedViewSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every saved view is a record of. */\nexport const VIEW_TABLE: SystemTableSpec = {\n slug: \"records_ui_view\",\n name: \"Saved views\",\n labelSingular: \"View\",\n labelPlural: \"Views\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"layout\", label: \"Layout\", type: \"text\", sort: 30, required: true },\n { key: \"group_field\", label: \"Group by\", type: \"text\", sort: 40 },\n { key: \"date_field\", label: \"Date field\", type: \"text\", sort: 50 },\n { key: \"image_field\", label: \"Image field\", type: \"text\", sort: 60 },\n { key: \"sorts\", label: \"Sorts\", type: \"text\", sort: 70, config: { multiline: true } },\n { key: \"rule_id\", label: \"Membership rule\", type: \"text\", sort: 80 },\n { key: \"is_default\", label: \"Default\", type: \"text\", sort: 90 },\n ],\n};\n\n/**\n * WHICH FIELD EACH LAYOUT CAN BE DRAWN FROM, decided from the FIELD'S OWN\n * DECLARATION and never from the values it happens to hold.\n *\n * A kanban makes columns from a choice: the Field whose value is one of a\n * closed set (FLD-5 / FLD-6 — a pick-list is a Table, and a select stores the\n * id of one of its records). Grouping by a free-text Field produces one column\n * per record, which is not a board. A calendar places a record in time, so it\n * needs a Field that holds a date.\n *\n * These two answers are here, beside the layouts, because the picker on the\n * screen and any agent writing a view spec must agree about what is offerable.\n */\nexport const LAYOUT_FIELD_KIND: Record<ViewLayout, \"choice\" | \"date\" | null> = {\n grid: null,\n kanban: \"choice\",\n calendar: \"date\",\n gallery: null,\n};\n\n/** The one sentence a layout says when the table holds no Field it could use. */\nexport const LAYOUT_NO_FIELD: Record<ViewLayout, string> = {\n grid: \"\",\n kanban:\n \"This table has no choice field yet, so there is nothing to make columns from. Add a field that \" +\n \"holds one of a set of choices — Add field, then Select — and it appears here.\",\n calendar:\n \"This table has no date field yet, so there is nothing to place records on. Add a field that holds \" +\n \"a date — Add field, then Date — and it appears here.\",\n gallery: \"\",\n};\n\n/** The spec as the one document the store holds. */\nexport function viewDocument(spec: SavedViewSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n layout: spec.layout,\n group_field: spec.groupField ?? null,\n date_field: spec.dateField ?? null,\n image_field: spec.imageField ?? null,\n sorts: JSON.stringify(spec.sorts ?? []),\n rule_id: spec.ruleId ?? null,\n is_default: spec.isDefault ? \"true\" : \"false\",\n };\n}\n\n/** One stored record back into the spec a screen and an agent both read. */\nexport function viewFromRecord(row: ReadRow): SavedView {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const layout = String(data[\"layout\"] ?? \"grid\");\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled view\"),\n subject: String(data[\"subject\"] ?? \"\"),\n layout: (VIEW_LAYOUTS as readonly string[]).includes(layout) ? (layout as ViewLayout) : \"grid\",\n groupField: (data[\"group_field\"] as string | null) ?? null,\n dateField: (data[\"date_field\"] as string | null) ?? null,\n imageField: (data[\"image_field\"] as string | null) ?? null,\n sorts: parseSorts(data[\"sorts\"]),\n ruleId: (data[\"rule_id\"] as string | null) ?? null,\n isDefault: data[\"is_default\"] === \"true\",\n };\n}\n\n/**\n * A PARTIAL change to a saved view, as the patch the store takes. Only the keys\n * the caller actually changed are written — a full document would re-write a\n * name or a rule the person edited in another tab.\n */\nexport function viewPatchDocument(patch: Partial<SavedViewSpec>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (patch.name !== undefined) out[\"name\"] = patch.name;\n if (patch.layout !== undefined) out[\"layout\"] = patch.layout;\n if (patch.groupField !== undefined) out[\"group_field\"] = patch.groupField ?? null;\n if (patch.dateField !== undefined) out[\"date_field\"] = patch.dateField ?? null;\n if (patch.imageField !== undefined) out[\"image_field\"] = patch.imageField ?? null;\n if (patch.sorts !== undefined) out[\"sorts\"] = JSON.stringify(patch.sorts ?? []);\n if (patch.ruleId !== undefined) out[\"rule_id\"] = patch.ruleId ?? null;\n if (patch.isDefault !== undefined) out[\"is_default\"] = patch.isDefault ? \"true\" : \"false\";\n return out;\n}\n\nfunction parseSorts(raw: unknown): ViewSort[] {\n if (Array.isArray(raw)) return raw as ViewSort[];\n if (typeof raw !== \"string\" || raw.trim() === \"\") return [];\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as ViewSort[]) : [];\n } catch {\n // A sort nobody can read is not silently dropped to \"no sort\": the view says\n // what it holds and the caller can see that it is not a sort list.\n return [];\n }\n}\n","\"use client\";\n\n// src/ViewSwitcher.tsx — @ai-matrx/records-ui · SCR-6\n//\n// ONE SAVED VIEW, FOUR WAYS TO LOOK AT IT: grid, kanban, calendar, gallery.\n//\n// The records are the SAME records in all four. Switching layout re-draws them;\n// it never re-queries something different and it never filters differently —\n// membership is the view's Rule and the STORE answers it (`custom.rule_members`),\n// so a card that disappears between two layouts would be a defect, not a\n// feature. A view with no Rule is the whole table, and the screen says which.\n//\n// A layout that cannot draw yet (a kanban with no Field to group by, a calendar\n// with no date Field) says the one sentence that fixes it. It never renders an\n// empty board that reads like \"there is nothing here\".\n\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { useFields, useRecords, useRecordsClient, type Field, type ReadRow, type StoredRecord, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { Grid } from \"./Grid\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { renderValue, scalarText } from \"./values\";\nimport { fieldName, rowName } from \"./names\";\nimport { editorKindFor } from \"./parity\";\nimport {\n LAYOUT_FIELD_KIND,\n LAYOUT_LABEL,\n LAYOUT_NEEDS,\n LAYOUT_NO_FIELD,\n VIEW_LAYOUTS,\n type SavedViewSpec,\n type ViewLayout,\n} from \"./views\";\n\nexport interface ViewSwitcherProps {\n /**\n * THE DECLARATIVE SPEC — an agent writes the whole thing, a person tweaks it.\n * `ViewBar` passes the saved view it loaded; a host with no saved views at all\n * can pass a literal here and the switcher works.\n */\n view: SavedViewSpec;\n /** Called when the person picks another layout, so the host can save it. */\n onLayoutChange?: ((layout: ViewLayout) => void) | undefined;\n /**\n * Called with whatever part of the view the person just changed — the layout,\n * the Field the kanban groups by, the Field the calendar reads. The HOST\n * saves it onto the view record, so the choice is remembered per saved view\n * rather than per page load. Unbound, the pickers still work for this visit\n * and the screen says the choice is not being kept.\n */\n onViewChange?: ((patch: Partial<SavedViewSpec>) => void) | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n /** The host's whole-record form, offered by the grid when an empty record is refused. */\n onNewRecordForm?: (() => void) | undefined;\n pageSize?: number | undefined;\n className?: string | undefined;\n}\n\n/** The records this view holds: its Rule's members when it names one, the table otherwise. */\nexport function useViewRecords(view: SavedViewSpec, pageSize = 200) {\n const client = useRecordsClient();\n const table = useRecords(view.ruleId ? null : view.subject, { pageSize });\n const [ruled, setRuled] = useState<{ rows: ReadRow[]; loading: boolean; error: RecordsError | null }>({\n rows: [],\n loading: Boolean(view.ruleId),\n error: null,\n });\n\n const ruleId = view.ruleId ?? null;\n useEffect(() => {\n if (!ruleId) return;\n let cancelled = false;\n setRuled({ rows: [], loading: true, error: null });\n void client.ruleMembers({ rule_id: ruleId }).then((result) => {\n if (cancelled) return;\n setRuled(\n result.ok\n ? { rows: (result.data ?? []).map(asReadRow), loading: false, error: null }\n : { rows: [], loading: false, error: result.error },\n );\n });\n return () => {\n cancelled = true;\n };\n }, [client, ruleId]);\n\n const rows = ruleId ? ruled.rows : (table.data?.rows ?? []);\n return {\n rows: sortRows(rows, view.sorts ?? []),\n loading: ruleId ? ruled.loading : table.loading,\n error: ruleId ? ruled.error : table.error,\n /** Where membership came from, in a sentence. A screen that hides this is hiding the view's meaning. */\n membership: ruleId\n ? \"Membership is this view's Rule, answered by the store.\"\n : \"This view has no Rule, so it holds the whole table.\",\n };\n}\n\n/**\n * `custom.rule_members` answers SETOF `custom.record` — it is the membership\n * door, not the read door, so its rows arrive in the row shape rather than the\n * masked-document shape. They are carried into the read door's shape HERE, at\n * the one seam, so a card is drawn by exactly one code path whichever door\n * produced it. What this cannot do is mask: a Rule's members come back as the\n * store stored them, which is the membership door's own gap, not this screen's.\n */\nfunction asReadRow(row: StoredRecord): ReadRow {\n return { id: row.id, document: (row.data ?? {}) as ReadRow[\"document\"], level: \"viewer\", hidden: {} };\n}\n\nfunction sortRows(rows: ReadRow[], sorts: { field: string; direction: \"asc\" | \"desc\" }[]): ReadRow[] {\n if (sorts.length === 0) return rows;\n return [...rows].sort((a, b) => {\n for (const sort of sorts) {\n const left = (a.document ?? {})[sort.field];\n const right = (b.document ?? {})[sort.field];\n if (left === right) continue;\n const order = (left ?? \"\") < (right ?? \"\") ? -1 : 1;\n return sort.direction === \"desc\" ? -order : order;\n }\n return 0;\n });\n}\n\nexport function ViewSwitcher({\n view,\n onLayoutChange,\n onViewChange,\n onOpenRecord,\n onNewRecordForm,\n pageSize = 200,\n className,\n}: ViewSwitcherProps) {\n const [layout, setLayout] = useState<ViewLayout>(view.layout);\n // The Fields the pickers below chose, so a host that binds no `onViewChange`\n // still gets a board rather than a sentence — and is TOLD it is not kept.\n const [local, setLocal] = useState<Partial<SavedViewSpec>>({});\n useEffect(() => {\n setLayout(view.layout);\n setLocal({});\n }, [view.layout, view.name, view.subject]);\n\n const pick = (next: ViewLayout) => {\n setLayout(next);\n onLayoutChange?.(next);\n onViewChange?.({ layout: next });\n };\n\n const change = (patch: Partial<SavedViewSpec>) => {\n setLocal((held) => ({ ...held, ...patch }));\n onViewChange?.(patch);\n };\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the view's name, the four layouts, nothing repeated. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-sm font-medium\">{view.name}</span>\n <div className=\"ml-auto flex items-center gap-0.5\" role=\"group\" aria-label=\"Layout\">\n {VIEW_LAYOUTS.map((option) => (\n <Button\n key={option}\n size=\"sm\"\n variant={option === layout ? \"secondary\" : \"ghost\"}\n aria-pressed={option === layout}\n onClick={() => pick(option)}\n >\n {LAYOUT_LABEL[option]}\n </Button>\n ))}\n </div>\n </div>\n\n {layout === \"grid\" ? (\n <Grid\n tableId={view.subject}\n pageSize={pageSize}\n {...(onOpenRecord ? { onOpenRecord } : {})}\n {...(onNewRecordForm ? { onNewRecordForm } : {})}\n />\n ) : (\n <Board\n view={{ ...view, ...local, layout }}\n pageSize={pageSize}\n onChange={change}\n remembered={Boolean(onViewChange)}\n {...(onOpenRecord ? { onOpenRecord } : {})}\n />\n )}\n </div>\n );\n}\n\n/** Which Fields a kanban may group by, and which a calendar may read. */\nfunction offerableFields(all: Field[], want: \"choice\" | \"date\"): Field[] {\n return all.filter((field) => {\n const kind = editorKindFor(field);\n if (want === \"choice\") return kind === \"select\" || kind === \"multi_select\";\n return kind === \"datetime\" || kind === \"date\";\n });\n}\n\nfunction Board({\n view,\n pageSize,\n onChange,\n remembered,\n onOpenRecord,\n}: {\n view: SavedViewSpec;\n pageSize: number;\n onChange: (patch: Partial<SavedViewSpec>) => void;\n remembered: boolean;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n}) {\n const fields = useFields(view.subject);\n const records = useViewRecords(view, pageSize);\n\n if (fields.error) return <RefusalNotice error={fields.error} />;\n if (records.error) return <RefusalNotice error={records.error} />;\n if (fields.loading || records.loading) return <Skeleton className=\"h-40 w-full\" />;\n\n const all = fields.data ?? [];\n const byKey = (key: string | null | undefined) => all.find((f) => f.key === key);\n const titleField = byKey(view.groupField) ? all.find((f) => f.key !== view.groupField) ?? all[0] : all[0];\n\n if (view.layout === \"kanban\") {\n const groupField = byKey(view.groupField);\n const picker = (\n <FieldPicker\n layout=\"kanban\"\n label=\"Group by\"\n all={all}\n chosen={groupField?.key ?? null}\n remembered={remembered}\n onPick={(key) => onChange({ groupField: key })}\n />\n );\n if (!groupField) return <Needs layout=\"kanban\" picker={picker} />;\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n {picker}\n <Kanban rows={records.rows} groupField={groupField} titleField={titleField} onOpenRecord={onOpenRecord} note={records.membership} />\n </div>\n );\n }\n if (view.layout === \"calendar\") {\n const dateField = byKey(view.dateField);\n const picker = (\n <FieldPicker\n layout=\"calendar\"\n label=\"Dates from\"\n all={all}\n chosen={dateField?.key ?? null}\n remembered={remembered}\n onPick={(key) => onChange({ dateField: key })}\n />\n );\n if (!dateField) return <Needs layout=\"calendar\" picker={picker} />;\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n {picker}\n <Calendar rows={records.rows} dateField={dateField} titleField={titleField} onOpenRecord={onOpenRecord} note={records.membership} />\n </div>\n );\n }\n return <Gallery rows={records.rows} fields={all} imageKey={view.imageField ?? null} onOpenRecord={onOpenRecord} note={records.membership} />;\n}\n\n/**\n * THE PICKER THE SENTENCE ALWAYS PROMISED. Before this, a kanban said \"pick one\n * and the board appears\" and there was no picker anywhere on the page — the\n * verdict of 19 September found the same dead end on the calendar. A screen\n * that names a remedy and does not offer it is worse than one that says\n * nothing, so the sentence and the control are now the same component.\n */\nfunction FieldPicker({\n layout,\n label,\n all,\n chosen,\n remembered,\n onPick,\n}: {\n layout: ViewLayout;\n label: string;\n all: Field[];\n chosen: string | null;\n remembered: boolean;\n onPick: (key: string | null) => void;\n}) {\n const want = LAYOUT_FIELD_KIND[layout];\n const offerable = want ? offerableFields(all, want) : [];\n if (offerable.length === 0) {\n // Honest, and it names the fix: this is not \"pick one\", because there is\n // nothing to pick.\n return <p className=\"text-xs text-muted-foreground\">{LAYOUT_NO_FIELD[layout]}</p>;\n }\n return (\n <div className=\"flex items-center gap-1.5 text-xs\">\n <label className=\"text-muted-foreground\" htmlFor={`view-field-${layout}`}>\n {label}\n </label>\n <select\n id={`view-field-${layout}`}\n aria-label={`${label} which field`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={chosen ?? \"\"}\n onChange={(event) => onPick(event.target.value === \"\" ? null : event.target.value)}\n >\n <option value=\"\">Choose a field</option>\n {offerable.map((field) => (\n <option key={field.key} value={field.key}>\n {fieldName(field)}\n </option>\n ))}\n </select>\n {remembered ? null : (\n <span className=\"text-muted-foreground\">\n Kept for this visit only — this screen has nowhere to save it onto the view.\n </span>\n )}\n </div>\n );\n}\n\n/** The one sentence that fixes an un-drawable layout, WITH the control that fixes it. */\nfunction Needs({ layout, picker }: { layout: ViewLayout; picker: ReactNode }) {\n return (\n <div className=\"flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground\">\n <p>{LAYOUT_NEEDS[layout]}</p>\n {picker}\n </div>\n );\n}\n\nfunction Note({ children }: { children: string }) {\n return <p className=\"text-xs text-muted-foreground\">{children}</p>;\n}\n\nfunction Kanban({\n rows,\n groupField,\n titleField,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n groupField: Field;\n titleField: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const columns = useMemo(() => {\n const map = new Map<string, ReadRow[]>();\n for (const row of rows) {\n const raw = (row.document ?? {})[groupField.key];\n // A record with no value for the grouping Field is NOT dropped: it gets\n // its own column, named for the absence, because losing rows between two\n // layouts is the defect this board could most easily ship.\n const key = raw === null || raw === undefined || raw === \"\" ? \"No value\" : scalarText(groupField, raw);\n map.set(key, [...(map.get(key) ?? []), row]);\n }\n return [...map.entries()].sort((a, b) => (a[0] === \"No value\" ? 1 : b[0] === \"No value\" ? -1 : a[0].localeCompare(b[0])));\n }, [rows, groupField]);\n\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <div className=\"flex min-h-0 gap-2 overflow-x-auto pb-2\">\n {columns.map(([name, cards]) => (\n <section key={name} className=\"flex w-64 shrink-0 flex-col rounded border bg-muted/30\">\n <header className=\"flex items-center gap-2 border-b px-2 py-1 text-xs font-medium\">\n <span className=\"truncate\">{name}</span>\n <span className=\"ml-auto text-muted-foreground\">{cards.length}</span>\n </header>\n <ul className=\"flex flex-col gap-1 p-1\">\n {cards.map((card) => (\n <li key={card.id}>\n <Card record={card} field={titleField} onOpenRecord={onOpenRecord} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n </div>\n );\n}\n\nfunction Calendar({\n rows,\n dateField,\n titleField,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n dateField: Field;\n titleField: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const { days, undated } = useMemo(() => {\n const byDay = new Map<string, ReadRow[]>();\n const without: ReadRow[] = [];\n for (const row of rows) {\n const raw = (row.document ?? {})[dateField.key];\n const at = typeof raw === \"string\" || typeof raw === \"number\" ? new Date(raw) : null;\n if (!at || Number.isNaN(at.getTime())) {\n without.push(row);\n continue;\n }\n const key = at.toISOString().slice(0, 10);\n byDay.set(key, [...(byDay.get(key) ?? []), row]);\n }\n return { days: [...byDay.entries()].sort((a, b) => a[0].localeCompare(b[0])), undated: without };\n }, [rows, dateField]);\n\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <ol className=\"flex min-h-0 flex-col divide-y overflow-y-auto rounded border\">\n {days.map(([day, cards]) => (\n <li key={day} className=\"flex gap-3 p-2\">\n <span className=\"w-24 shrink-0 text-xs font-medium tabular-nums\">\n {new Date(`${day}T00:00:00Z`).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" })}\n </span>\n <ul className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {cards.map((card) => (\n <li key={card.id}>\n <Card record={card} field={titleField} onOpenRecord={onOpenRecord} />\n </li>\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {undated.length > 0 ? (\n // Nothing fails silently: records with no date are NOT missing from the\n // calendar, they are named as records the calendar cannot place.\n <p className=\"text-xs text-muted-foreground\">\n {undated.length} {undated.length === 1 ? \"record has\" : \"records have\"} no {fieldName(dateField)},\n so the calendar cannot place {undated.length === 1 ? \"it\" : \"them\"}.\n </p>\n ) : null}\n </div>\n );\n}\n\nfunction Gallery({\n rows,\n fields,\n imageKey,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n fields: Field[];\n imageKey: string | null;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const shown = fields.slice(0, 4);\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <ul className=\"grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-2 overflow-y-auto\">\n {rows.map((row) => {\n const image = imageKey ? (row.document ?? {})[imageKey] : null;\n return (\n <li key={row.id}>\n <button\n type=\"button\"\n className=\"flex w-full flex-col gap-1 rounded border p-2 text-left hover:bg-muted\"\n onClick={() => onOpenRecord?.(row.id)}\n >\n {typeof image === \"string\" && image !== \"\" ? (\n <img src={image} alt=\"\" className=\"h-28 w-full rounded object-cover\" />\n ) : null}\n {shown.map((field) => (\n <span key={field.key} className=\"flex min-w-0 items-baseline gap-1 text-xs\">\n <span className=\"shrink-0 text-muted-foreground\">{fieldName(field)}</span>\n <span className=\"min-w-0 truncate\">{renderValue(field, (row.document ?? {})[field.key], row.document)}</span>\n </span>\n ))}\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\nfunction Card({\n record,\n field,\n onOpenRecord,\n}: {\n record: ReadRow;\n field: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n}) {\n const host = useRecordsUi();\n // Never a bare identifier on a card: the Field's own value when there is one,\n // the record's name when there is not.\n const label = field\n ? scalarText(field, (record.document ?? {})[field.key])\n : rowName(record, null, \"Untitled\");\n return (\n <button\n type=\"button\"\n className={cn(\n \"w-full truncate rounded border bg-background px-2 py-1 text-left text-xs hover:bg-muted\",\n host.density === \"spacious\" ? \"py-2\" : \"\",\n )}\n onClick={() => onOpenRecord?.(record.id)}\n title={label}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\n// src/ViewBar.tsx — @ai-matrx/records-ui · SCR-7, SCR-N-6\n//\n// THE SAVED VIEWS OF ONE TABLE, AS RECORDS.\n//\n// Each view is ONE record in this organization's own `records_ui_view` Table,\n// declared through the store's doors the first time anything asks for it\n// (`systemTable.ts`). That is what makes a view shareable, exportable,\n// historied and agent-writable without a line of code per feature: it is a\n// record, so everything this package does to records it already does to views.\n//\n// A view owns its LAYOUT and references its MEMBERSHIP RULE. The bar never\n// evaluates a predicate — picking a view hands `ViewSwitcher` a spec, and the\n// store answers who is in it.\n//\n// `seed` is the declarative half: an agent writes a complete view spec, the bar\n// saves it as a record on first sight, and the person only tweaks it.\n//\n// ONE CONTROL FOR ONE THING. This bar used to carry a layout `select` of its\n// own beside `ViewSwitcher`'s layout buttons, and the two disagreed on screen:\n// the verdict of 19 September watched the dropdown keep saying \"Grid\" while\n// Calendar was drawn. The switcher owns the LAYOUT; this bar owns WHICH VIEW.\n// Saving a layout — or a kanban's grouping Field, or a calendar's date Field —\n// onto the view record belongs to whoever owns the switcher (`TablePage`).\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\nimport {\n VIEW_TABLE,\n viewDocument,\n viewFromRecord,\n type SavedView,\n type SavedViewSpec,\n} from \"./views\";\n\nexport interface ViewBarProps {\n /** The Table whose views these are. */\n tableId: Uuid;\n /** The view that is showing. Leave it out and the bar picks the default, then the first. */\n activeViewId?: Uuid | null | undefined;\n onActiveView?: ((view: SavedView) => void) | undefined;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these whose name this\n * table does not have yet is saved as a record the first time the bar loads.\n * The person tweaks them afterwards like any other view.\n */\n seed?: SavedViewSpec[] | undefined;\n className?: string | undefined;\n}\n\nexport function ViewBar({ tableId, activeViewId, onActiveView, seed, className }: ViewBarProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(VIEW_TABLE);\n const [views, setViews] = useState<SavedView[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [active, setActive] = useState<Uuid | null>(activeViewId ?? null);\n const [naming, setNaming] = useState(false);\n const [draftName, setDraftName] = useState(\"\");\n\n const viewTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!viewTableId) return;\n const result = await client.list({ table_id: viewTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n const mine = result.data.rows.map(viewFromRecord).filter((v) => v.subject === tableId);\n\n // The agent's specs, saved once. A seed whose name already exists is left\n // alone — an agent re-running never overwrites what a person has tweaked.\n const missing = (seed ?? []).filter((s) => !mine.some((v) => v.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: viewTableId,\n data: viewDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: viewTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n setViews(again.data.rows.map(viewFromRecord).filter((v) => v.subject === tableId));\n return;\n }\n setError(null);\n setViews(mine);\n }, [client, viewTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!views || views.length === 0) return;\n const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? views.find((v) => v.isDefault) ?? views[0]!;\n if (chosen.id !== active) setActive(chosen.id);\n onActiveView?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [views, activeViewId]);\n\n async function create(name: string) {\n if (!viewTableId || name.trim() === \"\") return;\n const written = await client.recordWrite({\n table_id: viewTableId,\n data: viewDocument({ name: name.trim(), subject: tableId, layout: \"grid\" }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setNaming(false);\n setDraftName(\"\");\n setActive(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (error) return <RefusalNotice error={error} className={className} actions={<Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>Try again</Button>} />;\n if (home.loading || views === null) return <Skeleton className={cn(\"h-7 w-64\", className)} />;\n\n return (\n <div className={cn(\"flex items-center gap-1 overflow-x-auto\", className)} role=\"group\" aria-label=\"Saved views\">\n {views.map((view) => (\n <Button\n key={view.id}\n size=\"sm\"\n variant={view.id === active ? \"secondary\" : \"ghost\"}\n aria-pressed={view.id === active}\n onClick={() => {\n setActive(view.id);\n onActiveView?.(view);\n }}\n title={view.ruleId ? \"Membership is this view's Rule\" : \"The whole table\"}\n >\n {view.name}\n {view.isDefault ? <span className=\"ml-1 text-[10px] text-muted-foreground\">default</span> : null}\n </Button>\n ))}\n\n {/* SCR-4 again: saving a view is administering the table, so a member does\n not get a dead \"New view\" button — there is no button. */}\n {rights.admin ? (\n naming ? (\n <form\n className=\"ml-1 flex items-center gap-1\"\n onSubmit={(e) => {\n e.preventDefault();\n void create(draftName);\n }}\n >\n <Input\n autoFocus\n aria-label=\"Name for the new view\"\n value={draftName}\n onChange={(e) => setDraftName(e.target.value)}\n className=\"h-7 w-40 text-xs\"\n placeholder=\"View name\"\n />\n <Button size=\"sm\" type=\"submit\">\n Save\n </Button>\n </form>\n ) : (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-1\" onClick={() => setNaming(true)}>\n New view\n </Button>\n )\n ) : null}\n\n {views.length === 0 && !rights.admin ? (\n <span className=\"text-xs text-muted-foreground\">{rights.reason}</span>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/seedOnce.ts — @ai-matrx/records-ui\n//\n// THE SEED IS WRITTEN ONCE, AND \"once\" MEANS ONCE PER MOUNT — NOT ONCE PER\n// LOAD THAT HAPPENED TO SEE IT MISSING.\n//\n// Every `seed`-taking component in this package had the same shape: a loader\n// that reads what exists, works out what is missing, writes it, and re-reads.\n// The loader is a `useCallback` whose identity changes when its inputs settle\n// (the Fields arriving is the common one), so the effect runs it again — and if\n// the FIRST run is still in flight, the second run reads a list that does not\n// yet contain what the first is writing, and writes it a second time.\n//\n// It looks harmless until the store is slow. Against the live store this\n// produced two identical \"Agreement\" templates and a screen with two buttons of\n// the same name; the same class had already produced two `signed_by` Fields in\n// the demo's own harness, fixed there the same way. The instance is a race; the\n// class is \"a check against the server's list is not a lock\", and the fix is a\n// claim that lives in the component instance rather than in the answer.\n//\n// CLAIMING IS NOT PERSISTENCE. This never stops a SECOND mount, another tab or\n// another person from seeding — nothing here pretends to be a distributed lock.\n// It stops one component from racing itself, which is the whole of what went\n// wrong. Two tabs seeding at once is the store's problem to answer, and it does.\n\nimport { useCallback, useRef } from \"react\";\n\n/**\n * A per-mount claim over seed names. `claim(\"Agreement\")` answers true exactly\n * once; every later ask for the same name answers false, including while the\n * first write is still in flight.\n */\nexport function useSeedGuard(): (name: string) => boolean {\n const claimed = useRef<Set<string>>(new Set());\n return useCallback((name: string) => {\n if (claimed.current.has(name)) return false;\n claimed.current.add(name);\n return true;\n }, []);\n}\n","\"use client\";\n\n// src/ProposalRow.tsx — @ai-matrx/records-ui · SCR-11\n//\n// ONE ROW PER PROPOSED CHANGE: what changes, why, Accept, Reject — and nothing\n// folded behind a disclosure, because a person deciding needs every line at\n// once. This is the SAME row whether it appears inline in a chat, in the action\n// inbox, or beside a grid; a second reviewer somewhere else is the defect.\n//\n// It refuses to fake three things, and they are worth naming because each one\n// is a way a queue lies:\n// 1. A control that would do nothing is ABSENT, with the reason in words —\n// never a greyed button nobody can explain.\n// 2. The store's answer is shown VERBATIM. \"Written\", \"already there\" and a\n// refusal are three different sentences.\n// 3. Accepting a removal DELETES the record, so the confirmation says that in\n// those words rather than \"this cannot be undone\".\n//\n// Every change is expressed against the record store, because in this platform\n// a field proposal, a table change and a list change are all the same act: a\n// record written, updated or deleted through one door.\n\nimport { useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport { Badge, Button, cn } from \"@ai-matrx/design-system\";\n\n/** One proposed change, in the proposer's words plus the exact act it asks for. */\nexport interface ProposedChange {\n id: string;\n act: \"add\" | \"update\" | \"remove\";\n /**\n * The Table a NEW record lands in. Required for `add` and unused by `update`\n * and `remove`, which name a record instead — and it is optional for exactly\n * that reason: it used to be required for all three, so a proposer wanting to\n * change an existing record had to supply the id of the kernel Table that\n * record lives in, which is a fact the client has no door to ask for. A\n * required field a caller cannot fill is a field that gets filled with\n * something untrue.\n */\n table?: Uuid | undefined;\n /** The record it changes. Required for `update` and `remove`. */\n record?: Uuid | undefined;\n /** The document for `add`, or the patch for `update`. */\n data?: Record<string, unknown> | undefined;\n /** What this change is, in one line a person reads. */\n label: string;\n /** Why the proposer asks for it. Optional, and shown when it is there. */\n why?: string | undefined;\n}\n\nexport type ProposalOutcome =\n | { settled: \"accepted\"; sentence: string }\n | { settled: \"rejected\"; sentence: string }\n | { settled: \"refused\"; sentence: string };\n\nexport interface ProposalRowProps {\n change: ProposedChange;\n /** What already happened to this change, when the host remembers decisions. */\n outcome?: ProposalOutcome | undefined;\n /**\n * The apply port. Left unbound, the row applies the change through the record\n * store itself — the default that makes the component plug and play. A host\n * whose proposals land somewhere else (a different store, a server lane)\n * binds this and keeps the SAME row.\n */\n onApply?: ((change: ProposedChange) => Promise<ProposalOutcome>) | undefined;\n onReject?: ((change: ProposedChange) => Promise<ProposalOutcome> | ProposalOutcome) | undefined;\n /** Absent controls with this reason, instead of dead ones. */\n readOnlyReason?: string | undefined;\n onSettled?: ((outcome: ProposalOutcome) => void) | undefined;\n className?: string | undefined;\n}\n\nconst ACT_WORD: Record<ProposedChange[\"act\"], string> = {\n add: \"Add\",\n update: \"Update\",\n remove: \"Remove\",\n};\n\nexport function ProposalRow({\n change,\n outcome,\n onApply,\n onReject,\n readOnlyReason,\n onSettled,\n className,\n}: ProposalRowProps) {\n const client = useRecordsClient();\n const [settled, setSettled] = useState<ProposalOutcome | null>(outcome ?? null);\n const [busy, setBusy] = useState(false);\n const [confirming, setConfirming] = useState(false);\n\n async function applyThroughTheStore(): Promise<ProposalOutcome> {\n if (change.act === \"add\") {\n if (!change.table) {\n // Not a silent no-op: the proposal is malformed and says which part.\n return {\n settled: \"refused\",\n sentence:\n \"This proposal asks to add a record but does not name the table it goes in, so nothing was written.\",\n };\n }\n const written = await client.recordWrite({ table_id: change.table, data: change.data ?? {} });\n return written.ok\n ? { settled: \"accepted\", sentence: \"Written.\" }\n : { settled: \"refused\", sentence: written.error.message };\n }\n if (!change.record) {\n // Not a silent no-op: the proposal is malformed and says which part.\n return {\n settled: \"refused\",\n sentence: `This proposal asks to ${change.act} a record but does not name one, so nothing was changed.`,\n };\n }\n if (change.act === \"update\") {\n const updated = await client.recordUpdate({ record_id: change.record, patch: change.data ?? {} });\n return updated.ok\n ? { settled: \"accepted\", sentence: \"Written.\" }\n : { settled: \"refused\", sentence: updated.error.message };\n }\n const removed = await client.recordDelete({ record_id: change.record });\n return removed.ok\n ? { settled: \"accepted\", sentence: \"Deleted. The store keeps it restorable for this table's retention.\" }\n : { settled: \"refused\", sentence: removed.error.message };\n }\n\n async function accept() {\n setBusy(true);\n const result = onApply ? await onApply(change) : await applyThroughTheStore();\n setBusy(false);\n setConfirming(false);\n setSettled(result);\n onSettled?.(result);\n }\n\n async function reject() {\n const result: ProposalOutcome = onReject\n ? await onReject(change)\n : { settled: \"rejected\", sentence: \"Rejected.\" };\n setSettled(result);\n onSettled?.(result);\n }\n\n return (\n <div className={cn(\"flex flex-col gap-1 rounded border p-2\", className)}>\n {/* One row: the act, what changes, and the decision. No second header. */}\n <div className=\"flex items-baseline gap-2\">\n <Badge variant={change.act === \"remove\" ? \"destructive\" : \"secondary\"} className=\"text-[10px]\">\n {ACT_WORD[change.act]}\n </Badge>\n <span className=\"min-w-0 flex-1 truncate text-xs\" title={change.label}>\n {change.label}\n </span>\n {settled ? (\n <span\n className={cn(\n \"shrink-0 text-xs\",\n settled.settled === \"refused\" ? \"text-destructive\" : \"text-muted-foreground\",\n )}\n >\n {settled.settled === \"accepted\" ? \"Accepted\" : settled.settled === \"rejected\" ? \"Rejected\" : \"Refused\"}\n </span>\n ) : readOnlyReason ? null : (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={busy}\n onClick={() => void reject()}\n >\n Reject\n </Button>\n <Button\n size=\"sm\"\n disabled={busy}\n onClick={() => (change.act === \"remove\" ? setConfirming(true) : void accept())}\n >\n Accept\n </Button>\n </span>\n )}\n </div>\n\n {change.why ? <p className=\"text-xs text-muted-foreground\">{change.why}</p> : null}\n\n {/* The store's own sentence, verbatim. */}\n {settled ? <p className=\"text-xs text-muted-foreground\">{settled.sentence}</p> : null}\n\n {/* A destructive accept names the consequence in those words. */}\n {confirming ? (\n <div className=\"flex items-center gap-2 rounded bg-destructive/10 p-2 text-xs\">\n <span className=\"min-w-0 flex-1\">\n Accepting this deletes the record. It stays restorable for this table&apos;s retention, and after\n that it is gone.\n </span>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setConfirming(false)}>\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"destructive\" disabled={busy} onClick={() => void accept()}>\n Delete it\n </Button>\n </div>\n ) : null}\n\n {readOnlyReason && !settled ? <p className=\"text-xs text-muted-foreground\">{readOnlyReason}</p> : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/ActionInbox.tsx — @ai-matrx/records-ui · SCR-11\n//\n// ONE QUEUE. Approvals, assignments and agent proposals — field, table and\n// list-change alike — arrive in the same place, in the same row shape, with the\n// same two verbs.\n//\n// That is the whole point of the component: a platform where an approval lives\n// in one screen, an assignment in another and an agent's suggestion inline in a\n// chat is a platform where people miss things. Every one of them is a record in\n// this organization's own `records_ui_action` Table, so an agent files work for\n// a person with ONE `record_write` and it appears here.\n//\n// THE ROW IS `ProposalRow`, not a variant of it. A change in how a decision is\n// presented happens once, and every surface that shows one inherits it.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\nimport { ProposalRow, type ProposalOutcome, type ProposedChange } from \"./ProposalRow\";\n\n/** The three things that land in the queue. One word each, closed. */\nexport const ACTION_KINDS = [\"approval\", \"assignment\", \"proposal\"] as const;\nexport type ActionKind = (typeof ACTION_KINDS)[number];\n\n/** The package-owned Table every queued action is a record of. */\nexport const ACTION_TABLE: SystemTableSpec = {\n slug: \"records_ui_action\",\n name: \"Action inbox\",\n labelSingular: \"Action\",\n labelPlural: \"Actions\",\n titleField: \"title\",\n fields: [\n { key: \"title\", label: \"What\", type: \"text\", sort: 10, required: true },\n { key: \"kind\", label: \"Kind\", type: \"text\", sort: 20, required: true },\n { key: \"why\", label: \"Why\", type: \"text\", sort: 30, config: { multiline: true } },\n { key: \"status\", label: \"Status\", type: \"text\", sort: 40 },\n { key: \"assignee\", label: \"For\", type: \"text\", sort: 50 },\n { key: \"subject_table\", label: \"In table\", type: \"text\", sort: 60 },\n { key: \"subject\", label: \"About\", type: \"text\", sort: 70 },\n { key: \"changes\", label: \"Proposed changes\", type: \"text\", sort: 80, config: { multiline: true } },\n { key: \"answer\", label: \"Answer\", type: \"text\", sort: 90, config: { multiline: true } },\n // The read door answers documents, not row metadata, so when an action was\n // filed is part of the action.\n { key: \"at\", label: \"Filed\", type: \"text\", sort: 100 },\n ],\n};\n\n/**\n * THE DECLARATIVE SPEC an agent writes. One `record_write` of this document puts\n * a decision in front of a person — there is no per-feature approval plumbing\n * anywhere in the platform.\n */\nexport interface QueuedActionSpec {\n kind: ActionKind;\n title: string;\n why?: string | undefined;\n assignee?: Uuid | null | undefined;\n subjectTable?: Uuid | null | undefined;\n subject?: Uuid | null | undefined;\n /** For a proposal: the exact acts being asked for. */\n changes?: ProposedChange[] | undefined;\n}\n\nexport interface QueuedAction extends QueuedActionSpec {\n id: Uuid;\n /**\n * The version this row was read at. The read door answers documents and not\n * versions, so a queue row carries null and settling it is the store's\n * ordinary last-writer-wins write — the row's own `status` is what a second\n * settler then sees.\n */\n version: number | null;\n status: \"open\" | \"accepted\" | \"rejected\" | \"refused\";\n answer: string | null;\n at: string;\n}\n\nexport function actionDocument(spec: QueuedActionSpec): Record<string, unknown> {\n return {\n title: spec.title,\n kind: spec.kind,\n why: spec.why ?? null,\n status: \"open\",\n assignee: spec.assignee ?? null,\n subject_table: spec.subjectTable ?? null,\n subject: spec.subject ?? null,\n changes: JSON.stringify(spec.changes ?? []),\n answer: null,\n // The queue sorts newest first and the read door answers no row metadata,\n // so the moment it was filed is part of the action itself.\n at: new Date().toISOString(),\n };\n}\n\nexport interface ActionInboxProps {\n /** Narrow the queue to one table's actions. Left out, it is everything waiting. */\n tableId?: Uuid | null | undefined;\n /** Show settled actions too. The default is what is still waiting. */\n includeSettled?: boolean | undefined;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these the queue does not\n * already hold (by title) is filed as a record on first load.\n */\n seed?: QueuedActionSpec[] | undefined;\n onOpenRecord?: ((recordId: Uuid, tableId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function ActionInbox({ tableId, includeSettled = false, seed, onOpenRecord, className }: ActionInboxProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const home = useSystemTable(ACTION_TABLE);\n const [actions, setActions] = useState<QueuedAction[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n const queueTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!queueTableId) return;\n const result = await client.list({ table_id: queueTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n const held = result.data.rows.map(toAction);\n const missing = (seed ?? []).filter((s) => !held.some((a) => a.title === s.title));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.title)) continue;\n const written = await client.recordWrite({ table_id: queueTableId, data: actionDocument(spec) });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: queueTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n setError(null);\n setActions(again.data.rows.map(toAction));\n return;\n }\n setError(null);\n setActions(held);\n }, [client, queueTableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const shown = useMemo(() => {\n const all = actions ?? [];\n return all\n .filter((a) => (tableId ? a.subjectTable === tableId : true))\n .filter((a) => (includeSettled ? true : a.status === \"open\"))\n .sort((a, b) => b.at.localeCompare(a.at));\n }, [actions, tableId, includeSettled]);\n\n /** Stamp the action record with what happened, in the store's own sentence. */\n async function settle(action: QueuedAction, outcome: ProposalOutcome) {\n const updated = await client.recordUpdate({\n record_id: action.id,\n patch: { status: outcome.settled, answer: outcome.sentence },\n ...(action.version === null ? {} : { expectedVersion: action.version }),\n });\n if (!updated.ok) {\n setError(updated.error);\n return;\n }\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (home.loading || actions === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">Inbox</h3>\n <span className=\"text-xs text-muted-foreground\">{shown.length}</span>\n <div className=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Refresh\n </Button>\n </div>\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {shown.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {includeSettled ? \"Nothing has come through this queue yet.\" : \"Nothing is waiting on you.\"}\n </p>\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\">\n {shown.map((action) => (\n <li key={action.id} className=\"flex flex-col gap-1 rounded border p-2\">\n {/* One row: kind, what it is, when — no repeated title below. */}\n <div className=\"flex items-baseline gap-2\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {action.kind}\n </Badge>\n <span className=\"min-w-0 flex-1 truncate text-xs font-medium\">{action.title}</span>\n {action.subject && action.subjectTable && onOpenRecord ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-5 px-1 text-[11px]\"\n onClick={() => onOpenRecord(action.subject!, action.subjectTable!)}\n >\n Open\n </Button>\n ) : null}\n <span className=\"shrink-0 text-[11px] tabular-nums text-muted-foreground\">\n {new Date(action.at).toLocaleDateString()}\n </span>\n </div>\n {action.why ? <p className=\"text-xs text-muted-foreground\">{action.why}</p> : null}\n\n {(action.changes ?? []).length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {(action.changes ?? []).map((change) => (\n <li key={change.id}>\n {/* THE SAME ROW an inline chat proposal uses. */}\n <ProposalRow\n change={change}\n {...(action.status === \"open\"\n ? {}\n : { outcome: { settled: action.status, sentence: action.answer ?? \"\" } as ProposalOutcome })}\n onSettled={(outcome) => void settle(action, outcome)}\n />\n </li>\n ))}\n </ul>\n ) : action.status === \"open\" ? (\n // An approval or an assignment carries no change set, so it gets\n // the same two verbs with nothing to apply: the decision itself\n // is the act, and it is recorded on the action.\n <div className=\"flex items-center gap-1\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() =>\n void settle(action, {\n settled: \"rejected\",\n sentence: action.kind === \"assignment\" ? \"Declined.\" : \"Not approved.\",\n })\n }\n >\n {action.kind === \"assignment\" ? \"Decline\" : \"Reject\"}\n </Button>\n <Button\n size=\"sm\"\n onClick={() =>\n void settle(action, {\n settled: \"accepted\",\n sentence: action.kind === \"assignment\" ? \"Taken.\" : \"Approved.\",\n })\n }\n >\n {action.kind === \"assignment\" ? \"Take it\" : \"Approve\"}\n </Button>\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">{action.answer}</p>\n )}\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n\nfunction toAction(row: ReadRow): QueuedAction {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const status = String(data[\"status\"] ?? \"open\");\n return {\n id: row.id,\n version: null,\n kind: (ACTION_KINDS as readonly string[]).includes(String(data[\"kind\"])) ? (data[\"kind\"] as ActionKind) : \"approval\",\n title: String(data[\"title\"] ?? \"Untitled\"),\n why: (data[\"why\"] as string | undefined) ?? undefined,\n assignee: (data[\"assignee\"] as string | null) ?? null,\n subjectTable: (data[\"subject_table\"] as string | null) ?? null,\n subject: (data[\"subject\"] as string | null) ?? null,\n changes: parseChanges(data[\"changes\"]),\n status: ([\"open\", \"accepted\", \"rejected\", \"refused\"] as string[]).includes(status)\n ? (status as QueuedAction[\"status\"])\n : \"open\",\n answer: (data[\"answer\"] as string | null) ?? null,\n at: String(data[\"at\"] ?? \"\"),\n };\n}\n\nfunction parseChanges(raw: unknown): ProposedChange[] {\n if (Array.isArray(raw)) return raw as ProposedChange[];\n if (typeof raw !== \"string\" || raw.trim() === \"\") return [];\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as ProposedChange[]) : [];\n } catch {\n return [];\n }\n}\n","\"use client\";\n\n// src/HistoryPanel.tsx — @ai-matrx/records-ui · SCR-17\n//\n// WHO CHANGED WHAT, WHEN — from the record's own values, not from a log this\n// package keeps.\n//\n// The store writes a version envelope per VALUE (`custom.record_values_versioned`\n// answers `value_version`, `actor`, `on_behalf_of`, `written_at` and the\n// interned `source` for every field key), so the timeline is the record itself\n// read honestly. There is no second history table to drift from the record.\n//\n// VAL-8 / AGT-N-4 are visible here and they matter: an agent carries the exact\n// authority of the person operating it, so a line written by an agent names\n// BOTH — \"agent, on behalf of <person>\" — and never hides the person behind the\n// machine.\n//\n// THE UNDO DOOR is the store's own soft delete: `record_delete` is reversible\n// within the Table's retention and `record_restore` is the reversal. A deleted\n// record's panel therefore offers Restore and says when the door closes; it\n// does not pretend the record is gone.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport {\n useFields,\n useRecordsClient,\n useTable,\n type ReadValue,\n type RecordRead,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { scalarText } from \"./values\";\n\nexport interface HistoryPanelProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface Entry {\n fieldKey: string;\n label: string;\n version: number;\n at: string | null;\n actor: string;\n onBehalfOf: string | null;\n text: string;\n source: string | null;\n}\n\nexport function HistoryPanel({ tableId, recordId, className }: HistoryPanelProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const [read, setRead] = useState<RecordRead | null>(null);\n const [version, setVersion] = useState<number | null>(null);\n /** The store said `02000` for this record: it is soft-deleted, and Restore is its verb. */\n const [gone, setGone] = useState(false);\n const [values, setValues] = useState<Record<string, ReadValue> | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const [said, setSaid] = useState<string | null>(null);\n\n // THE TIMELINE IS THE RECORD. `record_values_versioned` gives every value its\n // own version, writer, `on_behalf_of` and moment, so there is no second\n // history table to drift. The read door answers documents and deliberately\n // not row metadata, so the record's own version and whether it is deleted\n // come from its revisions (`custom.io_revisions`) — the store, either way.\n const load = useCallback(async () => {\n const [read, versioned, revisions] = await Promise.all([\n client.recordRead({ record_id: recordId }),\n client.recordValuesVersioned({ record_id: recordId }),\n client.revisions({ record_id: recordId }),\n ]);\n // A SOFT-DELETED RECORD IS NOT AN ERROR ON THIS SCREEN. The read door says\n // `02000 There is no record …` for a record the store has deleted — which\n // is exactly the state whose one verb is Restore, so it is read as that\n // state rather than shown as a refusal. Any other refusal is still shown.\n if (!read.ok && read.error.sqlstate !== \"02000\") {\n setError(read.error);\n return;\n }\n setGone(!read.ok);\n if (!versioned.ok) {\n setError(versioned.error);\n return;\n }\n setError(null);\n const byKey: Record<string, ReadValue> = {};\n for (const value of versioned.data) byKey[value.field_key] = value;\n setValues(byKey);\n setVersion(\n revisions.ok\n ? revisions.data.reduce<number | null>(\n (held: number | null, r: { version: number }) => (held === null || r.version > held ? r.version : held),\n null,\n )\n : null,\n );\n setRead(read.ok ? read.data : { record_id: recordId, document: {}, hidden: {}, computed: [] });\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n // NO COMPONENT ACTS BEFORE THE STORE HAS ANSWERED. The undo verb is decided by\n // the TABLE's rights, so a panel drawn while the Table is still loading would\n // show a timeline with no verb on it and no reason why — the same class the\n // grid and the import wizard already wait for.\n if (!read || !values || fields.loading || table.loading) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n const labels = new Map((fields.data ?? []).map((f) => [f.key, f] as const));\n const entries: Entry[] = Object.values(values)\n .map((value) => {\n const field = labels.get(value.field_key);\n return {\n fieldKey: value.field_key,\n label: field?.label || value.field_key,\n version: value.value_version ?? 1,\n at: value.written_at,\n actor: value.actor ?? \"unknown\",\n onBehalfOf: value.on_behalf_of,\n text: value.absent_reason\n ? `absent — ${value.absent_reason}`\n : field\n ? scalarText(field, value.value)\n : JSON.stringify(value.value),\n source: value.source ? Object.values(value.source).map(String).join(\" · \") : null,\n };\n })\n .sort((a, b) => (b.at ?? \"\").localeCompare(a.at ?? \"\"));\n\n const deleted = gone;\n const retention = table.data?.retention_days ?? null;\n\n async function undo(action: \"delete\" | \"restore\") {\n setBusy(true);\n const result =\n action === \"delete\"\n ? await client.recordDelete({ record_id: recordId })\n : await client.recordRestore({ record_id: recordId });\n setBusy(false);\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setSaid(\n action === \"delete\"\n ? retention === null\n ? \"Deleted. The store keeps it reversible; Restore brings it back.\"\n : `Deleted. Restore brings it back for the next ${retention} days.`\n : \"Restored.\",\n );\n await load();\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row. The record's state and its one reversible verb. */}\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">History</h3>\n {version === null ? null : <span className=\"text-xs text-muted-foreground\">v{version}</span>}\n {deleted ? <Badge variant=\"destructive\" className=\"text-[10px]\">Deleted</Badge> : null}\n <div className=\"ml-auto flex items-center gap-1\">\n {rights.write ? (\n <Button size=\"sm\" variant={deleted ? \"secondary\" : \"ghost\"} disabled={busy} onClick={() => void undo(deleted ? \"restore\" : \"delete\")}>\n {deleted ? \"Restore\" : \"Delete\"}\n </Button>\n ) : null}\n </div>\n </div>\n\n {said ? <p className=\"text-xs text-muted-foreground\">{said}</p> : null}\n {deleted && !said ? (\n <p className=\"text-xs text-muted-foreground\">\n {retention === null\n ? \"This record is soft-deleted and Restore brings it back.\"\n : `This record is soft-deleted and stays restorable for ${retention} days.`}\n </p>\n ) : null}\n\n {entries.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">This record has no values yet, so there is nothing to show a history of.</p>\n ) : (\n <ol className=\"flex min-h-0 flex-col divide-y overflow-y-auto rounded border\">\n {entries.map((entry) => (\n <li key={`${entry.fieldKey}-${entry.version}`} className=\"flex items-baseline gap-2 px-2 py-1 text-xs\">\n <span className=\"w-28 shrink-0 truncate font-medium\">{entry.label}</span>\n <span className=\"min-w-0 flex-1 truncate\" title={entry.text}>\n {entry.text}\n </span>\n <span className=\"shrink-0 tabular-nums text-muted-foreground\">v{entry.version}</span>\n <span className=\"shrink-0 text-muted-foreground\" title={entry.source ?? undefined}>\n {/* AGT-N-4: an agent never hides the person it acted for. */}\n {entry.onBehalfOf ? `${entry.actor}, for ${entry.onBehalfOf}` : entry.actor}\n </span>\n <span className=\"w-36 shrink-0 text-right tabular-nums text-muted-foreground\">\n {entry.at ? new Date(entry.at).toLocaleString() : \"—\"}\n </span>\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n","\"use client\";\n\n// src/CommentThread.tsx — @ai-matrx/records-ui · SCR-18\n//\n// A COMMENT IS A RECORD. It lives in this organization's own\n// `records_ui_comment` Table (declared on first use through the store's doors),\n// which is what makes a comment searchable, exportable, agent-readable and\n// subject to the same organization wall as everything else — with no per-feature\n// comment table anywhere.\n//\n// SCR-18's right is `commenter`: a person who may comment but not write records\n// gets the composer, and a person who may not comment gets no composer AND the\n// reason, never a dead box that swallows what they typed.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, useTable, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\n\n/** The package-owned Table every comment is a record of. */\nexport const COMMENT_TABLE: SystemTableSpec = {\n slug: \"records_ui_comment\",\n name: \"Comments\",\n labelSingular: \"Comment\",\n labelPlural: \"Comments\",\n titleField: \"body\",\n fields: [\n { key: \"body\", label: \"Comment\", type: \"text\", sort: 10, required: true, config: { multiline: true } },\n { key: \"subject\", label: \"About\", type: \"text\", sort: 20, required: true },\n { key: \"subject_table\", label: \"In table\", type: \"text\", sort: 30 },\n { key: \"reply_to\", label: \"Reply to\", type: \"text\", sort: 40 },\n { key: \"resolved\", label: \"Resolved\", type: \"text\", sort: 50 },\n // The read door answers documents, not row metadata: who said it and when\n // are part of the comment.\n { key: \"by\", label: \"By\", type: \"text\", sort: 60 },\n { key: \"at\", label: \"At\", type: \"text\", sort: 70 },\n ],\n};\n\nexport interface CommentThreadProps {\n /** The Table the commented-on record belongs to — its rights decide the composer. */\n tableId: Uuid;\n /** The record being discussed. */\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface Comment {\n id: Uuid;\n body: string;\n replyTo: string | null;\n resolved: boolean;\n by: string | null;\n at: string;\n}\n\nexport function CommentThread({ tableId, recordId, className }: CommentThreadProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(COMMENT_TABLE);\n const [comments, setComments] = useState<Comment[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [draft, setDraft] = useState(\"\");\n const [replyTo, setReplyTo] = useState<Uuid | null>(null);\n const [busy, setBusy] = useState(false);\n\n const commentTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!commentTableId) return;\n const result = await client.list({ table_id: commentTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setError(null);\n setComments(\n result.data.rows\n .filter((row) => (row.document as Record<string, unknown>)?.[\"subject\"] === recordId)\n .map(toComment)\n .sort((a, b) => a.at.localeCompare(b.at)),\n );\n }, [client, commentTableId, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function post() {\n if (!commentTableId || draft.trim() === \"\") return;\n setBusy(true);\n const written = await client.recordWrite({\n table_id: commentTableId,\n data: {\n body: draft.trim(),\n subject: recordId,\n subject_table: tableId,\n reply_to: replyTo,\n resolved: \"false\",\n by: client.config.actor.user_id ?? null,\n at: new Date().toISOString(),\n },\n });\n setBusy(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setDraft(\"\");\n setReplyTo(null);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (home.loading || comments === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n const threads = comments.filter((c) => !c.replyTo);\n const repliesOf = (id: string) => comments.filter((c) => c.replyTo === id);\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">Comments</h3>\n <span className=\"text-xs text-muted-foreground\">{comments.length}</span>\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {threads.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No comments on this record yet.</p>\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\">\n {threads.map((comment) => (\n <li key={comment.id} className=\"rounded border p-2\">\n <Line comment={comment} onReply={rights.comment ? () => setReplyTo(comment.id) : undefined} />\n {repliesOf(comment.id).length > 0 ? (\n <ol className=\"mt-1 flex flex-col gap-1 border-l pl-2\">\n {repliesOf(comment.id).map((reply) => (\n <li key={reply.id}>\n <Line comment={reply} />\n </li>\n ))}\n </ol>\n ) : null}\n </li>\n ))}\n </ol>\n )}\n\n {rights.comment ? (\n <form\n className=\"flex flex-col gap-1\"\n onSubmit={(e) => {\n e.preventDefault();\n void post();\n }}\n >\n {replyTo ? (\n <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n Replying\n <Button size=\"sm\" variant=\"ghost\" type=\"button\" onClick={() => setReplyTo(null)}>\n Cancel\n </Button>\n </span>\n ) : null}\n <Textarea\n aria-label=\"Write a comment\"\n rows={2}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n className=\"text-xs\"\n placeholder=\"Write a comment\"\n />\n <div className=\"flex\">\n <Button size=\"sm\" type=\"submit\" className=\"ml-auto\" disabled={busy || draft.trim() === \"\"}>\n Comment\n </Button>\n </div>\n </form>\n ) : (\n // No dead composer. The reason the store or the host gave, in full.\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n )}\n </section>\n );\n}\n\nfunction Line({ comment, onReply }: { comment: Comment; onReply?: (() => void) | undefined }) {\n return (\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-baseline gap-2 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">{comment.by ?? \"unknown\"}</span>\n <span className=\"tabular-nums\">{new Date(comment.at).toLocaleString()}</span>\n {onReply ? (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-5 px-1 text-[11px]\" onClick={onReply}>\n Reply\n </Button>\n ) : null}\n </div>\n <p className=\"whitespace-pre-wrap text-xs\">{comment.body}</p>\n </div>\n );\n}\n\nfunction toComment(row: ReadRow): Comment {\n const data = (row.document ?? {}) as Record<string, unknown>;\n return {\n id: row.id,\n body: String(data[\"body\"] ?? \"\"),\n replyTo: (data[\"reply_to\"] as string | null) ?? null,\n resolved: data[\"resolved\"] === \"true\",\n by: (data[\"by\"] as string | null) ?? null,\n at: String(data[\"at\"] ?? \"\"),\n };\n}\n","\"use client\";\n\n// src/forms.ts — @ai-matrx/records-ui · SCR-13, SCR-14\n//\n// A FORM IS A VIEW ON A REAL TABLE.\n//\n// It is not a second data model with its own \"responses\" store that somebody\n// later has to reconcile with the records people actually work on. A form names\n// a Table, each of its questions names one of that Table's own Fields, and a\n// submission is an ORDINARY RECORD in that Table — so the moment it is sent it\n// is in the grid, in the views, in the exports, in History and in the agent's\n// context, with no plumbing in between.\n//\n// THE AI-FIRST LAW. We build a Typeform duplicate not because people will click\n// a form together one question at a time, but because an agent writes the WHOLE\n// thing in one `record_write` and the person only tweaks it. `FormSpec` below is\n// that complete declarative object: name, questions, conditional logic, theme,\n// thank-you screen. `FormBuilder` takes one as `seed`, exactly as `ViewBar` and\n// `ActionInbox` do.\n//\n// CONDITIONAL LOGIC IS A RULE, NOT AN `if`. `showIf` is a Rule expression the\n// STORE evaluates (`custom.rule_eval`), referencing Fields BY ID. So the same\n// form means the same thing to the runner, to the server and to an agent, and\n// nobody re-implements the predicate in JavaScript where it can drift.\n\nimport type { ReadRow, RuleExpression, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** How a form is put in front of a person. */\nexport const FORM_FLOWS = [\"one-at-a-time\", \"single-page\"] as const;\nexport type FormFlow = (typeof FORM_FLOWS)[number];\n\n/** One question. It ASKS FOR one Field of the subject Table — never its own column. */\nexport interface FormQuestionSpec {\n /** The Field's key on the subject Table. */\n field: string;\n /** Ask it in the form's own words. Left out, the Field's own label is the question. */\n ask?: string | null;\n /** One line under the question. */\n help?: string | null;\n /** Override the Field's own `required`. Left out, the Field decides. */\n required?: boolean | null;\n /**\n * CONDITIONAL LOGIC, AS A RULE. `{\"op\":\"eq\",\"args\":[{\"field\":\"<field id>\"},{\"const\":\"Yes\"}]}`\n * — the store answers it, this package never does. An UNDECIDED answer (the\n * store's `null`, which is what an unanswered question gives) SHOWS the\n * question: a person is never silently skipped past something.\n */\n showIf?: RuleExpression | null;\n}\n\n/** The look. Tokens, so light and dark both come out right without a second theme. */\nexport interface FormTheme {\n /** A design-system accent class or a CSS color. Left out, the app's own accent. */\n accent?: string | null;\n align?: \"left\" | \"center\" | null;\n}\n\n/** THE COMPLETE DECLARATIVE SPEC. One `record_write` and the form exists. */\nexport interface FormSpec {\n name: string;\n /** The Table a submission lands in. */\n subject: Uuid;\n intro?: string | null;\n questions: FormQuestionSpec[];\n flow?: FormFlow | null;\n theme?: FormTheme | null;\n thankYou?: { title: string; body?: string | null } | null;\n submitLabel?: string | null;\n /**\n * Is this form meant to be answerable by someone who is not signed in? The\n * runner does NOT make that true by itself — it needs the anonymous write\n * door, and until that door exists it says so BY NAME rather than writing as\n * whoever happens to be signed in and calling it public.\n */\n isPublic?: boolean;\n}\n\n/** A form as it comes back out of the store, with its record's own id and version. */\nexport interface SavedForm extends FormSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every form is a record of. */\nexport const FORM_TABLE: SystemTableSpec = {\n slug: \"records_ui_form\",\n name: \"Forms\",\n labelSingular: \"Form\",\n labelPlural: \"Forms\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"intro\", label: \"Intro\", type: \"text\", sort: 30, config: { multiline: true } },\n { key: \"questions\", label: \"Questions\", type: \"text\", sort: 40, config: { multiline: true } },\n { key: \"flow\", label: \"Flow\", type: \"text\", sort: 50 },\n { key: \"theme\", label: \"Theme\", type: \"text\", sort: 60, config: { multiline: true } },\n { key: \"thank_you\", label: \"Thank-you screen\", type: \"text\", sort: 70, config: { multiline: true } },\n { key: \"submit_label\", label: \"Submit button\", type: \"text\", sort: 80 },\n { key: \"is_public\", label: \"Public\", type: \"text\", sort: 90 },\n ],\n};\n\n/** The spec as the one document the store holds. */\nexport function formDocument(spec: FormSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n intro: spec.intro ?? null,\n questions: JSON.stringify(spec.questions ?? []),\n flow: spec.flow ?? \"one-at-a-time\",\n theme: JSON.stringify(spec.theme ?? {}),\n thank_you: JSON.stringify(spec.thankYou ?? null),\n submit_label: spec.submitLabel ?? null,\n is_public: spec.isPublic ? \"true\" : \"false\",\n };\n}\n\n/** One stored record back into the spec a screen and an agent both read. */\nexport function formFromRecord(row: ReadRow): SavedForm {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const flow = String(data[\"flow\"] ?? \"one-at-a-time\");\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled form\"),\n subject: String(data[\"subject\"] ?? \"\"),\n intro: (data[\"intro\"] as string | null) ?? null,\n questions: parseJson<FormQuestionSpec[]>(data[\"questions\"], []),\n flow: (FORM_FLOWS as readonly string[]).includes(flow) ? (flow as FormFlow) : \"one-at-a-time\",\n theme: parseJson<FormTheme>(data[\"theme\"], {}),\n thankYou: parseJson<{ title: string; body?: string | null } | null>(data[\"thank_you\"], null) ?? null,\n submitLabel: (data[\"submit_label\"] as string | null) ?? null,\n isPublic: data[\"is_public\"] === \"true\",\n };\n}\n\nfunction parseJson<T>(raw: unknown, fallback: T): T {\n if (raw === null || raw === undefined) return fallback;\n if (typeof raw !== \"string\") return raw as T;\n if (raw.trim() === \"\") return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\n/**\n * THE SOURCE STAMP every submission carries. A record that arrived through a\n * form is not indistinguishable from one somebody typed into the grid: it says\n * which form, which version of it, when, and who was acting. `_source` is a\n * stamp on the document beside the answers, so it travels with the record\n * through export, History and the agent's context without a parallel table.\n */\nexport function submissionStamp(args: {\n formId: Uuid | null;\n formName: string;\n actor: string;\n onBehalfOf?: string | null;\n}): Record<string, unknown> {\n return {\n _source: {\n via: \"form\",\n form_id: args.formId,\n form_name: args.formName,\n at: new Date().toISOString(),\n actor: args.actor,\n ...(args.onBehalfOf ? { on_behalf_of: args.onBehalfOf } : {}),\n },\n };\n}\n","\"use client\";\n\n// src/FormBuilder.tsx — @ai-matrx/records-ui · SCR-13\n//\n// THE FORM BUILDER, BUILT FOR THE AGENT FIRST.\n//\n// `seed` takes COMPLETE declarative `FormSpec`s an agent wrote — the whole form\n// in one object, questions, conditions, theme and thank-you screen included —\n// and saves each one that is not there yet as a record. That is the 45 seconds\n// the law is about. Everything else on this screen is the TWEAK: a person\n// changes what the agent got wrong, one control at a time, and never has to\n// assemble a form field by field to have one.\n//\n// The questions a person can add are the subject Table's own Fields, because a\n// form is a view on a real Table — there is no way in this screen to invent a\n// question that lands nowhere, which is why a submission is a record and not a\n// \"response\" in a second store.\n//\n// A condition is written as the store's own Rule expression, pointing at a\n// Field BY ID (REC-17). The builder never writes a field NAME into a rule: the\n// store refuses that by name, and it is right to.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, RuleExpression } from \"@ai-matrx/records\";\nimport {\n BasicInput,\n BasicTextarea,\n Button,\n Checkbox,\n Label,\n Skeleton,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useRecordVersion, useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { FormRunner } from \"./FormRunner\";\nimport { fieldName } from \"./names\";\nimport {\n FORM_FLOWS,\n FORM_TABLE,\n formDocument,\n formFromRecord,\n type FormFlow,\n type FormQuestionSpec,\n type FormSpec,\n type SavedForm,\n} from \"./forms\";\n\nexport interface FormBuilderProps {\n /** The Table this form collects into. A form is a view on a real Table. */\n tableId: Uuid;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these whose name this\n * table does not have yet is saved as a record the first time the builder\n * loads. A seed whose name exists is LEFT ALONE — an agent re-running never\n * overwrites what a person has since tweaked.\n */\n seed?: FormSpec[] | undefined;\n activeFormId?: Uuid | null | undefined;\n onActiveForm?: ((form: SavedForm) => void) | undefined;\n className?: string | undefined;\n}\n\n/** The comparisons a condition can make. The store's own operator names. */\nconst CONDITION_OPS: Array<{ op: string; label: string }> = [\n { op: \"eq\", label: \"is\" },\n { op: \"ne\", label: \"is not\" },\n { op: \"present\", label: \"has been answered\" },\n { op: \"gt\", label: \"is more than\" },\n { op: \"lt\", label: \"is less than\" },\n];\n\nexport function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }: FormBuilderProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const home = useSystemTable(FORM_TABLE);\n const [forms, setForms] = useState<SavedForm[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeFormId ?? null);\n const [draft, setDraft] = useState<SavedForm | null>(null);\n const [saving, setSaving] = useState(false);\n const [saved, setSaved] = useState<string | null>(null);\n // The version of the form record this screen LOADED, read for the one record\n // being edited. Null means the save is the store's last-writer-wins write.\n const loadedVersion = useRecordVersion(activeId);\n\n const formTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!formTableId) return;\n const result = await client.list({ table_id: formTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n let mine = result.data.rows.map(formFromRecord).filter((f) => f.subject === tableId);\n const missing = (seed ?? []).filter((s) => !mine.some((f) => f.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: formTableId,\n data: formDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: formTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n mine = again.data.rows.map(formFromRecord).filter((f) => f.subject === tableId);\n }\n setError(null);\n setForms(mine);\n }, [client, formTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!forms || forms.length === 0) return;\n const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n setDraft(chosen);\n onActiveForm?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [forms, activeFormId]);\n\n const byKey = useMemo(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);\n\n function patch(change: Partial<FormSpec>) {\n setDraft((prev) => (prev ? { ...prev, ...change } : prev));\n setSaved(null);\n }\n\n function patchQuestion(index: number, change: Partial<FormQuestionSpec>) {\n setDraft((prev) => {\n if (!prev) return prev;\n const questions = prev.questions.map((q, i) => (i === index ? { ...q, ...change } : q));\n return { ...prev, questions };\n });\n setSaved(null);\n }\n\n async function save() {\n if (!draft || !formTableId) return;\n setSaving(true);\n const document = formDocument(draft);\n const written = await client.recordUpdate({\n record_id: draft.id,\n patch: document,\n // The form record's own version: two people editing one form are TOLD.\n ...(loadedVersion === null ? {} : { expectedVersion: loadedVersion }),\n });\n setSaving(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setSaved(\"Saved.\");\n await load();\n }\n\n async function create(name: string) {\n if (!formTableId) return;\n const written = await client.recordWrite({\n table_id: formTableId,\n data: formDocument({ name, subject: tableId, questions: [] }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setActiveId(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (home.loading || fields.loading || forms === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!rights.admin) {\n // SCR-4 again: building a form is administering the table. There is no\n // greyed-out builder — there is no builder, and the reason is readable.\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n }\n\n return (\n <div className={cn(\"flex min-h-0 gap-3\", className)}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-2 overflow-auto\">\n {/* One row: the forms, the flow, the save. No repeated names. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Forms\">\n {forms.map((form) => (\n <Button\n key={form.id}\n size=\"sm\"\n variant={form.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={form.id === activeId}\n onClick={() => {\n setActiveId(form.id);\n setDraft(form);\n }}\n >\n {form.name}\n </Button>\n ))}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void create(`Form ${forms.length + 1}`)}>\n New form\n </Button>\n <span className=\"ml-auto flex items-center gap-2\">\n {saved ? <span className=\"text-xs text-muted-foreground\">{saved}</span> : null}\n <Button size=\"sm\" disabled={saving || !draft} onClick={() => void save()}>\n {saving ? \"Saving…\" : \"Save\"}\n </Button>\n </span>\n </div>\n\n {!draft ? (\n <p className=\"text-xs text-muted-foreground\">\n No form collects into this table yet. \"New form\" makes one, or an agent writes a whole one with a\n single record.\n </p>\n ) : (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Name</Label>\n <BasicInput value={draft.name} onChange={(e) => patch({ name: e.target.value })} />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Flow</Label>\n <select\n className=\"h-9 rounded border bg-background px-2 text-sm\"\n value={draft.flow ?? \"one-at-a-time\"}\n onChange={(e) => patch({ flow: e.target.value as FormFlow })}\n >\n {FORM_FLOWS.map((flow) => (\n <option key={flow} value={flow}>\n {flow === \"one-at-a-time\" ? \"One question at a time\" : \"All on one page\"}\n </option>\n ))}\n </select>\n </label>\n <label className=\"col-span-2 flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Intro</Label>\n <BasicTextarea\n rows={2}\n value={draft.intro ?? \"\"}\n onChange={(e) => patch({ intro: e.target.value || null })}\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Submit button</Label>\n <BasicInput\n value={draft.submitLabel ?? \"\"}\n placeholder=\"Submit\"\n onChange={(e) => patch({ submitLabel: e.target.value || null })}\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Thank-you title</Label>\n <BasicInput\n value={draft.thankYou?.title ?? \"\"}\n placeholder=\"Thank you\"\n onChange={(e) =>\n patch({\n thankYou: e.target.value\n ? { title: e.target.value, body: draft.thankYou?.body ?? null }\n : null,\n })\n }\n />\n </label>\n </div>\n\n {/* The questions. Each one asks for a Field this Table actually has. */}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Questions</span>\n <span>{draft.questions.length} of this table's {fields.data?.length ?? 0} fields</span>\n </div>\n {(fields.data ?? []).map((field) => {\n const index = draft.questions.findIndex((q) => q.field === field.key);\n const asked = index >= 0;\n const question = asked ? draft.questions[index]! : null;\n return (\n <div key={field.id} className=\"rounded border px-2 py-1.5\">\n <div className=\"flex items-center gap-2\">\n <Checkbox\n checked={asked}\n aria-label={`Ask for ${fieldName(field)}`}\n onCheckedChange={(checked) =>\n patch({\n questions: checked\n ? [...draft.questions, { field: field.key }]\n : draft.questions.filter((q) => q.field !== field.key),\n })\n }\n />\n <span className=\"text-xs font-medium\">{fieldName(field)}</span>\n <span className=\"text-xs text-muted-foreground\">{field.key}</span>\n {field.required ? <span className=\"text-xs text-destructive\">required</span> : null}\n </div>\n {asked && question ? (\n <div className=\"mt-1.5 grid grid-cols-2 gap-2 pl-6\">\n <BasicInput\n className=\"h-8 text-xs\"\n placeholder={fieldName(field)}\n aria-label={`How to ask for ${field.key}`}\n value={question.ask ?? \"\"}\n onChange={(e) => patchQuestion(index, { ask: e.target.value || null })}\n />\n <BasicInput\n className=\"h-8 text-xs\"\n placeholder=\"Help text\"\n aria-label={`Help text for ${field.key}`}\n value={question.help ?? \"\"}\n onChange={(e) => patchQuestion(index, { help: e.target.value || null })}\n />\n <Condition\n question={question}\n fieldKeys={fields.data ?? []}\n onChange={(showIf) => patchQuestion(index, { showIf })}\n />\n </div>\n ) : null}\n </div>\n );\n })}\n {draft.questions\n .filter((q) => !byKey.has(q.field))\n .map((q) => (\n <p key={q.field} className=\"text-xs text-destructive\">\n This form asks for \"{q.field}\" and this table has no such Field. It is shown here rather\n than quietly dropped.\n </p>\n ))}\n </div>\n </>\n )}\n </div>\n\n {/* The preview is the RUNNER, not a picture of it: what a person will actually meet. */}\n {draft ? (\n <aside className=\"w-96 shrink-0 overflow-auto rounded border p-2\">\n <FormRunner form={draft} preview />\n </aside>\n ) : null}\n </div>\n );\n}\n\n/** The one condition row. It writes the store's own Rule expression, by Field id. */\nfunction Condition({\n question,\n fieldKeys,\n onChange,\n}: {\n question: FormQuestionSpec;\n fieldKeys: Array<{ id: string; key: string; label: string }>;\n onChange: (showIf: RuleExpression | null) => void;\n}) {\n const expr = question.showIf as { op?: string; args?: Array<{ field?: string; const?: unknown }> } | null;\n const op = expr?.op ?? \"\";\n const onField = expr?.args?.[0]?.field ?? \"\";\n const value = expr?.args?.[1]?.const ?? \"\";\n\n function write(next: { op?: string; field?: string; value?: unknown }) {\n const chosenOp = next.op ?? op;\n const chosenField = next.field ?? onField;\n const chosenValue = next.value ?? value;\n if (!chosenOp || !chosenField) {\n onChange(null);\n return;\n }\n onChange(\n chosenOp === \"present\"\n ? ({ op: \"present\", args: [{ field: chosenField }] } as RuleExpression)\n : ({ op: chosenOp, args: [{ field: chosenField }, { const: chosenValue }] } as RuleExpression),\n );\n }\n\n return (\n <div className=\"col-span-2 flex items-center gap-1 text-xs\">\n <span className=\"text-muted-foreground\">Ask only when</span>\n <select\n aria-label=\"Condition field\"\n className=\"h-8 rounded border bg-background px-1 text-xs\"\n value={onField}\n onChange={(e) => write({ field: e.target.value })}\n >\n <option value=\"\">always</option>\n {fieldKeys.map((f) => (\n <option key={f.id} value={f.id}>\n {f.label || f.key}\n </option>\n ))}\n </select>\n {onField ? (\n <>\n <select\n aria-label=\"Condition comparison\"\n className=\"h-8 rounded border bg-background px-1 text-xs\"\n value={op}\n onChange={(e) => write({ op: e.target.value })}\n >\n {CONDITION_OPS.map((c) => (\n <option key={c.op} value={c.op}>\n {c.label}\n </option>\n ))}\n </select>\n {op !== \"present\" ? (\n <BasicInput\n className=\"h-8 w-28 text-xs\"\n aria-label=\"Condition value\"\n value={String(value ?? \"\")}\n onChange={(e) => write({ value: e.target.value })}\n />\n ) : null}\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/FormRunner.tsx — @ai-matrx/records-ui · SCR-14\n//\n// THE FORM, AS THE PERSON ANSWERING IT SEES IT. One question at a time, a\n// progress line that is honest about how many questions are actually left, the\n// keyboard doing what a keyboard does (Enter goes on, Shift+Enter goes back),\n// and a submission that is an ORDINARY RECORD in a real Table the moment it is\n// sent.\n//\n// FOUR THINGS THIS COMPONENT REFUSES TO DO:\n//\n// 1. It never evaluates a condition itself. `showIf` is a Rule and the STORE\n// answers it (`custom.rule_eval`), so the form branches the same way for a\n// person, for the server and for an agent. An UNDECIDED answer — which is\n// what the store returns for a question nobody has answered yet — SHOWS the\n// question. Undecided is not false, and silently skipping a person past\n// something is the exact failure the store's own null-handling avoids.\n// 2. It never draws a file chooser with nowhere to put the file. With no\n// `upload` port bound the attachment question says so in one sentence.\n// 3. It never calls itself public. `isPublic` needs the anonymous write door;\n// until that door exists the runner works SIGNED IN and says \"public link\n// pending\" naming `custom.anon_record_write` and the lane that owes it.\n// 4. It never invents its own editors. Every answer is taken with the same\n// `FieldControl` the record form uses, so a currency in a form and a\n// currency in the grid are the same control with the same unit.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useFields, useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport { doorExists, DOORS } from \"@ai-matrx/records/core\";\nimport type { Field, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Progress, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { FieldControl, FieldLabel } from \"./editors\";\nimport { editorKindFor } from \"./parity\";\nimport { NO_UPLOAD_REASON, useRecordsUi } from \"./host\";\nimport { submissionStamp, type FormSpec, type SavedForm } from \"./forms\";\n\nexport interface FormRunnerProps {\n /** The complete spec. An agent wrote it; `FormBuilder` saved it; this runs it. */\n form: FormSpec | SavedForm;\n /** Preview mode answers the questions but writes nothing, and says so. */\n preview?: boolean | undefined;\n onSubmitted?: ((recordId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\ntype Answers = Record<string, unknown>;\n\n/** One question resolved against the subject Table's own Fields. */\ninterface ResolvedQuestion {\n key: string;\n ask: string;\n help: string | null;\n required: boolean;\n /** Null when the Table has no such Field — named on screen, never dropped. */\n field: Field | null;\n showIf: unknown;\n}\n\nexport function FormRunner({ form, preview = false, onSubmitted, className }: FormRunnerProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const fields = useFields(form.subject);\n const [answers, setAnswers] = useState<Answers>({});\n const [at, setAt] = useState(0);\n const [error, setError] = useState<RecordsError | null>(null);\n const [writing, setWriting] = useState(false);\n const [done, setDone] = useState<Uuid | \"preview\" | null>(null);\n /** Which conditional questions the STORE said to hide. Keyed by field key. */\n const [hidden, setHidden] = useState<Record<string, boolean>>({});\n const stage = useRef<HTMLDivElement>(null);\n\n const questions: ResolvedQuestion[] = useMemo(() => {\n const byKey = new Map((fields.data ?? []).map((f) => [f.key, f]));\n return (form.questions ?? []).map((q) => {\n const field = byKey.get(q.field) ?? null;\n return {\n key: q.field,\n ask: q.ask ?? field?.label ?? q.field,\n help: q.help ?? null,\n required: q.required ?? field?.required ?? false,\n field,\n showIf: q.showIf ?? null,\n };\n });\n }, [fields.data, form.questions]);\n\n // ── the conditions, answered by the STORE ────────────────────────────────\n // Re-asked whenever an answer changes, because that is what a condition is\n // about. One call per conditional question; a form with no conditions makes\n // no calls at all.\n useEffect(() => {\n let cancelled = false;\n const conditional = questions.filter((q) => q.showIf);\n if (conditional.length === 0) return;\n void (async () => {\n const next: Record<string, boolean> = {};\n for (const q of conditional) {\n const answered = await client.ruleEval({ expr: q.showIf, values: answers });\n if (!answered.ok) {\n // A condition the store could not work out is NOT a silent hide: the\n // question stays, and the store's sentence is shown above the form.\n if (!cancelled) setError(answered.error);\n next[q.key] = false;\n continue;\n }\n // `null` is UNDECIDED. Undecided shows the question.\n next[q.key] = answered.data === false;\n }\n if (!cancelled) setHidden(next);\n })();\n return () => {\n cancelled = true;\n };\n }, [client, questions, answers]);\n\n const live = questions.filter((q) => !hidden[q.key]);\n const oneAtATime = (form.flow ?? \"one-at-a-time\") === \"one-at-a-time\";\n const index = Math.min(at, Math.max(live.length - 1, 0));\n const current = live[index];\n const centred = (form.theme?.align ?? \"center\") === \"center\";\n\n const answered = live.filter((q) => {\n const v = answers[q.key];\n return v !== undefined && v !== null && v !== \"\";\n }).length;\n\n const missing = live.filter((q) => {\n const v = answers[q.key];\n return q.required && (v === undefined || v === null || v === \"\");\n });\n\n const submit = useCallback(async () => {\n if (preview) {\n setDone(\"preview\");\n return;\n }\n setWriting(true);\n setError(null);\n const document = {\n ...Object.fromEntries(live.map((q) => [q.key, answers[q.key] ?? null])),\n ...submissionStamp({\n formId: (form as SavedForm).id ?? null,\n formName: form.name,\n actor: client.config.actor.actor,\n onBehalfOf: client.config.actor.on_behalf_of ?? null,\n }),\n };\n const written = await client.recordWrite({ table_id: form.subject, data: document });\n setWriting(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setDone(written.data);\n onSubmitted?.(written.data);\n }, [answers, client, form, live, onSubmitted, preview]);\n\n function advance() {\n if (!oneAtATime) return;\n if (index < live.length - 1) setAt(index + 1);\n else if (missing.length === 0) void submit();\n }\n\n function retreat() {\n if (oneAtATime && index > 0) setAt(index - 1);\n }\n\n // The keyboard flow. Enter goes on, Shift+Enter goes back — except inside a\n // long-text answer, where Enter is a new line and always has been.\n function onKeyDown(event: React.KeyboardEvent) {\n if (event.key !== \"Enter\") return;\n const target = event.target as HTMLElement;\n if (target.tagName === \"TEXTAREA\" && !event.metaKey && !event.ctrlKey) return;\n event.preventDefault();\n if (event.shiftKey) retreat();\n else advance();\n }\n\n useEffect(() => {\n // Moving to a question puts the caret in it: a person who is typing never\n // has to reach for the mouse to answer the next one.\n const input = stage.current?.querySelector<HTMLElement>(\"input, textarea, select, [role='combobox']\");\n input?.focus();\n }, [index, done]);\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (fields.loading) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n // ── the thank-you screen ─────────────────────────────────────────────────\n if (done) {\n return (\n <section className={cn(\"mx-auto max-w-xl py-10\", centred && \"text-center\", className)}>\n <h2 className=\"text-lg font-medium\">{form.thankYou?.title ?? \"Thank you\"}</h2>\n {form.thankYou?.body ? <p className=\"mt-1 text-sm text-muted-foreground\">{form.thankYou.body}</p> : null}\n <p className=\"mt-3 text-xs text-muted-foreground\">\n {done === \"preview\"\n ? \"This was a preview, so nothing was written.\"\n : `Saved as a record in ${form.name}. It is in the table now, with this form stamped on it.`}\n </p>\n </section>\n );\n }\n\n const unresolved = questions.filter((q) => !q.field);\n // W4-ANON LANDED, AND UNDER A DIFFERENT NAME THAN THIS PACKAGE GUESSED AT.\n // The lane is `custom.anon_write` behind `custom.anon_token_verify`, not one\n // door called `anon_record_write`, and while this file named the guess every\n // person answering a public form was told the feature was \"pending\" for\n // something that had shipped. A screen calling a live feature pending is the\n // same silent failure as a screen calling a missing one live.\n //\n // What is still true: a public answer is posted with an EMBED TOKEN, from an\n // allowed origin, into a PUBLISHED form — none of which a signed-in runner\n // has. So a public form mounted here still runs signed-in, and now says the\n // true reason and the exact thing to do about it.\n const publicPending = form.isPublic === true && !doorExists(DOORS.anonWrite);\n const publicNeedsEmbed = form.isPublic === true && doorExists(DOORS.anonWrite);\n\n return (\n <section\n className={cn(\"mx-auto flex max-w-xl flex-col gap-3 py-4\", centred && \"text-center\", className)}\n onKeyDown={onKeyDown}\n >\n {/* One row. The name, the progress, the count — no subtitle restating the name. */}\n <header className=\"flex items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{form.name}</span>\n <Progress value={live.length === 0 ? 0 : (answered / live.length) * 100} className=\"h-1 flex-1\" />\n <span className=\"tabular-nums\">\n {oneAtATime ? `${index + 1} of ${live.length}` : `${answered} of ${live.length}`}\n </span>\n </header>\n\n {publicPending ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-muted-foreground\">\n Public link pending: this store has no <code>custom.anon_write</code> door, so this form is being\n answered as the person signed in, and their name is what the record will carry.\n </p>\n ) : null}\n\n {publicNeedsEmbed ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-muted-foreground\">\n You are answering this signed in, so the record will carry your name. A stranger answers the same\n form through an embed: issue one with <code>EmbedFrame</code>, publish the form, and their answer\n arrives as a quarantined submission rather than a record written as whoever happened to be signed\n in here.\n </p>\n ) : null}\n\n {unresolved.length > 0 ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-destructive\">\n {unresolved.map((q) => q.key).join(\", \")} {unresolved.length === 1 ? \"is a question\" : \"are questions\"} this\n form asks for and this table has no such Field. Add the Field, or take the question out — it is\n shown here rather than quietly dropped, because a dropped question is an answer nobody gave.\n </p>\n ) : null}\n\n {form.intro && index === 0 ? <p className=\"text-sm text-muted-foreground\">{form.intro}</p> : null}\n\n {error ? <RefusalNotice error={error} className=\"text-left\" /> : null}\n\n <div ref={stage} className=\"flex flex-col gap-4 text-left\">\n {(oneAtATime ? (current ? [current] : []) : live).map((q) => (\n <Question\n key={q.key}\n question={q}\n value={answers[q.key]}\n onChange={(v) => setAnswers((prev) => ({ ...prev, [q.key]: v }))}\n upload={host.upload}\n />\n ))}\n {live.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n Every question in this form is hidden by its own condition right now, so there is nothing to\n answer yet.\n </p>\n ) : null}\n </div>\n\n <footer className={cn(\"flex items-center gap-2\", centred && \"justify-center\")}>\n {oneAtATime && index > 0 ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={retreat}>\n Back\n </Button>\n ) : null}\n {oneAtATime && index < live.length - 1 ? (\n <Button size=\"sm\" onClick={advance}>\n Next\n </Button>\n ) : (\n <Button size=\"sm\" disabled={writing || missing.length > 0} onClick={() => void submit()}>\n {writing ? \"Sending…\" : (form.submitLabel ?? \"Submit\")}\n </Button>\n )}\n {missing.length > 0 && (!oneAtATime || index === live.length - 1) ? (\n <span className=\"text-xs text-muted-foreground\">\n {missing.map((q) => q.ask).join(\", \")} still {missing.length === 1 ? \"needs\" : \"need\"} an answer.\n </span>\n ) : null}\n {preview ? <span className=\"text-xs text-muted-foreground\">Preview — nothing is written.</span> : null}\n </footer>\n </section>\n );\n}\n\n/** One question: the Field's own editor, or the honest sentence when it cannot be drawn. */\nfunction Question({\n question,\n value,\n onChange,\n upload,\n}: {\n question: ResolvedQuestion;\n value: unknown;\n onChange: (value: unknown) => void;\n upload: ReturnType<typeof useRecordsUi>[\"upload\"];\n}) {\n const [uploadError, setUploadError] = useState<string | null>(null);\n const field = question.field;\n if (!field) return null;\n\n const id = `form-${field.key}`;\n const isAttachment = editorKindFor(field) === \"attachment\";\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel field={{ ...field, label: question.ask, required: question.required }} htmlFor={id} />\n {question.help ? <p className=\"text-xs text-muted-foreground\">{question.help}</p> : null}\n {isAttachment && !upload ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_UPLOAD_REASON}</p>\n ) : isAttachment ? (\n <>\n <input\n id={id}\n type=\"file\"\n className=\"text-xs\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploadError(null);\n void upload?.(file).then((result) => {\n if (!result) return;\n if (result.ok) onChange(result.fileId);\n else setUploadError(result.reason);\n });\n }}\n />\n {uploadError ? <p className=\"text-xs text-destructive\">{uploadError}</p> : null}\n </>\n ) : (\n <FieldControl field={field} value={value} onChange={onChange} id={id} />\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/charts.ts — @ai-matrx/records-ui · SCR-15, SCR-16\n//\n// A CHART IS A QUESTION THE STORE ANSWERS, NOT A PILE OF ROWS A BROWSER SUMS.\n//\n// Every block here is drawn from ONE call to `custom.record_aggregate` — the\n// eighth verb (AGT-N-8) — whose aggregate node sits ABOVE the join to the read\n// door's visibility set. Two consequences, and both of them are the reason this\n// file exists at all:\n//\n// · A chart shows exactly the records this person may see. Rows they may not\n// see are never fetched, so they cannot be summed and then hidden — and a\n// total that quietly included them would be a screen lying in the one place\n// nobody would ever check.\n// · A dashboard over a hundred thousand records is one round trip per block,\n// not a hundred thousand rows over the wire.\n//\n// AND A DASHBOARD IS ONE RECORD. `DashboardSpec` is the whole thing — every\n// block, its question and its shape — so an agent writes a finished dashboard\n// with ONE `record_write` and the person only tweaks it.\n\nimport type { AggregateBucket, AggregateMeasure, ReadRow, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** The shapes a block can take. Closed: a shape nobody drew is not offered. */\nexport const CHART_KINDS = [\"bar\", \"column\", \"line\", \"donut\", \"number\", \"table\"] as const;\nexport type ChartKind = (typeof CHART_KINDS)[number];\n\nexport const CHART_KIND_LABEL: Record<ChartKind, string> = {\n bar: \"Bars\",\n column: \"Columns\",\n line: \"Line\",\n donut: \"Donut\",\n number: \"Number\",\n table: \"Table\",\n};\n\n/** What each shape needs before it can draw, in one sentence a block prints. */\nexport const CHART_NEEDS: Record<ChartKind, string | null> = {\n bar: \"A bar chart needs something to group by — pick a Field and the bars appear.\",\n column: \"A column chart needs something to group by — pick a Field and the columns appear.\",\n line: \"A line needs a date Field to run along — pick one and the line appears.\",\n donut: \"A donut needs something to group by — pick a Field and the slices appear.\",\n number: null,\n table: null,\n};\n\n/** ONE BLOCK: the question and the shape, in one declarative object. */\nexport interface ChartSpec {\n title: string;\n /** The Table this block asks about. */\n subject: Uuid;\n kind: ChartKind;\n /** Field keys whose values become the groups. */\n groupBy?: string[];\n /** A date Field truncated to a period — what a line runs along. */\n bucket?: { key: string; by: AggregateBucket } | null;\n /** `count` needs no key; every other measure reads one Field. */\n measures?: AggregateMeasure[];\n /** Equality only, and the store puts it in the SAME WHERE as visibility. */\n filter?: Record<string, string>;\n limit?: number;\n /** How wide this block sits on the canvas, in twelfths. */\n span?: number;\n}\n\n/** THE WHOLE DASHBOARD, as one object an agent writes in one call. */\nexport interface DashboardSpec {\n name: string;\n /** The Table most of its blocks are about. A block may name another. */\n subject: Uuid;\n blocks: ChartSpec[];\n}\n\nexport interface SavedDashboard extends DashboardSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every dashboard is a record of. */\nexport const DASHBOARD_TABLE: SystemTableSpec = {\n slug: \"records_ui_dashboard\",\n name: \"Dashboards\",\n labelSingular: \"Dashboard\",\n labelPlural: \"Dashboards\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"blocks\", label: \"Blocks\", type: \"text\", sort: 30, config: { multiline: true } },\n ],\n};\n\nexport function dashboardDocument(spec: DashboardSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n blocks: JSON.stringify(spec.blocks ?? []),\n };\n}\n\nexport function dashboardFromRecord(row: ReadRow): SavedDashboard {\n const data = (row.document ?? {}) as Record<string, unknown>;\n let blocks: ChartSpec[] = [];\n const raw = data[\"blocks\"];\n if (Array.isArray(raw)) blocks = raw as ChartSpec[];\n else if (typeof raw === \"string\" && raw.trim() !== \"\") {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (Array.isArray(parsed)) blocks = parsed as ChartSpec[];\n } catch {\n blocks = [];\n }\n }\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled dashboard\"),\n subject: String(data[\"subject\"] ?? \"\"),\n blocks,\n };\n}\n\n/**\n * The series palette. Six SEMANTIC tokens the design system already flips for\n * dark mode, so a chart is correct in both themes without a second palette and\n * without a hex code anywhere in this package.\n */\nexport const SERIES_COLORS = [\n \"hsl(var(--primary))\",\n \"hsl(var(--info))\",\n \"hsl(var(--success))\",\n \"hsl(var(--warning))\",\n \"hsl(var(--destructive))\",\n \"hsl(var(--accent-foreground))\",\n] as const;\n\n/** The label one aggregate row carries — its groups, joined the way a person reads them. */\nexport function groupLabel(groups: Record<string, string | null>): string {\n const parts = Object.values(groups).map((v) => (v === null || v === \"\" ? \"—\" : v));\n return parts.length === 0 ? \"All records\" : parts.join(\" · \");\n}\n","\"use client\";\n\n// src/docs.ts — @ai-matrx/records-ui · SCR-20, SCR-21, SCR-22\n//\n// DOCUMENTS OVER RECORDS. A template is a body whose tokens point at Fields BY\n// ID; a render is written ONCE and frozen with the SHA-256 of its own text; a\n// signature seals that exact version and is immutable once made.\n//\n// Three things this package refuses to re-implement, because the store already\n// does them and doing them twice is how two answers appear:\n// · which tokens a body contains — `custom.doc_tokens`;\n// · which of them this Table cannot answer, and why — `custom.doc_unresolved_tokens`;\n// · whether a signature still holds — `custom.doc_signature_intact`.\n//\n// The token syntax is the store's own: `{{field:<the field's id>}}`. A name\n// would be a token that silently stops resolving the day somebody renames a\n// Field, which is the exact failure REC-17 exists to prevent.\n\nimport type { Field, Uuid } from \"@ai-matrx/records\";\n\n/** The one token form, written the way the store's own pattern reads it. */\nexport function fieldToken(fieldId: Uuid): string {\n return `{{field:${fieldId}}}`;\n}\n\n/** THE DECLARATIVE SPEC an agent writes. One template, whole, in one object. */\nexport interface DocTemplateSpec {\n name: string;\n /** The body, tokens and all. */\n body: string;\n}\n\n/**\n * A template written in terms of Field KEYS — which is how an agent thinks and\n * how a person reads — turned into the store's id-based tokens. The agent writes\n * `{{title}}`; what is stored points at the Field's id, so a rename never\n * silently empties the document.\n *\n * A key this Table does not have is LEFT EXACTLY AS IT IS, so\n * `custom.doc_unresolved_tokens` names it and the screen shows the store's own\n * reason — it is never quietly deleted from the body.\n */\nexport function bodyFromKeys(body: string, fields: Field[]): string {\n const byKey = new Map(fields.map((f) => [f.key, f.id]));\n return body.replace(/\\{\\{\\s*([a-zA-Z0-9_]+)\\s*\\}\\}/g, (whole, key: string) => {\n const id = byKey.get(key);\n return id ? fieldToken(id) : whole;\n });\n}\n\n/** The reverse, for a person reading a stored body: ids shown as the Field's label. */\nexport function bodyForReading(body: string, fields: Field[]): string {\n const byId = new Map(fields.map((f) => [f.id, f.label || f.key]));\n return body.replace(/\\{\\{\\s*field:([0-9a-fA-F-]{36})\\s*\\}\\}/g, (whole, id: string) => {\n const label = byId.get(id);\n return label ? `{{${label}}}` : whole;\n });\n}\n\n/** VAL-10: a signature is a Value on a text Field whose format is `signature`. */\nexport function isSignatureField(field: Field): boolean {\n return field.type === \"text\" && (field.format ?? \"\").toLowerCase() === \"signature\";\n}\n","\"use client\";\n\n// src/DocTemplate.tsx — @ai-matrx/records-ui · SCR-20\n//\n// THE TEMPLATE EDITOR. A body, a palette of this Table's own Fields, and the\n// STORE's verdict on which tokens it cannot answer — never this package's.\n//\n// `custom.doc_unresolved_tokens` is asked on every change and its sentence is\n// shown verbatim beside the token it is about. A template is still saveable\n// with an unresolved token, because half-written is a normal state; what is not\n// allowed is publishing one and letting a token reach a person's document\n// looking like text somebody typed.\n//\n// `seed` is the agent's half, as everywhere: complete templates written in\n// Field KEYS (`{{title}}`), converted to the store's id-based tokens on the way\n// in, so a rename never silently empties a contract.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocTemplateRow, DocUnresolvedToken, RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, BasicTextarea, Button, Label, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useTableRights } from \"./host\";\nimport { bodyFromKeys, fieldToken, type DocTemplateSpec } from \"./docs\";\nimport { fieldName } from \"./names\";\n\nexport interface DocTemplateProps {\n /** The Table these templates render. */\n tableId: Uuid;\n /** COMPLETE templates an agent wrote, in Field keys. Saved once, never overwritten. */\n seed?: DocTemplateSpec[] | undefined;\n activeTemplateId?: Uuid | null | undefined;\n onActiveTemplate?: ((template: DocTemplateRow) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }: DocTemplateProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const [templates, setTemplates] = useState<DocTemplateRow[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeTemplateId ?? null);\n const [draftName, setDraftName] = useState(\"\");\n const [draftBody, setDraftBody] = useState(\"\");\n const [unresolved, setUnresolved] = useState<DocUnresolvedToken[]>([]);\n const [saving, setSaving] = useState(false);\n\n const load = useCallback(async () => {\n const held = await client.docTemplates({ table_id: tableId });\n if (!held.ok) {\n setError(held.error);\n return;\n }\n let rows = held.data;\n const missing = (seed ?? []).filter((s) => !rows.some((t) => t.name === s.name));\n if (missing.length > 0 && (fields.data ?? []).length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const saved = await client.docTemplateSave({\n table_id: tableId,\n name: spec.name,\n body: bodyFromKeys(spec.body, fields.data ?? []),\n });\n if (!saved.ok) {\n setError(saved.error);\n return;\n }\n }\n const again = await client.docTemplates({ table_id: tableId });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n rows = again.data;\n }\n setError(null);\n setTemplates(rows);\n }, [client, tableId, seed, fields.data]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!templates || templates.length === 0) return;\n const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n setDraftName(chosen.name);\n setDraftBody(chosen.body);\n onActiveTemplate?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [templates, activeTemplateId]);\n\n // The STORE's verdict on the body, re-asked as it is typed. Never this\n // package's own idea of which token resolves.\n useEffect(() => {\n let cancelled = false;\n if (draftBody.trim() === \"\") {\n setUnresolved([]);\n return;\n }\n void client.docUnresolvedTokens({ table_id: tableId, body: draftBody }).then((answered) => {\n if (cancelled) return;\n if (answered.ok) setUnresolved(answered.data);\n });\n return () => {\n cancelled = true;\n };\n }, [client, tableId, draftBody]);\n\n async function save() {\n setSaving(true);\n const saved = await client.docTemplateSave({\n table_id: tableId,\n name: draftName.trim() || \"Untitled template\",\n body: draftBody,\n template_id: activeId,\n });\n setSaving(false);\n if (!saved.ok) {\n setError(saved.error);\n return;\n }\n setActiveId(saved.data);\n await load();\n }\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (templates === null || fields.loading) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!rights.admin) {\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n }\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row: the templates, the version, the save. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Templates\">\n {templates.map((t) => (\n <Button\n key={t.id}\n size=\"sm\"\n variant={t.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={t.id === activeId}\n onClick={() => {\n setActiveId(t.id);\n setDraftName(t.name);\n setDraftBody(t.body);\n }}\n >\n {t.name}\n <span className=\"ml-1 text-[10px] text-muted-foreground\">v{t.template_version}</span>\n </Button>\n ))}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setActiveId(null);\n setDraftName(\"\");\n setDraftBody(\"\");\n }}\n >\n New template\n </Button>\n <Button size=\"sm\" className=\"ml-auto\" disabled={saving} onClick={() => void save()}>\n {saving ? \"Saving…\" : \"Save\"}\n </Button>\n </div>\n\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Name</Label>\n <BasicInput value={draftName} onChange={(e) => setDraftName(e.target.value)} placeholder=\"Agreement\" />\n </label>\n\n {/* The palette: this Table's own Fields, inserted as the store's own token. */}\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className=\"text-xs text-muted-foreground\">Insert</span>\n {(fields.data ?? []).map((field) => (\n <Button\n key={field.id}\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 px-1.5 text-xs\"\n onClick={() => setDraftBody((body) => `${body}${fieldToken(field.id)}`)}\n >\n {fieldName(field)}\n </Button>\n ))}\n </div>\n\n <BasicTextarea\n rows={10}\n aria-label=\"Template body\"\n className=\"font-mono text-xs\"\n value={draftBody}\n onChange={(e) => setDraftBody(e.target.value)}\n />\n\n {/* The store's own sentence per token it cannot answer — verbatim. */}\n {unresolved.length > 0 ? (\n <ul className=\"flex flex-col gap-0.5 rounded border border-dashed px-2 py-1 text-xs\">\n {unresolved.map((token) => (\n <li key={token.raw} className=\"text-destructive\">\n <code>{token.raw}</code> — {token.why}\n </li>\n ))}\n </ul>\n ) : draftBody.trim() !== \"\" ? (\n <p className=\"text-xs text-muted-foreground\">\n Every token in this body points at a Field this table can answer.\n </p>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/DocRender.tsx — @ai-matrx/records-ui · SCR-21\n//\n// ONE TEMPLATE, ONE RECORD, ONE DOCUMENT — and the preview and the frozen\n// version are the SAME bytes, because both come from the store.\n//\n// `custom.doc_render_body` resolves the tokens without writing anything, which\n// is the preview. `custom.doc_render_document` writes the render: the text and\n// the SHA-256 of that text, frozen. Everything downstream — a signature, a PDF,\n// a link somebody sends — is about a VERSION, never about \"the document as it\n// happens to read today\". That is the whole reason a render is a row and not a\n// function call a screen repeats.\n//\n// The PDF is `@ai-matrx/print`'s, not a second renderer: the platform has one\n// answer to \"make this a PDF\" and this screen uses it.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocRenderRow, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\n\nexport interface DocRenderProps {\n templateId: Uuid;\n recordId: Uuid;\n /** A name for the file when somebody takes the PDF. */\n filename?: string | undefined;\n onRendered?: ((render: DocRenderRow) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function DocRender({ templateId, recordId, filename, onRendered, className }: DocRenderProps) {\n const client = useRecordsClient();\n const [preview, setPreview] = useState<string | null>(null);\n const [renders, setRenders] = useState<DocRenderRow[] | null>(null);\n const [showing, setShowing] = useState<Uuid | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const paper = useRef<HTMLDivElement>(null);\n\n const load = useCallback(async () => {\n const [body, held] = await Promise.all([\n client.docRenderBody({ template_id: templateId, record_id: recordId }),\n client.docRenders({ record_id: recordId }),\n ]);\n if (!body.ok) {\n setError(body.error);\n return;\n }\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setPreview(body.data);\n setRenders(held.data.filter((r) => r.template_id === templateId));\n }, [client, templateId, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function freeze() {\n setBusy(\"freeze\");\n const written = await client.docRenderDocument({ template_id: templateId, record_id: recordId });\n setBusy(null);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n await load();\n setShowing(written.data);\n const made = (await client.docRenders({ record_id: recordId }));\n if (made.ok) {\n const row = made.data.find((r) => r.id === written.data);\n if (row) onRendered?.(row);\n }\n }\n\n async function toPdf() {\n const element = paper.current;\n if (!element) return;\n setBusy(\"pdf\");\n try {\n // The platform's ONE answer to \"make this a PDF\". A second renderer here\n // would produce a document that does not match the printed one.\n const { captureToPDF } = await import(\"@ai-matrx/print/pdf\");\n await captureToPDF(element, { filename: filename ?? \"document\" });\n } catch (thrown) {\n setError({\n code: \"internal\",\n message: \"The PDF could not be made on this screen.\",\n hint: thrown instanceof Error ? thrown.message : String(thrown),\n });\n } finally {\n setBusy(null);\n }\n }\n\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (preview === null || renders === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const frozen = showing ? (renders.find((r) => r.id === showing) ?? null) : null;\n const text = frozen ? frozen.body : preview;\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row: which version is on screen, and the two verbs. */}\n <div className=\"flex items-center gap-1 text-xs\">\n <Button\n size=\"sm\"\n variant={frozen ? \"ghost\" : \"secondary\"}\n aria-pressed={!frozen}\n onClick={() => setShowing(null)}\n >\n As it reads now\n </Button>\n {renders.map((render) => (\n <Button\n key={render.id}\n size=\"sm\"\n variant={render.id === showing ? \"secondary\" : \"ghost\"}\n aria-pressed={render.id === showing}\n onClick={() => setShowing(render.id)}\n title={`Template v${render.template_version} · ${render.content_hash.slice(0, 12)}`}\n >\n {new Date(render.rendered_at).toLocaleString()}\n </Button>\n ))}\n <span className=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" disabled={busy !== null} onClick={() => void freeze()}>\n {busy === \"freeze\" ? \"Freezing…\" : \"Freeze this version\"}\n </Button>\n <Button size=\"sm\" variant=\"ghost\" disabled={busy !== null} onClick={() => void toPdf()}>\n {busy === \"pdf\" ? \"Making the PDF…\" : \"PDF\"}\n </Button>\n </span>\n </div>\n\n {/* The document. Frozen bytes when a version is chosen, the live resolution\n otherwise — and the screen says which, because they are not the same thing. */}\n <div ref={paper} className=\"whitespace-pre-wrap rounded border bg-background p-4 text-sm text-foreground\">\n {text}\n </div>\n\n <p className=\"text-xs text-muted-foreground\">\n {frozen\n ? `Frozen ${new Date(frozen.rendered_at).toLocaleString()} from template v${frozen.template_version}. Its text and its SHA-256 (${frozen.content_hash.slice(0, 12)}…) are what any signature seals.`\n : \"This is how the template reads against this record right now. Nothing has been frozen, so there is no version for anyone to sign yet.\"}\n </p>\n </div>\n );\n}\n","\"use client\";\n\n// src/SignBlock.tsx — @ai-matrx/records-ui · SCR-22\n//\n// A SIGNATURE IS A VALUE, AND THE STORE DECIDES WHETHER IT STILL HOLDS.\n//\n// VAL-10: a signature is written on a text Field whose format is `signature`,\n// on the record's own Table, through `custom.doc_sign` — which writes it as an\n// ordinary Value with the envelope law's stamp plus the document version and\n// hash it sealed. So a signature is in History, in the export and in the agent's\n// context like any other Value, and there is no signatures feature bolted on.\n//\n// THREE THINGS THIS SCREEN NEVER DOES:\n// · It never checks a seal itself. `custom.doc_signature_intact` answers, and\n// its verdict is shown as the store said it.\n// · It never offers to re-sign. The door refuses a second signature on a Field\n// already signed, and the screen says the same sentence rather than showing a\n// button that will be refused.\n// · It never signs anything unfrozen. A seal is over a document VERSION, so\n// with no render there is no Sign — and the reason is on screen.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocRenderRow, DocSignatureRow, Field, RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\nimport { isSignatureField } from \"./docs\";\nimport { fieldName } from \"./names\";\n\nexport interface SignBlockProps {\n tableId: Uuid;\n recordId: Uuid;\n /** The frozen version being signed. Without one there is nothing to seal. */\n render: DocRenderRow | null;\n className?: string | undefined;\n}\n\nexport function SignBlock({ tableId, recordId, render, className }: SignBlockProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const [signatures, setSignatures] = useState<DocSignatureRow[] | null>(null);\n const [verdicts, setVerdicts] = useState<Record<string, unknown>>({});\n const [error, setError] = useState<RecordsError | null>(null);\n const [name, setName] = useState(\"\");\n const [busy, setBusy] = useState(false);\n\n const load = useCallback(async () => {\n const held = await client.docSignatures({ record_id: recordId });\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setSignatures(held.data);\n // Whether each seal still holds is the STORE's answer, asked for each one.\n const answers: Record<string, unknown> = {};\n for (const signature of held.data) {\n const intact = await client.docSignatureIntact({ signature_id: signature.id });\n answers[signature.id] = intact.ok ? intact.data : intact.error.message;\n }\n setVerdicts(answers);\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function sign(field: Field) {\n if (!render) return;\n setBusy(true);\n const signed = await client.docSign({\n render_id: render.id,\n field_key: field.key,\n signer_name: name.trim(),\n signer_user_id: client.config.actor.user_id ?? null,\n });\n setBusy(false);\n if (!signed.ok) {\n setError(signed.error);\n return;\n }\n setName(\"\");\n await load();\n }\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (fields.loading || signatures === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n const signable = (fields.data ?? []).filter(isSignatureField);\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Signatures</span>\n <span>{signatures.length} on this record</span>\n </div>\n\n {signatures.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {signatures.map((signature) => {\n const verdict = verdicts[signature.id];\n const intact = typeof verdict === \"object\" && verdict !== null ? (verdict as { intact?: boolean }).intact : undefined;\n return (\n <li key={signature.id} className=\"rounded border px-2 py-1.5 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{signature.signer_name}</span>\n <span className=\"text-muted-foreground\">{signature.field_key}</span>\n <span className=\"text-muted-foreground\">{new Date(signature.signed_at).toLocaleString()}</span>\n <span className=\"ml-auto font-mono text-[10px] text-muted-foreground\">\n v{signature.document_version} · {signature.document_hash.slice(0, 12)}\n </span>\n </div>\n {/* The store's verdict, not a check this screen invented. */}\n <p className={cn(\"mt-0.5\", intact === false ? \"text-destructive\" : \"text-muted-foreground\")}>\n {intact === true\n ? \"The store says what was signed is still exactly what is there.\"\n : intact === false\n ? typeof verdict === \"object\" && verdict !== null && \"reason\" in verdict\n ? String((verdict as { reason?: unknown }).reason)\n : \"The store says what is there no longer matches what was signed.\"\n : String(verdict ?? \"\")}\n </p>\n </li>\n );\n })}\n </ul>\n ) : null}\n\n {/* A seal is over a VERSION, so with nothing frozen there is no Sign at\n all — and the reason is on screen rather than a dead button. */}\n {!render ? (\n <p className=\"text-xs text-muted-foreground\">\n Nothing has been frozen yet, so there is no version to sign. A signature seals one exact document\n version and its hash — \"the document as it reads today\" is not something anyone can agree to.\n </p>\n ) : signable.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This table has no signature Field, so there is nowhere to write a signature. A signature is a Value\n on a text Field whose format is <code>signature</code> — add one and the signing appears.\n </p>\n ) : !rights.write ? (\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n ) : (\n <div className=\"flex flex-col gap-1\">\n {signable.map((field) => {\n const already = signatures.find((s) => s.field_key === field.key);\n if (already) {\n return (\n <p key={field.id} className=\"text-xs text-muted-foreground\">\n {fieldName(field)} is signed, and a signature is immutable once made. A further\n agreement is a further Field with its own signature, or a further version with its own seal.\n </p>\n );\n }\n return (\n <form\n key={field.id}\n className=\"flex items-center gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n if (name.trim() !== \"\") void sign(field);\n }}\n >\n <BasicInput\n className=\"h-8 w-56 text-xs\"\n aria-label={`Sign ${fieldName(field)}`}\n placeholder=\"Type your full name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n <Button size=\"sm\" type=\"submit\" disabled={busy || name.trim() === \"\"}>\n Sign\n </Button>\n <span className=\"text-xs text-muted-foreground\">\n seals version {render.template_version} · {render.content_hash.slice(0, 12)}…\n </span>\n </form>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/NotifyRuleEditor.tsx — @ai-matrx/records-ui · SCR-19\n//\n// \"TELL ME WHEN SOMETHING IN THIS VIEW CHANGES\" — and that sentence is a RULE\n// RECORD, not a notifications table.\n//\n// DOOR-18: a subscription is an ordinary Rule carrying a `subscription` block\n// that names a saved view, a cadence, a channel and the person to tell. The\n// store answers `custom.agg_subscriptions`, fires `custom.agg_subscription_fire`\n// and delivers through `communication.notification`. So there is one notifier in\n// this platform, and a subscription is readable, historied, exportable and\n// agent-writable exactly like everything else this package touches.\n//\n// THE PART THAT MATTERS MOST IS NOT ON THIS SCREEN. `custom.agg_view_admits`\n// runs the admission test as the SUBSCRIBER, not as the writer: a change to a\n// record the subscriber may not see is not a notification they are entitled to,\n// because the notification's existence would leak the record. This editor never\n// re-implements that test and never offers to turn it off.\n//\n// `seed` is the agent's half, as everywhere else: complete declarative\n// subscriptions, written once, never overwriting one a person has since changed.\n//\n// WHAT DOES NOT WORK YET, AND WHY IT SAYS SO INSTEAD OF PRETENDING. A\n// subscription is a RULE record, and `custom.record_write` — the one write door\n// — inserts `data_class = 'record'`. A document written that way is not a Rule:\n// `custom.agg_subscriptions` never sees it, so a screen that wrote one and said\n// \"subscribed\" would have subscribed nobody to anything and left a stray record\n// behind. Declaring a Rule needs a door of its own (`custom.rule_declare`,\n// W1-RULE's), so this editor asks for that door BY NAME and shows the store's\n// refusal. Reading, listing and stopping a subscription all work today; the day\n// the door lands, so does subscribing, with no change on this screen.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, Subscription } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { NO_SAVED_VIEWS_REASON, useRecordsUi, useTableRights } from \"./host\";\n\n/** THE DECLARATIVE SPEC an agent writes. One declaration and a person is told. */\nexport interface NotifyRuleSpec {\n name: string;\n savedViewId: Uuid;\n /** `immediate` fires on the change; `digest` is collected and sent on a schedule. */\n cadence?: string;\n /** The digest's schedule, in the store's own words. Meaningless for `immediate`. */\n schedule?: string | null;\n channel?: string;\n /** Who is told. Left out, the person setting it up — \"tell ME\". */\n recipientUserId?: Uuid | null;\n eventKey?: string;\n}\n\nexport interface NotifyRuleEditorProps {\n /** The Table these subscriptions are about — the Rule's scope. */\n tableId: Uuid;\n /** COMPLETE declarative subscriptions an agent wrote. Saved once, never overwritten. */\n seed?: NotifyRuleSpec[] | undefined;\n className?: string | undefined;\n}\n\nexport function NotifyRuleEditor({ tableId, seed, className }: NotifyRuleEditorProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [subscriptions, setSubscriptions] = useState<Subscription[] | null>(null);\n const [cadences, setCadences] = useState<string[]>([]);\n const [views, setViews] = useState<Array<{ id: Uuid; name: string }> | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n\n const load = useCallback(async () => {\n const [held, offered] = await Promise.all([\n client.aggSubscriptions(),\n // The cadences are ASKED of the store, never a list typed into a picker\n // here that could drift from what the digest runner understands.\n client.aggSubscriptionCadences(),\n ]);\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setSubscriptions(held.data);\n if (offered.ok) setCadences(offered.data);\n if (host.savedViews) setViews(await host.savedViews());\n else setViews(null);\n }, [client, host]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const write = useCallback(\n async (spec: NotifyRuleSpec) => {\n const declared = await client.ruleDeclare({\n spec: {\n name: spec.name,\n // REC-15: a subscription answers yes-or-no about a record, so it is a\n // predicate, and what it decides is membership of the view.\n kind: \"predicate\",\n uses: [\"membership\"],\n scope_table_id: tableId,\n applies_to_types: [],\n expr: { const: true },\n subscription: {\n saved_view_id: spec.savedViewId,\n cadence: spec.cadence ?? \"immediate\",\n schedule: spec.schedule ?? null,\n channel: spec.channel ?? \"in_app\",\n // \"Tell me\" is the default, and the store fires at nobody when this\n // is null — which it says out loud rather than dropping quietly.\n recipient_user_id: spec.recipientUserId ?? client.config.actor.user_id ?? null,\n event_key: spec.eventKey ?? \"records.changed\",\n },\n },\n });\n if (!declared.ok) {\n setError(declared.error);\n return false;\n }\n return true;\n },\n [client, tableId],\n );\n\n // The agent's specs, saved once. A seed whose name is already subscribed is\n // left alone — an agent re-running never overwrites a person's tweak.\n useEffect(() => {\n if (!subscriptions || !seed || seed.length === 0) return;\n const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));\n if (missing.length === 0) return;\n void (async () => {\n for (const spec of missing) {\n if (!(await write(spec))) return;\n }\n await load();\n })();\n }, [subscriptions, seed, write, load]);\n\n async function subscribe(viewId: Uuid, viewName: string, cadence: string) {\n setBusy(true);\n const ok = await write({ name: `${viewName} — ${cadence}`, savedViewId: viewId, cadence });\n setBusy(false);\n if (ok) await load();\n }\n\n async function unsubscribe(ruleId: Uuid) {\n setBusy(true);\n const deleted = await client.recordDelete({ record_id: ruleId });\n setBusy(false);\n if (!deleted.ok) {\n setError(deleted.error);\n return;\n }\n await load();\n }\n\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (subscriptions === null) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row. What this is, and how many there are — no subtitle repeating it. */}\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Tell me when</span>\n <span>{subscriptions.length} subscription{subscriptions.length === 1 ? \"\" : \"s\"}</span>\n </div>\n\n {subscriptions.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n Nothing is telling anyone about this yet. A subscription is a Rule over a saved view, so what\n you are told about is exactly what that view holds.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {subscriptions.map((held) => (\n <li key={held.rule_id} className=\"flex items-center gap-2 rounded border px-2 py-1.5 text-xs\">\n <span className=\"truncate font-medium\">{held.name}</span>\n <span className=\"text-muted-foreground\">{held.cadence}</span>\n <span className=\"text-muted-foreground\">{held.channel}</span>\n {held.cadence === \"digest\" && held.schedule ? (\n <span className=\"text-muted-foreground\">{held.schedule}</span>\n ) : null}\n {/* Nothing fails silently: a subscription that fires at nobody\n says so, rather than looking like it is working. */}\n {held.recipient_user_id === null ? (\n <span className=\"text-destructive\">\n This one has nobody to tell, so it fires at nobody.\n </span>\n ) : null}\n {held.saved_view_id === null ? (\n <span className=\"text-destructive\">\n This one names no view, so the store never admits a record to it.\n </span>\n ) : null}\n {rights.write ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto\"\n disabled={busy}\n onClick={() => void unsubscribe(held.rule_id)}\n >\n Stop telling me\n </Button>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n\n {/* Subscribing to a view needs the views, and the store has no door onto\n them — so with no port bound this says that, rather than showing an\n empty picker that reads like \"you have no views\". */}\n {views === null ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {NO_SAVED_VIEWS_REASON}\n </p>\n ) : views.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This organization has no saved views yet, so there is nothing to subscribe to. Save a view first.\n </p>\n ) : rights.write ? (\n <form\n className=\"flex items-center gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n const form = event.currentTarget;\n const view = (form.elements.namedItem(\"view\") as HTMLSelectElement).value;\n const cadence = (form.elements.namedItem(\"cadence\") as HTMLSelectElement).value;\n const name = views.find((v) => v.id === view)?.name ?? \"View\";\n if (view) void subscribe(view, name, cadence);\n }}\n >\n <select name=\"view\" aria-label=\"View to be told about\" className=\"h-7 rounded border bg-background px-1 text-xs\">\n {views.map((view) => (\n <option key={view.id} value={view.id}>\n {view.name}\n </option>\n ))}\n </select>\n <select name=\"cadence\" aria-label=\"How often\" className=\"h-7 rounded border bg-background px-1 text-xs\">\n {(cadences.length > 0 ? cadences : [\"immediate\"]).map((cadence) => (\n <option key={cadence} value={cadence}>\n {cadence === \"immediate\" ? \"as it happens\" : cadence}\n </option>\n ))}\n </select>\n <Button size=\"sm\" type=\"submit\" disabled={busy}>\n Tell me\n </Button>\n </form>\n ) : (\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/ChartBlock.tsx — @ai-matrx/records-ui · SCR-15\n//\n// ONE BLOCK, ONE CALL TO THE STORE. The grouping, the bucketing, the filter and\n// the measure are all `custom.record_aggregate`'s work, computed inside the\n// read door's own query — this file draws the answer and does not do any\n// arithmetic of its own beyond turning numbers into pixels.\n//\n// WHY NOT SUM IN THE BROWSER: the aggregate node sits above the visibility\n// join, so the total is over exactly the records this person may see. A browser\n// that fetched rows and summed them would either read rows it may not have or\n// under-count them silently, and a wrong total is the hardest lie to notice.\n//\n// A SHAPE THAT CANNOT BE DRAWN SAYS THE SENTENCE THAT FIXES IT. A donut with\n// nothing to group by and a line with no date Field print what they need; they\n// never draw an empty frame that reads like \"there is no data\".\n\nimport { useEffect, useState } from \"react\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport { measureKey, type AggregateRow, type RecordsError } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { CHART_NEEDS, SERIES_COLORS, groupLabel, type ChartSpec } from \"./charts\";\n\nexport interface ChartBlockProps {\n spec: ChartSpec;\n className?: string | undefined;\n}\n\nexport function ChartBlock({ spec, className }: ChartBlockProps) {\n const client = useRecordsClient();\n const [rows, setRows] = useState<AggregateRow[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n const measures = spec.measures && spec.measures.length > 0 ? spec.measures : [{ op: \"count\" as const }];\n const primary = measureKey(measures[0]!);\n const grouped = (spec.groupBy ?? []).length > 0 || !!spec.bucket;\n const needs = grouped ? null : CHART_NEEDS[spec.kind];\n\n const question = JSON.stringify({\n t: spec.subject,\n g: spec.groupBy ?? [],\n m: measures,\n b: spec.bucket ?? null,\n f: spec.filter ?? {},\n l: spec.limit ?? 50,\n });\n\n useEffect(() => {\n if (needs) return;\n let cancelled = false;\n setRows(null);\n setError(null);\n void client\n .recordAggregate({\n table_id: spec.subject,\n groupBy: spec.groupBy ?? [],\n measures,\n bucket: spec.bucket ?? null,\n filter: spec.filter ?? {},\n limit: spec.limit ?? 50,\n })\n .then((result) => {\n if (cancelled) return;\n if (result.ok) setRows(result.data);\n else setError(result.error);\n });\n return () => {\n cancelled = true;\n };\n // The QUESTION is the dependency, not the object identity: a parent that\n // rebuilds the same spec every render must not re-ask the store forever.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client, question, needs]);\n\n return (\n <figure className={cn(\"flex min-w-0 flex-col gap-1.5 rounded border p-2\", className)}>\n {/* One row. The title and what is being measured — no subtitle repeating the title. */}\n <figcaption className=\"flex items-baseline gap-2 text-xs\">\n <span className=\"truncate font-medium\">{spec.title}</span>\n <span className=\"ml-auto shrink-0 text-muted-foreground\">{primary.replace(\"_\", \" of \")}</span>\n </figcaption>\n\n {needs ? (\n <p className=\"px-1 py-3 text-xs text-muted-foreground\">{needs}</p>\n ) : error ? (\n <RefusalNotice error={error} />\n ) : rows === null ? (\n <Skeleton className=\"h-28 w-full\" />\n ) : rows.length === 0 ? (\n <p className=\"px-1 py-3 text-xs text-muted-foreground\">\n The store answered this question with no groups at all, so there is nothing to draw yet.\n </p>\n ) : (\n <Drawing kind={spec.kind} rows={rows} measure={primary} />\n )}\n </figure>\n );\n}\n\nfunction value(row: AggregateRow, measure: string): number {\n const held = row.measures?.[measure];\n return typeof held === \"number\" ? held : Number(held ?? 0);\n}\n\nfunction pretty(n: number): string {\n return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(undefined, { maximumFractionDigits: 2 });\n}\n\nfunction Drawing({ kind, rows, measure }: { kind: ChartSpec[\"kind\"]; rows: AggregateRow[]; measure: string }) {\n const points = rows.map((row) => ({ label: groupLabel(row.groups ?? {}), value: value(row, measure), n: row.row_count }));\n const top = Math.max(...points.map((p) => p.value), 0) || 1;\n\n if (kind === \"number\") {\n const total = points.reduce((sum, p) => sum + p.value, 0);\n return (\n <div className=\"flex items-baseline gap-2 px-1 py-2\">\n <span className=\"text-2xl font-semibold tabular-nums\">{pretty(total)}</span>\n <span className=\"text-xs text-muted-foreground\">\n from {points.reduce((sum, p) => sum + p.n, 0).toLocaleString()} records\n </span>\n </div>\n );\n }\n\n if (kind === \"table\") {\n return (\n <table className=\"w-full text-xs\">\n <tbody>\n {points.map((p) => (\n <tr key={p.label} className=\"border-t first:border-t-0\">\n <td className=\"py-0.5 pr-2 truncate\">{p.label}</td>\n <td className=\"py-0.5 text-right tabular-nums\">{pretty(p.value)}</td>\n <td className=\"py-0.5 pl-2 text-right tabular-nums text-muted-foreground\">{p.n}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n }\n\n if (kind === \"bar\") {\n // Horizontal bars, because a category label is words and words read across.\n return (\n <ul className=\"flex flex-col gap-1 px-1 py-1\">\n {points.map((p, i) => (\n <li key={p.label} className=\"flex items-center gap-2 text-xs\">\n <span className=\"w-28 shrink-0 truncate\" title={p.label}>\n {p.label}\n </span>\n <span className=\"h-3 min-w-0 flex-1 rounded-sm bg-muted\">\n <span\n className=\"block h-3 rounded-sm\"\n style={{ width: `${Math.max((p.value / top) * 100, 1)}%`, background: SERIES_COLORS[i % SERIES_COLORS.length] }}\n />\n </span>\n <span className=\"w-16 shrink-0 text-right tabular-nums\">{pretty(p.value)}</span>\n </li>\n ))}\n </ul>\n );\n }\n\n if (kind === \"column\" || kind === \"line\") {\n const width = 320;\n const height = 96;\n const step = points.length > 1 ? width / (points.length - 1) : width;\n const y = (v: number) => height - (v / top) * (height - 8) - 4;\n return (\n <div className=\"px-1 py-1\">\n <svg viewBox={`0 0 ${width} ${height}`} className=\"h-24 w-full\" role=\"img\" aria-label={`${measure} by group`}>\n {kind === \"line\" ? (\n <polyline\n fill=\"none\"\n stroke={SERIES_COLORS[0]}\n strokeWidth=\"2\"\n points={points.map((p, i) => `${i * step},${y(p.value)}`).join(\" \")}\n />\n ) : (\n points.map((p, i) => {\n const barWidth = Math.max(width / points.length - 4, 2);\n return (\n <rect\n key={p.label}\n x={(width / points.length) * i + 2}\n y={y(p.value)}\n width={barWidth}\n height={height - 4 - y(p.value)}\n rx=\"2\"\n fill={SERIES_COLORS[i % SERIES_COLORS.length]}\n />\n );\n })\n )}\n </svg>\n <ul className=\"mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-xs text-muted-foreground\">\n {points.map((p) => (\n <li key={p.label} className=\"tabular-nums\">\n {p.label} {pretty(p.value)}\n </li>\n ))}\n </ul>\n </div>\n );\n }\n\n // donut\n const total = points.reduce((sum, p) => sum + p.value, 0) || 1;\n let offset = 0;\n const radius = 34;\n const circumference = 2 * Math.PI * radius;\n return (\n <div className=\"flex items-center gap-3 px-1 py-1\">\n <svg viewBox=\"0 0 88 88\" className=\"h-24 w-24 shrink-0\" role=\"img\" aria-label={`${measure} by group`}>\n {points.map((p, i) => {\n const length = (p.value / total) * circumference;\n const dash = `${length} ${circumference - length}`;\n const node = (\n <circle\n key={p.label}\n cx=\"44\"\n cy=\"44\"\n r={radius}\n fill=\"none\"\n stroke={SERIES_COLORS[i % SERIES_COLORS.length]}\n strokeWidth=\"14\"\n strokeDasharray={dash}\n strokeDashoffset={-offset}\n transform=\"rotate(-90 44 44)\"\n />\n );\n offset += length;\n return node;\n })}\n </svg>\n <ul className=\"flex min-w-0 flex-col gap-0.5 text-xs\">\n {points.map((p, i) => (\n <li key={p.label} className=\"flex items-center gap-1.5\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-sm\"\n style={{ background: SERIES_COLORS[i % SERIES_COLORS.length] }}\n />\n <span className=\"truncate\">{p.label}</span>\n <span className=\"ml-auto shrink-0 tabular-nums\">{pretty(p.value)}</span>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","\"use client\";\n\n// src/DashboardCanvas.tsx — @ai-matrx/records-ui · SCR-16\n//\n// A DASHBOARD IS ONE RECORD, and its blocks are that record's own document. So\n// a dashboard is shareable, exportable, historied, commentable and\n// agent-writable for free — every one of those is something this package\n// already does to records, and none of it is written twice.\n//\n// `seed` is the agent's half: COMPLETE `DashboardSpec`s, each saved as a record\n// the first time the canvas loads and never overwritten afterwards. A person\n// adding a block, renaming one or changing its shape is the tweak.\n//\n// Every block is its own single call to `custom.record_aggregate`, so a canvas\n// of eight blocks is eight round trips over eight aggregates, never eight\n// downloads of the table.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useRecordVersion, useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { ChartBlock } from \"./ChartBlock\";\nimport {\n CHART_KINDS,\n CHART_KIND_LABEL,\n DASHBOARD_TABLE,\n dashboardDocument,\n dashboardFromRecord,\n type ChartKind,\n type ChartSpec,\n type DashboardSpec,\n type SavedDashboard,\n} from \"./charts\";\n\nexport interface DashboardCanvasProps {\n /** The Table these blocks are about. */\n tableId: Uuid;\n /** COMPLETE declarative dashboards an agent wrote. Saved once, never overwritten. */\n seed?: DashboardSpec[] | undefined;\n activeDashboardId?: Uuid | null | undefined;\n className?: string | undefined;\n}\n\nexport function DashboardCanvas({ tableId, seed, activeDashboardId, className }: DashboardCanvasProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const home = useSystemTable(DASHBOARD_TABLE);\n const [boards, setBoards] = useState<SavedDashboard[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeDashboardId ?? null);\n // The version of the board this canvas LOADED, for the one record being edited.\n const loadedVersion = useRecordVersion(activeId);\n\n const boardTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!boardTableId) return;\n const result = await client.list({ table_id: boardTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n let mine = result.data.rows.map(dashboardFromRecord).filter((d) => d.subject === tableId);\n const missing = (seed ?? []).filter((s) => !mine.some((d) => d.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: boardTableId,\n data: dashboardDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: boardTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n mine = again.data.rows.map(dashboardFromRecord).filter((d) => d.subject === tableId);\n }\n setError(null);\n setBoards(mine);\n }, [client, boardTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!boards || boards.length === 0) return;\n const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boards, activeDashboardId]);\n\n async function writeBlocks(board: SavedDashboard, blocks: ChartSpec[]) {\n const updated = await client.recordUpdate({\n record_id: board.id,\n patch: dashboardDocument({ ...board, blocks }),\n // The dashboard record's own version: two tabs editing one board are TOLD.\n ...(loadedVersion === null ? {} : { expectedVersion: loadedVersion }),\n });\n if (!updated.ok) {\n setError(updated.error);\n return;\n }\n await load();\n }\n\n async function create() {\n if (!boardTableId) return;\n const written = await client.recordWrite({\n table_id: boardTableId,\n data: dashboardDocument({ name: `Dashboard ${(boards?.length ?? 0) + 1}`, subject: tableId, blocks: [] }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setActiveId(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (home.loading || boards === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const board = boards.find((d) => d.id === activeId) ?? null;\n const groupable = (fields.data ?? []).filter((f) => f.type === \"text\" || f.type === \"list\");\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the boards, and the two verbs that change this one. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Dashboards\">\n {boards.map((d) => (\n <Button\n key={d.id}\n size=\"sm\"\n variant={d.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={d.id === activeId}\n onClick={() => setActiveId(d.id)}\n >\n {d.name}\n </Button>\n ))}\n {/* SCR-4: making a dashboard is administering the table, so a member\n gets no dead button — there is no button. */}\n {rights.admin ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void create()}>\n New dashboard\n </Button>\n ) : null}\n {board && rights.admin ? (\n <span className=\"ml-auto flex items-center gap-1\">\n <select\n aria-label=\"Add a block\"\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value=\"\"\n onChange={(e) => {\n const kind = e.target.value as ChartKind;\n if (!kind) return;\n const by = groupable[0]?.key;\n void writeBlocks(board, [\n ...board.blocks,\n {\n title: CHART_KIND_LABEL[kind],\n subject: tableId,\n kind,\n ...(by && kind !== \"number\" ? { groupBy: [by] } : {}),\n measures: [{ op: \"count\" }],\n },\n ]);\n }}\n >\n <option value=\"\">Add a block</option>\n {CHART_KINDS.map((kind) => (\n <option key={kind} value={kind}>\n {CHART_KIND_LABEL[kind]}\n </option>\n ))}\n </select>\n </span>\n ) : null}\n </div>\n\n {!board ? (\n <p className=\"text-xs text-muted-foreground\">\n {rights.admin\n ? \"No dashboard looks at this table yet. \\\"New dashboard\\\" makes one, or an agent writes a whole one with a single record.\"\n : rights.reason}\n </p>\n ) : board.blocks.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This dashboard has no blocks yet. Each one is a single question the store answers — grouped,\n bucketed and measured inside the read door.\n </p>\n ) : (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-3\">\n {board.blocks.map((block, index) => (\n <div key={`${block.title}-${index}`} className=\"flex min-w-0 flex-col gap-1\">\n <ChartBlock spec={{ ...block, subject: block.subject || tableId }} />\n {rights.admin ? (\n <div className=\"flex items-center gap-1 text-xs\">\n <select\n aria-label={`Shape of ${block.title}`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={block.kind}\n onChange={(e) =>\n void writeBlocks(\n board,\n board.blocks.map((b, i) => (i === index ? { ...b, kind: e.target.value as ChartKind } : b)),\n )\n }\n >\n {CHART_KINDS.map((kind) => (\n <option key={kind} value={kind}>\n {CHART_KIND_LABEL[kind]}\n </option>\n ))}\n </select>\n <select\n aria-label={`Group ${block.title} by`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={block.groupBy?.[0] ?? \"\"}\n onChange={(e) =>\n void writeBlocks(\n board,\n board.blocks.map((b, i) =>\n i === index ? { ...b, groupBy: e.target.value ? [e.target.value] : [] } : b,\n ),\n )\n }\n >\n <option value=\"\">no grouping</option>\n {groupable.map((f) => (\n <option key={f.id} value={f.key}>\n {f.label || f.key}\n </option>\n ))}\n </select>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => void writeBlocks(board, board.blocks.filter((_, i) => i !== index))}\n >\n Remove\n </Button>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/RecordChat.tsx — @ai-matrx/records-ui · SCR-26\n//\n// \"TALK TO THIS RECORD\" — AND THERE IS EXACTLY ONE CHAT SURFACE IN THIS\n// PLATFORM, WHICH IS NOT THIS ONE.\n//\n// The temptation here is to build a message list and a composer. Doing that\n// would give AI Matrx a second chat UI that streams differently, handles tool\n// asks differently, pages history differently and drifts from the real one\n// within a month — for the sake of a panel beside a record. So this component\n// builds NO chat UI at all.\n//\n// What it builds is the thing only the record store can build: the CONTEXT.\n// It reads the one record THROUGH THE READ DOOR (`custom.read_record`), turns\n// the Fields the store agreed this person may see into named context entries,\n// names the ones the store MASKED rather than pretending the record has fewer\n// fields than it has, and hands that to the host's chat port.\n//\n// WHAT matrx-frontend MUST PASS (the port, in its own words):\n//\n// <RecordsUiProvider value={{\n// chat: (ctx) => {\n// const { conversationId } = useAgentLauncher(agentId, {\n// surfaceKey: ctx.surfaceKey,\n// runtime: { context: Object.fromEntries(ctx.entries.map(e => [e.key, e.value])) },\n// });\n// return <AgentConversationColumn conversationId={conversationId} surfaceKey={ctx.surfaceKey} />;\n// },\n// }}>\n//\n// `AgentConversationColumn`\n// (matrx-frontend `features/agents/components/shared/AgentConversationColumn.tsx`)\n// is that one surface, and it cannot live in this package: it reads the app's\n// Redux store — conversations, messages, instance-context, surfaces — and a\n// package that imported those would stop being a package. The agent itself is\n// resolved through a Mandate on the host's side, never a UUID pinned here.\n//\n// UNBOUND, THIS COMPONENT IS ABSENT WITH ITS REASON. It never draws a dead\n// composer, and it never quietly renders a transcript that goes nowhere.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, HiddenFieldNotice, RecordsError } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { scalarText } from \"./values\";\n\n/** One named piece of grounding, shaped the way the platform's context slice takes them. */\nexport interface RecordChatEntry {\n key: string;\n value: unknown;\n label: string;\n /** `text` for a scalar, `json` for a structure. The host maps this to its own vocabulary. */\n type: \"text\" | \"json\";\n}\n\n/** A Field the STORE masked for this reader, named rather than silently dropped. */\nexport interface RecordChatWithheld {\n key: string;\n label: string;\n /** The store's own reason. */\n reason: string;\n}\n\n/** Everything the host's chat surface needs, and nothing about how it should look. */\nexport interface RecordChatContext {\n /**\n * A unique key per mounted conversation. Two record panels open at once must\n * not fight over focus, so this is derived from the record and never a\n * constant.\n */\n surfaceKey: string;\n tableId: Uuid;\n recordId: Uuid;\n tableName: string;\n /** The record's own title, for the panel's one-row header and the chip. */\n title: string;\n /** The grounding, already read through the read door. */\n entries: RecordChatEntry[];\n /** What this reader is NOT being given, with the store's reason for each. */\n withheld: RecordChatWithheld[];\n}\n\nexport const NO_CHAT_REASON =\n \"No chat port is bound, so this panel is absent rather than showing a composer that goes nowhere. \" +\n \"Bind `chat` on <RecordsUiProvider> with your host's own chat surface — in AI Matrx that is \" +\n \"`AgentConversationColumn`, launched through a Mandate — and this panel becomes that surface with \" +\n \"this record as its context. This package deliberately ships no second chat UI.\";\n\nexport interface RecordChatProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\nexport function RecordChat({ tableId, recordId, className }: RecordChatProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [read, setRead] = useState<{\n document: Record<string, unknown>;\n hidden: Record<string, HiddenFieldNotice>;\n } | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setRead(null);\n setError(null);\n void client.recordRead({ record_id: recordId }).then((answered) => {\n if (cancelled) return;\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setRead({\n document: answered.data.document as Record<string, unknown>,\n hidden: answered.data.hidden ?? {},\n });\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId]);\n\n const context: RecordChatContext | null = useMemo(() => {\n if (!read || !table.data || !fields.data) return null;\n const titleKey = table.data.title_field ?? fields.data[0]?.key ?? \"\";\n const title = String(read.document[titleKey] ?? \"this record\");\n const withheld: RecordChatWithheld[] = Object.entries(read.hidden).map(([key, notice]) => ({\n key,\n label: fields.data?.find((f) => f.key === key)?.label ?? key,\n reason: noticeText(notice),\n }));\n return {\n surfaceKey: `records-ui:record-chat:${recordId}`,\n tableId,\n recordId,\n tableName: table.data.name,\n title,\n entries: entriesFor(fields.data, read.document, table.data.name, title, withheld),\n // Two different absences, both named: what the STORE masked for this\n // reader, and what the organization's own policy keeps out of a\n // conversation. Neither one silently shrinks the record.\n withheld,\n };\n }, [read, table.data, fields.data, recordId, tableId]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (!context) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!host.chat) {\n // ABSENT, WITH THE REASON — and with what was going to be sent, because a\n // person reading \"no chat port is bound\" should be able to see that the\n // record half of this actually works.\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{context.title}</span>\n <span>{context.entries.length} facts ready</span>\n </header>\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_CHAT_REASON}</p>\n <Withheld withheld={context.withheld} />\n </section>\n );\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the record, and what the agent is holding. No repeated names. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{context.title}</span>\n <span>{context.entries.length} facts in context</span>\n </header>\n <Withheld withheld={context.withheld} />\n <div className=\"flex min-h-0 flex-1 flex-col\">{host.chat(context)}</div>\n </section>\n );\n}\n\n/**\n * The store masked something, and the person is TOLD.\n *\n * An agent answering out of a record it was given nine of eleven fields from\n * will answer confidently and wrongly about the other two. A screen that hid\n * that would be the record store lying about what it handed over.\n */\nfunction Withheld({ withheld }: { withheld: RecordChatWithheld[] }) {\n if (withheld.length === 0) return null;\n return (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n Not in this conversation: {withheld.map((w) => w.label).join(\", \")}.{\" \"}\n {withheld[0]?.reason ? withheld[0].reason : \"The store masked it for this reader.\"} An answer here is\n an answer without {withheld.length === 1 ? \"that field\" : \"those fields\"}.\n </p>\n );\n}\n\n/**\n * THE GROUNDING, AND IT CARRIES THE FIELD'S MEANING.\n *\n * FLD-N-1: a unit and a format are on the Field because they change what the\n * value MEANS, so `48000` reaches the agent as `$48,000` exactly as it reaches\n * the screen. An agent given the bare number is an agent one currency away from\n * a confident mistake.\n */\nfunction entriesFor(\n fields: Field[],\n document: Record<string, unknown>,\n tableName: string,\n title: string,\n held: RecordChatWithheld[],\n): RecordChatEntry[] {\n const entries: RecordChatEntry[] = [\n {\n key: \"record_subject\",\n label: \"Record\",\n type: \"text\",\n value: `${title} — a ${tableName} record.`,\n },\n ];\n for (const field of fields) {\n // AGT-7 / VAL-6: a Field's sensitivity is a CEILING. The store's four words\n // are public · internal · confidential · restricted, and the top two are\n // ceilings no conversation rises through. Both these and FLD-12's `exclude`\n // and `on_request` are left out HERE and named in `held` below: a field\n // that quietly vanished would be a field the agent answers around.\n // FLD-12 is the FIELD'S OWN ANSWER to \"may an agent see this?\", in the\n // store's four words, and `exclude` means exactly that. AGT-7 adds a\n // ceiling on top: `confidential` and `restricted` values are not handed to\n // a conversation whatever the policy says.\n const guarded = field.sensitivity === \"confidential\" || field.sensitivity === \"restricted\";\n if (guarded || field.context_policy === \"exclude\" || field.context_policy === \"on_request\") {\n held.push({\n key: field.key,\n label: field.label,\n reason: guarded\n ? `This field is marked ${field.sensitivity}, so it is not handed to a conversation.`\n : field.context_policy === \"exclude\"\n ? \"This field says an agent may not see its values.\"\n : \"This field is given on request, so the agent asks for it rather than being handed it.\",\n });\n continue;\n }\n const raw = document[field.key];\n if (raw === undefined || raw === null || raw === \"\") continue;\n const structured = typeof raw === \"object\";\n entries.push({\n key: field.key,\n label: field.label,\n type: structured ? \"json\" : \"text\",\n value: structured ? raw : scalarText(field, raw),\n });\n }\n return entries;\n}\n\nfunction noticeText(notice: HiddenFieldNotice): string {\n const bag = notice as unknown as Record<string, unknown>;\n const said = bag[\"reason\"] ?? bag[\"message\"] ?? bag[\"why\"];\n return typeof said === \"string\" && said.length > 0 ? said : \"The store masked this field for this reader.\";\n}\n","\"use client\";\n\n// src/EnrichPanel.tsx — @ai-matrx/records-ui · SCR-27\n//\n// PER-FIELD AI FILL, AND THE THREE FACTS IT REFUSES TO FAKE.\n//\n// A Field whose `source` is `agent` is a Field the organization said an agent\n// keeps filled (FLD-7). `review_interval_days` is how often (AGT-6). Those two\n// live on the Field record, so this panel does not decide which fields are\n// agent-filled and it does not decide when they are stale — it READS both, and\n// a Table with no agent Fields says so instead of offering a Fill button over\n// nothing.\n//\n// 1. FRESHNESS IS THE VALUE'S OWN. `_values.<key>.at` is when it was written\n// and `.actor` is who wrote it; `review_interval_days` turns those into\n// \"due\" or \"fresh\". A screen that timed this off `updated_at` on the row\n// would call every field stale because one of them changed.\n//\n// 2. THE PROVENANCE BADGE IS NOT DECORATION. VAL-8: a value knows whether a\n// person or an agent wrote it, and which person the agent was acting for.\n// That is shown on every agent-filled value, always, because a number a\n// machine guessed and a number a person typed are different facts and the\n// difference must survive into the screen.\n//\n// 3. THE FILL GOES THROUGH THE SERVER, NEVER THROUGH THIS CLIENT. The write\n// has to be stamped actor `agent` on behalf of the person, and a browser\n// that stamped itself `agent` would be a browser claiming to be an agent.\n// The server's own `records` tool does it properly\n// (aidream `packages/matrx-records/matrx_records/agent/tool.py`:\n// `Actor.agent(principal)` → the reserved document keys `_actor` and\n// `_on_behalf_of`), so this panel asks the HOST to make that call.\n//\n// WHAT matrx-frontend MUST PASS:\n//\n// <RecordsUiProvider value={{\n// enrich: async (ask) =>\n// fetch(\"/api/ai/tools/execute\", { method: \"POST\", body: JSON.stringify({\n// tool_name: \"records\", surface: \"records-ui:enrich\",\n// arguments: { action: \"record_write\", record_id: ask.recordId,\n// values: Object.fromEntries(ask.fields.map(f => [f.key, null])) },\n// })}).then(...)\n//\n// TWO LIVE GATES SIT IN FRONT OF THAT CALL TODAY, and this panel names them\n// rather than spinning: the knob `custom/code_paths_enabled` resolves false\n// (the tool refuses every action while it does), and the `records` row in\n// `tool.binding` is `is_active = false`. Both are switches somebody flips on\n// purpose; neither is something a screen may work around.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, RecordDocument, RecordsError, ValueEnvelope } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { envelopeFor, renderValue } from \"./values\";\n\n/** What the host is asked to have the server's `records` tool do. */\nexport interface EnrichAsk {\n tableId: Uuid;\n recordId: Uuid;\n /** The agent Fields to refill, each with why this panel thinks it is due. */\n fields: Array<{ key: string; label: string; because: string }>;\n}\n\nexport interface EnrichOutcome {\n ok: boolean;\n /** What happened, in a sentence — the server's own words when it has some. */\n message: string;\n}\n\nexport const NO_ENRICH_REASON =\n \"No enrich port is bound, so nothing here offers to fill a field it cannot fill. An AI fill is \" +\n \"written by the SERVER with actor `agent` on behalf of you — a browser that stamped itself `agent` \" +\n \"would be a browser claiming to be one — so bind `enrich` on <RecordsUiProvider> with a call to the \" +\n \"server's own `records` tool (action `record_write`). Two switches also sit in front of it today: \" +\n \"the knob `custom/code_paths_enabled` resolves false, and the `records` row in `tool.binding` is \" +\n \"`is_active = false`.\";\n\nexport interface EnrichPanelProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface AgentField {\n field: Field;\n envelope: ValueEnvelope | undefined;\n value: unknown;\n /** Days since it was written, or null when it has never been written. */\n ageDays: number | null;\n /** The Field's own interval, null when the organization set none. */\n everyDays: number | null;\n due: boolean;\n /** Why it is due, or why it is not — said in words, never left to a colour. */\n because: string;\n}\n\nexport function EnrichPanel({ tableId, recordId, className }: EnrichPanelProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const [document, setDocument] = useState<RecordDocument | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [outcome, setOutcome] = useState<EnrichOutcome | null>(null);\n\n const load = useCallback(async () => {\n const answered = await client.recordRead({ record_id: recordId });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setError(null);\n setDocument(answered.data.document);\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const agentFields: AgentField[] | null = useMemo(() => {\n if (!fields.data || !document) return null;\n // FLD-7: the STORE says which fields an agent keeps filled. This panel has\n // no list of its own and no heuristic — a Field is here because its own\n // record says `source = 'agent'`.\n return fields.data.filter((f) => f.source === \"agent\").map((field) => describe(field, document));\n }, [fields.data, document]);\n\n const runFill = useCallback(\n async (targets: AgentField[]) => {\n if (!host.enrich || targets.length === 0) return;\n setBusy(targets.length === 1 ? (targets[0] as AgentField).field.key : \"*\");\n setOutcome(null);\n const answered = await host.enrich({\n tableId,\n recordId,\n fields: targets.map((t) => ({ key: t.field.key, label: t.field.label, because: t.because })),\n });\n setBusy(null);\n setOutcome(answered);\n // Re-read either way: a refused fill leaves the record exactly as it was,\n // and a screen that assumed so without looking would be guessing.\n await load();\n },\n [host, load, recordId, tableId],\n );\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) return <RefusalNotice error={error} className={className} />;\n if (!agentFields) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n if (agentFields.length === 0) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n No Field on {table.data?.name ?? \"this table\"} says an agent keeps it filled, so there is nothing\n here to enrich. A Field becomes agent-filled by carrying <code>source = agent</code> on its own\n record — set it in the field editor and it appears here with its review interval.\n </p>\n );\n }\n\n const due = agentFields.filter((f) => f.due);\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the count, what is due, and the one verb. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">AI fill</span>\n <span>\n {agentFields.length} agent {agentFields.length === 1 ? \"field\" : \"fields\"}\n {due.length > 0 ? `, ${due.length} due` : \", all fresh\"}\n </span>\n {host.enrich && rights.write && due.length > 0 ? (\n <Button size=\"sm\" className=\"ml-auto\" disabled={busy !== null} onClick={() => void runFill(due)}>\n {busy === \"*\" ? \"Asking…\" : `Refill ${due.length}`}\n </Button>\n ) : null}\n </header>\n\n {/* The port is not bound: absent verb, stated reason. Never a dead button. */}\n {!host.enrich ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_ENRICH_REASON}</p>\n ) : null}\n {host.enrich && !rights.write ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{rights.reason}</p>\n ) : null}\n\n {outcome ? (\n <p\n className={cn(\n \"rounded border px-2 py-1 text-xs\",\n outcome.ok ? \"text-muted-foreground\" : \"border-destructive text-destructive\",\n )}\n >\n {outcome.message}\n </p>\n ) : null}\n\n <ul className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {agentFields.map((entry) => (\n <li key={entry.field.key} className=\"rounded border p-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-xs font-medium\">{entry.field.label}</span>\n <ProvenanceBadge envelope={entry.envelope} />\n <span className={cn(\"text-[11px]\", entry.due ? \"text-destructive\" : \"text-muted-foreground\")}>\n {entry.because}\n </span>\n {host.enrich && rights.write ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto h-6 px-2 text-[11px]\"\n disabled={busy !== null}\n onClick={() => void runFill([entry])}\n >\n {busy === entry.field.key ? \"Asking…\" : \"Fill\"}\n </Button>\n ) : null}\n </div>\n <div className=\"mt-1 text-xs\">{renderValue(entry.field, entry.value, document ?? undefined)}</div>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\n/**\n * VAL-8 ON SCREEN. Who wrote this value, and — when it was an agent — which\n * person they were acting for. AGT-N-4 is the whole reason the second half is\n * shown: an agent carries the exact authority of the person operating it, so\n * \"an agent, for Dana\" is the true sentence and \"an agent\" is not.\n */\nfunction ProvenanceBadge({ envelope }: { envelope: ValueEnvelope | undefined }) {\n if (!envelope) return null;\n if (envelope.actor !== \"agent\") {\n return (\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {envelope.actor === \"system\" ? \"written by the system\" : \"written by a person\"}\n </Badge>\n );\n }\n return (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {envelope.on_behalf_of ? `filled by an agent, for ${envelope.on_behalf_of}` : \"filled by an agent\"}\n </Badge>\n );\n}\n\n/**\n * IS THIS VALUE DUE? Read off the value's own envelope and the Field's own\n * interval, and said in a sentence.\n *\n * An interval nobody set is NOT silently \"never due\" and not silently \"always\n * due\": the Field has no review interval, that is stated, and the value is left\n * alone. A knob nobody turned is not a decision somebody made.\n */\nfunction describe(field: Field, document: RecordDocument): AgentField {\n const envelope = envelopeFor(document, field.key);\n const value = (document as Record<string, unknown>)[field.key];\n const everyDays = field.review_interval_days ?? null;\n const writtenAt = envelope?.at ? Date.parse(envelope.at) : Number.NaN;\n const ageDays = Number.isNaN(writtenAt) ? null : Math.floor((Date.now() - writtenAt) / 86_400_000);\n\n if (value === undefined || value === null || value === \"\") {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: true,\n because: \"never filled\",\n };\n }\n if (everyDays === null) {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: false,\n because:\n ageDays === null ? \"no review interval set\" : `filled ${ageDays}d ago, no review interval set`,\n };\n }\n if (ageDays === null) {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: true,\n because: `every ${everyDays}d, and this value carries no date`,\n };\n }\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: ageDays >= everyDays,\n because: ageDays >= everyDays ? `${ageDays}d old, due every ${everyDays}d` : `${ageDays}d old of ${everyDays}d`,\n };\n}\n","\"use client\";\n\n// src/ChecklistRunner.tsx — @ai-matrx/records-ui · SCR-28\n//\n// A CHECKLIST IS NOT A LIST OF STRINGS. Every step is a REAL RECORD in a real\n// Table, related to the others, so a step can be assigned, commented on,\n// exported, historied and read by an agent exactly like anything else in this\n// store — and \"step 3 of the onboarding\" is a row somebody can find six months\n// later rather than a line in a JSON blob.\n//\n// THE TEMPLATE IS INSTANTIATED IN ONE ACT (REC-70). `custom.work_template_instantiate`\n// judges the whole graph before writing any of it, so a half-made checklist is\n// not a state this store can be in — and this component does not loop writing\n// steps one at a time, which is exactly how half-made checklists happen.\n//\n// THE STORE OWNS THE ORDER, THE TURN AND THE STATES:\n// · `custom.work_states()` is the five states and what each may become. This\n// screen hardcodes none of them; a picker built from a hardcoded list is a\n// second source of truth waiting to disagree.\n// · `custom.work_whose_turn` says whose turn each step is and whether its\n// state is terminal.\n// · `custom.work_transition_refusal` says why a move is refused, ASKED FIRST,\n// so a person is told before they try rather than after.\n//\n// `seed` is the agent's half: a complete declarative template, saved the first\n// time it is seen, exactly as `ViewBar`, `FormBuilder` and `DashboardCanvas`\n// take theirs. An agent writes a twelve-step checklist in one object.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, useTable, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, WorkGraph, WorkState, WorkTurn } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\n\n/** THE COMPLETE DECLARATIVE SPEC — one object, one `record_write`, a whole checklist. */\nexport interface ChecklistSpec {\n name: string;\n /** The Table the steps become records in. */\n subject: Uuid;\n steps: ChecklistStepSpec[];\n}\n\nexport interface ChecklistStepSpec {\n /** The document this step's record starts life with. `title` is what a person reads. */\n title: string;\n /** Anything else the subject Table's Fields take. */\n data?: Record<string, unknown>;\n}\n\n/**\n * The package-owned Table a checklist RUN is recorded in. The steps are records\n * in the subject Table — this holds only which template was instantiated and\n * when, so re-opening a checklist finds the same steps rather than making new\n * ones. (Running the same checklist twice on purpose is two rows here, which is\n * the correct answer: they are two runs.)\n */\nexport const CHECKLIST_TABLE: SystemTableSpec = {\n slug: \"records_ui_checklist_run\",\n name: \"Checklist runs\",\n labelSingular: \"Checklist run\",\n labelPlural: \"Checklist runs\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"template_id\", label: \"Template\", type: \"text\", sort: 30 },\n { key: \"instantiation_id\", label: \"Instantiation\", type: \"text\", sort: 40 },\n { key: \"step_ids\", label: \"Steps\", type: \"text\", sort: 50, config: { multiline: true } },\n { key: \"started_at\", label: \"Started\", type: \"text\", sort: 60 },\n ],\n};\n\nexport interface ChecklistRunnerProps {\n /** The Table the steps live in — normally the same Table the checklist is about. */\n tableId: Uuid;\n /** The agent's half. Each spec not already run is instantiated once. */\n seed?: ChecklistSpec[] | undefined;\n className?: string | undefined;\n}\n\ninterface Run {\n id: Uuid;\n name: string;\n subject: Uuid;\n templateId: Uuid | null;\n stepIds: Uuid[];\n startedAt: string;\n}\n\nexport function ChecklistRunner({ tableId, seed, className }: ChecklistRunnerProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(CHECKLIST_TABLE);\n const [runs, setRuns] = useState<Run[] | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(null);\n const [turns, setTurns] = useState<WorkTurn[] | null>(null);\n const [states, setStates] = useState<WorkState[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const [note, setNote] = useState<string | null>(null);\n\n const runTableId = home.tableId;\n\n // The five states, from the store. Asked once, never typed out here.\n useEffect(() => {\n let cancelled = false;\n void client.workStates().then((answered) => {\n if (cancelled || !answered.ok) return;\n setStates([...answered.data].sort((a, b) => a.sort - b.sort));\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n const loadRuns = useCallback(async (): Promise<Run[] | null> => {\n if (!runTableId) return null;\n const listed = await client.list({ table_id: runTableId, limit: 200 });\n if (!listed.ok) {\n setError(listed.error);\n return null;\n }\n setError(null);\n const held = listed.data.rows.map(toRun).filter((r) => r.subject === tableId);\n setRuns(held);\n return held;\n }, [client, runTableId, tableId]);\n\n useEffect(() => {\n void loadRuns();\n }, [loadRuns]);\n\n // ── the seed: instantiated ONCE, never on top of a run that exists ────────\n useEffect(() => {\n let cancelled = false;\n if (!runTableId || !seed || seed.length === 0 || runs === null) return;\n const missing = seed.filter((spec) => !runs.some((run) => run.name === spec.name));\n if (missing.length === 0) return;\n void (async () => {\n for (const spec of missing) {\n if (cancelled) return;\n const started = await start(client, runTableId, spec);\n if (!started.ok) {\n setError(started.error);\n return;\n }\n }\n if (!cancelled) await loadRuns();\n })();\n return () => {\n cancelled = true;\n };\n }, [client, loadRuns, runTableId, runs, seed]);\n\n const active = useMemo(\n () => runs?.find((r) => r.id === activeId) ?? runs?.[0] ?? null,\n [runs, activeId],\n );\n\n // Whose turn each step is — the STORE's answer, over the whole subject Table,\n // narrowed here to this run's own steps.\n const loadTurns = useCallback(async () => {\n const answered = await client.workWhoseTurn({ table_id: tableId, includeFinished: true });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setTurns(answered.data);\n }, [client, tableId]);\n\n // Re-asked whenever the RUN changes, not only on mount: the seed instantiates\n // its steps AFTER the first read, so a screen that asked once would draw a\n // checklist whose every step said \"you cannot see this\" — records that had\n // been written a second earlier.\n useEffect(() => {\n void loadTurns();\n }, [loadTurns, active?.id, active?.stepIds.length]);\n\n async function move(step: Uuid, to: string) {\n setBusy(true);\n setNote(null);\n const written = await client.recordUpdate({ record_id: step, patch: { status: to } });\n setBusy(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setError(null);\n setNote(`Moved to ${to}.`);\n await loadTurns();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (home.loading || runs === null) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n if (!active) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n No checklist has been run against {table.data?.name ?? \"this table\"} yet. Pass a complete template as{\" \"}\n <code>seed</code> — a name and its ordered steps — and it is instantiated once, as real records.\n </p>\n );\n }\n\n const steps = active.stepIds\n .map((id) => turns?.find((t) => t.record_id === id) ?? null)\n .map((turn, index) => ({ turn, index, id: active.stepIds[index] as Uuid }));\n const done = steps.filter((s) => s.turn?.terminal === true).length;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: which run, and how far through. No subtitle restating the name. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{active.name}</span>\n <span className=\"tabular-nums\">\n {done} of {steps.length} done\n </span>\n {runs.length > 1 ? (\n <select\n aria-label=\"Checklist run\"\n className=\"ml-auto h-7 rounded border bg-background px-1 text-xs\"\n value={active.id}\n onChange={(e) => setActiveId(e.target.value as Uuid)}\n >\n {runs.map((r) => (\n <option key={r.id} value={r.id}>\n {r.name}\n </option>\n ))}\n </select>\n ) : null}\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n {note ? <p className=\"text-xs text-muted-foreground\">{note}</p> : null}\n\n {turns === null ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {steps.map(({ turn, index, id }) => (\n <li key={id} className=\"flex items-center gap-2 rounded border p-2\">\n <span className=\"w-5 shrink-0 text-right text-[11px] tabular-nums text-muted-foreground\">\n {index + 1}\n </span>\n <span className={cn(\"min-w-0 flex-1 truncate text-xs\", turn?.terminal && \"text-muted-foreground line-through\")}>\n {turn?.title ??\n // The step is a record the read door did not return. That is a\n // fact about visibility, not an empty row, so it says so.\n \"This step is a record you cannot see — it is in the run, and the store did not return it to you.\"}\n </span>\n {turn?.assignee_id ? (\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {turn.turn ?? \"assigned\"}\n </Badge>\n ) : null}\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {turn?.status ?? turn?.state ?? \"Not started\"}\n </Badge>\n {/* The next states are the STORE's `next` for the state this step\n is actually in. A move nobody may make is never offered. */}\n {rights.write && turn && states ? (\n <NextMove\n states={states}\n current={turn.status ?? turn.state ?? null}\n disabled={busy}\n onMove={(to) => void move(id, to)}\n />\n ) : null}\n </li>\n ))}\n </ol>\n )}\n\n {!rights.write ? <p className=\"text-xs text-muted-foreground\">{rights.reason}</p> : null}\n </section>\n );\n}\n\n/**\n * The moves this step may actually make, from `custom.work_states()`.\n *\n * A state the store does not list as `next` is not shown greyed out — it is not\n * there. Offering a move that will be refused, and only saying so afterwards,\n * is the screen making a person find out by failing.\n */\nfunction NextMove({\n states,\n current,\n disabled,\n onMove,\n}: {\n states: WorkState[];\n current: string | null;\n disabled: boolean;\n onMove: (to: string) => void;\n}) {\n const here = states.find((s) => s.name === current) ?? states[0];\n const next = here?.next ?? [];\n if (next.length === 0) {\n return <span className=\"text-[11px] text-muted-foreground\">finished</span>;\n }\n return (\n <span className=\"flex shrink-0 gap-1\">\n {next.map((to) => (\n <Button key={to} size=\"sm\" variant=\"ghost\" className=\"h-6 px-2 text-[11px]\" disabled={disabled} onClick={() => onMove(to)}>\n {to}\n </Button>\n ))}\n </span>\n );\n}\n\n/**\n * ONE ACT. The template is declared, judged and instantiated, and only then is\n * the run recorded — so a refused graph leaves nothing behind at all.\n */\nasync function start(\n client: ReturnType<typeof useRecordsClient>,\n runTableId: Uuid,\n spec: ChecklistSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const graph: WorkGraph = {\n // A ref is lower-case letters, digits and underscores — the store refuses\n // `step-1` by name (\"every record in a template needs a name made of\n // lower-case letters, digits and underscores\"). Refs are built here rather\n // than taken from a person's step title for exactly that reason.\n nodes: spec.steps.map((step, index) => ({\n ref: `step_${index + 1}`,\n table: spec.subject,\n data: { title: step.title, ...(step.data ?? {}) },\n })),\n // Each step owns the next, so the order is a fact in the store rather than\n // an array index a screen remembered.\n relations: spec.steps.slice(1).map((_, index) => ({ from: `step_${index + 1}`, to: `step_${index + 2}` })),\n };\n\n // ASKED BEFORE IT IS WRITTEN. The store says why a graph would be refused,\n // and a refusal here costs nothing rather than leaving a declared template\n // nobody can instantiate.\n const refusal = await client.workTemplateRefusal({ graph });\n if (!refusal.ok) return refusal;\n if (refusal.data) {\n return {\n ok: false,\n error: {\n code: \"refused_by_rule\",\n message: refusal.data,\n hint: \"The store judged the whole graph before anything was written, so nothing was — fix the template and run it again.\",\n },\n };\n }\n\n const declared = await client.workTemplateDeclare({ name: spec.name, graph });\n if (!declared.ok) return declared;\n const made = await client.workTemplateInstantiate({ template_id: declared.data });\n if (!made.ok) return made;\n\n return client.recordWrite({\n table_id: runTableId,\n data: {\n name: spec.name,\n subject: spec.subject,\n template_id: declared.data,\n instantiation_id: made.data.instantiation_id,\n step_ids: JSON.stringify(made.data.records),\n started_at: new Date().toISOString(),\n },\n });\n}\n\nfunction toRun(row: ReadRow): Run {\n const data = (row.document ?? {}) as Record<string, unknown>;\n let stepIds: Uuid[] = [];\n try {\n const raw = data[\"step_ids\"];\n stepIds = typeof raw === \"string\" ? (JSON.parse(raw) as Uuid[]) : Array.isArray(raw) ? (raw as Uuid[]) : [];\n } catch {\n stepIds = [];\n }\n return {\n id: row.id,\n name: String(data[\"name\"] ?? \"Checklist\"),\n subject: String(data[\"subject\"] ?? \"\"),\n templateId: (data[\"template_id\"] as Uuid | null) ?? null,\n stepIds,\n startedAt: String(data[\"started_at\"] ?? \"\"),\n };\n}\n","\"use client\";\n\n// src/BookingSlots.tsx — @ai-matrx/records-ui · SCR-29\n//\n// AVAILABILITY, A SLOT PICKER, AND THE ONE THING THAT MAKES BOOKING HARD:\n// TWO PEOPLE PICKING THE SAME SLOT AT THE SAME MOMENT.\n//\n// This screen does not decide that. `custom.work_slot_hold` does, under a\n// unique index, and the loser is TOLD — not shown a spinner, not silently given\n// the next slot, not left believing they have a booking that somebody else has.\n// A picker that filtered out taken slots client-side would be correct roughly\n// until two people used it.\n//\n// WHERE A HOLD LIVES, AND WHY IT IS NOT THE BOOKING TABLE. Measured against the\n// live store: `custom.work_slot_hold` WRITES a record for the hold, so pointing\n// it at the bookings Table is refused by that Table's own Rules (\"Title is\n// required\"), and `custom.work_slot_holds` then reads every booking back as a\n// hold with no slot key. A slot has to live in a Table declared for it, by\n// `custom.work_slots_declare`, which builds the UNIQUE INDEX that makes one\n// hold per slot true in the database rather than true in an application. So\n// this component declares that Table once, through the same doors everything\n// else uses, and holds against it.\n//\n// THE THREE PARTS, AND WHO OWNS EACH:\n// · AVAILABILITY is the organization's own: a start hour, an end hour, a slot\n// length, over N days. Those are knobs on this component with sensible\n// defaults, because they are an opinion and opinions are settings.\n// · WHAT IS TAKEN is the store's: `custom.work_slot_holds` lists every hold\n// with whether it has LAPSED, so a slot that came back says why rather than\n// reappearing mysteriously.\n// · WHAT A BOOKING *IS* is `FormRunner`'s: the person answers the form's own\n// questions and the submission is an ORDINARY RECORD in a real Table. There\n// is no bookings table, no second data model, and no reconciliation later.\n//\n// THE ORDER MATTERS AND IT IS THE STRICT ONE: hold the slot FIRST, then take\n// the details, then release the hold only if they abandon it. Taking details\n// first and holding after is how two people fill in a form and one of them\n// finds out at the end.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, WorkSlotHold } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { FormRunner } from \"./FormRunner\";\nimport type { FormSpec } from \"./forms\";\n\nexport interface BookingSlotsProps {\n /** The Table holds are taken against, and the Table a booking lands in. */\n tableId: Uuid;\n /** The form a person fills in once they hold a slot. Its `subject` is the Table. */\n form: FormSpec;\n /** Availability — the organization's opinion, with a default rather than a question. */\n availability?: {\n /** First hour offered, 24h. Default 9. */\n fromHour?: number;\n /** Last hour offered, exclusive. Default 17. */\n toHour?: number;\n /** Minutes per slot. Default 60. */\n everyMinutes?: number;\n /** How many days ahead to offer. Default 5. */\n days?: number;\n };\n /** How long a hold lasts before the store lets the slot go. Default 15 minutes. */\n holdFor?: string;\n onBooked?: ((recordId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\ninterface Slot {\n /** The key the STORE holds. Stable, sortable, and the same string for everyone. */\n key: string;\n at: Date;\n taken: boolean;\n /** Set when the slot is taken: who by, so a person can see it is their own. */\n holder: string | null;\n}\n\nexport function BookingSlots({\n tableId,\n form,\n availability,\n holdFor = \"15 minutes\",\n onBooked,\n className,\n}: BookingSlotsProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const [slotTableId, setSlotTableId] = useState<Uuid | null>(null);\n const [holds, setHolds] = useState<WorkSlotHold[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [held, setHeld] = useState<{ slot: Slot; holdId: Uuid | null } | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [refused, setRefused] = useState<string | null>(null);\n\n const me = client.config.actor.user_id ?? \"anonymous\";\n const slug = `records_ui_slots_${tableId.replace(/-/g, \"\").slice(0, 16)}`;\n\n // ── the slots Table, declared once, through the store's own doors ─────────\n // A Home first (REC-1: a Table has to live somewhere), then the declaration\n // — the same sequence `ensureSystemTable` obeys, and for the same reason.\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n // FOUND BEFORE IT IS MADE. Two screens open on the same bookings Table\n // must hold against the SAME slots Table, or each one has its own\n // private idea of what is free and the unique index protects nothing.\n const tables = await client.tableList();\n if (!tables.ok) {\n if (!cancelled) setError(tables.error);\n return;\n }\n const already = tables.data.find((t) => t.slug === slug);\n if (already) {\n if (!cancelled) setSlotTableId(already.id);\n return;\n }\n const kernel = await client.personKernelId();\n if (!kernel.ok) {\n if (!cancelled) setError(kernel.error);\n return;\n }\n const home = await client.recordWrite({\n table_id: kernel.data,\n data: { name: `Slots for ${tableId}` },\n });\n if (!home.ok) {\n if (!cancelled) setError(home.error);\n return;\n }\n const declared = await client.workSlotsDeclare({\n name: `Slots for ${table.data?.name ?? \"bookings\"}`,\n slug,\n homeId: home.data,\n });\n if (cancelled) return;\n if (!declared.ok) {\n // THE STORE REFUSED TO MAKE SLOTS AT ALL — most often because it\n // cannot build the unique index that keeps one hold per slot. That is\n // shown verbatim and NO PICKER IS DRAWN: a booking screen over a store\n // that cannot decide a double-booking is a screen that will sell the\n // same hour twice and look fine doing it.\n setError(declared.error);\n return;\n }\n const made = (declared.data ?? {}) as Record<string, unknown>;\n setSlotTableId((made[\"table_id\"] as Uuid | undefined) ?? null);\n })();\n return () => {\n cancelled = true;\n };\n }, [client, slug, table.data, tableId]);\n\n const loadHolds = useCallback(async () => {\n if (!slotTableId) return;\n const answered = await client.workSlotHolds({ table_id: slotTableId });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setError(null);\n setHolds(answered.data);\n }, [client, slotTableId]);\n\n useEffect(() => {\n void loadHolds();\n }, [loadHolds]);\n\n const slots: Slot[] = useMemo(() => {\n const fromHour = availability?.fromHour ?? 9;\n const toHour = availability?.toHour ?? 17;\n const everyMinutes = availability?.everyMinutes ?? 60;\n const days = availability?.days ?? 5;\n // A LAPSED hold is not a taken slot. The store says which is which, so the\n // slot comes back on its own and nobody has to guess from a clock.\n const taken = new Map(\n (holds ?? []).filter((h) => !h.expired).map((h) => [h.slot_key, h.holder] as const),\n );\n const out: Slot[] = [];\n const first = new Date();\n first.setHours(0, 0, 0, 0);\n for (let day = 0; day < days; day += 1) {\n for (let minute = fromHour * 60; minute < toHour * 60; minute += everyMinutes) {\n const at = new Date(first);\n at.setDate(at.getDate() + day);\n at.setMinutes(minute);\n if (at.getTime() < Date.now()) continue;\n const key = at.toISOString();\n out.push({ key, at, taken: taken.has(key), holder: taken.get(key) ?? null });\n }\n }\n return out;\n }, [availability, holds]);\n\n async function take(slot: Slot) {\n if (!slotTableId) return;\n setBusy(slot.key);\n setRefused(null);\n setError(null);\n const answered = await client.workSlotHold({\n table_id: slotTableId,\n slotKey: slot.key,\n holder: me,\n ttl: holdFor,\n });\n setBusy(null);\n if (!answered.ok) {\n // THE LOSING HALF OF A RACE, AND IT IS THE DATABASE'S ANSWER.\n // `already_exists` is the unique index refusing a second hold on one\n // slot; the store's own sentence names the index that did it. Shown\n // verbatim, because \"the slot is already held\" is a fact a person can act\n // on and a spinner is not.\n if (answered.error.code === \"already_exists\") {\n setRefused(answered.error.message);\n } else {\n setError(answered.error);\n }\n await loadHolds();\n return;\n }\n const outcome = (answered.data ?? {}) as Record<string, unknown>;\n const holdId = (outcome[\"hold_id\"] as Uuid | undefined) ?? null;\n if (!holdId) {\n setRefused(\n \"The store did not hold that slot and did not say why, so nothing was booked. Pick another, and \" +\n \"report this — a hold that neither succeeds nor refuses is a defect, not a busy moment.\",\n );\n await loadHolds();\n return;\n }\n setHeld({ slot, holdId });\n }\n\n async function letGo() {\n if (held?.holdId) await client.workSlotRelease({ hold_id: held.holdId });\n setHeld(null);\n await loadHolds();\n }\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n // A refusal from the declaration is the END of this screen, not a banner over\n // a working picker.\n if (error && !slotTableId) return <RefusalNotice error={error} className={className} />;\n if (holds === null || !slotTableId) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n // ── the slot is held: now, and only now, the details ──────────────────────\n if (held) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{whenText(held.slot.at)}</span>\n <span>held for you for {holdFor}</span>\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-6 px-2 text-[11px]\" onClick={() => void letGo()}>\n Pick another\n </Button>\n </header>\n <FormRunner\n // The booking IS the submission: an ordinary record in a real Table,\n // carrying the slot it was made for, so it is in the grid and the\n // exports the moment it is sent.\n form={{\n ...form,\n questions: form.questions,\n }}\n onSubmitted={(recordId) => {\n void client\n .recordUpdate({ record_id: recordId, patch: { slot: held.slot.key } })\n .then(() => loadHolds());\n onBooked?.(recordId);\n }}\n />\n </section>\n );\n }\n\n const free = slots.filter((s) => !s.taken).length;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: what is on offer. No subtitle restating it. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Pick a time</span>\n <span className=\"tabular-nums\">\n {free} free of {slots.length}\n </span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n {refused ? <p className=\"rounded border border-destructive px-2 py-1 text-xs text-destructive\">{refused}</p> : null}\n\n {slots.length === 0 ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n There is no time left today inside the hours this is offered in. Tomorrow's slots appear here\n from midnight — this is empty because the day is over, not because something failed.\n </p>\n ) : (\n <ol className=\"flex flex-wrap gap-1\">\n {slots.map((slot) => (\n <li key={slot.key}>\n {/* A taken slot is not a dead button: it is not a button. */}\n {slot.taken ? (\n <span\n className=\"inline-flex h-8 items-center rounded border border-dashed px-2 text-[11px] text-muted-foreground\"\n title={slot.holder === me ? \"You are holding this one.\" : \"Somebody is holding this one.\"}\n >\n {whenText(slot.at)} · {slot.holder === me ? \"yours\" : \"taken\"}\n </span>\n ) : (\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-8 px-2 text-[11px]\"\n disabled={busy !== null}\n onClick={() => void take(slot)}\n >\n {busy === slot.key ? \"Holding…\" : whenText(slot.at)}\n </Button>\n )}\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n\nfunction whenText(at: Date): string {\n return at.toLocaleString(undefined, { weekday: \"short\", hour: \"numeric\", minute: \"2-digit\" });\n}\n","\"use client\";\n\n// src/CaptureSheet.tsx — @ai-matrx/records-ui · SCR-30\n//\n// A PHONE, IN A BASEMENT, WITH NO SIGNAL — AND THE CAPTURE STILL COUNTS.\n//\n// Everything hard about offline capture is one question: when the phone comes\n// back and fires the same capture for the thirtieth time, does the store write\n// thirty records? The answer is the OFFLINE CAPTURE CONTRACT, and both halves\n// of it are load-bearing:\n//\n// 1. THE CLIENT MINTS THE ID, BEFORE THE FIRST ATTEMPT, OFFLINE. `clientKey`\n// is decided the moment a person hits Capture — not when the write lands,\n// because a key minted by the server is a key that does not exist while\n// there is no server. It is never re-minted on retry: re-minting is exactly\n// how a retry becomes a second capture.\n// 2. THE STORE DEDUPES ON IT. `custom.anon_capture` writes a replay-ledger row\n// `on conflict do nothing` under a unique index and returns the record id\n// the FIRST attempt produced. So the second, third and thirtieth replay all\n// take the same branch whatever this client believes, and a phone that\n// crashed mid-send loses nothing.\n//\n// THREE MORE THINGS THIS SHEET REFUSES TO FAKE:\n// · It never claims a capture is saved while it is queued. The queue is\n// visible, counted, and each waiting item says what the store last said.\n// · With no `captureQueue` port bound the queue is IN MEMORY for the life of\n// the page and SAYS SO — a queue that silently died with the tab is the\n// precise failure this component exists to prevent.\n// · A camera or a microphone this browser will not give it is named, not\n// rendered as a button that does nothing. Bytes go through the host's\n// `upload` port; with none bound, the photo and voice capture say so and\n// the reading capture — which is just a number and a note — still works.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { NO_UPLOAD_REASON, useRecordsUi, type PendingCapture } from \"./host\";\n\n/** The three things a phone captures. Each one writes the SAME kind of record. */\nexport const CAPTURE_MODES = [\"reading\", \"photo\", \"voice\"] as const;\nexport type CaptureMode = (typeof CAPTURE_MODES)[number];\n\nexport const IN_MEMORY_QUEUE_REASON =\n \"No capture queue is bound, so anything that cannot be sent right now is held in this page's memory \" +\n \"and is lost if the page closes. Bind `captureQueue` on <RecordsUiProvider> with your host's own \" +\n \"durable store (IndexedDB in a browser) and a queued capture survives the tab, the reload and the \" +\n \"flight. It is said here rather than discovered later.\";\n\nexport interface CaptureSheetProps {\n /** The Table a capture becomes a record in. */\n tableId: Uuid;\n /** Which Field a reading's number goes in. Defaults to the first range Field. */\n readingField?: string | undefined;\n /** Which Field the note goes in. Defaults to the Table's title field. */\n noteField?: string | undefined;\n /** Which Field an attachment's file id goes in. */\n attachmentField?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * THE CLIENT-MINTED ID. `crypto.randomUUID` where there is one; a time-and-\n * randomness key where there is not. Either way it is decided HERE, offline,\n * before anything is attempted.\n */\nfunction mintClientKey(): string {\n const c = globalThis.crypto as { randomUUID?: () => string } | undefined;\n if (typeof c?.randomUUID === \"function\") return `capture:${c.randomUUID()}`;\n return `capture:${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;\n}\n\nfunction deviceName(): string {\n const nav = globalThis.navigator as { userAgent?: string } | undefined;\n return nav?.userAgent ? nav.userAgent.slice(0, 120) : \"unknown device\";\n}\n\nexport function CaptureSheet({\n tableId,\n readingField,\n noteField,\n attachmentField,\n className,\n}: CaptureSheetProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [mode, setMode] = useState<CaptureMode>(\"reading\");\n const [reading, setReading] = useState(\"\");\n const [note, setNote] = useState(\"\");\n const [fileId, setFileId] = useState<Uuid | null>(null);\n const [pending, setPending] = useState<PendingCapture[] | null>(null);\n const [saved, setSaved] = useState<Uuid[]>([]);\n const [error, setError] = useState<RecordsError | null>(null);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [flushing, setFlushing] = useState(false);\n /** Kept in a ref as well so a flush never races the render that queued an item. */\n const queue = useRef<PendingCapture[]>([]);\n\n const keep = useCallback(\n async (next: PendingCapture[]) => {\n queue.current = next;\n setPending(next);\n if (host.captureQueue) await host.captureQueue.save(next);\n },\n [host],\n );\n\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n const held = host.captureQueue ? await host.captureQueue.load() : [];\n if (cancelled) return;\n queue.current = held;\n setPending(held);\n })();\n return () => {\n cancelled = true;\n };\n }, [host]);\n\n const resolved = useCallback(() => {\n const all = fields.data ?? [];\n return {\n reading: readingField ?? all.find((f) => f.type === \"range\")?.key ?? null,\n note: noteField ?? table.data?.title_field ?? all[0]?.key ?? null,\n attachment: attachmentField ?? all.find((f) => f.format === \"file\" || f.format === \"image\")?.key ?? null,\n };\n }, [attachmentField, fields.data, noteField, readingField, table.data]);\n\n /**\n * SEND EVERYTHING WAITING. Each item goes through `custom.anon_capture` with\n * the key it was minted with — so an item that actually landed last time\n * comes back with the same record id and leaves the queue, and an item that\n * did not is tried again. Nothing here decides \"this probably worked\".\n */\n const flush = useCallback(async () => {\n if (flushing || queue.current.length === 0) return;\n setFlushing(true);\n const left: PendingCapture[] = [];\n const landed: Uuid[] = [];\n for (const item of queue.current) {\n const answered = await client.anonCapture({\n table_id: item.tableId,\n clientKey: item.clientKey,\n payload: item.payload,\n device: item.device,\n capturedAt: item.capturedAt,\n });\n if (answered.ok) {\n landed.push(answered.data);\n continue;\n }\n left.push({ ...item, attempts: item.attempts + 1, lastRefusal: answered.error.message });\n setError(answered.error);\n }\n if (landed.length > 0) {\n setSaved((held) => [...held, ...landed]);\n setError(null);\n }\n await keep(left);\n setFlushing(false);\n }, [client, flushing, keep]);\n\n // A capture is queued first and sent immediately after, which is the same\n // path a reconnect takes. There is no \"online\" branch that skips the queue:\n // one path means the offline path is the one that is actually exercised.\n async function capture() {\n const keys = resolved();\n const payload: Record<string, unknown> = {};\n if (keys.note && note.trim() !== \"\") payload[keys.note] = note.trim();\n if (mode === \"reading\" && keys.reading && reading.trim() !== \"\") {\n payload[keys.reading] = Number(reading);\n }\n if (mode !== \"reading\" && keys.attachment && fileId) payload[keys.attachment] = fileId;\n if (Object.keys(payload).length === 0) return;\n\n const item: PendingCapture = {\n // MINTED HERE. Before the attempt, not after it.\n clientKey: mintClientKey(),\n tableId,\n payload,\n capturedAt: new Date().toISOString(),\n device: deviceName(),\n attempts: 0,\n lastRefusal: null,\n };\n setReading(\"\");\n setNote(\"\");\n setFileId(null);\n await keep([...queue.current, item]);\n await flush();\n }\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (fields.loading || pending === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const keys = resolved();\n\n return (\n <section className={cn(\"mx-auto flex w-full max-w-sm flex-col gap-2\", className)}>\n {/* One row, phone-first: the three modes and the queue count. */}\n <header className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {CAPTURE_MODES.map((m) => (\n <Button\n key={m}\n size=\"sm\"\n variant={m === mode ? \"default\" : \"ghost\"}\n className=\"h-8 px-3 text-[11px] capitalize\"\n onClick={() => setMode(m)}\n >\n {m}\n </Button>\n ))}\n <span className=\"ml-auto tabular-nums\">\n {pending.length > 0 ? `${pending.length} waiting` : `${saved.length} saved`}\n </span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {mode === \"reading\" ? (\n keys.reading ? (\n <Input\n aria-label=\"Reading\"\n inputMode=\"decimal\"\n // A phone keyboard, and a touch target a thumb can hit.\n className=\"h-12 text-lg\"\n placeholder=\"0\"\n value={reading}\n onChange={(e) => setReading(e.target.value)}\n />\n ) : (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {table.data?.name ?? \"This table\"} has no number Field for a reading to go in, so this mode\n would have nowhere to put what you typed. Add one, or name it with <code>readingField</code>.\n </p>\n )\n ) : null}\n\n {mode !== \"reading\" ? (\n !host.upload ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_UPLOAD_REASON}</p>\n ) : !keys.attachment ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {table.data?.name ?? \"This table\"} has no Field a file id can go in, so a {mode} capture would\n upload the bytes and then have nowhere to record them. Add one, or name it with{\" \"}\n <code>attachmentField</code>.\n </p>\n ) : (\n <>\n <input\n aria-label={mode === \"photo\" ? \"Take a photo\" : \"Record a voice note\"}\n type=\"file\"\n className=\"text-xs\"\n // Phone-first: this is what opens the camera and the microphone\n // rather than a file browser.\n accept={mode === \"photo\" ? \"image/*\" : \"audio/*\"}\n capture={mode === \"photo\" ? \"environment\" : undefined}\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploadError(null);\n void host.upload?.(file).then((result) => {\n if (result.ok) setFileId(result.fileId);\n else setUploadError(result.reason);\n });\n }}\n />\n {fileId ? <p className=\"text-[11px] text-muted-foreground\">Attached.</p> : null}\n {uploadError ? <p className=\"text-xs text-destructive\">{uploadError}</p> : null}\n </>\n )\n ) : null}\n\n <Textarea\n aria-label=\"Note\"\n rows={2}\n className=\"text-sm\"\n placeholder=\"Note\"\n value={note}\n onChange={(e) => setNote(e.target.value)}\n />\n\n <Button className=\"h-12\" onClick={() => void capture()}>\n Capture\n </Button>\n\n {/* The queue, visible and honest. Never a capture that claims to be saved. */}\n {pending.length > 0 ? (\n <div className=\"flex flex-col gap-1 rounded border p-2\">\n <div className=\"flex items-center gap-2 text-xs\">\n <span className=\"font-medium\">Waiting to send</span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto h-6 px-2 text-[11px]\"\n disabled={flushing}\n onClick={() => void flush()}\n >\n {flushing ? \"Sending…\" : \"Try now\"}\n </Button>\n </div>\n <ul className=\"flex flex-col gap-0.5\">\n {pending.map((item) => (\n <li key={item.clientKey} className=\"text-[11px] text-muted-foreground\">\n {new Date(item.capturedAt).toLocaleTimeString()} · {item.attempts} tried\n {item.lastRefusal ? ` · ${item.lastRefusal}` : \"\"}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {!host.captureQueue ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-[11px] text-muted-foreground\">\n {IN_MEMORY_QUEUE_REASON}\n </p>\n ) : null}\n </section>\n );\n}\n","\"use client\";\n\n// src/PortalShell.tsx — @ai-matrx/records-ui · SCR-23\n//\n// AN OUTSIDER'S WHOLE WORLD: their list, their record, their form — and NOTHING\n// ELSE, because they are not in the organization.\n//\n// VIS-31 is the fact this shell is built on, and it is subtle enough that the\n// store says it in one place so no screen can invent a second answer: \"no\n// organization\" cannot mean \"no row in the membership table\", because signup\n// mints every account a PERSONAL organization — under that reading nobody would\n// ever be external. `iam.is_external_principal` means no membership of a\n// NON-personal organization, and `iam.external_principal_card` says WHY in\n// plain English, which is what this shell shows instead of an empty page.\n//\n// WHAT AN OUTSIDER REACHES IS NOT \"THEIR ORGANIZATION'S RECORDS\". It is\n// `iam.external_principal_reach` — exactly the resource ids Visibility handed\n// them, one by one. A portal that listed a Table and relied on the read door to\n// filter would be a portal whose correctness depended on a filter running; this\n// one asks for the list of ids first and reads only those.\n//\n// AND THE SHELL IS HONEST ABOUT THE LANE. While `custom/external_principal_enabled`\n// is false the doors refuse BY NAME, which is the answer the platform gave\n// before this campaign, and this screen shows that sentence rather than an\n// empty list that reads like \"you have nothing\".\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { ExternalPrincipalCard, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { Peek } from \"./Peek\";\nimport { FormRunner } from \"./FormRunner\";\nimport type { FormSpec } from \"./forms\";\n\nexport interface PortalShellProps {\n /** The Table the outsider's records belong to. */\n tableId: Uuid;\n /** OPTIONAL. A form the outsider may send — their one way to put something in. */\n form?: FormSpec | undefined;\n /** What the resources are called in `iam`'s own vocabulary. Default `record`. */\n resourceType?: string;\n className?: string | undefined;\n}\n\nexport function PortalShell({ tableId, form, resourceType = \"record\", className }: PortalShellProps) {\n const client = useRecordsClient();\n const [card, setCard] = useState<ExternalPrincipalCard | null>(null);\n const [reach, setReach] = useState<Uuid[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [open, setOpen] = useState<Uuid | null>(null);\n const [sending, setSending] = useState(false);\n\n const load = useCallback(async () => {\n // WHO THEY ARE, FIRST. A portal that read records before it knew whose\n // portal it was would be a portal deciding that for itself.\n const who = await client.externalPrincipalCard();\n if (!who.ok) {\n setError(who.error);\n return;\n }\n setError(null);\n setCard(who.data);\n const reached = await client.externalPrincipalReach({ resourceType });\n if (!reached.ok) {\n setError(reached.error);\n return;\n }\n setReach(reached.data.map((row) => row.resource_id));\n }, [client, resourceType]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) {\n // The lane is closed, or the outsider is not one. Either way the sentence\n // is `iam`'s own, verbatim — never softened into \"nothing to show\".\n return <RefusalNotice error={error} className={className} />;\n }\n if (!card || reach === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!card.external) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n {card.explanation ||\n \"You are a member of an organization here, so this portal is not yours — a portal is the scoped \" +\n \"view an OUTSIDER gets. You have the full application instead.\"}\n </p>\n );\n }\n\n if (sending && form) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{form.name}</span>\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-6 px-2 text-[11px]\" onClick={() => setSending(false)}>\n Back\n </Button>\n </header>\n <FormRunner\n form={form}\n onSubmitted={() => {\n setSending(false);\n void load();\n }}\n />\n </section>\n );\n }\n\n if (open) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <Peek tableId={tableId} recordId={open} onClose={() => setOpen(null)} />\n </section>\n );\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: how many things are theirs, and the one thing they may do. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Shared with you</span>\n <span className=\"tabular-nums\">{reach.length}</span>\n {form ? (\n <Button size=\"sm\" className=\"ml-auto h-7 px-2 text-[11px]\" onClick={() => setSending(true)}>\n {form.submitLabel ?? form.name}\n </Button>\n ) : null}\n </header>\n\n {reach.length === 0 ? (\n // EMPTY, AND IT SAYS WHICH EMPTY. \"Nobody has shared anything with you\"\n // and \"the store would not tell us\" are different sentences, and a\n // person acts on them differently.\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n Nothing has been shared with you yet. {card.explanation} When somebody shares a record with you it\n appears here — this list is exactly what Visibility gave you, one record at a time, never an\n organization's list.\n </p>\n ) : (\n <ul className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {reach.map((id) => (\n <li key={id}>\n <button\n type=\"button\"\n className=\"w-full truncate rounded border px-2 py-1.5 text-left text-xs hover:bg-muted\"\n onClick={() => setOpen(id)}\n >\n <PortalRow tableId={tableId} recordId={id} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n );\n}\n\n/**\n * One line for one record the outsider may see. It reads through the SAME read\n * door as everything else — there is no portal read path, because a second read\n * path is a second place for a visibility bug to live.\n */\nfunction PortalRow({ tableId, recordId }: { tableId: Uuid; recordId: Uuid }) {\n const client = useRecordsClient();\n const [title, setTitle] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void client.recordRead({ record_id: recordId }).then((answered) => {\n if (cancelled) return;\n if (!answered.ok) {\n setTitle(answered.error.message);\n return;\n }\n const document = answered.data.document as Record<string, unknown>;\n const first = Object.values(document).find((v) => typeof v === \"string\" && v !== \"\");\n setTitle(typeof first === \"string\" ? first : recordId);\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId, tableId]);\n\n return <span>{title ?? \"…\"}</span>;\n}\n","\"use client\";\n\n// src/PublicViewPage.tsx — @ai-matrx/records-ui · SCR-24\n//\n// THE PUBLIC PAGE A SIGNED-OUT VISITOR LANDS ON, AND THE NOTE IT REFUSES TO\n// LEAVE OFF.\n//\n// VIS-32: a share, however generous, produces NO public address. A public\n// address exists only because somebody made a publish binding on purpose, and\n// the binding carries its own RENDER MODE — this page does not choose between\n// a list and a detail, it is TOLD.\n//\n// `iam.resolve_publish_binding` is the whole of the resolution, and three\n// different-looking situations deliberately resolve identically to NOTHING: an\n// address nobody ever made, an address that was revoked, and an address whose\n// lane was closed again. They are one 404, because an address that answered\n// differently for a revoked binding would be an existence oracle — \"this used\n// to be something\" is information a stranger should not get for free.\n//\n// D-15, AND IT IS NOT DECORATION. Nothing was scanned before this was listed:\n// there is no pre-listing scan, no quarantine, no report-and-takedown ranking.\n// `iam.world_publish_gap_notice()` is ONE function so the screen, the API, the\n// admission row and this page cannot drift into four different admissions of\n// the same gap — or into none. The note is carried on EVERY read and is shown\n// here every time, including when everything worked.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, RecordsError, ResolvedPublishBinding } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { renderValue } from \"./values\";\n\nexport interface PublicViewPageProps {\n /** The public address, exactly as it appears in the URL. */\n slug: string;\n className?: string | undefined;\n}\n\nexport function PublicViewPage({ slug, className }: PublicViewPageProps) {\n const client = useRecordsClient();\n const [binding, setBinding] = useState<ResolvedPublishBinding | null | \"none\">(null);\n const [rows, setRows] = useState<ReadRow[] | null>(null);\n const [fields, setFields] = useState<Field[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n /** D-15's sentence, read from the store even when a binding did not resolve. */\n const [gap, setGap] = useState<string | null>(null);\n\n const load = useCallback(async () => {\n // The gap notice is read FIRST and unconditionally: a page that only\n // admitted the gap on the happy path would be a page that stops admitting\n // it exactly when something is wrong.\n const notice = await client.worldPublishGapNotice();\n if (notice.ok) setGap(notice.data);\n\n const resolved = await client.resolvePublishBinding({ slug });\n if (!resolved.ok) {\n setError(resolved.error);\n return;\n }\n setError(null);\n const found = resolved.data[0];\n if (!found) {\n setBinding(\"none\");\n return;\n }\n setBinding(found);\n\n // The render mode says which read to do. It is the BINDING's decision, made\n // when it was published, not a guess this page makes from the shape of the\n // answer.\n if (found.render_mode === \"list\") {\n const listed = await client.list({ table_id: found.resource_id, limit: 100 });\n if (!listed.ok) {\n setError(listed.error);\n return;\n }\n setRows(listed.data.rows);\n const held = await client.fields({ table_id: found.resource_id });\n if (held.ok) setFields(held.data);\n return;\n }\n const read = await client.recordRead({ record_id: found.resource_id });\n if (!read.ok) {\n setError(read.error);\n return;\n }\n setRows([{ id: found.resource_id, document: read.data.document, level: \"viewer\", hidden: read.data.hidden } as ReadRow]);\n }, [client, slug]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n if (binding === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (binding === \"none\") {\n // THE 404, AND IT IS THE SAME 404 FOR ALL THREE CAUSES. Nothing here hints\n // that this address ever existed.\n return (\n <main className={cn(\"mx-auto max-w-2xl py-16 text-center\", className)}>\n <h1 className=\"text-lg font-medium\">Nothing here</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n There is no public page at this address.\n </p>\n {gap ? <p className=\"mt-6 text-xs text-muted-foreground\">{gap}</p> : null}\n </main>\n );\n }\n\n return (\n <main className={cn(\"mx-auto flex max-w-2xl flex-col gap-3 py-8\", className)}>\n {/* One row. The namespace it was published under, and nothing restating it. */}\n <header className=\"flex items-baseline gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{binding.namespace ?? \"Published\"}</span>\n <span>{binding.render_mode === \"list\" ? `${rows?.length ?? 0} items` : \"Shared publicly\"}</span>\n </header>\n\n {rows === null ? (\n <Skeleton className=\"h-40 w-full\" />\n ) : rows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">This page has nothing on it yet.</p>\n ) : (\n <ol className=\"flex flex-col gap-2\">\n {rows.map((row) => (\n <li key={row.id} className=\"rounded border p-3\">\n <PublicRow row={row} fields={fields} />\n </li>\n ))}\n </ol>\n )}\n\n {/* D-15, ON EVERY READ, INCLUDING THE HAPPY ONE. */}\n <footer className=\"mt-4 border-t pt-3 text-xs text-muted-foreground\">\n {binding.notice || gap || \"Nothing was scanned before this was listed.\"}\n </footer>\n </main>\n );\n}\n\n/**\n * One public row. It draws through the same `renderValue` as every other screen\n * in this package, so a unit and a format mean the same thing to a stranger as\n * they do to the person who typed the value.\n */\nfunction PublicRow({ row, fields }: { row: ReadRow; fields: Field[] | null }) {\n const document = (row.document ?? {}) as Record<string, unknown>;\n if (!fields) {\n const first = Object.entries(document).filter(([key]) => !key.startsWith(\"_\"));\n return (\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm\">\n {first.map(([key, value]) => (\n <div key={key} className=\"contents\">\n <dt className=\"text-xs text-muted-foreground\">{key}</dt>\n <dd className=\"text-sm\">{String(value ?? \"\")}</dd>\n </div>\n ))}\n </dl>\n );\n }\n return (\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1\">\n {fields.map((field) => (\n <div key={field.key} className=\"contents\">\n <dt className=\"text-xs text-muted-foreground\">{field.label}</dt>\n <dd className=\"text-sm\">{renderValue(field, document[field.key], row.document)}</dd>\n </div>\n ))}\n </dl>\n );\n}\n","\"use client\";\n\n// src/EmbedFrame.tsx — @ai-matrx/records-ui · SCR-25\n//\n// PUTTING ONE OF OUR FORMS OR VIEWS ON SOMEBODY ELSE'S WEBSITE, WITHOUT HANDING\n// THEM A WAY INTO EVERYTHING ELSE.\n//\n// This component is two halves that must not be confused:\n//\n// · THE ISSUING HALF (`EmbedFrame`) runs on OUR side, signed in, for the\n// person who owns the form. It mints a token through\n// `custom.anon_token_issue` and shows the snippet to paste. The secret comes\n// back ONCE — only its digest is stored, so a database read, a backup or a\n// leaked dump cannot produce a working token — which is why this screen says\n// so out loud and offers to mint a new one rather than pretending it can\n// show the old one again.\n//\n// · THE HANDSHAKE (`useEmbedHandshake`) runs on THEIR page, inside the iframe.\n// It calls `custom.anon_token_verify` with the secret and the ORIGIN, and\n// the store decides. It is the store that decides, and the check is EXACT —\n// `https://example.com.evil.test` passes a suffix match and fails this one.\n//\n// THE THREE THINGS THE STORE REFUSES, AND THIS SCREEN NAMES BEFORE IT ASKS:\n// 1. A token with no origin list. An empty list does not mean \"everywhere\" —\n// it is refused at issue, because a token that works from any page on the\n// internet includes an attacker's.\n// 2. A token carrying both read and write. One credential, one decision; the\n// second is always the one nobody meant to grant.\n// 3. A write token for a form nobody published. Closed by default.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { AnonTokenBinding, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\n\nexport interface EmbedFrameProps {\n /** The Table whose rights decide whether an embed may be issued at all. */\n tableId: Uuid;\n /** A write embed names the form it writes into. */\n formId?: Uuid | null | undefined;\n /** A read embed names the saved view or the record it shows. */\n savedViewId?: Uuid | null | undefined;\n recordId?: Uuid | null | undefined;\n /** Where the embedded page is served from — the `src` of the iframe. */\n embedUrl: string;\n className?: string | undefined;\n}\n\nexport function EmbedFrame({\n tableId,\n formId,\n savedViewId,\n recordId,\n embedUrl,\n className,\n}: EmbedFrameProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [origins, setOrigins] = useState(\"\");\n const [secret, setSecret] = useState<string | null>(null);\n const [tokenId, setTokenId] = useState<Uuid | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n\n // A write embed needs a form; a read embed needs a view or a record. The mode\n // is therefore a FACT about what was passed, never a toggle somebody can set\n // to a value the store will refuse.\n const mode: \"read\" | \"write\" = formId ? \"write\" : \"read\";\n\n const parsed = origins\n .split(/[\\s,]+/)\n .map((o) => o.trim())\n .filter((o) => o.length > 0);\n\n const issue = useCallback(async () => {\n setBusy(true);\n setError(null);\n const minted = await client.anonTokenIssue({\n mode,\n allowedOrigins: parsed,\n formId: formId ?? null,\n savedViewId: savedViewId ?? null,\n recordId: recordId ?? null,\n });\n setBusy(false);\n if (!minted.ok) {\n setError(minted.error);\n return;\n }\n setSecret(minted.data.secret);\n setTokenId(minted.data.token_id);\n host.notify?.success(\"Embed token issued. Copy it now — it is never shown again.\");\n }, [client, formId, host, mode, parsed, recordId, savedViewId]);\n\n const revoke = useCallback(async () => {\n if (!tokenId) return;\n setBusy(true);\n const done = await client.anonTokenRevoke({ token_id: tokenId });\n setBusy(false);\n if (!done.ok) {\n setError(done.error);\n return;\n }\n setSecret(null);\n setTokenId(null);\n }, [client, tokenId]);\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (table.loading) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n // Issuing an embed hands a stranger a way in, so the store asks for `admin`\n // on the Table. Without it there is no control here at all — not a greyed\n // one — and the reason is shown.\n if (!rights.admin) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n {rights.reason} Issuing an embed opens a way in from somebody else's website, so the store asks for\n the admin level on this table before it will mint one.\n </p>\n );\n }\n\n const snippet = secret\n ? `<iframe src=\"${embedUrl}#t=${secret}\" style=\"width:100%;height:640px;border:0\" loading=\"lazy\"></iframe>`\n : null;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: what kind of embed this is, and where it may run. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Embed</span>\n <span>{mode === \"write\" ? \"a form people can send\" : \"a read-only view\"}</span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n <label className=\"flex flex-col gap-1 text-xs\">\n <span className=\"text-muted-foreground\">Sites this embed works on</span>\n <Input\n aria-label=\"Allowed origins\"\n className=\"h-8 text-xs\"\n placeholder=\"https://example.com\"\n value={origins}\n onChange={(e) => setOrigins(e.target.value)}\n />\n {/* Said BEFORE the refusal, because a person should not have to be\n refused to learn the rule. */}\n <span className=\"text-[11px] text-muted-foreground\">\n Name every site, scheme and host and port. An empty list is refused rather than quietly meaning\n \"anywhere\": a token that works from any page on the internet includes an attacker's. The match is\n exact, so <code>example.com.evil.test</code> will not pass.\n </span>\n </label>\n\n {!secret ? (\n <Button size=\"sm\" className=\"self-start\" disabled={busy || parsed.length === 0} onClick={() => void issue()}>\n {busy ? \"Issuing…\" : \"Issue embed\"}\n </Button>\n ) : (\n <>\n <p className=\"rounded border px-2 py-1 text-xs text-muted-foreground\">\n Copy this now. Only its digest is stored, so nobody — including us — can show it to you again;\n if it is lost, issue a new one and replace the old.\n </p>\n <Textarea aria-label=\"Embed snippet\" readOnly rows={3} className=\"font-mono text-[11px]\" value={snippet ?? \"\"} />\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void navigator.clipboard?.writeText(snippet ?? \"\")}\n >\n Copy\n </Button>\n <Button size=\"sm\" variant=\"ghost\" disabled={busy} onClick={() => void revoke()}>\n Revoke\n </Button>\n </div>\n </>\n )}\n </section>\n );\n}\n\n/**\n * THE OTHER HALF, RUNNING INSIDE THE IFRAME ON SOMEBODY ELSE'S PAGE.\n *\n * It hands the secret and this page's own origin to the store and uses whatever\n * comes back. It decides nothing itself: a handshake that checked the origin in\n * JavaScript would be a handshake an attacker can edit.\n *\n * `origin` is taken from `window.location.origin` by default rather than from a\n * prop, because a prop is a value the embedding page controls and the origin\n * must not be.\n */\nexport function useEmbedHandshake(args: { secret: string; requiredMode?: \"read\" | \"write\"; origin?: string }): {\n binding: AnonTokenBinding | null;\n error: RecordsError | null;\n loading: boolean;\n} {\n const client = useRecordsClient();\n const [binding, setBinding] = useState<AnonTokenBinding | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [loading, setLoading] = useState(true);\n const origin = args.origin ?? (typeof location === \"undefined\" ? \"\" : location.origin);\n const { secret, requiredMode } = args;\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(null);\n void client\n .anonTokenVerify({ secret, origin, requiredMode: requiredMode ?? null })\n .then((answered) => {\n if (cancelled) return;\n setLoading(false);\n if (!answered.ok) {\n setError(answered.error);\n setBinding(null);\n return;\n }\n setBinding(answered.data);\n });\n return () => {\n cancelled = true;\n };\n }, [client, origin, requiredMode, secret]);\n\n return { binding, error, loading };\n}\n","\"use client\";\n\n// src/RecordsMount.tsx — @ai-matrx/records-ui\n//\n// THE ONE LINE A HOST ROUTE WRITES. `<RecordsProvider>` from @ai-matrx/records\n// and `<RecordsUiProvider>` from this package are two providers that must be\n// nested in one order, every time — so a route that got the order wrong would\n// fail with \"useRecordsClient was called outside <RecordsProvider>\" at the\n// bottom of a screen nobody was looking at. This mounts both, in the one order\n// that is correct, so a route file stays a mount and nothing more.\n//\n// THE RIGHTS QUESTION, ANSWERED HONESTLY BY DEFAULT.\n// `TableRights` is a port because this package refuses to guess who may\n// administer a table. But a host that binds nothing gets `NO_RIGHTS` — every\n// administering control ABSENT — which is the safe default and a poor product\n// for a host whose authority IS the store's. `storeDecidesRights` is the other\n// honest answer and it is opt-in: offer the control, let the doors decide, and\n// show the store's own refusal verbatim when they refuse. It never claims a\n// right; it says, in its reason, that the store is the authority.\n//\n// Kernel Tables (REC-27) are excluded from it outright: the nine Tables the\n// platform ships are not administered from a person's screen.\n\nimport type { ReactNode } from \"react\";\nimport type { RecordsActor, RecordsConfig, RecordsDataSource, Table, Uuid } from \"@ai-matrx/records\";\nimport { RecordsProvider } from \"@ai-matrx/records/react\";\n\nimport { RecordsUiProvider, type RecordsUiHost, type TableRights } from \"./host\";\n\nexport const STORE_DECIDES_REASON =\n \"This host offers the control and lets the record store decide: the doors are the authority here, \" +\n \"and a door that refuses you says so in its own words on this screen. Kernel tables are not \" +\n \"administered from a screen at all.\";\n\nexport const KERNEL_REASON =\n \"This is one of the Tables the platform ships, so it is not administered from a screen. Make your \" +\n \"own table to change fields.\";\n\n/**\n * The rights answer for a host whose authority IS the record store's doors.\n * Offers the control; the store refuses with its own sentence if it must.\n */\nexport function storeDecidesRights(table: Table): TableRights {\n if (table.is_kernel) {\n return { admin: false, comment: true, write: false, reason: KERNEL_REASON };\n }\n return { admin: true, comment: true, write: true, reason: STORE_DECIDES_REASON };\n}\n\nexport interface RecordsMountProps {\n /** The store config: the host's session-carrying client, the actor, the organization. */\n config: RecordsConfig;\n /** What this host binds on top — links, toasts, uploads, rights. */\n host?: RecordsUiHost | undefined;\n /**\n * Use `storeDecidesRights` when the host binds no `rights` of its own. Left\n * off, an unbound host gets `NO_RIGHTS` and every administering control is\n * absent with its reason.\n */\n letTheStoreDecideRights?: boolean | undefined;\n children: ReactNode;\n}\n\nexport function RecordsMount({\n config,\n host,\n letTheStoreDecideRights,\n children,\n}: RecordsMountProps) {\n const bound: RecordsUiHost = {\n ...(host ?? {}),\n ...(host?.rights\n ? {}\n : letTheStoreDecideRights\n ? { rights: storeDecidesRights }\n : {}),\n };\n return (\n <RecordsProvider config={config}>\n <RecordsUiProvider value={bound}>{children}</RecordsUiProvider>\n </RecordsProvider>\n );\n}\n\n/**\n * The actor a signed-in person is. `user` is the store's own word (the closed\n * ACTOR_VOCABULARY is `user` · `agent` · `system`), and AGT-N-4 means an agent\n * acting for this person carries exactly this authority and no other.\n */\nexport function personActor(userId: Uuid | null | undefined): RecordsActor {\n return userId ? { actor: \"user\", user_id: userId } : { actor: \"user\" };\n}\n\n/**\n * A supabase-js client AS this package's data seam.\n *\n * `RecordsDataSource` is deliberately a small structural subset of\n * `SupabaseClient` — the package holds no key and opens no connection, the host\n * hands it a client that already carries the person's session.\n *\n * IT IS NOT AN IDENTITY CAST, and it cost a live screen to learn why\n * (2026-09-19, /data-v2's first load): the port's `rpc(fn, args, { schema })`\n * says the schema OUT LOUD, because every door of this store is `custom.<name>`\n * and every door of the trust layer is `iam.<name>`. supabase-js's own\n * `rpc(fn, args, options)` has no `schema` option at all — its third argument is\n * `{ head, get, count }` — so a client passed straight through silently asked\n * its default PostgREST profile and the store answered, correctly and uselessly,\n * \"Could not find the function public.table_kernel_id ... PGRST202\". The schema\n * is chosen the one way supabase-js offers: `client.schema(name).rpc(...)`.\n *\n * `schema(name).from(table)` already agrees structurally and is passed through.\n *\n * `fallbackSchema` is the profile a call that says NOTHING is sent to. No caller\n * in `@ai-matrx/records` omits the option — `callDoor` always says `custom` and\n * `trustDoor` always says `iam` — so it never fires today; it exists so that a\n * call which one day forgets lands on the store rather than silently on\n * `public`. It is a FALLBACK and not the answer: a version of this adapter that\n * sent EVERY door to one fixed schema would route the `iam` trust doors (the\n * external principal, the publish binding) into `custom` and get a PGRST202\n * naming the wrong schema.\n *\n * The cast itself stays HERE, once, where it is explained: a generated\n * `Database` type makes `schema().from().select()` enormous, and a host app that\n * passes its client straight into `config` gets `TS2589: Type instantiation is\n * excessively deep and possibly infinite` in its own build (matrx-frontend,\n * 2026-09-18, on all three campaign routes at once).\n */\nexport function recordsDataSource(client: object, fallbackSchema = \"custom\"): RecordsDataSource {\n const supabase = client as unknown as {\n rpc: (fn: string, args: Record<string, unknown>) => PromiseLike<unknown>;\n schema: (name: string) => {\n rpc: (fn: string, args: Record<string, unknown>) => PromiseLike<unknown>;\n from: (table: string) => unknown;\n };\n };\n return {\n rpc(fn, args, options) {\n const on = supabase.schema(options?.schema ?? fallbackSchema);\n return on.rpc(fn, args) as ReturnType<RecordsDataSource[\"rpc\"]>;\n },\n schema(name) {\n return supabase.schema(name) as ReturnType<RecordsDataSource[\"schema\"]>;\n },\n };\n}\n","\"use client\";\n\n// src/TablesHome.tsx — @ai-matrx/records-ui\n//\n// THE LIST OF A PERSON'S TABLES — AND IT IS NEVER A FLAT PILE.\n//\n// Four lanes, always, in this order: mine · my organization · system ·\n// community. The lane a Table is in is read off the Table record itself and is\n// not a guess:\n//\n// · mine — `visibility = 'personal'` (the store's own enum word)\n// · organization — `visibility = 'internal'`\n// · system — `is_kernel` (REC-27: the Tables the platform ships)\n// · community — `visibility` is `link` or `public`\n//\n// A lane with nothing in it SAYS SO in one sentence that tells a person how it\n// fills up. An empty heading with nothing under it reads as \"broken\"; this\n// reads as \"nothing here yet, and here is what puts something here\".\n//\n// Creating and importing are both here, because both make a Table, and they go\n// through the store's own doors — `declareTable` walks Home → table_declare →\n// Fields, and the import mounts `ImportWizard` on the Table it just declared.\n\nimport { useCallback, useState } from \"react\";\nimport type { Table, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient, useTables } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\n\nimport { RefusalNotice } from \"./Refusal\";\nimport { ImportWizard } from \"./ImportWizard\";\nimport { declareTable, tokenFor } from \"./createTable\";\nimport { tableName } from \"./names\";\n\nexport type TableLane = \"mine\" | \"organization\" | \"system\" | \"community\" | \"app\";\n\n/** The five lanes, in the order a person reads them. Never a flat list. */\nexport const TABLE_LANES: readonly TableLane[] = [\"mine\", \"organization\", \"system\", \"community\", \"app\"];\n\nexport const LANE_TITLE: Record<TableLane, string> = {\n mine: \"Mine\",\n organization: \"My organization\",\n system: \"System\",\n community: \"Community\",\n app: \"Kept by the app\",\n};\n\n/**\n * THE APP'S OWN BOOKKEEPING, MARKED AS SUCH.\n *\n * A saved view, a comment, a queued action and a form are records in Tables\n * this package declares in the organization's own store (`systemTable.ts`) —\n * which is what makes them shareable, historied and agent-writable. The price\n * is that using the product creates Tables in the person's own list: the\n * verdict of 19 September watched \"Saved views · 9 fields · records_ui_view\"\n * appear among somebody's data, and then \"Comments\" appear beside it the\n * moment a record was opened.\n *\n * They are not hidden — hiding a real Table from the person who owns it is its\n * own lie, and they hold that person's comments. They get their own lane,\n * last, with a sentence that says what they are.\n */\nconst APP_TABLE_PREFIX = \"records_ui_\";\n\n/** What fills an empty lane. A heading with nothing under it must still teach. */\nexport const LANE_EMPTY: Record<TableLane, string> = {\n mine: \"Nothing of your own yet. New table makes one that only you can see.\",\n organization:\n \"No tables shared across your organization yet. A table you make is yours until you change its visibility to internal.\",\n system: \"The platform's own tables are not in this organization's store.\",\n community: \"Nothing shared beyond your organization. A table published by link or to the world lands here.\",\n app:\n \"The app has not needed a table of its own in this organization yet. Saving a view, writing a \" +\n \"comment or building a form makes one, and it appears here rather than among your own data.\",\n};\n\n/** Which lane one Table belongs to, from the record's own columns. */\nexport function laneFor(table: Table): TableLane {\n if (table.is_kernel) return \"system\";\n if ((table.slug ?? \"\").startsWith(APP_TABLE_PREFIX)) return \"app\";\n if (table.visibility === \"public\" || table.visibility === \"link\") return \"community\";\n if (table.visibility === \"personal\") return \"mine\";\n return \"organization\";\n}\n\nexport interface TablesHomeProps {\n /** Where a table opens. Absent and the card is a plain row with no pretend link. */\n onOpenTable?: ((tableId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TablesHome({ onOpenTable, className }: TablesHomeProps) {\n const client = useRecordsClient();\n const tables = useTables();\n const [creating, setCreating] = useState(false);\n const [name, setName] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<RecordsError | null>(null);\n const [importInto, setImportInto] = useState<Uuid | null>(null);\n\n const create = useCallback(\n async (mode: \"open\" | \"import\") => {\n const trimmed = name.trim();\n if (!trimmed) return;\n setBusy(true);\n setError(null);\n const result = await declareTable(client, { name: trimmed, slug: tokenFor(trimmed) });\n setBusy(false);\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setName(\"\");\n setCreating(false);\n tables.reload();\n if (mode === \"import\") setImportInto(result.data);\n else onOpenTable?.(result.data);\n },\n [client, name, onOpenTable, tables],\n );\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-4\", className)}>\n {/* One row. The page's own header already says where you are. */}\n <div className=\"flex items-center gap-2\">\n {creating ? (\n <>\n <BasicInput\n autoFocus\n value={name}\n placeholder=\"Table name\"\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") void create(\"open\");\n if (e.key === \"Escape\") setCreating(false);\n }}\n className=\"h-8 max-w-xs\"\n />\n <Button size=\"sm\" disabled={busy || name.trim().length === 0} onClick={() => void create(\"open\")}>\n {busy ? \"Declaring…\" : \"Create\"}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={busy || name.trim().length === 0}\n onClick={() => void create(\"import\")}\n >\n Create and import a file\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setCreating(false)}>\n Cancel\n </Button>\n </>\n ) : (\n <Button size=\"sm\" onClick={() => setCreating(true)}>\n New table\n </Button>\n )}\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {importInto ? (\n <div className=\"rounded-md border p-3\">\n <ImportWizard tableId={importInto} onDone={() => setImportInto(null)} />\n <Button size=\"sm\" variant=\"ghost\" className=\"mt-2\" onClick={() => onOpenTable?.(importInto)}>\n Open the table\n </Button>\n </div>\n ) : null}\n\n {tables.error ? <RefusalNotice error={tables.error} /> : null}\n {tables.loading && !tables.data ? (\n <div className=\"space-y-2\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n ) : null}\n\n {tables.data\n ? TABLE_LANES.map((lane) => {\n const rows = tables.data!.filter((t) => laneFor(t) === lane);\n return (\n <section key={lane} className=\"space-y-1.5\">\n <div className=\"flex items-baseline gap-2\">\n <h2 className=\"text-sm font-medium\">{LANE_TITLE[lane]}</h2>\n <span className=\"text-xs opacity-60\">{rows.length}</span>\n </div>\n {rows.length === 0 ? (\n <p className=\"text-xs opacity-70\">{LANE_EMPTY[lane]}</p>\n ) : (\n <ul className=\"grid gap-1.5 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((table) => (\n <li key={table.id}>\n <button\n type=\"button\"\n onClick={() => onOpenTable?.(table.id)}\n className={cn(\n \"w-full rounded-md border px-3 py-2 text-left transition-colors\",\n onOpenTable ? \"hover:bg-accent\" : \"cursor-default\",\n )}\n >\n {/* The Table's NAME, never its token: `records_ui_view`\n and `v78_widget2` are machine names and no product\n a person judges puts one on a card. */}\n <span className=\"block truncate text-sm\">{tableName(table)}</span>\n <span className=\"block truncate text-xs opacity-60\">\n {table.fields.length} field{table.fields.length === 1 ? \"\" : \"s\"}\n {table.label_plural && table.label_plural !== table.name\n ? ` · ${table.label_plural}`\n : \"\"}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n );\n })\n : null}\n </div>\n );\n}\n","// src/createTable.ts — @ai-matrx/records-ui\n//\n// DECLARING A TABLE, THE WAY THE STORE MAKES YOU DECLARE ONE.\n//\n// REC-1: a Table has to live somewhere. `custom._table_shape_guard` refuses a\n// Table with no Home in those words (\"a table has to live somewhere - give it a\n// home\"), so the sequence is fixed and this module is the one place that walks\n// it for a person-made table:\n//\n// 1. `personKernelId()` — the kernel Table a Home record lives in.\n// 2. `record_write` — the Home record.\n// 3. `table_declare` — the Table, under that Home.\n// 4. one `record_write` per Field, into the field kernel.\n//\n// Nothing here works around a guard; every step is a door. A Field the store\n// refused stops the sequence and hands back the store's own sentence, because a\n// Table that quietly lost a column is the silent failure this package exists to\n// prevent.\n\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport type { RecordsError, Uuid } from \"@ai-matrx/records\";\n\n/** One Field a person asked for, in the store's own behaviour words (FLD-1). */\nexport interface NewFieldSpec {\n key: string;\n label: string;\n /** A parity type — the thirteen come from the store, see `PARITY_FIELD_TYPES`. */\n type: string;\n sort?: number;\n required?: boolean;\n multi?: boolean;\n config?: Record<string, unknown>;\n}\n\nexport interface NewTableSpec {\n name: string;\n /** The token the Table is addressed by. Derived from the name when absent. */\n slug?: string;\n labelSingular?: string;\n labelPlural?: string;\n /** The Field whose value is the record's title (REC-2). Defaults to the first Field. */\n titleField?: string;\n fields?: NewFieldSpec[];\n}\n\nexport type DeclareResult =\n | { ok: true; data: Uuid }\n | { ok: false; error: RecordsError };\n\n/** `My Sales Pipeline` → `my_sales_pipeline`. A token, never a sentence. */\nexport function tokenFor(name: string): string {\n return (\n name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 48) || \"table\"\n );\n}\n\n/** The one Field a Table cannot be declared without: something to call a record. */\nexport const DEFAULT_FIELDS: NewFieldSpec[] = [\n { key: \"title\", label: \"Title\", type: \"text\", sort: 10, required: true },\n];\n\nexport async function declareTable(\n client: RecordsClient,\n spec: NewTableSpec,\n): Promise<DeclareResult> {\n const fields = spec.fields && spec.fields.length > 0 ? spec.fields : DEFAULT_FIELDS;\n const slug = spec.slug ?? tokenFor(spec.name);\n const titleField = spec.titleField ?? fields[0]!.key;\n\n const personKernel = await client.personKernelId();\n if (!personKernel.ok) return personKernel;\n\n const home = await client.recordWrite({\n table_id: personKernel.data,\n data: { name: `${spec.name} Home` },\n });\n if (!home.ok) return home;\n\n const table = await client.tableDeclare({\n homeId: home.data,\n spec: {\n name: spec.name,\n slug,\n type: \"entity\",\n label_singular: spec.labelSingular ?? spec.name,\n label_plural: spec.labelPlural ?? spec.name,\n display: \"list\",\n weight: \"light\",\n ordered: false,\n row_order: \"manual\",\n title_field: titleField,\n retention_days: 365,\n // AGT-1: a table a person made is agent-writable by declaration; the\n // organization turns it off, never this package.\n agent_writable: true,\n default_sort: [{ field: titleField, direction: \"asc\" }],\n fields: fields.map((f) => ({ name: f.key })),\n },\n });\n if (!table.ok) return table;\n\n const written = await addFields(client, table.data, fields);\n if (!written.ok) return written;\n return { ok: true, data: table.data };\n}\n\n/** Write Field records for an existing Table. Used by the create path and by import. */\nexport async function addFields(\n client: RecordsClient,\n tableId: Uuid,\n fields: NewFieldSpec[],\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n for (const field of fields) {\n const result = await client.recordWrite({\n table_id: fieldKernel.data,\n data: {\n key: field.key,\n label: field.label,\n type: field.type,\n sort: field.sort ?? 100,\n required: field.required ?? false,\n multi: field.multi ?? false,\n dated: false,\n rules: [],\n config: field.config ?? {},\n source: \"manual\",\n depends_on: [],\n sensitivity: \"internal\",\n source_config: {},\n context_policy: \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n },\n });\n if (!result.ok) return result;\n }\n return { ok: true, data: tableId };\n}\n","\"use client\";\n\n// src/TablePage.tsx — @ai-matrx/records-ui\n//\n// ONE TABLE'S WHOLE PAGE, assembled from this package's own components and\n// nothing else. A host route mounts this and passes the table token; every\n// screen below it is the canonical one, so a table reached from /data, from a\n// portal or from an agent's link looks and behaves identically.\n//\n// WHAT IS ON IT, and which contract row each part answers:\n// ViewBar (SCR-7) the saved views, and saving a new one\n// ViewSwitcher (SCR-6) grid · kanban · calendar · gallery over the SAME records\n// RecordForm (SCR-N-1) adding a record\n// FieldEditor (SCR-9) adding or retyping a field\n// TableSettings (SCR-3/4/5) rename, reorder, retype, delete, proposals\n// ActionInbox (SCR-11) approvals, assignments and agent proposals\n// Peek (SCR-N-3) a record, opened in place\n// HistoryPanel (SCR-17) that record's own versioned timeline\n// CommentThread (SCR-18) that record's comments\n// ExportMenu (SCR-31) the same bytes a script would produce\n// ImportWizard (SCR-10) rows in through the one write door\n//\n// ONE PANEL AT A TIME. The right-hand rail shows exactly one of settings,\n// inbox, import, the new-field editor or the opened record — a page that opens\n// four rails at once is a page nobody can read.\n\nimport { useCallback, useState } from \"react\";\nimport { viewPatchDocument, type SavedView, type SavedViewSpec } from \"./views\";\nimport type { Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient, useTable } from \"@ai-matrx/records/react\";\nimport { Button, Separator, Skeleton, cn } from \"@ai-matrx/design-system\";\n\nimport { ActionInbox } from \"./ActionInbox\";\nimport { CommentThread } from \"./CommentThread\";\nimport { ExportMenu } from \"./ExportMenu\";\nimport { FieldEditor } from \"./FieldEditor\";\nimport { HistoryPanel } from \"./HistoryPanel\";\nimport { ImportWizard } from \"./ImportWizard\";\nimport { Peek } from \"./Peek\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { TableSettings } from \"./TableSettings\";\nimport { ViewBar } from \"./ViewBar\";\nimport { ViewSwitcher } from \"./ViewSwitcher\";\nimport { useTableRights } from \"./host\";\nimport { tableName } from \"./names\";\nimport { useRecordVersion } from \"./systemTable\";\n\ntype Rail = \"none\" | \"settings\" | \"inbox\" | \"import\" | \"field\" | \"record\" | \"new-record\";\n\nexport interface TablePageProps {\n tableId: Uuid;\n /** Rows per page for every layout. */\n pageSize?: number | undefined;\n /**\n * The views this table should have. Each one whose NAME the table does not\n * hold yet is saved the first time the bar loads, and a name a person has\n * since tweaked is never overwritten. Left out, `DEFAULT_VIEW_NAME` below is\n * used — see why that default is not optional.\n */\n seedViews?: SavedViewSpec[] | undefined;\n /**\n * What a person does when the table is not theirs to see — switch\n * organization, go back to the list. Absent, the screen still SAYS what\n * happened; it just has no button to offer, which is honest and is never a\n * blank frame.\n */\n onLeave?: (() => void) | undefined;\n /** The word on that button. Defaults to \"Back to your tables\". */\n leaveLabel?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * THE SENTENCE A TABLE YOU CANNOT SEE SAYS.\n *\n * Measured on the real screen (independent verdict, 19 September): opening a\n * table's page while another organization was active left the main area's text\n * \"literally the empty string\" after eighteen seconds — no sentence, no\n * spinner, no console error. A made-up id did the same. The cause is exactly\n * one line of this file: `custom.table_list` correctly answers the tables this\n * person can see in THIS organization, the table is not among them, so\n * `useTable` answers `{ data: null, error: null }` — not a refusal, just\n * absence — and the page rendered a skeleton for ever.\n *\n * Absence is an ANSWER and it gets a sentence. It deliberately does not say\n * whether the table exists: this person cannot see it, and which of the two it\n * is is not theirs to learn.\n */\nexport const TABLE_NOT_REACHABLE =\n \"This table is not in the organization you are working in, so there is nothing here to show. \" +\n \"Switch to the organization that owns it and open it again — or it may have been deleted.\";\n\n/**\n * THE VIEW EVERY TABLE HAS, AND WHY IT IS NOT OPTIONAL.\n *\n * A view is a record, so a table nobody has saved a view for has none — and\n * this page then renders its own honest sentence (\"Waiting for this table's\n * views\") and NO RECORDS AT ALL. Measured on 2026-09-19 by walking the real\n * product: declare a table, write a record, open the table — and the record is\n * not on the screen, with the only remedy being a control the person has no\n * reason to press. That is a dead end on the first table anybody makes.\n *\n * So the page seeds one: every record, newest work first, as a grid. It is an\n * ordinary saved view record like any other — renamable, re-sortable,\n * deletable — not a hidden built-in mode, because a \"special\" default view is a\n * second kind of view that every feature after it has to know about.\n */\nexport const DEFAULT_VIEW_NAME = \"All records\";\n\nfunction defaultView(tableId: Uuid): SavedViewSpec {\n return { name: DEFAULT_VIEW_NAME, subject: tableId, layout: \"grid\", isDefault: true };\n}\n\nexport function TablePage({\n tableId,\n pageSize = 100,\n seedViews,\n onLeave,\n leaveLabel = \"Back to your tables\",\n className,\n}: TablePageProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [view, setView] = useState<SavedView | null>(null);\n const [rail, setRail] = useState<Rail>(\"none\");\n const [openRecord, setOpenRecord] = useState<Uuid | null>(null);\n // The view record's own version at load, so two tabs tweaking one view are TOLD.\n const viewVersion = useRecordVersion(view?.id ?? null);\n\n const show = (next: Rail) => setRail((current) => (current === next ? \"none\" : next));\n\n /**\n * A change the switcher made — the layout, the kanban's grouping Field, the\n * calendar's date Field — saved onto the VIEW RECORD, which is what makes it\n * remembered per saved view rather than per page load. The local copy moves\n * first so the board redraws at once; the store is the one that keeps it.\n */\n const patchView = useCallback(\n async (patch: Partial<SavedViewSpec>) => {\n const current = view;\n if (!current) return;\n setView({ ...current, ...patch });\n const document = viewPatchDocument(patch);\n if (Object.keys(document).length === 0) return;\n await client.recordUpdate({\n record_id: current.id,\n patch: document,\n ...(viewVersion === null ? {} : { expectedVersion: viewVersion }),\n });\n },\n [client, view, viewVersion],\n );\n\n if (table.error) return <RefusalNotice error={table.error} />;\n if (table.loading) return <Skeleton className=\"h-40 w-full\" />;\n if (!table.data) {\n // NOT a blank frame, and not a spinner that never ends.\n return (\n <div className={cn(\"flex flex-col items-start gap-2 rounded-md border border-dashed p-6\", className)}>\n <p className=\"text-sm font-medium\">This table is not here</p>\n <p className=\"max-w-prose text-xs text-muted-foreground\">{TABLE_NOT_REACHABLE}</p>\n {onLeave ? (\n <Button size=\"sm\" variant=\"outline\" onClick={onLeave}>\n {leaveLabel}\n </Button>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-h-0 gap-4\", className)}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {/* One row of controls. The route's own header already carries the name. */}\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <ViewBar\n tableId={tableId}\n onActiveView={setView}\n seed={seedViews ?? [defaultView(tableId)]}\n className=\"min-w-0 flex-1\"\n />\n {/* ONE \"New record\" ON SCREEN, EVER. The grid carries its own — it\n adds a row and puts you straight into the first cell, which is the\n gesture a person expects — so this page's button would be a second\n control for one thing (and was: the walk found two buttons of the\n same name in one header). It exists for the layouts that have no\n cells to type into. */}\n {rights.write && view && view.layout !== \"grid\" ? (\n <Button size=\"sm\" onClick={() => show(\"new-record\")}>\n New record\n </Button>\n ) : null}\n {rights.admin ? (\n <>\n <Button size=\"sm\" variant=\"outline\" onClick={() => show(\"field\")}>\n Add field\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"settings\")}>\n Settings\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"import\")}>\n Import\n </Button>\n </>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"inbox\")}>\n Inbox\n </Button>\n <ExportMenu tableId={tableId} />\n </div>\n\n {view ? (\n <ViewSwitcher\n view={view}\n pageSize={pageSize}\n onViewChange={(patch) => void patchView(patch)}\n {...(rights.write ? { onNewRecordForm: () => setRail(\"new-record\") } : {})}\n onOpenRecord={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n />\n ) : (\n <p className=\"text-xs opacity-70\">\n Waiting for {tableName(table.data)}&apos;s views. The bar above saves the first one.\n </p>\n )}\n </div>\n\n {rail === \"none\" ? null : (\n <aside className=\"w-[26rem] shrink-0 overflow-y-auto rounded-md border p-3\">\n {rail === \"settings\" ? <TableSettings tableId={tableId} /> : null}\n {rail === \"inbox\" ? (\n <ActionInbox\n tableId={tableId}\n onOpenRecord={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n />\n ) : null}\n {rail === \"import\" ? <ImportWizard tableId={tableId} onDone={() => setRail(\"none\")} /> : null}\n {rail === \"field\" ? (\n <FieldEditor tableId={tableId} onSaved={() => setRail(\"none\")} onCancel={() => setRail(\"none\")} />\n ) : null}\n {rail === \"new-record\" ? (\n <RecordForm\n tableId={tableId}\n onSaved={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n onCancel={() => setRail(\"none\")}\n />\n ) : null}\n {rail === \"record\" && openRecord ? (\n <div className=\"space-y-3\">\n <Peek tableId={tableId} recordId={openRecord} onClose={() => setRail(\"none\")} />\n <Separator />\n <HistoryPanel tableId={tableId} recordId={openRecord} />\n <Separator />\n <CommentThread tableId={tableId} recordId={openRecord} />\n </div>\n ) : null}\n </aside>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["value","document","value","import_react","import_design_system","import_react","import_design_system","import_react","import_jsx_runtime","value","import_jsx_runtime","value","import_jsx_runtime","value","id","import_react","import_design_system","import_design_system","import_jsx_runtime","import_design_system","import_jsx_runtime","document","value","import_jsx_runtime","value","import_react","import_design_system","import_jsx_runtime","import_react","import_core","import_design_system","import_jsx_runtime","document","import_react","import_core","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_core","import_design_system","import_react","import_jsx_runtime","document","value","import_jsx_runtime","document","import_react","import_records","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","document","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","read","value","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_core","import_design_system","import_jsx_runtime","answered","document","value","import_jsx_runtime","document","value","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_records","import_design_system","import_jsx_runtime","total","step","import_react","import_design_system","import_jsx_runtime","board","import_react","import_design_system","import_jsx_runtime","document","tableName","import_react","import_design_system","import_jsx_runtime","document","ProvenanceBadge","value","import_react","import_design_system","import_jsx_runtime","step","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","keys","import_react","import_design_system","import_jsx_runtime","document","import_react","import_design_system","import_jsx_runtime","document","value","import_react","import_design_system","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_react","import_design_system","import_jsx_runtime","document"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/host.tsx","../src/names.ts","../src/PersonPicker.tsx","../src/editors.tsx","../src/parity.ts","../src/fieldTypes.ts","../src/RelationPicker.tsx","../src/gridEditing.tsx","../src/Refusal.tsx","../src/values.tsx","../src/labels.tsx","../src/Grid.tsx","../src/ExportMenu.tsx","../src/ImportWizard.tsx","../src/CustomFieldsSection.tsx","../src/RecordForm.tsx","../src/systemTable.ts","../src/FieldEditor.tsx","../src/TableSettings.tsx","../src/Peek.tsx","../src/ShareControl.tsx","../src/views.ts","../src/ViewSwitcher.tsx","../src/ViewBar.tsx","../src/seedOnce.ts","../src/ProposalRow.tsx","../src/ActionInbox.tsx","../src/HistoryPanel.tsx","../src/CommentThread.tsx","../src/forms.ts","../src/FormBuilder.tsx","../src/FormRunner.tsx","../src/charts.ts","../src/docs.ts","../src/DocTemplate.tsx","../src/DocRender.tsx","../src/SignBlock.tsx","../src/NotifyRuleEditor.tsx","../src/ChartBlock.tsx","../src/DashboardCanvas.tsx","../src/RecordChat.tsx","../src/EnrichPanel.tsx","../src/ChecklistRunner.tsx","../src/BookingSlots.tsx","../src/CaptureSheet.tsx","../src/PortalShell.tsx","../src/PublicViewPage.tsx","../src/EmbedFrame.tsx","../src/RecordsMount.tsx","../src/TablesHome.tsx","../src/createTable.ts","../src/TablePage.tsx"],"sourcesContent":["// src/index.ts — @ai-matrx/records-ui\n//\n// The canonical screens of the AI Matrx record store. Every component here\n// reads and writes ONLY through @ai-matrx/records, renders through\n// @ai-matrx/design-system's own primitives and data table, and carries\n// @ai-matrx/alchemy's menu where a person would reach for one.\n//\n// There is no bespoke per-feature record UI in this platform: a feature that\n// needs a grid, a form, a picker or a peek mounts one of these.\n\nexport {\n RecordsUiProvider,\n useRecordsUi,\n useTableRights,\n NO_RIGHTS,\n NO_UPLOAD_REASON,\n NO_SAVED_VIEWS_REASON, NO_SHARE_REASON,\n NO_MEMBERS_REASON,\n} from \"./host\";\nexport type { RecordsUiHost, TableRights, OrganizationMember, ShareSubject } from \"./host\";\nexport { humanize, fieldName, tableName, recordName, rowName } from \"./names\";\nexport { PersonPicker, memberName, personRecordForMember } from \"./PersonPicker\";\nexport type { PersonPickerProps } from \"./PersonPicker\";\nexport { GridCell, useGridEditing, fieldIsEditable } from \"./gridEditing\";\nexport type { GridEditing, CellAddress, CellState, CellRefusal } from \"./gridEditing\";\nexport { RefusalNotice, RefusalLine } from \"./Refusal\";\nexport { Grid, columnForField } from \"./Grid\";\nexport type { GridProps } from \"./Grid\";\nexport { ExportMenu } from \"./ExportMenu\";\nexport type { ExportMenuProps } from \"./ExportMenu\";\nexport { ImportWizard } from \"./ImportWizard\";\nexport type { ImportWizardProps } from \"./ImportWizard\";\nexport { CustomFieldsSection } from \"./CustomFieldsSection\";\nexport type { CustomFieldsSectionProps } from \"./CustomFieldsSection\";\nexport { FieldEditor, keyFor } from \"./FieldEditor\";\nexport type { FieldEditorProps } from \"./FieldEditor\";\nexport { TableSettings } from \"./TableSettings\";\nexport type { TableSettingsProps, FieldProposalRow } from \"./TableSettings\";\nexport { Peek } from \"./Peek\";\nexport type { PeekProps } from \"./Peek\";\nexport { RecordForm } from \"./RecordForm\";\nexport type { RecordFormProps } from \"./RecordForm\";\nexport { RelationPicker } from \"./RelationPicker\";\nexport type { RelationPickerProps } from \"./RelationPicker\";\nexport { FieldControl, FieldLabel, RecordChip } from \"./editors\";\nexport type { FieldEditorControlProps } from \"./editors\";\nexport { renderValue, scalarText, envelopeFor, ProvenanceBadge, RecordValue } from \"./values\";\nexport { RecordLabelProvider, useRecordLabels, pointsAtRecords, idsOf, isId } from \"./labels\";\nexport type { LabelLookup } from \"./labels\";\nexport { editorKindFor, fieldTypeLabel, PARITY_LABEL, PARITY_MADE_OF } from \"./parity\";\nexport {\n FIELD_TYPE_CHOICES,\n FIELD_TYPE_GROUPS,\n fieldTypeChoice,\n isPlainFieldType,\n parityTypesWithNoExplanation,\n} from \"./fieldTypes\";\nexport type { FieldTypeChoice, PickableFieldType, PlainFieldType } from \"./fieldTypes\";\nexport type { EditorKind } from \"./parity\";\nexport { ensureSystemTable, useSystemTable } from \"./systemTable\";\nexport type { SystemTableSpec, SystemFieldSpec, UseSystemTableState, TrackedVersion } from \"./systemTable\";\nexport {\n VIEW_LAYOUTS,\n VIEW_TABLE,\n LAYOUT_LABEL,\n LAYOUT_NEEDS,\n LAYOUT_FIELD_KIND,\n LAYOUT_NO_FIELD,\n viewDocument,\n viewFromRecord,\n viewPatchDocument,\n} from \"./views\";\nexport type { SavedView, SavedViewSpec, ViewLayout, ViewSort } from \"./views\";\nexport { ViewSwitcher, useViewRecords } from \"./ViewSwitcher\";\nexport type { ViewSwitcherProps } from \"./ViewSwitcher\";\nexport { ViewBar } from \"./ViewBar\";\nexport type { ViewBarProps } from \"./ViewBar\";\nexport { ProposalRow } from \"./ProposalRow\";\nexport type { ProposalRowProps, ProposedChange, ProposalOutcome } from \"./ProposalRow\";\nexport { ActionInbox, ACTION_KINDS, ACTION_TABLE, actionDocument } from \"./ActionInbox\";\nexport type { ActionInboxProps, ActionKind, QueuedAction, QueuedActionSpec } from \"./ActionInbox\";\nexport { HistoryPanel } from \"./HistoryPanel\";\nexport type { HistoryPanelProps } from \"./HistoryPanel\";\nexport { CommentThread, COMMENT_TABLE } from \"./CommentThread\";\nexport {\n FORM_FLOWS,\n FORM_TABLE,\n formDocument,\n formFromRecord,\n submissionStamp,\n} from \"./forms\";\nexport type { FormFlow, FormQuestionSpec, FormSpec, FormTheme, SavedForm } from \"./forms\";\nexport { FormBuilder } from \"./FormBuilder\";\nexport type { FormBuilderProps } from \"./FormBuilder\";\nexport {\n CHART_KINDS,\n CHART_KIND_LABEL,\n CHART_NEEDS,\n DASHBOARD_TABLE,\n SERIES_COLORS,\n dashboardDocument,\n dashboardFromRecord,\n groupLabel,\n} from \"./charts\";\nexport type { ChartKind, ChartSpec, DashboardSpec, SavedDashboard } from \"./charts\";\nexport { bodyFromKeys, bodyForReading, fieldToken, isSignatureField } from \"./docs\";\nexport type { DocTemplateSpec } from \"./docs\";\nexport { DocTemplate } from \"./DocTemplate\";\nexport type { DocTemplateProps } from \"./DocTemplate\";\nexport { DocRender } from \"./DocRender\";\nexport type { DocRenderProps } from \"./DocRender\";\nexport { SignBlock } from \"./SignBlock\";\nexport type { SignBlockProps } from \"./SignBlock\";\nexport { NotifyRuleEditor } from \"./NotifyRuleEditor\";\nexport type { NotifyRuleEditorProps, NotifyRuleSpec } from \"./NotifyRuleEditor\";\nexport { ChartBlock } from \"./ChartBlock\";\nexport type { ChartBlockProps } from \"./ChartBlock\";\nexport { DashboardCanvas } from \"./DashboardCanvas\";\nexport type { DashboardCanvasProps } from \"./DashboardCanvas\";\nexport { FormRunner } from \"./FormRunner\";\nexport type { FormRunnerProps } from \"./FormRunner\";\nexport type { CommentThreadProps } from \"./CommentThread\";\nexport { RecordChat, NO_CHAT_REASON } from \"./RecordChat\";\nexport type { RecordChatProps, RecordChatContext, RecordChatEntry, RecordChatWithheld } from \"./RecordChat\";\nexport { EnrichPanel, NO_ENRICH_REASON } from \"./EnrichPanel\";\nexport type { EnrichPanelProps, EnrichAsk, EnrichOutcome } from \"./EnrichPanel\";\nexport { ChecklistRunner, CHECKLIST_TABLE } from \"./ChecklistRunner\";\nexport type { ChecklistRunnerProps, ChecklistSpec, ChecklistStepSpec } from \"./ChecklistRunner\";\nexport { BookingSlots } from \"./BookingSlots\";\nexport type { BookingSlotsProps } from \"./BookingSlots\";\nexport { CaptureSheet, CAPTURE_MODES, IN_MEMORY_QUEUE_REASON } from \"./CaptureSheet\";\nexport type { CaptureSheetProps, CaptureMode } from \"./CaptureSheet\";\nexport { PortalShell } from \"./PortalShell\";\nexport type { PortalShellProps } from \"./PortalShell\";\nexport { PublicViewPage } from \"./PublicViewPage\";\nexport type { PublicViewPageProps } from \"./PublicViewPage\";\nexport { EmbedFrame, useEmbedHandshake } from \"./EmbedFrame\";\nexport type { EmbedFrameProps } from \"./EmbedFrame\";\nexport type { CaptureQueuePort, PendingCapture } from \"./host\";\n\n// The two page assemblies a host route mounts, and the provider pair they need.\nexport { RecordsMount, storeDecidesRights, personActor, recordsDataSource, STORE_DECIDES_REASON, KERNEL_REASON } from \"./RecordsMount\";\nexport type { RecordsMountProps } from \"./RecordsMount\";\nexport { TablesHome, TABLE_LANES, LANE_TITLE, LANE_EMPTY, laneFor } from \"./TablesHome\";\nexport type { TablesHomeProps, TableLane } from \"./TablesHome\";\nexport { TablePage, TABLE_NOT_REACHABLE, DEFAULT_VIEW_NAME } from \"./TablePage\";\nexport type { TablePageProps } from \"./TablePage\";\nexport { declareTable, addFields, tokenFor, DEFAULT_FIELDS } from \"./createTable\";\nexport type { NewTableSpec, NewFieldSpec, DeclareResult } from \"./createTable\";\n\n// SCR-N-5 — the Share button, and the host port that supplies the app's one share dialog.\nexport { ShareControl, useCanShare, shareUnavailableReason } from \"./ShareControl\";\nexport type { ShareControlProps } from \"./ShareControl\";\n","\"use client\";\n\n// src/host.tsx — @ai-matrx/records-ui\n//\n// THE ONE BINDING POINT. A host mounts `<RecordsUiProvider>` once, inside\n// `<RecordsProvider>` from @ai-matrx/records, and every component in this\n// package reads what it needs from here. There is no module-level state: two\n// organizations in two tabs must never share one.\n//\n// WHAT A HOST BINDS, AND WHAT HAPPENS WHEN IT DOES NOT\n// ----------------------------------------------------\n// `rights` answers \"may this person administer this table?\" — the question the\n// \"+\" add-field affordance turns on (SCR-2 / SCR-4). It is a PORT and not a\n// guess, and its default answer is `false` WITH A REASON, so the control is\n// ABSENT rather than disabled, and the reason is available to anyone who asks\n// why. A disabled-looking control that nobody can explain is the screen lying.\n\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport type { Table, Uuid } from \"@ai-matrx/records\";\nimport type { RecordChatContext } from \"./RecordChat\";\nimport type { EnrichAsk, EnrichOutcome } from \"./EnrichPanel\";\n\n/** What a person may do to one table. The words are the store's, not ours. */\nexport interface TableRights {\n /** SCR-2: holders of `admin` on the table see the \"+\" and the settings panel. */\n admin: boolean;\n /** SCR-18: `commenter` and no higher right. */\n comment: boolean;\n /** May write records at all. */\n write: boolean;\n /**\n * Why this answer, in a sentence a person can read. Never empty: a right that\n * is false without a reason is the silent failure this package refuses.\n */\n reason: string;\n}\n\nexport const NO_RIGHTS: TableRights = {\n admin: false,\n comment: false,\n write: false,\n reason:\n \"No rights port is bound, so this screen assumes nothing. Bind `rights` on <RecordsUiProvider> \" +\n \"with your host's answer to 'may this person administer this table?'. Until then every \" +\n \"administering control is ABSENT rather than shown-and-dead.\",\n};\n\nexport interface RecordsUiHost {\n /** Answer the rights question for one table. Synchronous: a screen renders now. */\n rights?: (table: Table) => TableRights;\n /** Where a record's own page lives, when the host has one. A peek is used when it does not. */\n hrefForRecord?: (args: { table: Table; recordId: Uuid }) => string | undefined;\n /** The host's own link element, so routing stays the host's business. */\n Link?: (props: { href: string; children: ReactNode; className?: string }) => ReactNode;\n /** Toasts. Absent means the screen shows the sentence inline instead — never silence. */\n notify?: { success: (message: string) => void; error: (message: string) => void };\n /** Density for every table this package renders. */\n density?: \"condensed\" | \"normal\" | \"spacious\";\n /**\n * OPTIONAL. Where a file a person attached actually goes. A File is a record\n * in the kernel File Table (REC-31), but the BYTES are the host's file\n * service, not this package's business — so this is a port.\n *\n * Unbound, an attachment question does NOT draw a file chooser that quietly\n * loses the file: it says, in one sentence, that no file store is bound and\n * names this port. Absent or honest, never dead.\n */\n upload?: (file: File) => Promise<{ ok: true; fileId: Uuid } | { ok: false; reason: string }>;\n /**\n * OPTIONAL. The organization's saved views as `platform.saved_view` holds\n * them — which is what a subscription points at (DOOR-18). The record store\n * has NO door onto that table, because it is the platform's and not the\n * store's, so this is a port rather than a read this package invents.\n *\n * Unbound, `NotifyRuleEditor` shows the subscriptions that exist and says, in\n * one sentence, that it cannot offer a view to subscribe to. It never renders\n * an empty picker that looks like \"you have no views\".\n */\n savedViews?: () => Promise<Array<{ id: Uuid; name: string }>>;\n /**\n * OPTIONAL. WHO IS IN THIS ORGANIZATION (FLD-11 `member`).\n *\n * A person field must offer PEOPLE. Who the people are is the platform's\n * answer — organization membership lives in `iam`, not in the record store —\n * and the store has no door onto it, so this is a port rather than a read\n * this package invents. `PersonPicker` resolves whoever is picked to their\n * record in the kernel Person Table, which is what the Field actually stores.\n *\n * Unbound, a person question is ABSENT with `NO_MEMBERS_REASON`. It never\n * falls back to listing the kernel Person Table's contents: that Table also\n * holds the Homes this package writes, and offering \"Comments Home\" as a\n * person is exactly what this port exists to stop.\n */\n members?: () => Promise<OrganizationMember[]>;\n /**\n * OPTIONAL. THE HOST'S OWN CHAT SURFACE (SCR-26).\n *\n * This package ships no chat UI, on purpose: AI Matrx has exactly one, it\n * lives in matrx-frontend (`AgentConversationColumn`), and it reads that app's\n * Redux store — so a second one here would drift within a month and a package\n * that imported the first would stop being a package. `RecordChat` therefore\n * builds the CONTEXT (the record, through the read door, with the masked\n * fields named) and hands it to this port.\n *\n * Unbound, the panel is ABSENT with that reason, never a composer that goes\n * nowhere.\n */\n chat?: (context: RecordChatContext) => ReactNode;\n /**\n * OPTIONAL. THE SERVER'S `records` TOOL (SCR-27).\n *\n * An AI fill must be written with actor `agent` on behalf of the person, and\n * only the server can honestly say that — a browser stamping itself `agent`\n * is a browser claiming to be one. So `EnrichPanel` asks here, and the host\n * calls the server's own `records` tool (`action: \"record_write\"`), which\n * stamps `_actor` and `_on_behalf_of` itself.\n *\n * Unbound, no Fill control is drawn at all and the reason names this port.\n */\n enrich?: (ask: EnrichAsk) => Promise<EnrichOutcome>;\n /**\n * OPTIONAL. WHERE AN OFFLINE CAPTURE WAITS (SCR-30).\n *\n * `CaptureSheet` mints the id for a capture BEFORE it tries to send it, so a\n * phone with no signal has already decided what the write will be called.\n * Where that queue physically lives is the host's business — IndexedDB in a\n * browser, a file in a desktop app — so it is a port. Unbound, the sheet\n * keeps its queue in memory for the life of the page AND SAYS SO, because a\n * queue that silently died with the tab is the failure this exists to avoid.\n */\n captureQueue?: CaptureQueuePort;\n /**\n * OPTIONAL. THE HOST'S OWN SHARE DIALOG (SCR-N-5).\n *\n * This package ships no share dialog, ON PURPOSE, and for the same reason it\n * ships no chat: AI Matrx has exactly ONE sharing surface — matrx-frontend's\n * `features/sharing` ShareModal, with its people picker, its level picker, its\n * grant list and its \"who can see this, and why\" panel — and a second one here\n * would be a parallel sharing UI within a month. Sharing is the access model's\n * front door, and two front doors is how a platform ends up with two answers\n * to \"who can see this\".\n *\n * So `ShareControl` draws the BUTTON (which belongs on the record and table\n * screens, beside everything else a person does to a thing) and hands the\n * subject to this port, which returns the host's own dialog.\n *\n * Unbound, the button is ABSENT and `NO_SHARE_REASON` says which port to bind.\n * Never a Share button that opens nothing.\n */\n share?: (subject: ShareSubject) => ReactNode;\n}\n\n/**\n * What a host's share dialog is being opened ON. A Table is a record in this\n * store (a `custom.record` row whose table is the Table kernel), so ONE subject\n * shape covers both screens and `kind` is what the sentences say, not what the\n * store looks up.\n */\nexport interface ShareSubject {\n kind: \"record\" | \"table\";\n /** The store is keyed (organization_id, id); this package never guesses one. */\n organizationId: Uuid;\n subjectId: Uuid;\n /** What to call it on screen. Never empty — the id's first eight characters at worst. */\n name: string;\n /** Close the dialog. The control owns the open/closed state, the host owns the dialog. */\n onClose: () => void;\n}\n\n/** One member of the organization, in the words a person reads. */\nexport interface OrganizationMember {\n /** The platform's user id. This is what a Person record carries as `user_id`. */\n userId: string;\n /** Their display name, when the platform has one. */\n name?: string | null;\n email?: string | null;\n avatarUrl?: string | null;\n}\n\n/** The durable half of offline capture: read the queue, write it, that is all. */\nexport interface CaptureQueuePort {\n load: () => Promise<PendingCapture[]>;\n save: (pending: PendingCapture[]) => Promise<void>;\n}\n\n/** One capture waiting to be written, with the id the CLIENT minted for it. */\nexport interface PendingCapture {\n /**\n * The client key. Minted offline, before the first attempt, and never\n * re-minted on retry — that is exactly what lets the store's replay ledger\n * tell a retry from a second capture.\n */\n clientKey: string;\n tableId: Uuid;\n payload: Record<string, unknown>;\n capturedAt: string;\n device: string;\n /** How many times sending has been tried, and what the store last said. */\n attempts: number;\n lastRefusal?: string | null;\n}\n\n/** The sentence the notify editor shows when no saved-view port is bound. */\nexport const NO_SAVED_VIEWS_REASON =\n \"No saved-view port is bound, so there is nothing here to subscribe to. A subscription points at a \" +\n \"`platform.saved_view`, which the record store has no door onto — bind `savedViews` on \" +\n \"<RecordsUiProvider> with your host's own list and the picker appears.\";\n\n/** The sentence a person question shows when no membership port is bound. */\nexport const NO_MEMBERS_REASON =\n \"No membership port is bound, so this question cannot offer anybody. A person field points at the \" +\n \"kernel Person Table, and who is in this organization is the platform's answer rather than the \" +\n \"record store's — bind `members` on <RecordsUiProvider> with your host's own roster and the picker \" +\n \"appears.\";\n\n/** The sentence shown when no share dialog is bound. */\nexport const NO_SHARE_REASON =\n \"No share dialog is bound, so this screen offers no Share button rather than one that opens \" +\n \"nothing. Bind `share` on <RecordsUiProvider> with the app's own sharing dialog — AI Matrx has \" +\n \"exactly one (features/sharing), and this package deliberately does not ship a second.\";\n\n/** The sentence an attachment question shows when no file store is bound. */\nexport const NO_UPLOAD_REASON =\n \"No file store is bound, so this question cannot take a file. Bind `upload` on \" +\n \"<RecordsUiProvider> with your host's file service and the chooser appears.\";\n\nconst HostContext = createContext<RecordsUiHost | null>(null);\n\nexport function RecordsUiProvider({ value, children }: { value: RecordsUiHost; children: ReactNode }) {\n const bound = useMemo(() => value, [value]);\n return <HostContext.Provider value={bound}>{children}</HostContext.Provider>;\n}\n\nexport function useRecordsUi(): RecordsUiHost {\n return useContext(HostContext) ?? {};\n}\n\n/** The rights for one table — `NO_RIGHTS`, with its reason, when nothing is bound. */\nexport function useTableRights(table: Table | null | undefined): TableRights {\n const host = useRecordsUi();\n return useMemo(() => {\n if (!table) return NO_RIGHTS;\n if (!host.rights) return NO_RIGHTS;\n return host.rights(table);\n }, [host, table]);\n}\n","// src/names.ts — @ai-matrx/records-ui\n//\n// WHAT A PERSON READS, NEVER WHAT THE MACHINE STORES.\n//\n// Measured on the real screens (independent verdict, 19 September): a table row\n// read `Saved views · 9 fields · records_ui_view`, a relation cell read a bare\n// `8f2c…` identifier, a header read `stage` because the Field's label was\n// blank, and the type word on a column tooltip read `long_text`. Airtable,\n// Notion and Linear never show a person an internal name; the verdict called\n// this one of the three things a first-time user feels within a minute.\n//\n// So every place this package prints something a person reads goes through one\n// of these three functions. They are deliberately dumb: they choose the best\n// human string that IS AVAILABLE and, when none is, say what the thing is\n// rather than printing the token. No screen in this package formats a name of\n// its own any more.\n\nimport type { Field, ReadRow, RecordDocument, Table } from \"@ai-matrx/records\";\n\n/**\n * A token (`records_ui_view`, `long_text`, `v78_widget2`) as a person would\n * write it. Used ONLY as a last resort, when the thing carries no label at all\n * — a raw token on a screen is the defect, and a humanised token is the least\n * bad honest answer, because it still names the same thing.\n */\nexport function humanize(token: string): string {\n const words = token\n .replace(/[_\\-.]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .trim();\n if (words === \"\") return token;\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** The name of one Field, as a header, a form label or a peek's term. */\nexport function fieldName(field: Field): string {\n const label = (field.label ?? \"\").trim();\n if (label !== \"\") return label;\n const name = (field.name ?? \"\").trim();\n if (name !== \"\") return name;\n return humanize(field.key);\n}\n\n/** The name of one Table, as a card, a heading or a breadcrumb. */\nexport function tableName(table: Table): string {\n const name = (table.name ?? \"\").trim();\n if (name !== \"\") return name;\n const singular = (table.label_singular ?? \"\").trim();\n if (singular !== \"\") return singular;\n return humanize(table.slug ?? \"\");\n}\n\n/**\n * The name of one RECORD, for a chip, a card, a relation cell or a peek title.\n *\n * `titleKey` is the Table's own `title_field` when the caller knows the Table —\n * that is the store's answer to \"what makes this record a chip\" (REC-2) — and\n * the conventional keys are tried after it. A record with nothing readable is\n * NOT shown as a truncated uuid: it says it has no name yet, because \"8f2c1b0a\"\n * tells a person nothing and looks like a bug.\n */\nexport function recordName(\n document: RecordDocument | undefined,\n titleKey?: string | null,\n fallback = \"Untitled\",\n): string {\n const data = (document ?? {}) as Record<string, unknown>;\n const keys = [titleKey, \"title\", \"name\", \"label\", \"full_name\", \"subject\", \"summary\"].filter(\n (key): key is string => typeof key === \"string\" && key !== \"\",\n );\n for (const key of keys) {\n const value = data[key];\n if (typeof value === \"string\" && value.trim() !== \"\") return value.trim();\n if (typeof value === \"number\") return String(value);\n }\n return fallback;\n}\n\n/** The same question for a row the read door returned. */\nexport function rowName(row: ReadRow | undefined, titleKey?: string | null, fallback = \"Untitled\"): string {\n return recordName(row?.document, titleKey, fallback);\n}\n","\"use client\";\n\n// src/PersonPicker.tsx — @ai-matrx/records-ui · FLD-11 (`member`)\n//\n// PICKING A PERSON MEANS PICKING A PERSON.\n//\n// What it replaced, measured on the real screen (independent verdict, 19\n// September): the \"Owner\" field — which the settings panel itself calls a\n// Person field — offered \"Comments Home\", \"Saved views Home\" and \"V78 Home\".\n// Those are not people. They are the Home records this package writes into the\n// kernel Person Table so that its own Tables have somewhere to live (REC-1),\n// and the generic relation picker was listing the Table's contents, which is\n// exactly right for a relation and exactly wrong for a person.\n//\n// SO A PERSON FIELD ASKS A DIFFERENT QUESTION. The list is the ORGANIZATION'S\n// MEMBERS — who those are is the platform's answer and not the record store's,\n// so it arrives through the `members` port on the host, the same way saved\n// views and file uploads do. The record store has no door onto organization\n// membership and this package does not invent one.\n//\n// WHAT IS STORED IS STILL A RECORD ID, because a member field is a relation to\n// the kernel Person Table and the store's foreign key is real. So picking a\n// member resolves that member to their Person record — by the `user_id` the\n// record carries — and writes one when the organization has not got one yet.\n// That write is the same `record_write` everything else in this package uses;\n// there is no second storage path, and a Home (a Person record with no\n// `user_id`) is never offered and never picked.\n//\n// Unbound port: the control is ABSENT with its reason, never a dead box and\n// never a list of the wrong things.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { Field, ReadRow, RecordsError, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport {\n BasicInput,\n Button,\n Popover,\n PopoverContent,\n PopoverTrigger,\n ScrollArea,\n cn,\n} from \"@ai-matrx/design-system\";\n\nimport { RecordChip } from \"./editors\";\nimport { useRecordsUi, type OrganizationMember } from \"./host\";\nimport { NO_MEMBERS_REASON } from \"./host\";\nimport { fieldName } from \"./names\";\n\nexport interface PersonPickerProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n className?: string | undefined;\n}\n\n/** A Person record in the kernel Table, as this picker needs to read it. */\ninterface PersonRecord {\n id: Uuid;\n userId: string | null;\n name: string;\n}\n\nfunction personFromRow(row: ReadRow): PersonRecord {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const userId = data[\"user_id\"];\n return {\n id: row.id,\n userId: typeof userId === \"string\" && userId !== \"\" ? userId : null,\n name: String(data[\"full_name\"] ?? data[\"name\"] ?? data[\"email\"] ?? \"\").trim(),\n };\n}\n\n/** The member's own name, as a person reads it. Never a uuid. */\nexport function memberName(member: OrganizationMember): string {\n const display = (member.name ?? \"\").trim();\n if (display !== \"\") return display;\n const email = (member.email ?? \"\").trim();\n if (email !== \"\") return email;\n return \"A member with no name set\";\n}\n\n/**\n * Find (or write) the kernel Person record for one member. Exported because\n * an agent filling a person field server-side needs exactly the same answer,\n * and two implementations of \"which record is this person\" is two answers.\n */\nexport async function personRecordForMember(\n client: RecordsClient,\n personTableId: Uuid,\n people: PersonRecord[],\n member: OrganizationMember,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const held = people.find((p) => p.userId === member.userId);\n if (held) return { ok: true, data: held.id };\n const written = await client.recordWrite({\n table_id: personTableId,\n data: {\n user_id: member.userId,\n full_name: memberName(member),\n ...(member.email ? { email: member.email } : {}),\n },\n });\n return written;\n}\n\nexport function PersonPicker({ field, value, onChange, disabled, id, className }: PersonPickerProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const [members, setMembers] = useState<OrganizationMember[] | null>(null);\n const [people, setPeople] = useState<PersonRecord[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [search, setSearch] = useState(\"\");\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const membersPort = host.members;\n const personTable = field.relation_target;\n\n const picked = useMemo<string[]>(\n () => (Array.isArray(value) ? value.map(String) : value === null || value === undefined ? [] : [String(value)]),\n [value],\n );\n\n const load = useCallback(async () => {\n if (!membersPort) return;\n const [roster, records] = await Promise.all([\n membersPort(),\n personTable ? client.list({ table_id: personTable, limit: 500 }) : Promise.resolve(null),\n ]);\n setMembers(roster);\n if (records && !records.ok) {\n setError(records.error.message);\n return;\n }\n setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);\n }, [membersPort, client, personTable]);\n\n useEffect(() => {\n if (!open) return;\n void load();\n }, [open, load]);\n\n // The names of the records that are already picked, whether or not the list\n // has been opened — a chip that read `8f2c1b0a` is the defect this closes.\n useEffect(() => {\n if (picked.length === 0 || !personTable || people.length > 0) return;\n let cancelled = false;\n void client.list({ table_id: personTable, limit: 500 }).then((result) => {\n if (cancelled || !result.ok) return;\n setPeople(result.data.rows.map(personFromRow).filter((p) => p.userId !== null));\n });\n return () => {\n cancelled = true;\n };\n }, [client, personTable, picked.length, people.length]);\n\n if (!membersPort) {\n // ABSENT AND HONEST. A person question with nobody to offer is not a box\n // that silently does nothing — it names the port that fills it.\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{NO_MEMBERS_REASON}</p>;\n }\n\n if (!personTable) {\n return (\n <p className={cn(\"text-xs text-muted-foreground\", className)}>\n {fieldName(field)} is a person field, but it does not say which Table the people are\n records of yet, so there is nothing to pick from. A table admin sets its target in the field\n editor.\n </p>\n );\n }\n\n const nameOfRecord = (recordId: string) => {\n const person = people.find((p) => p.id === recordId);\n if (!person) return \"Loading…\";\n if (person.name !== \"\") return person.name;\n const member = (members ?? []).find((m) => m.userId === person.userId);\n return member ? memberName(member) : \"A member with no name set\";\n };\n\n const pick = async (member: OrganizationMember) => {\n setBusy(true);\n setError(null);\n const resolved = await personRecordForMember(client, personTable, people, member);\n setBusy(false);\n if (!resolved.ok) {\n setError(resolved.error.message);\n return;\n }\n // Keep the newly written record so the chip can be named at once.\n if (!people.some((p) => p.id === resolved.data)) {\n setPeople((held) => [...held, { id: resolved.data, userId: member.userId, name: memberName(member) }]);\n }\n if (!field.multi) {\n onChange(picked[0] === resolved.data ? null : resolved.data);\n setOpen(false);\n return;\n }\n const next = new Set(picked);\n if (next.has(resolved.data)) next.delete(resolved.data);\n else next.add(resolved.data);\n onChange(next.size === 0 ? null : [...next]);\n };\n\n const drop = (recordId: string) => {\n const next = picked.filter((id) => id !== recordId);\n onChange(next.length === 0 ? null : field.multi ? next : (next[0] ?? null));\n };\n\n const visible = (members ?? []).filter((member) =>\n search.trim() === \"\" ? true : memberName(member).toLowerCase().includes(search.trim().toLowerCase()),\n );\n const pickedUserIds = new Set(\n picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean),\n );\n\n return (\n <div className={cn(\"flex flex-wrap items-center gap-1\", className)}>\n {picked.map((recordId) => (\n <RecordChip\n key={recordId}\n title={nameOfRecord(recordId)}\n {...(disabled ? {} : { onRemove: () => drop(recordId) })}\n />\n ))}\n {disabled ? null : (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n aria-label={`Pick a person for ${fieldName(field)}`}\n >\n {picked.length === 0 ? \"Pick a person\" : \"Change\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-64 p-1\" align=\"start\">\n <BasicInput\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search people\"\n className=\"mb-1 h-7 text-xs\"\n />\n {error ? <p className=\"p-2 text-xs text-destructive\">{error}</p> : null}\n {members === null ? <p className=\"p-2 text-xs text-muted-foreground\">Reading the members…</p> : null}\n <ScrollArea className=\"max-h-56\">\n <ul>\n {visible.map((member) => (\n <li key={member.userId}>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void pick(member)}\n className={cn(\n \"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted\",\n pickedUserIds.has(member.userId) ? \"bg-accent text-accent-foreground\" : \"\",\n )}\n >\n {/* A name and an email with nothing between them read as\n one run-on string (verdict, 19 September). They are two\n facts, so they are drawn as two. */}\n <span>{memberName(member)}</span>\n {member.email && member.email !== memberName(member) ? (\n <span className=\"ml-1.5 opacity-60\">· {member.email}</span>\n ) : null}\n </button>\n </li>\n ))}\n </ul>\n {members !== null && visible.length === 0 ? (\n <p className=\"p-2 text-xs text-muted-foreground\">\n {members.length === 0\n ? \"This organization has no other members yet, so there is nobody to assign.\"\n : \"Nobody in this organization matches.\"}\n </p>\n ) : null}\n </ScrollArea>\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/editors.tsx — @ai-matrx/records-ui\n//\n// ONE EDITOR PER PARITY TYPE, and every one of them is a design-system\n// primitive. There is no bespoke input in this package and no per-feature\n// editor anywhere in the platform: a Field decides which of these is drawn,\n// from what the STORE stores about it (behaviour + modifiers + format + unit +\n// relation target), never from the value it happens to hold.\n//\n// FLD-9: a Formula is worked out by the system. Its editor is not a disabled\n// text box — it is the value with the sentence the store itself would say if\n// you tried to type into it.\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { Field, RecordDocument, StoredRecord, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n BasicTextarea,\n Badge,\n Button,\n Checkbox,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { editorKindFor } from \"./parity\";\nimport { fieldName, recordName } from \"./names\";\nimport { RelationPicker } from \"./RelationPicker\";\nimport { PersonPicker } from \"./PersonPicker\";\n\nexport interface FieldEditorControlProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n}\n\n/** The label row every editor shares: one line, the label, the unit, the required mark. */\nexport function FieldLabel({ field, htmlFor, children }: { field: Field; htmlFor: string; children?: ReactNode }) {\n return (\n <div className=\"flex items-baseline gap-1.5\">\n <Label htmlFor={htmlFor} className=\"text-xs font-medium\">\n {fieldName(field)}\n </Label>\n {field.required ? <span className=\"text-xs text-destructive\">required</span> : null}\n {field.unit ? <span className=\"text-xs text-muted-foreground\">{field.unit}</span> : null}\n {children}\n </div>\n );\n}\n\nexport function FieldControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const kind = editorKindFor(field);\n const inputId = id ?? `field-${field.key}`;\n\n switch (kind) {\n case \"formula\":\n case \"lookup\":\n case \"rollup\":\n return (\n <div className=\"rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground\">\n {/* The store's own sentence for typing into a computed field. */}\n {value === null || value === undefined ? \"—\" : String(value)}\n <span className=\"ml-2 italic\">\n {fieldName(field)} is worked out by the system, so it cannot be typed in\n </span>\n </div>\n );\n case \"json\":\n return <JsonControl field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"long_text\":\n return (\n <BasicTextarea\n id={inputId}\n rows={3}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"number\":\n case \"currency\":\n case \"percent\":\n return (\n <BasicInput\n id={inputId}\n type=\"number\"\n inputMode=\"decimal\"\n className=\"tabular-nums\"\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n />\n );\n case \"datetime\":\n return (\n <BasicInput\n id={inputId}\n type={field.format === \"datetime\" ? \"datetime-local\" : \"date\"}\n value={value === null || value === undefined ? \"\" : String(value).slice(0, field.format === \"datetime\" ? 16 : 10)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"email\":\n case \"phone\":\n case \"url\":\n return (\n <BasicInput\n id={inputId}\n type={kind === \"email\" ? \"email\" : kind === \"phone\" ? \"tel\" : \"url\"}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n case \"select\":\n case \"multi_select\":\n return <OptionControl field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"member\":\n // A person field asks who is in the organization, never what is in a\n // Table — see PersonPicker's header for the screen that made this split.\n return <PersonPicker field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n case \"relation\":\n case \"attachment\":\n return <RelationPicker field={field} value={value} onChange={onChange} disabled={disabled} id={inputId} />;\n default:\n if (typeof value === \"boolean\" || field.config?.[\"kind\"] === \"boolean\") {\n return (\n <Checkbox\n id={inputId}\n checked={value === true}\n disabled={disabled}\n onCheckedChange={(next) => onChange(next === true)}\n />\n );\n }\n return (\n <BasicInput\n id={inputId}\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === \"\" ? null : e.target.value)}\n />\n );\n }\n}\n\n/**\n * A document-shaped value, edited as the text it is. It is parsed on every\n * keystroke and the PARSE FAILURE IS SHOWN — a box that silently handed the\n * store unparseable text and let it answer `22P02 invalid input syntax` is a\n * refusal the person could have been spared half a second earlier.\n */\nfunction JsonControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const initial = value === null || value === undefined ? \"\" : typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n const [text, setText] = useState(initial);\n const [broken, setBroken] = useState<string | null>(null);\n return (\n <div className=\"flex flex-col gap-1\">\n <BasicTextarea\n id={id}\n rows={4}\n className=\"font-mono text-[11px]\"\n value={text}\n disabled={disabled}\n onChange={(e) => {\n const next = e.target.value;\n setText(next);\n if (next.trim() === \"\") {\n setBroken(null);\n onChange(null);\n return;\n }\n try {\n onChange(JSON.parse(next));\n setBroken(null);\n } catch (thrown) {\n setBroken(thrown instanceof Error ? thrown.message : String(thrown));\n }\n }}\n />\n {broken ? (\n <p className=\"text-xs text-destructive\">\n {fieldName(field)} is not readable as structured data yet: {broken}\n </p>\n ) : null}\n </div>\n );\n}\n\n/**\n * FLD-5 / FLD-6. A list field stores the ID OF AN OPTION RECORD, because every\n * pick-list is already a Table. The options are read through the store's own\n * `custom.field_options` door, which resolves the options Table from the\n * Field's config — this component never has to know which Table that is.\n */\nfunction OptionControl({ field, value, onChange, disabled, id }: FieldEditorControlProps) {\n const client = useRecordsClient();\n const [options, setOptions] = useState<StoredRecord[] | null>(null);\n const [refusal, setRefusal] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void client.fieldOptions({ field_id: field.id }).then((result) => {\n if (cancelled) return;\n if (result.ok) setOptions(result.data ?? []);\n else setRefusal(result.error.message);\n });\n return () => {\n cancelled = true;\n };\n }, [client, field.id]);\n\n if (refusal) return <p className=\"text-xs text-destructive\">{refusal}</p>;\n if (!options) return <p className=\"text-xs text-muted-foreground\">Reading this field&apos;s choices…</p>;\n if (options.length === 0) {\n // Two different facts, and a person acts on them differently: a choice\n // field whose Table is empty, and a choice field that names no Table at\n // all. One blank control for both is the silent failure.\n return (\n <p className=\"text-xs text-muted-foreground\">\n {field.options_table_id\n ? `${fieldName(field)} takes its choices from a Table that has no records yet — add the choices there and they appear here.`\n : `${fieldName(field)} does not name the Table its choices come from yet, so there is nothing to choose. A table admin sets it in the field editor.`}\n </p>\n );\n }\n\n const titleOf = (option: StoredRecord) =>\n recordName(option.data as RecordDocument | undefined, null, \"Unnamed choice\");\n\n if (field.multi) {\n const picked = new Set((Array.isArray(value) ? value : []).map(String));\n return (\n <div className=\"flex flex-wrap gap-1\">\n {options.map((option) => (\n <Button\n key={option.id}\n type=\"button\"\n size=\"sm\"\n variant={picked.has(option.id) ? \"default\" : \"outline\"}\n disabled={disabled}\n onClick={() => {\n const next = new Set(picked);\n if (next.has(option.id)) next.delete(option.id);\n else next.add(option.id);\n onChange(next.size === 0 ? null : [...next]);\n }}\n >\n {titleOf(option)}\n </Button>\n ))}\n </div>\n );\n }\n\n return (\n <Select\n value={value === null || value === undefined ? \"\" : String(value)}\n disabled={disabled ?? false}\n onValueChange={(next) => onChange(next === \"\" ? null : next)}\n >\n <SelectTrigger id={id} size=\"sm\">\n <SelectValue placeholder=\"Choose\" />\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.id} value={option.id}>\n {titleOf(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\n/** The chip a picked record shows as — REC-2's \"a record is a chip\" in one place. */\nexport function RecordChip({\n title,\n onRemove,\n className,\n}: {\n title: string;\n onRemove?: (() => void) | undefined;\n className?: string | undefined;\n}) {\n return (\n <Badge variant=\"secondary\" className={cn(\"gap-1 text-[11px]\", className)}>\n {title}\n {onRemove ? (\n <button type=\"button\" onClick={onRemove} aria-label={`Remove ${title}`} className=\"opacity-60 hover:opacity-100\">\n ×\n </button>\n ) : null}\n </Badge>\n );\n}\n\nexport type { Uuid };\n","// src/parity.ts — @ai-matrx/records-ui\n//\n// FLD-11, the parity floor. A Field stores a BEHAVIOUR (one of five) plus\n// modifiers, unit and format; a person picked one of THIRTEEN parity types in\n// the UI. This resolves the second from the first, using the same facts the\n// store's own `custom.parity_field_types()` describes — which is generated into\n// `@ai-matrx/records` and imported here, never retyped.\n//\n// Nothing in this file decides policy. It decides which editor to draw.\n\nimport { KERNEL_TABLES, PARITY_FIELD_TYPES, type Field, type ParityFieldType } from \"@ai-matrx/records\";\nimport { humanize } from \"./names\";\nimport { fieldTypeChoice } from \"./fieldTypes\";\n\n/** The kernel ids come from the store's own kernel rows, never from a literal here. */\nconst kernelId = (name: string): string =>\n KERNEL_TABLES.find((t) => t.name === name)?.id ?? \"\";\nconst KERNEL_FILE_TABLE = kernelId(\"File\");\nconst KERNEL_PERSON_TABLE = kernelId(\"Person\");\n\nexport const PARITY_LABEL: Record<ParityFieldType, string> = {\n attachment: \"Attachment\",\n currency: \"Currency\",\n datetime: \"Date\",\n email: \"Email\",\n formula: \"Formula\",\n lookup: \"Lookup\",\n member: \"Person\",\n multi_select: \"Multi-select\",\n percent: \"Percent\",\n phone: \"Phone\",\n rollup: \"Rollup\",\n select: \"Select\",\n url: \"Link\",\n};\n\n/** The \"made of\" sentence the store itself publishes, for the field editor's help text. */\nexport const PARITY_MADE_OF: Record<string, string> = Object.fromEntries(\n PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of]),\n);\n\n/** Plain text and plain number are behaviours with no parity type of their own. */\nexport type EditorKind =\n | ParityFieldType\n | \"relation\"\n | \"text\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"json\"\n | \"long_text\";\n\n/**\n * Which editor one Field wants. Reads the Field's own declaration only — the\n * behaviour, the modifiers, the format, the relation target and the config —\n * because those are what the store stores, and a screen that guessed from a\n * value would draw a different editor for an empty record.\n */\nexport function editorKindFor(field: Field): EditorKind {\n const format = (field.format ?? \"\").toLowerCase();\n const config = field.config ?? {};\n switch (field.type) {\n case \"text\":\n if (format === \"email\") return \"email\";\n if (format === \"phone\") return \"phone\";\n if (format === \"url\") return \"url\";\n // FLD-1: a document-shaped value is a `text` behaviour carrying a format.\n // It gets its own editor because a person typing JSON into a one-line box\n // and getting `22P02` back is the failure this resolves ahead of time.\n if (format === \"json\" || config[\"json\"] === true) return \"json\";\n if (format === \"long\" || config[\"multiline\"] === true) return \"long_text\";\n return \"text\";\n case \"range\": {\n const kind = String(config[\"kind\"] ?? \"number\");\n if (kind === \"date\" || kind === \"datetime\") return \"datetime\";\n // THE FORMAT, AND ONLY THE FORMAT. This used to read\n // `format === \"currency\" || (field.unit ?? \"\").length > 1`, and a unit is\n // not a currency: a quantity in `units` was drawn as money, which is how\n // three of something rendered as \"units3\" (verdict, 19 September). The\n // store's own `custom.parity_type` asks the same question the same way —\n // a currency is a range whose FORMAT is currency and which has a unit.\n if (format === \"currency\") return \"currency\";\n if (format === \"percent\" || field.unit === \"%\") return \"percent\";\n return \"number\";\n }\n case \"list\":\n return field.multi ? \"multi_select\" : \"select\";\n case \"relation\":\n return relationEditor(field);\n case \"formula\": {\n const via = config[\"via\"];\n if (via && config[\"agg\"]) return \"rollup\";\n if (via) return \"lookup\";\n return \"formula\";\n }\n default:\n return \"text\";\n }\n}\n\n/**\n * REC-31 / FLD-11: a relation is an `attachment` when it points at the kernel\n * File Table and a `member` when it points at the kernel Person Table. Every\n * other relation is drawn by the generic picker, which is what `\"relation\"`\n * means here — the one primitive SCR-N-2 says must exist.\n */\nfunction relationEditor(field: Field): EditorKind {\n const parity = String(field.config?.[\"parity\"] ?? \"\");\n if (parity === \"attachment\" || parity === \"member\") return parity;\n if (field.relation_target === KERNEL_FILE_TABLE) return \"attachment\";\n if (field.relation_target === KERNEL_PERSON_TABLE) return \"member\";\n return \"relation\" as EditorKind;\n}\n\n/**\n * The type word a person sees in a header or a settings row — and it is the\n * SAME word the field panel offers, read from `FIELD_TYPE_CHOICES`, so a column\n * added as \"Money\" is never described anywhere else as \"Currency\".\n */\nexport function fieldTypeLabel(field: Field): string {\n const kind = editorKindFor(field);\n const known = fieldTypeChoice(kind)?.label;\n if (known) return field.multi && kind !== \"multi_select\" ? `${known} (many)` : known;\n const plain: Record<string, string> = {\n boolean: \"Yes / no\",\n date: \"Date\",\n json: \"Structured data\",\n relation: \"Link to a record\",\n };\n // Never a raw token on a screen: an editor kind this table has not named is\n // still written the way a person writes it.\n return plain[kind] ?? humanize(kind);\n}\n","// src/fieldTypes.ts — @ai-matrx/records-ui\n//\n// THE SIXTEEN THINGS A COLUMN CAN HOLD, IN THE WORDS A PERSON USES.\n//\n// The store publishes thirteen parity types and, for each, a sentence about what\n// it is MADE OF — \"REC-31: a File record reached through a relation, target the\n// kernel `File` Table\", \"FLD-9: a declared computation, on read or on write,\n// evaluated by custom.rule_eval\", \"config.via names the relation field,\n// config.pick the Value on the far side\". Those sentences are true and they are\n// for us. The 19 September verdict found them printed at the person choosing a\n// column type, alongside contract row ids, and called it what it is: machine\n// identity where a person is looking.\n//\n// So this file holds the OTHER sentence — what the type is FOR — and the field\n// panel shows that one. The store's own `made_of` stays where it belongs, in\n// `PARITY_MADE_OF`, for an engineer reading the package.\n//\n// The LIST itself is still the store's: `PARITY_FIELD_TYPES` is generated from\n// `custom.parity_field_types()`, and `assertEveryParityTypeIsExplained` (run by\n// the suite) fails the moment the store ships a fourteenth and nobody wrote a\n// sentence for it. A type with no explanation would otherwise appear with a\n// blank line under it, which is the silent version of the same defect.\n\nimport { PARITY_FIELD_TYPES, type ParityFieldType } from \"@ai-matrx/records\";\n\n/** The three behaviours that carry no parity type of their own. */\nexport type PlainFieldType = \"text\" | \"long_text\" | \"number\";\n\n/** What a person picks in the panel: one of the thirteen, or one of the three. */\nexport type PickableFieldType = ParityFieldType | PlainFieldType;\n\nexport interface FieldTypeChoice {\n id: PickableFieldType;\n /** The word on the menu. */\n label: string;\n /** One line, under the word, saying what it is FOR. Never what it is made of. */\n explanation: string;\n /** The heading it sits under, so sixteen choices read as four short lists. */\n group: \"Words\" | \"Numbers and dates\" | \"Choices and people\" | \"Worked out\";\n}\n\nexport const FIELD_TYPE_CHOICES: FieldTypeChoice[] = [\n { id: \"text\", group: \"Words\", label: \"Text\", explanation: \"A short line of writing — a name, a reference, a title.\" },\n { id: \"long_text\", group: \"Words\", label: \"Long text\", explanation: \"Several lines — a description, notes, an address.\" },\n { id: \"email\", group: \"Words\", label: \"Email address\", explanation: \"An email address, checked as you type and ready to write to.\" },\n { id: \"phone\", group: \"Words\", label: \"Phone number\", explanation: \"A phone number, checked as you type.\" },\n { id: \"url\", group: \"Words\", label: \"Link\", explanation: \"A web address that opens in a new tab when you click it.\" },\n\n { id: \"number\", group: \"Numbers and dates\", label: \"Number\", explanation: \"A plain number you can total up and sort by.\" },\n { id: \"currency\", group: \"Numbers and dates\", label: \"Money\", explanation: \"An amount of money, shown with its currency wherever it appears.\" },\n { id: \"percent\", group: \"Numbers and dates\", label: \"Percentage\", explanation: \"A number out of a hundred, kept between 0 and 100.\" },\n { id: \"datetime\", group: \"Numbers and dates\", label: \"Date\", explanation: \"A day, or a day and a time. Dates are what the calendar view reads.\" },\n\n { id: \"select\", group: \"Choices and people\", label: \"Choice\", explanation: \"One answer from a list you write here. Choices are what the board view groups by.\" },\n { id: \"multi_select\", group: \"Choices and people\", label: \"Several choices\", explanation: \"Any number of answers from a list you write here.\" },\n { id: \"member\", group: \"Choices and people\", label: \"Person\", explanation: \"Somebody in this organization, picked from the people who are in it.\" },\n { id: \"attachment\", group: \"Choices and people\", label: \"File\", explanation: \"A file or a picture kept with the record.\" },\n\n { id: \"lookup\", group: \"Worked out\", label: \"Borrowed value\", explanation: \"A value read from a record this one points at, kept in step with it.\" },\n { id: \"rollup\", group: \"Worked out\", label: \"Total of linked records\", explanation: \"A count or a total worked out from the records this one points at.\" },\n { id: \"formula\", group: \"Worked out\", label: \"Worked out from other columns\", explanation: \"A value this record works out for itself from its own other columns.\" },\n];\n\nexport const FIELD_TYPE_GROUPS: FieldTypeChoice[\"group\"][] = [\n \"Words\",\n \"Numbers and dates\",\n \"Choices and people\",\n \"Worked out\",\n];\n\nconst BY_ID = new Map<string, FieldTypeChoice>(FIELD_TYPE_CHOICES.map((c) => [c.id, c]));\n\nexport function fieldTypeChoice(id: string): FieldTypeChoice | undefined {\n return BY_ID.get(id);\n}\n\n/** The three that are a plain behaviour rather than one of the thirteen. */\nexport function isPlainFieldType(id: string): id is PlainFieldType {\n return id === \"text\" || id === \"long_text\" || id === \"number\";\n}\n\n/**\n * THE GUARD THIS FILE NEEDS, because the list it explains is generated.\n *\n * Returns the parity types the store ships that nothing here explains. The\n * suite asserts it is empty; a fourteenth type would otherwise reach the menu\n * with a blank line under it and nobody would notice until a person did.\n */\nexport function parityTypesWithNoExplanation(): string[] {\n return PARITY_FIELD_TYPES.map((row) => row.parity_type).filter((type) => !BY_ID.has(type));\n}\n","\"use client\";\n\n// src/RelationPicker.tsx — @ai-matrx/records-ui · SCR-N-2\n//\n// THE ONE GENERIC RELATION PICKER. Before it, every relation-shaped field in\n// the product had a type-specific picker (image, file, url, scope) and a plain\n// `relation` field was not editable at all.\n//\n// It reads the target Table's records through the read door, shows each one as\n// its own chip (REC-2: the title field is what makes a record a chip), and\n// respects `relation_max` by saying the number rather than silently dropping a\n// pick.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { Field, ReadRow } from \"@ai-matrx/records\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n Button,\n Popover,\n PopoverContent,\n PopoverTrigger,\n ScrollArea,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { RecordChip } from \"./editors\";\nimport { fieldName, rowName } from \"./names\";\n\nexport interface RelationPickerProps {\n field: Field;\n value: unknown;\n onChange: (value: unknown) => void;\n disabled?: boolean | undefined;\n id?: string | undefined;\n className?: string | undefined;\n}\n\nexport function RelationPicker({ field, value, onChange, disabled, id, className }: RelationPickerProps) {\n const client = useRecordsClient();\n const [rows, setRows] = useState<ReadRow[] | null>(null);\n const [refusal, setRefusal] = useState<string | null>(null);\n const [search, setSearch] = useState(\"\");\n const [open, setOpen] = useState(false);\n\n const picked = useMemo<string[]>(\n () => (Array.isArray(value) ? value.map(String) : value === null || value === undefined ? [] : [String(value)]),\n [value],\n );\n\n useEffect(() => {\n if (!open || rows || !field.relation_target) return;\n let cancelled = false;\n void client.list({ table_id: field.relation_target, limit: 200 }).then((result) => {\n if (cancelled) return;\n if (result.ok) setRows(result.data.rows);\n else setRefusal(result.error.message);\n });\n return () => {\n cancelled = true;\n };\n }, [client, field.relation_target, open, rows]);\n\n if (!field.relation_target) {\n // Absent, and honest about why: a relation with no declared target is a\n // Field the store has not finished, not a picker that \"has no options\".\n return (\n <p className=\"text-xs text-muted-foreground\">\n {fieldName(field)} points at records, but it does not say which Table yet, so there is nothing to pick\n from. A table admin sets its target in the field editor.\n </p>\n );\n }\n\n const byId = new Map((rows ?? []).map((row) => [row.id, row]));\n // A chip carries the record's NAME. Before `names.ts`, a relation whose\n // target had not loaded yet drew `8f2c1b0a` — a bare identifier, which the\n // verdict of 19 September counted among the three things a first-time user\n // feels within a minute.\n const titleOf = (recordId: string) => rowName(byId.get(recordId), null, \"Loading…\");\n const full = field.multi && field.relation_max !== null && picked.length >= field.relation_max;\n\n const toggle = (recordId: string) => {\n if (!field.multi) {\n onChange(picked[0] === recordId ? null : recordId);\n setOpen(false);\n return;\n }\n const next = new Set(picked);\n if (next.has(recordId)) next.delete(recordId);\n else if (!full) next.add(recordId);\n onChange(next.size === 0 ? null : [...next]);\n };\n\n const visible = (rows ?? []).filter((row) =>\n search.trim() === \"\" ? true : titleOf(row.id).toLowerCase().includes(search.trim().toLowerCase()),\n );\n\n return (\n <div className={cn(\"flex flex-wrap items-center gap-1\", className)}>\n {picked.map((recordId) => (\n <RecordChip\n key={recordId}\n title={titleOf(recordId)}\n {...(disabled ? {} : { onRemove: () => toggle(recordId) })}\n />\n ))}\n {disabled ? null : (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button id={id} type=\"button\" size=\"sm\" variant=\"outline\" aria-label={`Pick for ${fieldName(field)}`}>\n {picked.length === 0 ? \"Pick\" : \"Change\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-64 p-1\" align=\"start\">\n <BasicInput\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search\"\n className=\"mb-1 h-7 text-xs\"\n />\n {refusal ? <p className=\"p-2 text-xs text-destructive\">{refusal}</p> : null}\n {!rows && !refusal ? <p className=\"p-2 text-xs text-muted-foreground\">Reading…</p> : null}\n {full ? (\n <p className=\"p-2 text-xs text-muted-foreground\">\n {fieldName(field)} can point at {field.relation_max} at most. Remove one to add another.\n </p>\n ) : null}\n <ScrollArea className=\"max-h-56\">\n <ul>\n {visible.map((row) => (\n <li key={row.id}>\n <button\n type=\"button\"\n onClick={() => toggle(row.id)}\n className={cn(\n \"w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted\",\n picked.includes(row.id) ? \"bg-accent text-accent-foreground\" : \"\",\n )}\n >\n {titleOf(row.id)}\n </button>\n </li>\n ))}\n </ul>\n {rows && visible.length === 0 ? (\n <p className=\"p-2 text-xs text-muted-foreground\">Nothing in that table matches.</p>\n ) : null}\n </ScrollArea>\n </PopoverContent>\n </Popover>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/gridEditing.tsx — @ai-matrx/records-ui · SCR-1 / REC-9\n//\n// EDITING A RECORD WHERE IT IS SHOWN.\n//\n// Until this file existed, the grid was a read-only window: double-clicking a\n// cell opened a panel of raw JSON with no control, no Save and no Delete, and\n// the only way to write anything was the whole \"New record\" form. The\n// independent verdict of 19 September put it first of three: \"In Airtable you\n// click a cell and type. Here a cell opens a read-only window of programming\n// text… Every other gap is downstream of this one.\"\n//\n// WHAT THIS IS, AND WHAT IT DELIBERATELY IS NOT\n// ---------------------------------------------\n// `@ai-matrx/design-system`'s data table HAS an inline editor\n// (`EditableTableCell`) and this package does not use it here, for one reason\n// that is not taste: that editor speaks six value shapes (string, number,\n// boolean, select, tags, date) and collects edits into a draft map that a\n// floating Save pill persists. A Field in this store is one of THIRTEEN parity\n// types — a relation, a person, a file, a multi-choice whose options are the\n// records of another Table, a json document, a formula that cannot be typed\n// into at all — and every one of them already has exactly one editor in this\n// package (`FieldControl`, itself built from design-system primitives). Two\n// editing models on one screen is the fork the inventory law forbids, so the\n// cell hosts the ONE editor a Field already has, and the write goes through the\n// ONE write door with the version the person started from.\n//\n// THE CONCURRENCY STORY, WHICH IS THE WHOLE POINT OF REC-9\n// -------------------------------------------------------\n// The read door answers documents, never versions. So the FIRST time a person\n// edits a given record in this session, the version is read for that one record\n// (`custom.io_revisions`) and remembered. Every save from then on carries it,\n// and the store — not this screen — decides whether somebody else got there\n// first. When it did, the store raises `PT409` with the other person's value in\n// the detail, and the cell shows THAT: their value, beside the value being\n// written, with a Retry that re-reads the version and writes again, and a\n// \"Keep theirs\" that drops the edit. Nothing is silently overwritten and\n// nothing is silently lost.\n//\n// OPTIMISTIC, BUT NEVER DISHONEST: the typed value is shown the instant it is\n// committed, and it is REMOVED again the moment the store refuses. A cell that\n// kept showing a value the store rejected is the lie this package exists to\n// prevent.\n\nimport { useCallback, useMemo, useRef, useState, type FocusEvent } from \"react\";\nimport type { Field, ReadRow, RecordsError, Uuid } from \"@ai-matrx/records\";\nimport type { WriteConflict } from \"@ai-matrx/records\";\nimport { asWriteConflict, type RecordsClient } from \"@ai-matrx/records/core\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport { Button, cn } from \"@ai-matrx/design-system\";\n\nimport { FieldControl } from \"./editors\";\nimport { RefusalLine } from \"./Refusal\";\nimport { editorKindFor } from \"./parity\";\nimport { fieldName } from \"./names\";\nimport { RecordValue } from \"./values\";\n\n/** Which cell is open. A grid opens exactly one at a time, like every other grid. */\nexport interface CellAddress {\n rowId: Uuid;\n key: string;\n}\n\n/** What one cell is doing right now, so nothing about it is guessed by a caller. */\nexport type CellState = \"clean\" | \"saving\" | \"refused\";\n\nexport interface CellRefusal {\n error: RecordsError;\n /** Present when the store said `PT409`: the other person's value, from the store. */\n conflict: WriteConflict | null;\n /** The value that was being written, so Retry can write it again. */\n attempted: unknown;\n}\n\n/**\n * FLD-9. A computed Field is not editable and never will be — the store works\n * it out. Saying so here, once, keeps every caller from re-deciding it.\n */\nexport function fieldIsEditable(field: Field): boolean {\n const kind = editorKindFor(field);\n return kind !== \"formula\" && kind !== \"lookup\" && kind !== \"rollup\";\n}\n\nexport interface GridEditing {\n /** The value to DRAW for one cell — the optimistic one when there is one. */\n valueFor: (row: ReadRow, field: Field) => unknown;\n editing: CellAddress | null;\n stateOf: (rowId: Uuid, key: string) => CellState;\n refusalOf: (rowId: Uuid, key: string) => CellRefusal | null;\n begin: (address: CellAddress) => void;\n cancel: () => void;\n /** Commit the open cell. `move` opens the next/previous editable cell after it. */\n commit: (value: unknown, move?: \"next\" | \"previous\" | null) => void;\n /** Write the attempted value again, after re-reading the version. */\n retry: (rowId: Uuid, key: string) => void;\n /** Drop the edit and show what the other person wrote. */\n keepTheirs: (rowId: Uuid, key: string) => void;\n /** Soft delete, through the store's own door. Answers the store's refusal, or null. */\n remove: (rowId: Uuid) => Promise<RecordsError | null>;\n /** Write an empty record and open its first editable cell. */\n addRecord: () => Promise<RecordsError | null>;\n /** The last refusal from a delete or an add, for the grid to print. */\n rowError: RecordsError | null;\n clearRowError: () => void;\n busy: boolean;\n}\n\ninterface Options {\n tableId: Uuid;\n fields: Field[];\n rows: ReadRow[];\n /** Re-read the page once the store has accepted something. */\n reload: () => void;\n /** May this person write records at all? A read-only grid opens no editor. */\n canWrite: boolean;\n}\n\n/**\n * THE VERSION THE PERSON STARTED FROM, read once per record per session.\n *\n * Not read for the page: a list of two hundred records would be two hundred\n * extra door calls for a person who is going to edit one cell. Not guessed\n * either — `null` means \"we never read one\", and the save then carries no\n * expected version and is the store's ordinary last-writer-wins write, exactly\n * as the store defines it.\n */\nasync function versionOf(\n client: RecordsClient,\n cache: Map<string, number>,\n recordId: Uuid,\n): Promise<number | null> {\n const held = cache.get(recordId);\n if (held !== undefined) return held;\n const answered = await client.revisions({ record_id: recordId });\n if (!answered.ok) return null;\n const newest = answered.data.reduce<number | null>(\n (best, row) => (best === null || row.version > best ? row.version : best),\n null,\n );\n if (newest !== null) cache.set(recordId, newest);\n return newest;\n}\n\nexport function useGridEditing({ tableId, fields, rows, reload, canWrite }: Options): GridEditing {\n const client = useRecordsClient();\n const [editing, setEditing] = useState<CellAddress | null>(null);\n const [optimistic, setOptimistic] = useState<Record<string, unknown>>({});\n const [saving, setSaving] = useState<Record<string, true>>({});\n const [refusals, setRefusals] = useState<Record<string, CellRefusal>>({});\n const [rowError, setRowError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const versions = useRef(new Map<string, number>());\n // ONE WRITE AT A TIME PER RECORD. Tabbing across a row commits each cell the\n // instant the next one opens, so two writes of the SAME record were in flight\n // together and the second carried the version the first had already moved:\n // the store answered PT409 and a person tabbing through their own row was\n // shown a conflict with themselves. Measured 2026-09-19 in the headless walk.\n // The store was right both times; the screen was firing them in parallel.\n const queues = useRef(new Map<string, Promise<void>>());\n\n const editable = useMemo(() => fields.filter(fieldIsEditable), [fields]);\n const order = useMemo(() => editable.map((f) => f.key), [editable]);\n const rowIds = useMemo(() => rows.map((r) => r.id), [rows]);\n\n const cellKey = (rowId: Uuid, key: string) => `${rowId}::${key}`;\n\n const valueFor = useCallback(\n (row: ReadRow, field: Field) => {\n const held = optimistic[cellKey(row.id, field.key)];\n return held === undefined ? row.document?.[field.key] : held;\n },\n [optimistic],\n );\n\n const stateOf = useCallback(\n (rowId: Uuid, key: string): CellState => {\n const id = cellKey(rowId, key);\n if (saving[id]) return \"saving\";\n if (refusals[id]) return \"refused\";\n return \"clean\";\n },\n [saving, refusals],\n );\n\n const refusalOf = useCallback(\n (rowId: Uuid, key: string) => refusals[cellKey(rowId, key)] ?? null,\n [refusals],\n );\n\n const begin = useCallback(\n (address: CellAddress) => {\n if (!canWrite) return;\n setEditing(address);\n // The version this edit starts from, read once for this record.\n void versionOf(client, versions.current, address.rowId);\n },\n [canWrite, client],\n );\n\n const cancel = useCallback(() => setEditing(null), []);\n\n /** The write itself. `writeCell` below is what callers use; it queues these. */\n const writeCellNow = useCallback(\n async (rowId: Uuid, key: string, value: unknown) => {\n const id = cellKey(rowId, key);\n setOptimistic((held) => ({ ...held, [id]: value }));\n setSaving((held) => ({ ...held, [id]: true }));\n setRefusals((held) => {\n if (!held[id]) return held;\n const next = { ...held };\n delete next[id];\n return next;\n });\n\n const version = await versionOf(client, versions.current, rowId);\n const written = await client.recordUpdate({\n record_id: rowId,\n patch: { [key]: value },\n ...(version === null ? {} : { expectedVersion: version }),\n });\n\n setSaving((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n\n if (written.ok) {\n // The store's own new version, so the NEXT edit of this record carries it.\n versions.current.set(rowId, written.data);\n reload();\n return;\n }\n\n // Refused: the optimistic value comes straight back off the screen, and\n // the store's own sentence goes on it.\n setOptimistic((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n // A stale write means the version we hold is wrong; forget it so the\n // retry reads the current one rather than repeating the same refusal.\n if (written.error.code === \"stale_write\") versions.current.delete(rowId);\n setRefusals((held) => ({\n ...held,\n [id]: {\n error: written.error,\n conflict: asWriteConflict(written.error, rowId),\n attempted: value,\n },\n }));\n },\n [client, reload],\n );\n\n /** One write of one Field of one record, with whatever version we hold. */\n const writeCell = useCallback(\n (rowId: Uuid, key: string, value: unknown): Promise<void> => {\n // Queued behind whatever is already in flight for THIS record; two\n // different records still write in parallel.\n const behind = queues.current.get(rowId) ?? Promise.resolve();\n const next = behind.then(() => writeCellNow(rowId, key, value));\n queues.current.set(\n rowId,\n next.then(\n () => undefined,\n () => undefined,\n ),\n );\n return next;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, reload],\n );\n\n const commit = useCallback(\n (value: unknown, move: \"next\" | \"previous\" | null = null) => {\n const open = editing;\n if (!open) return;\n const row = rows.find((r) => r.id === open.rowId);\n const unchanged = row !== undefined && sameValue(row.document?.[open.key], value);\n if (!unchanged) void writeCell(open.rowId, open.key, value);\n\n if (!move) {\n setEditing(null);\n return;\n }\n const next = step(open, order, rowIds, move);\n setEditing(next);\n if (next) void versionOf(client, versions.current, next.rowId);\n },\n [editing, rows, writeCell, order, rowIds, client],\n );\n\n const retry = useCallback(\n (rowId: Uuid, key: string) => {\n const held = refusals[cellKey(rowId, key)];\n if (!held) return;\n void writeCell(rowId, key, held.attempted);\n },\n [refusals, writeCell],\n );\n\n const keepTheirs = useCallback(\n (rowId: Uuid, key: string) => {\n const id = cellKey(rowId, key);\n versions.current.delete(rowId);\n setRefusals((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n setOptimistic((held) => {\n const next = { ...held };\n delete next[id];\n return next;\n });\n reload();\n },\n [reload],\n );\n\n const remove = useCallback(\n async (rowId: Uuid) => {\n setBusy(true);\n setRowError(null);\n const done = await client.recordDelete({ record_id: rowId });\n setBusy(false);\n if (done.ok) {\n versions.current.delete(rowId);\n reload();\n return null;\n }\n setRowError(done.error);\n return done.error;\n },\n [client, reload],\n );\n\n const addRecord = useCallback(async () => {\n setBusy(true);\n setRowError(null);\n // AIRTABLE'S GESTURE: a new row appears and you type into it. The store\n // decides whether an empty record is allowed — a Table with a required\n // Field refuses, in its own words, and the grid offers the whole form.\n const written = await client.recordWrite({ table_id: tableId, data: {} });\n setBusy(false);\n if (!written.ok) {\n setRowError(written.error);\n return written.error;\n }\n reload();\n const first = order[0];\n if (first) setEditing({ rowId: written.data, key: first });\n return null;\n }, [client, tableId, reload, order]);\n\n return {\n valueFor,\n editing,\n stateOf,\n refusalOf,\n begin,\n cancel,\n commit,\n retry,\n keepTheirs,\n remove,\n addRecord,\n rowError,\n clearRowError: () => setRowError(null),\n busy,\n };\n}\n\n/** Tab order: across the row, then on to the next row. Stops at the ends. */\nfunction step(\n from: CellAddress,\n order: string[],\n rowIds: Uuid[],\n move: \"next\" | \"previous\",\n): CellAddress | null {\n const column = order.indexOf(from.key);\n const row = rowIds.indexOf(from.rowId);\n if (column < 0 || row < 0) return null;\n const delta = move === \"next\" ? 1 : -1;\n let nextColumn = column + delta;\n let nextRow = row;\n if (nextColumn >= order.length) {\n nextColumn = 0;\n nextRow += 1;\n } else if (nextColumn < 0) {\n nextColumn = order.length - 1;\n nextRow -= 1;\n }\n const key = order[nextColumn];\n const rowId = rowIds[nextRow];\n if (key === undefined || rowId === undefined) return null;\n return { rowId, key };\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (left === null || left === undefined) return right === null || right === undefined || right === \"\";\n if (right === null || right === undefined) return left === \"\";\n if (typeof left === \"object\" || typeof right === \"object\") {\n try {\n return JSON.stringify(left) === JSON.stringify(right);\n } catch {\n return false;\n }\n }\n return false;\n}\n\n/**\n * ONE CELL. Read, until somebody asks to change it; then the Field's own\n * editor, in place, with the keys a person expects from a grid.\n *\n * `data-matrx-cell-control` is the data table's own opt-out from whole-row\n * click, so opening a cell never also opens the record panel behind it.\n */\nexport function GridCell({\n field,\n row,\n editing,\n canWrite,\n}: {\n field: Field;\n row: ReadRow;\n editing: GridEditing;\n canWrite: boolean;\n}) {\n const open = editing.editing?.rowId === row.id && editing.editing.key === field.key;\n const value = editing.valueFor(row, field);\n const state = editing.stateOf(row.id, field.key);\n const refusal = editing.refusalOf(row.id, field.key);\n const editable = canWrite && fieldIsEditable(field);\n\n if (open) {\n return (\n <OpenCell\n field={field}\n value={value}\n onCommit={(next, move) => editing.commit(next, move)}\n onCancel={editing.cancel}\n />\n );\n }\n\n return (\n <span data-matrx-cell-control=\"\" className=\"flex min-w-0 flex-col gap-0.5\">\n <span\n role={editable ? \"button\" : undefined}\n tabIndex={editable ? 0 : undefined}\n aria-label={editable ? `Edit ${fieldName(field)}` : undefined}\n title={editable ? `${fieldName(field)} — press Enter to edit` : undefined}\n className={cn(\n \"block min-w-0 truncate rounded px-1 py-0.5\",\n editable ? \"cursor-text hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\" : \"\",\n state === \"saving\" ? \"opacity-60\" : \"\",\n state === \"refused\" ? \"ring-1 ring-destructive\" : \"\",\n )}\n onClick={editable ? () => editing.begin({ rowId: row.id, key: field.key }) : undefined}\n onKeyDown={\n editable\n ? (event) => {\n if (event.key === \"Enter\" || event.key === \"F2\") {\n event.preventDefault();\n editing.begin({ rowId: row.id, key: field.key });\n }\n }\n : undefined\n }\n >\n <RecordValue field={field} value={value} document={row.document} />\n </span>\n\n {state === \"saving\" ? <span className=\"px-1 text-[10px] text-muted-foreground\">Saving…</span> : null}\n\n {refusal ? (\n <span className=\"flex flex-col gap-0.5 rounded border border-destructive/40 p-1\">\n <RefusalLine error={refusal.error} />\n {refusal.conflict ? (\n <span className=\"text-[11px]\">\n {/* The other person's value, as the store sent it. */}\n Theirs: <strong>{formatTheirs(refusal.conflict, field.key)}</strong>\n </span>\n ) : null}\n <span className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"outline\" onClick={() => editing.retry(row.id, field.key)}>\n Try again\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => editing.keepTheirs(row.id, field.key)}>\n Keep theirs\n </Button>\n </span>\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction formatTheirs(conflict: WriteConflict, key: string): string {\n const theirs = conflict.contested_fields?.[key];\n if (theirs === null || theirs === undefined || theirs === \"\") return \"(empty)\";\n return typeof theirs === \"object\" ? JSON.stringify(theirs) : String(theirs);\n}\n\n/**\n * WHICH EDITORS CLOSE THEMSELVES ON BLUR, AND WHY THE OTHERS MUST NOT.\n *\n * A typed box (text, number, date, email, url, phone) is finished when you look\n * away, exactly as a spreadsheet is. A PICKER is not: a select, a relation\n * picker and a person picker all open a Radix popover, which is portalled OUT\n * of this cell, so \"focus left the cell\" fires the instant the list opens.\n * Committing there would save the old value and shut the list a person just\n * asked for. So pickers carry an explicit Save and Cancel, and the keys work on\n * both.\n */\nfunction closesOnBlur(field: Field): boolean {\n switch (editorKindFor(field)) {\n case \"select\":\n case \"multi_select\":\n case \"relation\":\n case \"member\":\n case \"attachment\":\n return false;\n default:\n return true;\n }\n}\n\n/**\n * The open cell. Enter commits, Escape cancels, Tab commits and opens the next\n * one — the three keys every grid in the world binds, so nobody has to be told.\n * A long-text Field takes Enter for a newline and commits on Ctrl/Cmd+Enter,\n * because the alternative is a text box you cannot put a paragraph in.\n */\nfunction OpenCell({\n field,\n value,\n onCommit,\n onCancel,\n}: {\n field: Field;\n value: unknown;\n onCommit: (value: unknown, move: \"next\" | \"previous\" | null) => void;\n onCancel: () => void;\n}) {\n const [draft, setDraft] = useState<unknown>(value);\n const multiline = editorKindFor(field) === \"long_text\";\n const blurCommits = closesOnBlur(field);\n // ONE COMMIT PER OPENING. Tab moves focus, so the key handler AND the blur\n // handler both fired for the same cell: two writes of one value, the second\n // against the version the first had just moved, and the store — correctly —\n // answered PT409. A person tabbing through their own row was shown a\n // conflict with themselves. Measured 2026-09-19 in the headless walk.\n const done = useRef(false);\n const once = (run: () => void) => {\n if (done.current) return;\n done.current = true;\n run();\n };\n\n const blur = blurCommits\n ? {\n onBlur: (event: FocusEvent<HTMLSpanElement>) => {\n // Leaving the cell altogether commits, exactly as a spreadsheet does.\n // Moving between the editor's own parts does not.\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n once(() => onCommit(draft, null));\n },\n }\n : {};\n\n return (\n <span\n data-matrx-cell-control=\"\"\n className=\"flex min-w-[10rem] flex-col gap-1\"\n ref={(node) => {\n if (!node) return;\n const control = node.querySelector<HTMLElement>(\"input, textarea, [role='combobox'], button\");\n if (control && document.activeElement !== control) control.focus();\n }}\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n once(onCancel);\n return;\n }\n if (event.key === \"Tab\") {\n event.preventDefault();\n event.stopPropagation();\n once(() => onCommit(draft, event.shiftKey ? \"previous\" : \"next\"));\n return;\n }\n if (event.key === \"Enter\" && (!multiline || event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n event.stopPropagation();\n once(() => onCommit(draft, null));\n }\n }}\n {...blur}\n >\n <FieldControl field={field} value={draft} onChange={setDraft} id={`cell-${field.id}`} />\n {blurCommits ? (\n <span className=\"text-[10px] text-muted-foreground\">\n {multiline ? \"⌘⏎ saves · Esc cancels · Tab next\" : \"⏎ saves · Esc cancels · Tab next\"}\n </span>\n ) : (\n <span className=\"flex items-center gap-1\">\n <Button size=\"sm\" onClick={() => once(() => onCommit(draft, null))}>\n Save\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => once(onCancel)}>\n Cancel\n </Button>\n </span>\n )}\n </span>\n );\n}\n","\"use client\";\n\n// src/Refusal.tsx — @ai-matrx/records-ui\n//\n// THE ONE PLACE A REFUSAL IS SHOWN, and it shows the STORE'S OWN SENTENCE.\n// Nothing in this package writes its own copy for something the store already\n// explained: \"Someone else changed this record while you were working on it\" was\n// written to be read by the person who hit it.\n//\n// Every component here renders this when a call comes back `{ok:false}`. A\n// component that rendered an empty list instead would be the lie the whole\n// record package exists to prevent.\n\nimport type { ReactNode } from \"react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Alert, AlertDescription, AlertTitle, cn } from \"@ai-matrx/design-system\";\n\nconst TITLE: Record<string, string> = {\n stale_write: \"Someone else wrote first\",\n door: \"The store did not open this door\",\n door_absent: \"That door does not exist yet\",\n refused_by_rule: \"The store refused this\",\n invalid_argument: \"The store refused this\",\n not_found: \"Not there any more\",\n missing_reference: \"That points somewhere it cannot\",\n already_exists: \"That already exists\",\n not_supported: \"The store does not do that\",\n store_limit: \"The store hit a limit\",\n store_not_served: \"The store is not being served\",\n internal: \"The store said something this package does not recognise\",\n};\n\nexport function RefusalNotice({\n error,\n className,\n actions,\n}: {\n error: RecordsError;\n className?: string | undefined;\n actions?: ReactNode | undefined;\n}) {\n return (\n <Alert\n variant=\"destructive\"\n className={cn(\"text-xs\", className)}\n {...(error.sqlstate ? { title: `The store's code for this was ${error.sqlstate}` } : {})}\n >\n <AlertTitle className=\"text-xs font-medium\">{TITLE[error.code] ?? \"The store refused this\"}</AlertTitle>\n <AlertDescription className=\"space-y-1 text-xs\">\n {/* The store's own words, verbatim. */}\n <p>{error.message}</p>\n {error.hint ? <p className=\"opacity-80\">{error.hint}</p> : null}\n {/* The store's CODE is a fact for whoever has to debug it, not a\n sentence for the person reading the refusal — printing `42501` in\n the body made the screen read like a stack trace (verdict, 19\n September). It stays, on the notice, where an engineer can find it. */}\n {error.sqlstate ? (\n <p className=\"sr-only\" data-sqlstate={error.sqlstate}>\n The store&apos;s code for this was {error.sqlstate}.\n </p>\n ) : null}\n {actions}\n </AlertDescription>\n </Alert>\n );\n}\n\n/** A small inline one, for a cell or a field where a block would break the layout. */\nexport function RefusalLine({ error, className }: { error: RecordsError; className?: string | undefined }) {\n return (\n <p className={cn(\"text-xs text-destructive\", className)} title={error.hint ?? undefined}>\n {error.message}\n </p>\n );\n}\n","\"use client\";\n\n// src/values.tsx — @ai-matrx/records-ui\n//\n// HOW A VALUE IS SHOWN, one function, used by the grid cell, the peek, the\n// custom-fields section and the form's read state alike. Per SCR it is never\n// per-feature: every surface that shows a Value in this platform shows it the\n// same way, because the way is a property of the Field, not of the screen.\n//\n// VAL-2: a blank is never unexplained. When the record's envelope says why a\n// value is missing, the reason is what is shown — \"never asked\" and \"refused\"\n// are different facts and a person acts on them differently.\n\nimport type { Field, RecordDocument, ValueEnvelope } from \"@ai-matrx/records\";\nimport { Badge, cn } from \"@ai-matrx/design-system\";\nimport { editorKindFor } from \"./parity\";\nimport { isId, useRecordLabels, type LabelLookup } from \"./labels\";\n\n/** The envelope for one key, when the document carries one. */\nexport function envelopeFor(document: RecordDocument | undefined, key: string): ValueEnvelope | undefined {\n const block = document?._values as Record<string, ValueEnvelope> | undefined;\n return block?.[key];\n}\n\nconst ABSENCE_WORDS: Record<string, string> = {\n \"never asked\": \"never asked\",\n none: \"none\",\n refused: \"refused\",\n conflicting: \"conflicting\",\n};\n\nexport function renderValue(field: Field, value: unknown, document?: RecordDocument, labels?: LabelLookup) {\n const envelope = envelopeFor(document, field.key);\n if (envelope?.absent) {\n return (\n <span className=\"text-xs italic text-muted-foreground\" title={`VAL-2: ${envelope.absent}`}>\n {ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent)}\n </span>\n );\n }\n if (value === null || value === undefined || value === \"\") {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n const kind = editorKindFor(field);\n if (Array.isArray(value)) {\n return (\n <span className=\"flex flex-wrap gap-1\">\n {value.map((item, i) => (\n <Badge key={`${String(item)}-${i}`} variant=\"secondary\" className=\"text-[11px]\">\n {scalarText(field, item, labels)}\n </Badge>\n ))}\n </span>\n );\n }\n if (kind === \"url\" && typeof value === \"string\") {\n return (\n <a className=\"truncate text-primary underline-offset-2 hover:underline\" href={value} target=\"_blank\" rel=\"noreferrer\">\n {value}\n </a>\n );\n }\n if (kind === \"email\" && typeof value === \"string\") {\n return (\n <a className=\"truncate text-primary underline-offset-2 hover:underline\" href={`mailto:${value}`}>\n {value}\n </a>\n );\n }\n if (typeof value === \"boolean\") {\n return <span>{value ? \"Yes\" : \"No\"}</span>;\n }\n return <span className={cn(\"truncate\", kind === \"number\" || kind === \"currency\" || kind === \"percent\" ? \"tabular-nums\" : \"\")}>{scalarText(field, value, labels)}</span>;\n}\n\n/**\n * The text of one scalar, with the Field's UNIT and FORMAT applied — FLD-N-1\n * says both change the MEANING — and with an id resolved to the NAME of the\n * record it points at.\n *\n * `labels` is the resolver from `RecordLabelProvider`. Without it, an id is\n * drawn as \"Loading…\" and never as itself: a 36-character identifier in a cell\n * reads like a value, and the 19 September verdict found it in choice cells,\n * relation cells and as every Kanban column heading.\n */\nexport function scalarText(field: Field, value: unknown, labels?: LabelLookup): string {\n if (value === null || value === undefined) return \"—\";\n const kind = editorKindFor(field);\n if (isId(value) && (field.type === \"list\" || field.type === \"relation\")) {\n return labels?.(field, String(value)) ?? \"Loading…\";\n }\n if (typeof value === \"number\") {\n if (kind === \"percent\") return `${value}%`;\n // The symbol goes in FRONT of an amount of money and a unit goes AFTER a\n // quantity: `$3` and `3 units`. Before this, `editorKindFor` called any\n // range field with a unit longer than one character a currency, so three\n // things measured in units rendered as \"units3\".\n if (kind === \"currency\") return field.unit ? `${field.unit}${value.toLocaleString()}` : value.toLocaleString();\n return field.unit ? `${value.toLocaleString()} ${field.unit}` : value.toLocaleString();\n }\n if (kind === \"datetime\" && typeof value === \"string\") {\n const at = new Date(value);\n if (!Number.isNaN(at.getTime())) {\n return field.format === \"datetime\" ? at.toLocaleString() : at.toLocaleDateString();\n }\n }\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The provenance badge a value carries when the store interned a source for it (SCR-27). */\nexport function ProvenanceBadge({ document, fieldKey }: { document: RecordDocument | undefined; fieldKey: string }) {\n const envelope = envelopeFor(document, fieldKey);\n if (!envelope?.src) return null;\n const sources = document?._sources as Record<string, Record<string, unknown>> | undefined;\n const source = sources?.[envelope.src];\n const label = source ? Object.values(source).map(String).join(\" · \") : envelope.src;\n return (\n <Badge variant=\"outline\" className=\"text-[10px] font-normal\" title={`Written by ${envelope.actor ?? \"?\"}${envelope.at ? ` at ${envelope.at}` : \"\"}`}>\n {label}\n </Badge>\n );\n}\n\n/**\n * THE VALUE, AS A COMPONENT, so a cell can resolve the ids it holds.\n *\n * `renderValue` is a plain function called from inside a column's `cell`\n * callback and from a dozen other places; a function cannot ask the resolver\n * for a name, because asking is a hook. Every read-only surface therefore draws\n * through this instead, and the one that needs the raw function (a plain-text\n * export, a chat line) keeps calling `renderValue` with no resolver and says\n * \"Loading…\" rather than printing an id.\n */\nexport function RecordValue({\n field,\n value,\n document,\n}: {\n field: Field;\n value: unknown;\n document?: RecordDocument | undefined;\n}) {\n const labels = useRecordLabels(ONE_FIELD_ARRAY_CACHE(field));\n return <>{renderValue(field, value, document, labels)}</>;\n}\n\n/**\n * `useRecordLabels` takes an array and declares what it is about to draw. A new\n * array literal per cell would re-declare on every render, so each Field gets\n * exactly one array for the life of the process.\n */\nconst ONE_FIELD_ARRAYS = new WeakMap<Field, Field[]>();\nfunction ONE_FIELD_ARRAY_CACHE(field: Field): Field[] {\n const held = ONE_FIELD_ARRAYS.get(field);\n if (held) return held;\n const made = [field];\n ONE_FIELD_ARRAYS.set(field, made);\n return made;\n}\n","\"use client\";\n\n// src/labels.tsx — @ai-matrx/records-ui\n//\n// WHAT AN ID IS CALLED, ONCE, FOR EVERY SCREEN THAT DRAWS A VALUE.\n//\n// A choice field stores the ID of an option record and a relation field stores\n// the ID of the record it points at (FLD-5 / FLD-6, REL-1) — that is the store\n// being right, and it is also why the 19 September verdict saw a bare\n// 36-character identifier in a relation cell, in a choice cell, and as the\n// HEADING OF EVERY KANBAN COLUMN. The pickers resolved those ids because each\n// one loaded its own list; the read-only surfaces never did, so the same value\n// read as a name in the form and as a machine id in the grid.\n//\n// One resolver, provided once inside the mount, so every surface gets the same\n// answer and asks the store once per Field rather than once per cell:\n//\n// · a list field → `custom.field_options`, which resolves the options Table\n// from the Field's own config, so no screen has to know which Table it is\n// · a relation field → the read door on the Field's declared target\n//\n// WHAT IT DOES WHILE IT IS LOOKING. It returns `null`, and every caller draws\n// the word \"Loading…\" rather than the id. Showing the id \"until it resolves\" is\n// how the defect got shipped in the first place: it looks like a value.\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { useRecordsClient, type Field, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordDocument } from \"@ai-matrx/records\";\nimport { recordName } from \"./names\";\n\n/** Answers \"what is the record with this id called\", for one Field's values. */\nexport type LabelLookup = (field: Field, id: string) => string | null;\n\nconst LabelContext = createContext<{\n lookup: LabelLookup;\n want: (field: Field) => void;\n}>({\n // With no provider the resolver is ABSENT, not silently empty: a caller gets\n // null and says \"Loading…\" forever, which is visible. The mount always\n // provides one, so this is only ever a bare unit test.\n lookup: () => null,\n want: () => {},\n});\n\n/** Which ids a Field's stored value refers to. */\nexport function idsOf(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String).filter(isId);\n if (typeof value === \"string\" && isId(value)) return [value];\n return [];\n}\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function isId(value: unknown): boolean {\n return typeof value === \"string\" && UUID.test(value);\n}\n\n/** True when this Field's values are ids of other records rather than values. */\nexport function pointsAtRecords(field: Field): boolean {\n return field.type === \"list\" || field.type === \"relation\";\n}\n\nexport function RecordLabelProvider({ children }: { children: ReactNode }) {\n const client = useRecordsClient();\n const [names, setNames] = useState<Record<string, string>>({});\n const asked = useRef<Set<string>>(new Set());\n\n const want = useCallback(\n (field: Field) => {\n if (!pointsAtRecords(field)) return;\n if (asked.current.has(field.id)) return;\n asked.current.add(field.id);\n\n void (async () => {\n if (field.type === \"list\") {\n const result = await client.fieldOptions({ field_id: field.id });\n if (!result.ok) return;\n setNames((current) => {\n const next = { ...current };\n for (const option of result.data ?? []) {\n next[option.id] = recordName(option.data as RecordDocument | undefined, null, \"Unnamed choice\");\n }\n return next;\n });\n return;\n }\n const target = field.relation_target;\n if (!target) return;\n const result = await client.list({ table_id: target as Uuid, limit: 200 });\n if (!result.ok) return;\n setNames((current) => {\n const next = { ...current };\n for (const row of result.data.rows) {\n next[row.id] = recordName(row.document, null, \"Untitled\");\n }\n return next;\n });\n })();\n },\n [client],\n );\n\n const lookup = useCallback<LabelLookup>((_field, id) => names[id] ?? null, [names]);\n\n const value = useMemo(() => ({ lookup, want }), [lookup, want]);\n return <LabelContext.Provider value={value}>{children}</LabelContext.Provider>;\n}\n\n/**\n * The hook a surface uses: it declares the Fields it is about to draw, and gets\n * back the lookup. Declaring is what makes one request per Field instead of one\n * per cell, and it is why a grid of 200 rows asks the store twice.\n */\nexport function useRecordLabels(fields: readonly Field[] | undefined): LabelLookup {\n const { lookup, want } = useContext(LabelContext);\n useEffect(() => {\n for (const field of fields ?? []) want(field);\n }, [fields, want]);\n return lookup;\n}\n","\"use client\";\n\n// src/Grid.tsx — @ai-matrx/records-ui · SCR-1, SCR-2, SCR-4, SCR-31\n//\n// A custom table opens as a grid: RECORDS ARE ROWS, FIELDS ARE COLUMNS, AND A\n// CELL IS WHERE YOU CHANGE IT.\n//\n// It is the canonical `MatrxDataTable` — not a table this package drew. The\n// columns are built from the Table's own Field records, the rows are the\n// records the read door returned, and the \"+\" at the end of the column headers\n// is present for a holder of `admin` on the table and ABSENT — never disabled,\n// never greyed — for everybody else (SCR-4).\n//\n// EDITING IS HERE, NOT IN A PANEL SOMEWHERE ELSE (`gridEditing.tsx`). Click a\n// cell, or focus it and press Enter, and the Field's own editor opens in place;\n// Enter saves, Escape cancels, Tab saves and opens the next one. The save goes\n// through the one write door carrying the version the person started from, so\n// the STORE decides whether somebody else got there first — and when it did,\n// the cell shows their value with a Try again beside it. A row is deleted from\n// its own row menu, with the consequence named before the delete, and a new\n// record is one button that puts you straight into the first cell.\n//\n// Every refusal is the store's own sentence (`RefusalNotice`). A grid that\n// rendered \"no records\" because the door refused is the defect this package\n// exists to prevent, so the empty state and the refusal are different things\n// and both are shown.\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport {\n useFields,\n useRecords,\n useTable,\n type Field,\n type ReadRow,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport { MatrxDataTable } from \"@ai-matrx/design-system/data-table\";\nimport type { MatrxColumnDef } from \"@ai-matrx/design-system/data-table/types\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { editorKindFor, fieldTypeLabel } from \"./parity\";\nimport { fieldName, tableName } from \"./names\";\nimport { RecordValue } from \"./values\";\nimport { GridCell, useGridEditing, type GridEditing } from \"./gridEditing\";\n\nexport interface GridProps {\n tableId: Uuid;\n /** Rows per page. The table's own pagination handles the rest. */\n pageSize?: number | undefined;\n /** Opened when a row is clicked. A host that has a record page passes its own. */\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n /** SCR-2. Called when an admin clicks the \"+\" at the end of the headers. */\n onAddField?: (() => void) | undefined;\n /**\n * The host's whole-record form. Offered BY NAME when the store refuses an\n * empty record — a Table with a required Field cannot be added to one cell at\n * a time, and saying so beats a button that fails.\n */\n onNewRecordForm?: (() => void) | undefined;\n /** Extra toolbar content — the view switcher, the export menu, the view bar. */\n toolbarActions?: ReactNode | undefined;\n /** Editing in place is on by default; a read-only surface (a portal) turns it off. */\n editable?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport function Grid({\n tableId,\n pageSize = 50,\n onOpenRecord,\n onAddField,\n onNewRecordForm,\n toolbarActions,\n editable = true,\n className,\n}: GridProps) {\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [page, setPage] = useState(0);\n const records = useRecords(tableId, { pageSize, page });\n const rights = useTableRights(table.data);\n const canWrite = Boolean(editable) && rights.write;\n\n const rows = useMemo(() => records.data?.rows ?? [], [records.data]);\n const editing = useGridEditing({\n tableId,\n fields: fields.data ?? [],\n rows,\n reload: records.reload,\n canWrite,\n });\n\n const columns = useMemo<MatrxColumnDef<ReadRow>[]>(\n () => (fields.data ?? []).map((field) => columnForField(field, canWrite ? editing : null)),\n [fields.data, canWrite, editing],\n );\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n\n const loading = table.loading || fields.loading;\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* SCR-N-4 / the one-row header rule: the table's name, its row count and\n its controls on ONE line. No repeated name, no subtitle restating it. */}\n <div className=\"flex items-center gap-2\">\n <h2 className=\"truncate text-sm font-medium\">\n {table.data ? tableName(table.data) : <Skeleton className=\"h-4 w-32\" />}\n </h2>\n {records.data?.total !== null && records.data?.total !== undefined ? (\n <span className=\"text-xs text-muted-foreground\">{records.data.total}</span>\n ) : null}\n <div className=\"ml-auto flex items-center gap-1\">{toolbarActions}</div>\n </div>\n\n {records.error ? <RefusalNotice error={records.error} /> : null}\n\n {/* A delete or an add the store refused, in the store's own sentence, with\n the one control that can still get the person what they asked for. */}\n {editing.rowError ? (\n <RefusalNotice\n error={editing.rowError}\n actions={\n <div className=\"mt-1 flex gap-1\">\n {onNewRecordForm ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n editing.clearRowError();\n onNewRecordForm();\n }}\n >\n Fill it in on the full form\n </Button>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={editing.clearRowError}>\n Dismiss\n </Button>\n </div>\n }\n />\n ) : null}\n\n {!records.live ? (\n // Nothing fails silently: a list that stopped updating says so.\n <p className=\"text-xs text-muted-foreground\">{records.liveReason}</p>\n ) : null}\n\n <MatrxDataTable<ReadRow>\n data={rows}\n columns={columns}\n getRowId={(row) => row.id}\n isLoading={loading || records.loading}\n density={host.density ?? \"condensed\"}\n tableId={`records-grid-${tableId}`}\n stickyHeader\n pageSize={pageSize}\n {...(onOpenRecord ? { onRowOpen: (row: ReadRow) => onOpenRecord(row.id) } : {})}\n {...(canWrite\n ? {\n rowActions: (row: ReadRow) => (\n <DeleteRecordButton\n row={row}\n retentionDays={table.data?.retention_days ?? null}\n onDelete={() => editing.remove(row.id)}\n />\n ),\n }\n : {})}\n emptyState={{\n title: \"No records yet\",\n description: rights.write\n ? \"Add the first one and it appears here.\"\n : \"Nothing has been written to this table.\",\n }}\n toolbar={{\n search: true,\n searchPlaceholder: \"Search records\",\n // SCR-2 / SCR-4: PRESENT for an admin, ABSENT for everyone else.\n // There is no third state: this package ships no disabled variant of\n // these controls, so a member cannot be shown a dead one by mistake.\n actions: (\n <>\n {canWrite ? (\n <Button size=\"sm\" disabled={editing.busy} onClick={() => void editing.addRecord()}>\n {editing.busy ? \"Adding…\" : \"New record\"}\n </Button>\n ) : null}\n {rights.admin && onAddField ? <AddFieldButton onClick={onAddField} /> : null}\n </>\n ),\n }}\n />\n\n <Pager\n page={page}\n pageSize={pageSize}\n total={records.data?.total ?? null}\n rows={rows.length}\n onPage={setPage}\n />\n </div>\n );\n}\n\n/**\n * SCR-2. The \"+\" at the far right of the column headers. It exists only for a\n * holder of `admin`: the caller above decides, and there is no disabled variant\n * of this button anywhere in the package.\n */\nfunction AddFieldButton({ onClick }: { onClick: () => void }) {\n return (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onClick}\n aria-label=\"Add a field\"\n title=\"Add a field to this table\"\n >\n +\n </Button>\n );\n}\n\n/**\n * DELETING NAMES THE CONSEQUENCE BEFORE IT HAPPENS. One press asks; the second\n * one does it. The sentence is the store's own truth about this Table — a soft\n * delete that stays reversible for the Table's own retention window (REC-23),\n * or, when the Table declares none, the plain fact that it can be restored.\n */\nfunction DeleteRecordButton({\n row,\n retentionDays,\n onDelete,\n}: {\n row: ReadRow;\n retentionDays: number | null;\n onDelete: () => Promise<unknown>;\n}) {\n const [asking, setAsking] = useState(false);\n if (!asking) {\n return (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Delete this record\"\n title=\"Delete this record\"\n onClick={() => setAsking(true)}\n >\n Delete\n </Button>\n );\n }\n return (\n <span className=\"flex items-center gap-1 text-[11px]\">\n <span className=\"text-muted-foreground\">\n {retentionDays\n ? `Removes it from the table. Restorable for ${retentionDays} days.`\n : \"Removes it from the table. It can be restored from the record's history.\"}\n </span>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => {\n setAsking(false);\n void onDelete();\n }}\n >\n Delete\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setAsking(false)}>\n Keep\n </Button>\n <span className=\"sr-only\">{row.id}</span>\n </span>\n );\n}\n\nfunction Pager({\n page,\n pageSize,\n total,\n rows,\n onPage,\n}: {\n page: number;\n pageSize: number;\n total: number | null;\n rows: number;\n onPage: (page: number) => void;\n}) {\n const from = page * pageSize;\n const last = total === null ? rows < pageSize : from + rows >= total;\n if (page === 0 && last) return null;\n return (\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <Button size=\"sm\" variant=\"ghost\" disabled={page === 0} onClick={() => onPage(page - 1)}>\n Previous\n </Button>\n <span>\n {from + 1}–{from + rows}\n {total === null ? \"\" : ` of ${total}`}\n </span>\n <Button size=\"sm\" variant=\"ghost\" disabled={last} onClick={() => onPage(page + 1)}>\n Next\n </Button>\n </div>\n );\n}\n\n/**\n * One Field becomes one column. The header is the Field's own NAME — never its\n * key (`names.ts`) — and the cell is the value, rendered by its parity type and\n * editable in place when an editing session is passed.\n */\nexport function columnForField(field: Field, editing?: GridEditing | null): MatrxColumnDef<ReadRow> {\n const name = fieldName(field);\n return {\n id: field.key,\n header: name,\n label: name,\n accessorFn: (row) => row.document?.[field.key],\n sortable: true,\n filter: editorKindFor(field) === \"select\" || editorKindFor(field) === \"multi_select\" ? \"select\" : \"auto\",\n cell: (row) =>\n editing ? (\n <GridCell field={field} row={row} editing={editing} canWrite />\n ) : (\n <RecordValue field={field} value={row.document?.[field.key]} document={row.document} />\n ),\n headerClassName: \"whitespace-nowrap\",\n // The type is in the header's tooltip rather than a second header row: one\n // row of headers, always — and it is the parity type's own WORD, not a\n // token (`Long text`, never `long_text`).\n className: \"align-top\",\n ...({ title: fieldTypeLabel(field) } as Record<string, unknown>),\n };\n}\n","\"use client\";\n\n// src/ExportMenu.tsx — @ai-matrx/records-ui · SCR-31\n//\n// ANY VIEW EXPORTS AS CSV OR XLSX, CARRYING EXACTLY THE COLUMNS AND ROWS THE\n// READING PRINCIPAL MAY SEE — which is not a filter this component applies. The\n// rows it exports are the rows the READ DOOR returned, and the columns are the\n// Fields the store said APPLY. There is no wider read anywhere in this file, so\n// an export can never contain something the screen did not.\n//\n// The bytes are `@ai-matrx/records`' own `exportCsv` / `exportXlsx`, so an\n// export from a screen and an export from a script are the same file.\n\nimport { useState } from \"react\";\nimport { useFields, useRecords, type Field, type ReadRow, type ReadValue, type Uuid } from \"@ai-matrx/records/react\";\nimport { exportCsv, exportXlsx, type ExportRow } from \"@ai-matrx/records/core\";\nimport { AlchemyMenu } from \"@ai-matrx/alchemy/react\";\nimport { Button, cn } from \"@ai-matrx/design-system\";\nimport { RefusalLine } from \"./Refusal\";\n\nexport interface ExportMenuProps {\n tableId: Uuid;\n /** The rows on screen. Absent means \"this table's first page\", read the same way. */\n rows?: ReadRow[] | undefined;\n /** What the file is called. The table's name by default. */\n label?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * The rows, in the package's own `ExportRow` shape — the value AND its envelope,\n * so the exported cell can carry the store's own absence WORD instead of a blank\n * (VAL-2: \"never asked\" and \"refused\" are different facts, and the file says\n * which).\n */\nfunction toRows(fields: Field[], records: ReadRow[]): ExportRow[] {\n return records.map((record) => {\n const document = record.document ?? {};\n const envelopes = (document[\"_values\"] ?? {}) as Record<string, { absent?: string | null }>;\n const row: ExportRow = {};\n for (const field of fields) {\n const envelope = envelopes[field.key];\n row[field.key] = {\n field_key: field.key,\n value: document[field.key] ?? null,\n absent_reason: (envelope?.absent ?? null) as ReadValue[\"absent_reason\"],\n } as ReadValue;\n }\n return row;\n });\n}\n\nfunction download(name: string, mime: string, bytes: BlobPart) {\n const url = URL.createObjectURL(new Blob([bytes], { type: mime }));\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = name;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\nexport function ExportMenu({ tableId, rows, label, className }: ExportMenuProps) {\n const fields = useFields(tableId);\n const page = useRecords(tableId, { pageSize: 500 });\n const [failure, setFailure] = useState<string | null>(null);\n\n const records = rows ?? page.data?.rows ?? [];\n const name = label ?? \"records\";\n\n if (fields.error) return <RefusalLine error={fields.error} className={className} />;\n if (!rows && page.error) return <RefusalLine error={page.error} className={className} />;\n if (!fields.data || (!rows && !page.data)) {\n // The columns ARE the Fields and the rows are the read door's answer, so\n // there is no export to offer until both have arrived. A button that\n // produced a headerless or rowless file would be worse than a moment's wait.\n return <span className={cn(\"text-xs text-muted-foreground\", className)}>Reading this table…</span>;\n }\n\n const exported = () => toRows(fields.data ?? [], records);\n\n return (\n <div className={cn(\"flex items-center gap-1\", className)}>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => download(`${name}.csv`, \"text/csv;charset=utf-8\", exportCsv(fields.data ?? [], exported()))}\n >\n CSV\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n try {\n void exportXlsx(fields.data ?? [], exported(), name).then((bytes) =>\n download(\n `${name}.xlsx`,\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n bytes as unknown as BlobPart,\n ),\n );\n } catch (thrown) {\n // Nothing fails silently: say what broke and what to do instead.\n setFailure(\n `The spreadsheet could not be written (${thrown instanceof Error ? thrown.message : String(thrown)}). ` +\n `The CSV beside this button carries the same rows.`,\n );\n }\n }}\n >\n XLSX\n </Button>\n {/* The same menu every other surface on the platform carries. */}\n <AlchemyMenu\n label={name}\n sourceId={`records:${tableId}`}\n size=\"xs\"\n json={() => records.map((r) => r.document)}\n human={() => exportCsv(fields.data ?? [], exported())}\n />\n {failure ? <p className=\"text-xs text-destructive\">{failure}</p> : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/ImportWizard.tsx — @ai-matrx/records-ui · SCR-10, SCR-N-7\n//\n// MAP A FILE'S COLUMNS ONTO FIELDS, PREVIEW THE ROWS IT WILL WRITE, AND OFFER\n// ANY UNMAPPED COLUMN AS A FIELD PROPOSAL.\n//\n// The parsing and the matching are `@ai-matrx/records`' own `importCsv` /\n// `importXlsx`, so a file imported from a screen and a file imported from a\n// script land identically. An unmapped column is NEVER dropped quietly: it is\n// listed, and \"add this as a field\" sits beside it under the same right as the\n// grid's \"+\" (SCR-N-7) — absent, not disabled, for anybody else.\n//\n// Every row is written through the ONE write door, one at a time, and a row the\n// store refuses keeps its own refusal beside it. A partial import that pretended\n// to be a whole one is the failure this screen exists to make impossible.\n\nimport { useState } from \"react\";\nimport { useFields, useRecordMutation, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport { importCsv, importXlsx, type ParsedImport } from \"@ai-matrx/records/core\";\nimport { Badge, Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldName } from \"./names\";\n\nexport interface ImportWizardProps {\n tableId: Uuid;\n /** SCR-N-7: what \"add this as a field\" does. Absent means the offer is not made. */\n onProposeField?: ((header: string) => void) | undefined;\n onDone?: ((written: number) => void) | undefined;\n className?: string | undefined;\n}\n\ninterface RowOutcome {\n index: number;\n recordId: string | null;\n refusal: string | null;\n}\n\nexport function ImportWizard({ tableId, onProposeField, onDone, className }: ImportWizardProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const mutation = useRecordMutation();\n const [parsed, setParsed] = useState<ParsedImport | null>(null);\n const [outcomes, setOutcomes] = useState<RowOutcome[]>([]);\n const [reading, setReading] = useState<string | null>(null);\n\n const take = async (file: File) => {\n setReading(null);\n setOutcomes([]);\n try {\n const declared = fields.data ?? [];\n const result = file.name.toLowerCase().endsWith(\".xlsx\")\n ? await importXlsx(declared, await file.arrayBuffer())\n : importCsv(declared, await file.text());\n setParsed(result);\n } catch (thrown) {\n setReading(`That file could not be read: ${thrown instanceof Error ? thrown.message : String(thrown)}`);\n }\n };\n\n const write = async () => {\n if (!parsed) return;\n const done: RowOutcome[] = [];\n for (const [index, row] of parsed.rows.entries()) {\n const id = await mutation.write({ table_id: tableId, data: row });\n done.push({ index, recordId: id, refusal: id ? null : (mutation.error?.message ?? \"The store refused this row.\") });\n setOutcomes([...done]);\n }\n onDone?.(done.filter((d) => d.recordId).length);\n };\n\n const written = outcomes.filter((o) => o.recordId).length;\n const refused = outcomes.filter((o) => !o.recordId).length;\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Import</span>\n <span className=\"text-muted-foreground\">{table.data?.name}</span>\n {/* A file cannot be mapped before the store has said which Fields\n apply, so the chooser waits rather than matching against nothing and\n reporting every column as unmapped. It ALSO waits for the Table\n itself: the rights that decide whether \"add this as a field\" is\n offered are read from the Table, and a chooser that opened first\n could show an admin a mapping with the offer missing — a control\n silently absent for the one person who may use it. Both answers, or\n no chooser.\n (Found by the suite under load, 2026-09-18: the Fields arrived\n before the Table and the offer was not there.) */}\n {fields.data && table.data ? (\n <input\n type=\"file\"\n accept=\".csv,.xlsx\"\n aria-label=\"Choose a file to import\"\n className=\"ml-auto text-xs\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void take(file);\n }}\n />\n ) : (\n <span className=\"ml-auto text-muted-foreground\">\n {fields.data ? \"Reading this table…\" : \"Reading this table's fields…\"}\n </span>\n )}\n </div>\n\n {reading ? <p className=\"text-destructive\">{reading}</p> : null}\n\n {parsed ? (\n <>\n {/* The mapping, column by column, with nothing hidden. */}\n <ul className=\"flex flex-wrap gap-1\">\n {parsed.columns.map((column) => (\n <li key={column.header}>\n <Badge variant={column.field ? \"secondary\" : \"outline\"} className=\"gap-1 text-[11px] font-normal\">\n {column.header}\n <span className=\"opacity-60\">→</span>\n {column.field ? (\n column.field.label || column.field.key\n ) : (\n <span className=\"text-destructive\">no field</span>\n )}\n {/* SCR-N-7, and it is gated by the SAME right as the grid's \"+\". */}\n {!column.field && rights.admin && onProposeField ? (\n <button\n type=\"button\"\n className=\"underline underline-offset-2\"\n onClick={() => onProposeField(column.header)}\n >\n add as a field\n </button>\n ) : null}\n </Badge>\n </li>\n ))}\n </ul>\n\n {parsed.unmapped.length > 0 ? (\n <p className=\"text-muted-foreground\">\n {parsed.unmapped.length} column{parsed.unmapped.length === 1 ? \"\" : \"s\"} match no Field and{\" \"}\n {rights.admin && onProposeField\n ? \"can be added as fields above.\"\n : \"will not be written. Nothing is dropped quietly: the columns are listed above.\"}\n </p>\n ) : null}\n\n <Separator />\n\n {/* The preview: exactly the rows the write door will be handed. */}\n <p className=\"text-muted-foreground\">\n {parsed.rows.length} row{parsed.rows.length === 1 ? \"\" : \"s\"} to write\n </p>\n <div className=\"max-h-56 overflow-auto rounded border\">\n <table className=\"w-full\">\n <thead className=\"sticky top-0 bg-muted\">\n <tr>\n {(fields.data ?? []).map((field) => (\n <th key={field.id} className=\"px-2 py-1 text-left font-medium\">\n {fieldName(field)}\n </th>\n ))}\n <th className=\"px-2 py-1 text-left font-medium\">Result</th>\n </tr>\n </thead>\n <tbody>\n {parsed.rows.slice(0, 50).map((row, index) => {\n const outcome = outcomes.find((o) => o.index === index);\n return (\n <tr key={index} className=\"border-t\">\n {(fields.data ?? []).map((field) => (\n <td key={field.id} className=\"max-w-40 truncate px-2 py-1\">\n {row[field.key] ?? \"\"}\n </td>\n ))}\n <td className=\"px-2 py-1\">\n {outcome?.recordId ? (\n <span className=\"text-muted-foreground\">written</span>\n ) : outcome?.refusal ? (\n // The store's own sentence, on the row it refused.\n <span className=\"text-destructive\">{outcome.refusal}</span>\n ) : null}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {mutation.error && outcomes.length === 0 ? <RefusalNotice error={mutation.error} /> : null}\n\n <div className=\"flex items-center gap-2\">\n <Button size=\"sm\" disabled={mutation.saving || !rights.write} onClick={() => void write()}>\n {mutation.saving ? \"Writing…\" : `Write ${parsed.rows.length} rows`}\n </Button>\n {outcomes.length > 0 ? (\n <span className=\"text-muted-foreground\">\n {written} written{refused > 0 ? `, ${refused} refused — each one says why on its row` : \"\"}\n </span>\n ) : null}\n </div>\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/CustomFieldsSection.tsx — @ai-matrx/records-ui · SCR-12\n//\n// THE ONE LINE A STANDARD ENTITY PAGE ADDS.\n//\n// <CustomFieldsSection entityToken=\"agent\" recordId={agent.id} />\n//\n// A standard entity's page grows its organization's custom Fields in one\n// section, resolved from the Field records, WITH NO PER-ENTITY CODE. That is the\n// whole point: nobody writes a section per entity, and an organization that adds\n// a field to Agents sees it on every Agent page the same afternoon.\n//\n// FLD-8 / REC-34: a Field that extends a standard entity carries\n// `entity_definition_id`, and only entity and detail table types carry custom\n// fields at all. When a token carries none, this renders NOTHING — an empty\n// titled box on every page in the product would be worse than silence, and the\n// section says so in its own docs rather than on the screen.\n\nimport { useMemo, useState } from \"react\";\nimport { useFields, useRecord, useTable, useTables, type Uuid } from \"@ai-matrx/records/react\";\nimport { Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalLine } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { ProvenanceBadge, RecordValue } from \"./values\";\nimport { fieldName } from \"./names\";\n\nexport interface CustomFieldsSectionProps {\n /**\n * The Table the Fields extend. For a standard entity this is the Table record\n * that stands for that entity — the host passes it, because which entity a\n * page is showing is the page's own fact.\n *\n * A page that knows the entity's TOKEN rather than its id passes `entityToken`\n * instead, and this section resolves it: an entity page must not have to run\n * a lookup of its own to add one line.\n */\n tableId?: Uuid | undefined;\n /** The entity's registered token (REC-33), e.g. `party`. Resolved to its Table. */\n entityToken?: string | undefined;\n recordId: Uuid;\n /** The heading. One row, no subtitle restating it. */\n title?: string | undefined;\n className?: string | undefined;\n}\n\nexport function CustomFieldsSection({\n tableId,\n entityToken,\n recordId,\n title = \"Custom fields\",\n className,\n}: CustomFieldsSectionProps) {\n // A token is resolved through the same `tableList` door everything else uses.\n // A token this organization's store does not know is NOT an error a person\n // must act on — it means the entity has no Table here yet, and the section is\n // absent exactly as it is when the Table has no custom Fields.\n const all = useTables();\n const resolved = useMemo<Uuid | null>(() => {\n if (tableId) return tableId;\n if (!entityToken) return null;\n return all.data?.find((t) => t.slug === entityToken)?.id ?? null;\n }, [tableId, entityToken, all.data]);\n\n return resolved ? (\n <ResolvedCustomFields\n tableId={resolved}\n recordId={recordId}\n title={title}\n className={className}\n />\n ) : null;\n}\n\nfunction ResolvedCustomFields({\n tableId,\n recordId,\n title,\n className,\n}: {\n tableId: Uuid;\n recordId: Uuid;\n title: string;\n className?: string | undefined;\n}) {\n const fields = useFields(tableId);\n const record = useRecord(recordId);\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [editing, setEditing] = useState(false);\n\n // FLD-8: a Field that EXTENDS a standard entity is one whose\n // `entity_definition_id` names that entity's Table. That is the whole test —\n // there is no per-entity list of \"which fields are custom\" anywhere.\n const custom = useMemo(\n () => (fields.data ?? []).filter((field) => field.entity_definition_id === tableId),\n [fields.data, tableId],\n );\n\n // Nothing to grow: render nothing at all rather than an empty titled box.\n if (!fields.loading && custom.length === 0) return null;\n if (fields.error) return <RefusalLine error={fields.error} className={className} />;\n\n const document = record.data?.document;\n\n return (\n <section className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">{title}</h3>\n <span className=\"text-muted-foreground\">{custom.length}</span>\n {rights.write ? (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto\" onClick={() => setEditing((e) => !e)}>\n {editing ? \"Done\" : \"Edit\"}\n </Button>\n ) : null}\n </div>\n <Separator />\n {editing ? (\n <RecordForm\n tableId={tableId}\n recordId={recordId}\n onSaved={() => {\n setEditing(false);\n record.reload();\n }}\n />\n ) : (\n <dl className=\"grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5\">\n {custom.map((field) => (\n <div key={field.id} className=\"contents\">\n <dt className=\"flex items-baseline gap-1 truncate text-muted-foreground\">\n {fieldName(field)}\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </dt>\n <dd className=\"min-w-0\"><RecordValue field={field} value={document?.[field.key]} document={document} /></dd>\n </div>\n ))}\n </dl>\n )}\n </section>\n );\n}\n","\"use client\";\n\n// src/RecordForm.tsx — @ai-matrx/records-ui · SCR-N-1\n//\n// THE GENERIC CREATE / EDIT FORM, RESOLVED FROM THE FIELD RECORDS. Before it,\n// every create and edit form in the product was hand-written per feature, which\n// is why a custom table could not open a record at all.\n//\n// Two honest halves:\n// · BEFORE the write, the mirror (`predictWriteRefusals`) says what the store\n// is about to refuse, in the store's own sentence. It is not validation —\n// the store validates — it just says it half a second earlier.\n// · AFTER the write, whatever the store said is shown verbatim, including the\n// conflict object when somebody else wrote first.\n//\n// It never blocks a save on its own opinion: the mirror's sentences are shown,\n// and the write is still attempted, because the store is the one that decides.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport {\n useFields,\n useRecord,\n useRecordMutation,\n type Field,\n type RecordDocument,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport { predictWriteRefusals } from \"@ai-matrx/records/core\";\nimport { Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { FieldControl, FieldLabel } from \"./editors\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { ProvenanceBadge } from \"./values\";\nimport { useRecordVersion } from \"./systemTable\";\n\nexport interface RecordFormProps {\n tableId: Uuid;\n /** Absent means \"create\". Present means \"edit that record\". */\n recordId?: Uuid | undefined;\n /** FLD-10: which Fields apply is the store's decision, and it takes the record type. */\n recordType?: string | undefined;\n onSaved?: ((recordId: Uuid) => void) | undefined;\n onCancel?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function RecordForm({\n tableId,\n recordId,\n recordType,\n onSaved,\n onCancel,\n className,\n}: RecordFormProps) {\n const host = useRecordsUi();\n const fields = useFields(tableId, recordType);\n const existing = useRecord(recordId ?? null);\n const mutation = useRecordMutation();\n const [draft, setDraft] = useState<Record<string, unknown>>({});\n const [touched, setTouched] = useState(false);\n // REC-9: the version this form LOADED, so a second writer is TOLD rather than\n // overwritten. The read door answers documents, never versions.\n const loaded = useRecordVersion(recordId ?? null);\n const loadedVersion = loaded.version;\n\n // The record's own document is the starting draft. A form that started empty\n // over an existing record would silently propose blanking every field.\n useEffect(() => {\n const document = existing.data?.document;\n if (document) setDraft({ ...document });\n }, [existing.data?.record_id, loadedVersion]);\n\n const document = useMemo<RecordDocument>(() => {\n const out: RecordDocument = {};\n for (const [key, value] of Object.entries(draft)) {\n if (key.startsWith(\"_\")) continue;\n if (value !== undefined) out[key] = value;\n }\n return out;\n }, [draft]);\n\n const predicted = useMemo(\n () => (fields.data ? predictWriteRefusals({ fields: fields.data, document, ...(recordType ? { recordType } : {}) }) : []),\n [fields.data, document, recordType],\n );\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (existing.error) return <RefusalNotice error={existing.error} className={className} />;\n\n const save = async () => {\n setTouched(true);\n if (recordId) {\n const version = loadedVersion;\n const moved = await mutation.update({\n record_id: recordId,\n patch: document,\n ...(version === null ? {} : { expectedVersion: version }),\n });\n if (moved !== null) {\n // The store's own new version, so saving twice in a row is two saves\n // and not a conflict with yourself.\n loaded.note(moved);\n host.notify?.success(\"Saved\");\n existing.reload();\n onSaved?.(recordId);\n }\n return;\n }\n const written = await mutation.write({ table_id: tableId, data: document });\n if (written) {\n host.notify?.success(\"Saved\");\n onSaved?.(written);\n }\n };\n\n return (\n <form\n className={cn(\"flex min-w-0 flex-col gap-3\", className)}\n onSubmit={(e) => {\n e.preventDefault();\n void save();\n }}\n >\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {(fields.data ?? []).map((field) => (\n <FieldRow\n key={field.id}\n field={field}\n value={draft[field.key]}\n document={existing.data?.document}\n problems={touched ? predicted.filter((p) => p.field_key === field.key) : []}\n onChange={(value) => setDraft((d) => ({ ...d, [field.key]: value }))}\n />\n ))}\n </div>\n\n {/* A refusal with no field of its own — a size or envelope refusal. */}\n {touched\n ? predicted\n .filter((p) => !p.field_key)\n .map((p) => (\n <p key={p.message} className=\"text-xs text-destructive\">\n {p.message}\n </p>\n ))\n : null}\n\n {mutation.error ? (\n <RefusalNotice\n error={mutation.error}\n {...(mutation.conflict\n ? {\n actions: (\n <div className=\"mt-1 space-y-1\">\n {/* The conflict, field by field, as the store sent it. */}\n {Object.entries(mutation.conflict.contested_fields).map(([key, theirs]) => (\n <p key={key} className=\"font-mono text-[11px]\">\n {key}: yours {JSON.stringify(draft[key])} · theirs {JSON.stringify(theirs)}\n </p>\n ))}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n existing.reload();\n mutation.clearConflict();\n }}\n >\n Take theirs and start again\n </Button>\n </div>\n ),\n }\n : {})}\n />\n ) : null}\n\n <Separator />\n <div className=\"flex items-center gap-2\">\n <Button type=\"submit\" size=\"sm\" disabled={mutation.saving}>\n {mutation.saving ? \"Saving…\" : recordId ? \"Save\" : \"Create\"}\n </Button>\n {onCancel ? (\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n ) : null}\n </div>\n </form>\n );\n}\n\nfunction FieldRow({\n field,\n value,\n document,\n problems,\n onChange,\n}: {\n field: Field;\n value: unknown;\n document: RecordDocument | undefined;\n problems: Array<{ message: string }>;\n onChange: (value: unknown) => void;\n}) {\n const id = `field-${field.id}`;\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <FieldLabel field={field} htmlFor={id}>\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </FieldLabel>\n <FieldControl field={field} value={value} onChange={onChange} id={id} />\n {problems.map((problem) => (\n <p key={problem.message} className=\"text-xs text-destructive\">\n {problem.message}\n </p>\n ))}\n </div>\n );\n}\n","\"use client\";\n\n// src/systemTable.ts — @ai-matrx/records-ui\n//\n// THE PACKAGE'S OWN TABLES, MADE THE WAY EVERY OTHER TABLE IS MADE.\n//\n// A saved view, a queued action, a comment and a form are all RECORDS. They are\n// not a second storage system bolted onto the side of the record store, and\n// they are not rows this package writes into `platform.*` behind the store's\n// back — the data source port this package's client speaks has no insert on it\n// at all, on purpose. So each of them is an ordinary Table in the organization's\n// own store, declared once, through the store's own doors:\n//\n// 1. REC-1 — a Table has to live somewhere, and a Home is an ordinary record\n// in the person kernel, so a Home is written first (`record_write`).\n// 2. `table_declare` declares the Table under that Home.\n// 3. Each Field is a record in the field kernel carrying the new Table's id.\n//\n// That is exactly the sequence the store forced on us: declaring a Table with\n// no Home is refused by `custom._table_shape_guard` with \"a table has to live\n// somewhere - give it a home\". Nothing here works around a guard; it obeys one.\n//\n// WHAT THIS BUYS: a saved view is readable, exportable, historied, commentable\n// and agent-writable by every other component in this package, for free,\n// because it is a record like any other. An agent can write a whole view — or a\n// whole form — with one `record_write`.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport type { RecordsError, Uuid } from \"@ai-matrx/records\";\n\n/** One Field of a package-owned Table, in the store's own words. */\nexport interface SystemFieldSpec {\n key: string;\n label: string;\n /** FLD-1: one of the five behaviours. `text` covers the json-ish ones too. */\n type: \"text\" | \"range\" | \"list\" | \"relation\" | \"formula\";\n sort: number;\n required?: boolean;\n multi?: boolean;\n config?: Record<string, unknown>;\n}\n\nexport interface SystemTableSpec {\n /** The token this Table is addressed by. Every package table starts `records_ui_`. */\n slug: string;\n name: string;\n labelSingular: string;\n labelPlural: string;\n titleField: string;\n fields: SystemFieldSpec[];\n}\n\n/**\n * One in-flight declaration per (organization, slug), so two components that\n * mount at the same moment do not declare the same Table twice. Keyed by the\n * organization, never global: two organizations in two tabs never share one.\n */\nconst inFlight = new Map<string, Promise<Uuid>>();\n\n/** Find this organization's copy of a package-owned Table, declaring it the first time. */\nexport async function ensureSystemTable(\n client: RecordsClient,\n spec: SystemTableSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const cacheKey = `${client.config.organizationId}:${spec.slug}`;\n const running = inFlight.get(cacheKey);\n if (running) {\n try {\n return { ok: true, data: await running };\n } catch {\n inFlight.delete(cacheKey);\n }\n }\n\n const tables = await client.tableList();\n if (!tables.ok) return tables;\n const found = tables.data.find((t) => t.slug === spec.slug);\n if (found) {\n // A PACKAGE TABLE GROWS. A later version of this package declares a Field\n // the organization's copy was made without, and an organization that got\n // its copy first would otherwise be the one where the new Field silently\n // does not exist. So every load reconciles: the Fields in the spec that\n // the Table has not got are added, through the same two writes a Field is\n // always made with. Nothing is ever renamed or removed here.\n const grown = await addMissingFields(client, spec, found.id);\n if (!grown.ok) return grown;\n // A PACKAGE TABLE ALSO CHANGES SHAPE. Adding what is missing is only half\n // of level: a Field the organization already holds can carry a DIFFERENT\n // behaviour from the one this version of the package declares, and then\n // every write of that Field is refused by the store for a reason the\n // person cannot act on. See `reconcileFieldShapes`.\n const levelled = await reconcileFieldShapes(client, spec, found.id);\n if (!levelled.ok) return levelled;\n return { ok: true, data: found.id };\n }\n\n let settle: (id: Uuid) => void = () => undefined;\n let fail: (reason: unknown) => void = () => undefined;\n const pending = new Promise<Uuid>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n // The refusal is RETURNED, below, as this package's never-throw envelope.\n // Without this the same refusal is also an unhandled promise rejection on\n // every host that never happened to have a second caller waiting here — a\n // red console (and, under a test runner, a failed run) for a refusal that\n // was in fact reported properly.\n pending.catch(() => undefined);\n inFlight.set(cacheKey, pending);\n\n const declared = await declare(client, spec);\n if (declared.ok) settle(declared.data);\n else {\n fail(declared.error);\n inFlight.delete(cacheKey);\n }\n return declared;\n}\n\n/**\n * The Fields of `spec` the organization's copy of this Table has not got yet,\n * added the way a Field is always added: the Table's own declaration first\n * (REC-1 — the Table declares its fields), then the definition in the field\n * kernel. Idempotent, and a no-op for a Table that is already level.\n */\nasync function addMissingFields(\n client: RecordsClient,\n spec: SystemTableSpec,\n tableId: Uuid,\n): Promise<{ ok: true; data: true } | { ok: false; error: RecordsError }> {\n const held = await client.fields({ table_id: tableId });\n if (!held.ok) return held;\n const have = new Set(held.data.map((f) => f.key));\n const missing = spec.fields.filter((f) => !have.has(f.key));\n if (missing.length === 0) return { ok: true, data: true };\n\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n const declaration = [...held.data.map((f) => ({ name: f.key })), ...missing.map((f) => ({ name: f.key }))];\n const redeclared = await client.recordUpdate({ record_id: tableId, patch: { fields: declaration } });\n if (!redeclared.ok) return redeclared;\n\n for (const field of missing) {\n const written = await client.recordWrite({\n table_id: fieldKernel.data,\n data: fieldDocument(field, tableId),\n });\n if (!written.ok) return written;\n }\n return { ok: true, data: true };\n}\n\n/**\n * THE FIELD THAT CHANGED BEHAVIOUR UNDER AN ORGANIZATION THAT ALREADY HAD ONE.\n *\n * Found live on 2026-09-19: `ActionInbox` could not record an outcome in one\n * organization, because that organization's copy of `records_ui_action` held\n * `status` as a `relation` while this package declares it `text`. Every write\n * of an outcome was refused `22P02 invalid input syntax for type uuid: \"open\"`\n * — the store was right, the package was the one out of date, and\n * `addMissingFields` never looked at a Field it already had.\n *\n * So the reconciliation is two questions, not one: which Fields are MISSING,\n * and which Fields are THERE WITH THE WRONG SHAPE. Shape here means exactly the\n * two properties that decide what a value is made of and therefore what the\n * store will accept — the behaviour (FLD-1) and whether it is multi (FLD-2).\n *\n * WHAT IS DELIBERATELY NOT RECONCILED: label, sort, required, config. Those are\n * presentation and policy, an organization may legitimately have moved them,\n * and none of them can make a write fail. Nothing is ever renamed or removed\n * here — this only ever moves a Field back onto the behaviour the package's own\n * components write against.\n */\nasync function reconcileFieldShapes(\n client: RecordsClient,\n spec: SystemTableSpec,\n tableId: Uuid,\n): Promise<{ ok: true; data: true } | { ok: false; error: RecordsError }> {\n const held = await client.fields({ table_id: tableId });\n if (!held.ok) return held;\n const byKey = new Map(held.data.map((f) => [f.key, f]));\n\n for (const field of spec.fields) {\n const have = byKey.get(field.key);\n if (!have) continue; // `addMissingFields` owns that half and already ran.\n const patch: Record<string, unknown> = {};\n if (have.type !== field.type) patch.type = field.type;\n if (have.multi !== (field.multi ?? false)) patch.multi = field.multi ?? false;\n if (Object.keys(patch).length === 0) continue;\n\n // The Field definition is an ordinary record in the field kernel, so it is\n // levelled through the ordinary write door — never a second storage path.\n const written = await client.recordUpdate({ record_id: have.id, patch });\n // A Field this package cannot level is a Table whose writes will keep being\n // refused, so the refusal is reported rather than swallowed.\n if (!written.ok) return written;\n }\n return { ok: true, data: true };\n}\n\n/** One Field record's document — the same one whether it is declared with the Table or added later. */\nfunction fieldDocument(field: SystemFieldSpec, tableId: Uuid): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: field.type,\n sort: field.sort,\n required: field.required ?? false,\n multi: field.multi ?? false,\n dated: false,\n rules: [],\n config: field.config ?? {},\n source: \"manual\",\n depends_on: [],\n sensitivity: \"internal\",\n source_config: {},\n context_policy: \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n };\n}\n\nasync function declare(\n client: RecordsClient,\n spec: SystemTableSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const personKernel = await client.personKernelId();\n if (!personKernel.ok) return personKernel;\n\n const home = await client.recordWrite({\n table_id: personKernel.data,\n data: { name: `${spec.name} Home` },\n });\n if (!home.ok) return home;\n\n const table = await client.tableDeclare({\n homeId: home.data,\n spec: {\n name: spec.name,\n slug: spec.slug,\n type: \"entity\",\n label_singular: spec.labelSingular,\n label_plural: spec.labelPlural,\n display: \"list\",\n weight: \"light\",\n ordered: false,\n row_order: \"manual\",\n title_field: spec.titleField,\n retention_days: 365,\n // AGT-1: the whole point is that an agent writes a view or a form in one\n // call, so a package-owned Table is agent-writable by declaration.\n agent_writable: true,\n default_sort: [{ field: spec.titleField, direction: \"asc\" }],\n fields: spec.fields.map((f) => ({ name: f.key })),\n },\n });\n if (!table.ok) return table;\n\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n for (const field of spec.fields) {\n const written = await client.recordWrite({\n table_id: fieldKernel.data,\n data: fieldDocument(field, table.data),\n });\n // A Field the store refused is a Table that would quietly lose a column, so\n // it is reported rather than skipped.\n if (!written.ok) return written;\n }\n\n return { ok: true, data: table.data };\n}\n\nexport interface UseSystemTableState {\n tableId: Uuid | null;\n loading: boolean;\n error: RecordsError | null;\n}\n\n/** The hook every package-owned component opens with. */\nexport function useSystemTable(spec: SystemTableSpec): UseSystemTableState {\n const client = useRecordsClient();\n const [state, setState] = useState<UseSystemTableState>({ tableId: null, loading: true, error: null });\n const slug = spec.slug;\n const stable = useMemo(() => spec, [slug]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n let cancelled = false;\n setState({ tableId: null, loading: true, error: null });\n void ensureSystemTable(client, stable).then((result) => {\n if (cancelled) return;\n setState(\n result.ok\n ? { tableId: result.data, loading: false, error: null }\n : { tableId: null, loading: false, error: result.error },\n );\n });\n return () => {\n cancelled = true;\n };\n }, [client, stable]);\n\n return state;\n}\n\n/**\n * THE VERSION OF THE ONE RECORD BEING EDITED.\n *\n * The read door (`custom.read_records`) answers documents, never versions —\n * deliberately, because a version is a fact about the row and not about what\n * this reader may see. A screen that saves optimistically still needs the\n * version it LOADED, so it reads it here, for the one record it is editing and\n * never for a list, through `custom.io_revisions`.\n *\n * `null` is an honest answer: the save then carries no expected version and is\n * the store's ordinary last-writer-wins write. It is never a guess.\n */\n/** What `useRecordVersion` hands a screen that writes the record more than once. */\nexport interface TrackedVersion {\n /** The version this screen is writing against, or `null` when none was read. */\n version: number | null;\n /**\n * TELL IT THE STORE MOVED. Every successful write answers the record's NEW\n * version; a screen that does not hand it back here will write against the\n * old one next time and the store will — correctly — refuse it as a conflict\n * with somebody who turns out to be the same person. Measured 2026-09-19:\n * switching a saved view's layout twice in a row did exactly that.\n */\n note: (version: number) => void;\n}\n\nexport function useRecordVersion(recordId: Uuid | null | undefined): TrackedVersion {\n const client = useRecordsClient();\n const [version, setVersion] = useState<number | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setVersion(null);\n if (!recordId) return;\n void client.revisions({ record_id: recordId }).then((answered) => {\n if (cancelled || !answered.ok) return;\n const newest = answered.data.reduce<number | null>(\n (held, row) => (held === null || row.version > held ? row.version : held),\n null,\n );\n setVersion(newest);\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId]);\n\n return { version, note: setVersion };\n}\n","\"use client\";\n\n// src/FieldEditor.tsx — @ai-matrx/records-ui · SCR-9\n//\n// ADDING A COLUMN, WHICH IS THE FIRST THING ANYBODY DOES WITH A TABLE.\n//\n// On 19 September this panel refused every column a person tried to add — a\n// Number and a Date with \"the table does not declare a field called day_rate —\n// declare it there first\", a Person as though it were a formula, and a choice\n// list with \"has to say which table its choices come from\" and nowhere to say\n// it. One cause: the panel assembled a Field DOCUMENT itself and wrote it with\n// the ordinary record writer, which can neither tell the Table about the field\n// nor stamp the row as a field. Both of those are the store's to do, and now it\n// does them: `custom.field_declare` takes what a person knows — a type, a name,\n// and for a choice list the choices — and turns it into the document its own\n// guards demand.\n//\n// So this panel's whole job is to collect an INTENTION. It never writes a\n// behaviour, a format, a unit, a relation target, a relation maximum, a\n// compute_on or a pattern Rule; every one of those is the store's answer to the\n// type a person picked, and a screen that answered them itself is a second\n// place for the thirteen types to be wrong.\n//\n// The key is derived from the name and shown, never demanded: a blank, unmarked,\n// required box that refused the first attempt every time is what a person hit\n// before anything else on this panel.\n\nimport { useMemo, useState } from \"react\";\nimport {\n type ContextPolicy,\n type Field,\n type FieldPatch,\n type FieldRule,\n type FieldSensitivity,\n type NewFieldDeclaration,\n type Uuid,\n} from \"@ai-matrx/records\";\nimport { useFieldMutation, useFields, useTable } from \"@ai-matrx/records/react\";\nimport {\n BasicInput,\n BasicTextarea,\n Button,\n Checkbox,\n Label,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n Separator,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { editorKindFor } from \"./parity\";\nimport {\n FIELD_TYPE_CHOICES,\n FIELD_TYPE_GROUPS,\n fieldTypeChoice,\n isPlainFieldType,\n type PickableFieldType,\n} from \"./fieldTypes\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldName } from \"./names\";\n\nconst RULE_KINDS: { kind: FieldRule[\"kind\"]; label: string }[] = [\n { kind: \"min\", label: \"At least\" },\n { kind: \"max\", label: \"At most\" },\n { kind: \"length\", label: \"No longer than\" },\n { kind: \"pattern\", label: \"Looks like\" },\n { kind: \"equals_field\", label: \"Same as the column\" },\n { kind: \"differs_from_field\", label: \"Different from the column\" },\n];\n\n/** FLD-12, in the words the setting actually means to the person setting it. */\nconst SENSITIVITIES: { value: string; label: string }[] = [\n { value: \"public\", label: \"Anyone who can open the record\" },\n { value: \"internal\", label: \"People in this organization\" },\n { value: \"confidential\", label: \"People who have been given the record\" },\n { value: \"restricted\", label: \"Owners and administrators only\" },\n];\n\nconst AGENT_VISIBILITY: { value: string; label: string }[] = [\n { value: \"include\", label: \"Yes, an assistant can read it\" },\n { value: \"summarize\", label: \"Only a summary of it\" },\n { value: \"on_request\", label: \"Only when somebody asks for it\" },\n { value: \"exclude\", label: \"No, keep it away from assistants\" },\n];\n\nconst ROLLUP_OPERATIONS: { value: NonNullable<NewFieldDeclaration[\"agg\"]>; label: string }[] = [\n { value: \"count\", label: \"How many there are\" },\n { value: \"sum\", label: \"The total of\" },\n { value: \"avg\", label: \"The average of\" },\n { value: \"min\", label: \"The smallest\" },\n { value: \"max\", label: \"The largest\" },\n];\n\nconst FORMULA_OPERATIONS: { value: string; label: string; joins: boolean }[] = [\n { value: \"concat\", label: \"Join them together\", joins: true },\n { value: \"add\", label: \"Add them up\", joins: true },\n { value: \"sub\", label: \"Take the second from the first\", joins: false },\n { value: \"mul\", label: \"Multiply them\", joins: true },\n { value: \"div\", label: \"Divide the first by the second\", joins: false },\n];\n\n/** `Day rate` → `day_rate`. Shown, so nothing about it is a surprise. */\nexport function keyFor(label: string): string {\n const token = label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 48);\n if (token === \"\") return \"\";\n return /^[a-z]/.test(token) ? token : `f_${token}`;\n}\n\nexport interface FieldEditorProps {\n tableId: Uuid;\n /** The Field being edited. Absent means a new one. */\n field?: Field | undefined;\n onSaved?: (() => void) | undefined;\n onCancel?: (() => void) | undefined;\n /** Called after the store has accepted the removal, so the list can re-read. */\n onRemoved?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }: FieldEditorProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const mutation = useFieldMutation();\n\n const [label, setLabel] = useState(field?.label ?? \"\");\n const [type, setType] = useState<PickableFieldType>(() => startingType(field));\n const [required, setRequired] = useState(field?.required ?? false);\n const [multi, setMulti] = useState(field?.multi ?? false);\n const [dated, setDated] = useState(field?.dated ?? false);\n const [sensitivity, setSensitivity] = useState(String(field?.sensitivity ?? \"internal\"));\n const [contextPolicy, setContextPolicy] = useState(String(field?.context_policy ?? \"include\"));\n const [rules, setRules] = useState<FieldRule[]>(field?.rules ?? []);\n const [optionText, setOptionText] = useState(\"\");\n const [unit, setUnit] = useState(field?.unit ?? \"$\");\n const [withTime, setWithTime] = useState(String(field?.config?.[\"kind\"] ?? \"date\") === \"datetime\");\n const [via, setVia] = useState(String(field?.config?.[\"via\"] ?? \"\"));\n const [pick, setPick] = useState(String(field?.config?.[\"pick\"] ?? \"\"));\n const [agg, setAgg] = useState<NonNullable<NewFieldDeclaration[\"agg\"]>>(\n (field?.config?.[\"agg\"] as NewFieldDeclaration[\"agg\"]) ?? \"count\",\n );\n const [of, setOf] = useState(String(field?.config?.[\"of\"] ?? \"\"));\n const [formulaOp, setFormulaOp] = useState(\"concat\");\n const [formulaFields, setFormulaFields] = useState<string[]>([]);\n const [askingToRemove, setAskingToRemove] = useState(false);\n\n const others = useMemo(\n () => (fields.data ?? []).filter((f) => f.id !== field?.id),\n [fields.data, field?.id],\n );\n const relations = useMemo(() => others.filter((f) => f.type === \"relation\"), [others]);\n const manyRelations = useMemo(() => relations.filter((f) => f.multi), [relations]);\n const choice = fieldTypeChoice(type);\n const editing = Boolean(field);\n // The key is DERIVED and shown, never asked for: the blank, unmarked, required\n // box it replaces refused the first attempt on this panel every single time.\n const derivedKey = field?.key ?? keyFor(label);\n\n // SCR-4: a person who does not administer the table never sees this panel.\n if (!rights.admin) {\n return (\n <p className={cn(\"text-xs text-muted-foreground\", className)}>\n {/* Honest, not dead: the reason, in a sentence. */}\n {rights.reason}\n </p>\n );\n }\n\n const options = optionText\n .split(\"\\n\")\n .map((word) => word.trim())\n .filter((word) => word !== \"\");\n\n const save = async () => {\n if (editing && field) {\n const patch: FieldPatch = {\n label,\n required,\n dated,\n sensitivity: sensitivity as FieldSensitivity,\n context_policy: contextPolicy as ContextPolicy,\n rules,\n ...(unitApplies(type) ? { unit } : {}),\n // An empty box means \"leave the choices alone\"; a list replaces them.\n ...(optionText.trim() === \"\" ? {} : { options }),\n };\n const written = await mutation.update({ field_id: field.id, patch });\n if (written !== null) onSaved?.();\n return;\n }\n const spec: NewFieldDeclaration = {\n label,\n ...(isPlainFieldType(type) ? { plain: type } : { parity_type: type }),\n required,\n dated,\n multi: multiApplies(type) ? multi : type === \"multi_select\",\n sensitivity: sensitivity as FieldSensitivity,\n context_policy: contextPolicy as ContextPolicy,\n rules,\n ...(type === \"select\" || type === \"multi_select\" ? { options } : {}),\n ...(type === \"currency\" ? { unit } : {}),\n ...(type === \"datetime\" ? { kind: withTime ? (\"datetime\" as const) : (\"date\" as const) } : {}),\n ...(type === \"lookup\" ? { via, pick } : {}),\n ...(type === \"rollup\" ? { via, agg, ...(agg === \"count\" ? {} : { of }) } : {}),\n ...(type === \"formula\" ? { expr: formulaExpression(formulaOp, formulaFields) } : {}),\n };\n const written = await mutation.declare({ table_id: tableId, spec });\n if (written !== null) onSaved?.();\n };\n\n const remove = async () => {\n if (!field) return;\n const gone = await mutation.retire({ field_id: field.id });\n setAskingToRemove(false);\n if (gone) (onRemoved ?? onSaved)?.();\n };\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-3 text-xs\", className)}>\n {/* One row of header: what this is, and nothing restating it. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{field ? `Field · ${fieldName(field)}` : \"New field\"}</span>\n <span className=\"ml-auto text-muted-foreground\">{table.data?.name}</span>\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Name</Label>\n <BasicInput\n value={label}\n autoFocus\n aria-label=\"Field name\"\n placeholder=\"Day rate\"\n onChange={(e) => setLabel(e.target.value)}\n />\n <p className=\"text-[11px] text-muted-foreground\">What people will read at the top of the column.</p>\n </label>\n\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">What it holds</Label>\n <Select\n value={type}\n disabled={editing}\n onValueChange={(next) => setType(next as PickableFieldType)}\n >\n <SelectTrigger size=\"sm\" aria-label=\"What this field holds\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FIELD_TYPE_GROUPS.map((group) => (\n <SelectGroup key={group}>\n <SelectLabel>{group}</SelectLabel>\n {FIELD_TYPE_CHOICES.filter((c) => c.group === group).map((c) => (\n <SelectItem key={c.id} value={c.id}>\n {c.label}\n </SelectItem>\n ))}\n </SelectGroup>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-[11px] text-muted-foreground\">\n {editing\n ? \"What a column holds cannot be changed here — every value already saved would have to be converted. Add a new column and move the values across.\"\n : (choice?.explanation ?? \"\")}\n </p>\n </div>\n </div>\n\n {/* WHAT THE PANEL ASKS FOR NEXT depends entirely on the answer above, and\n nothing else on this panel knows the difference between the sixteen. */}\n {!editing || type === \"select\" || type === \"multi_select\" ? (\n <TypeQuestions\n type={type}\n editing={editing}\n optionText={optionText}\n setOptionText={setOptionText}\n unit={unit}\n setUnit={setUnit}\n withTime={withTime}\n setWithTime={setWithTime}\n via={via}\n setVia={setVia}\n pick={pick}\n setPick={setPick}\n agg={agg}\n setAgg={setAgg}\n of={of}\n setOf={setOf}\n formulaOp={formulaOp}\n setFormulaOp={setFormulaOp}\n formulaFields={formulaFields}\n setFormulaFields={setFormulaFields}\n relations={relations}\n manyRelations={manyRelations}\n others={others}\n existingOptionsTable={Boolean(field?.options_table_id ?? field?.config?.[\"options_table_id\"])}\n />\n ) : null}\n\n <div className=\"flex flex-wrap items-center gap-4\">\n <label className=\"flex items-center gap-1.5\">\n <Checkbox\n checked={required}\n aria-label=\"Every record has to have one\"\n onCheckedChange={(v) => setRequired(v === true)}\n />\n Every record has to have one\n </label>\n {multiApplies(type) ? (\n <label className=\"flex items-center gap-1.5\">\n <Checkbox\n checked={multi}\n disabled={editing}\n aria-label=\"Can hold more than one\"\n onCheckedChange={(v) => setMulti(v === true)}\n />\n Can hold more than one\n </label>\n ) : null}\n <label className=\"flex items-center gap-1.5\">\n <Checkbox\n checked={dated}\n aria-label=\"Each value has its own date\"\n onCheckedChange={(v) => setDated(v === true)}\n />\n Each value has its own date\n </label>\n </div>\n\n {!editing ? (\n <p className=\"text-[11px] text-muted-foreground\">\n Saved under the name <span className=\"font-mono\">{derivedKey || \"—\"}</span>, which is how the\n records find it. It is made from the name and you will not need it again.\n </p>\n ) : null}\n\n <Separator />\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Who can see what is in it</Label>\n <Select value={sensitivity} onValueChange={setSensitivity}>\n <SelectTrigger size=\"sm\" aria-label=\"Who can see what is in it\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SENSITIVITIES.map((row) => (\n <SelectItem key={row.value} value={row.value}>\n {row.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Can an assistant read it</Label>\n <Select value={contextPolicy} onValueChange={setContextPolicy}>\n <SelectTrigger size=\"sm\" aria-label=\"Can an assistant read it\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {AGENT_VISIBILITY.map((row) => (\n <SelectItem key={row.value} value={row.value}>\n {row.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <Separator />\n\n {/* FLD-3: a constraint is a RULE attached to the Field, never a behaviour. */}\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">What counts as a good value</span>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"ml-auto\"\n onClick={() => setRules([...rules, { kind: \"min\", value: 0 }])}\n >\n Add a check\n </Button>\n </div>\n {rules.length === 0 ? (\n <p className=\"text-muted-foreground\">No checks. Anything this kind of column can hold will be accepted.</p>\n ) : null}\n {rules.map((rule, index) => (\n <div key={`${rule.kind}-${index}`} className=\"flex items-center gap-1\">\n <Select\n value={rule.kind}\n onValueChange={(kind) =>\n setRules(rules.map((r, i) => (i === index ? { ...r, kind: kind as FieldRule[\"kind\"] } : r)))\n }\n >\n <SelectTrigger size=\"sm\" className=\"w-52\" aria-label={`Check ${index + 1}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RULE_KINDS.map((row) => (\n <SelectItem key={row.kind} value={row.kind}>\n {row.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <BasicInput\n className=\"h-8\"\n value={String(rule.value ?? \"\")}\n aria-label={`Check ${index + 1} value`}\n onChange={(e) => setRules(rules.map((r, i) => (i === index ? { ...r, value: e.target.value } : r)))}\n />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Remove check ${index + 1}`}\n onClick={() => setRules(rules.filter((_, i) => i !== index))}\n >\n ×\n </Button>\n </div>\n ))}\n </div>\n\n {mutation.error ? <RefusalNotice error={mutation.error} /> : null}\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button size=\"sm\" disabled={mutation.saving || label.trim() === \"\"} onClick={() => void save()}>\n {mutation.saving ? \"Saving…\" : field ? \"Save field\" : \"Add field\"}\n </Button>\n {onCancel ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n ) : null}\n {field ? (\n <div className=\"ml-auto flex items-center gap-2\">\n {askingToRemove ? (\n <>\n {/* Destructive, so the consequence is named BEFORE it happens. */}\n <span className=\"text-destructive\">\n Removing {fieldName(field)} takes it off every record of this table. The values stay in\n the record&apos;s history and nothing else is deleted.\n </span>\n <Button size=\"sm\" variant=\"destructive\" disabled={mutation.saving} onClick={() => void remove()}>\n Remove it\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setAskingToRemove(false)}>\n Keep it\n </Button>\n </>\n ) : (\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAskingToRemove(true)}>\n Remove this field\n </Button>\n )}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\n/** Whether \"can hold more than one\" is a question for this type at all. */\nfunction multiApplies(type: PickableFieldType): boolean {\n return type === \"member\" || type === \"attachment\" || type === \"text\";\n}\n\nfunction unitApplies(type: PickableFieldType): boolean {\n return type === \"currency\";\n}\n\n/** Which of the sixteen an existing Field already is. */\nfunction startingType(field: Field | undefined): PickableFieldType {\n if (!field) return \"text\";\n const kind = editorKindFor(field);\n if (fieldTypeChoice(kind)) return kind as PickableFieldType;\n return \"text\";\n}\n\n/**\n * REC-15 / REC-17: a Rule expression is an object of nodes, and it points at a\n * Field BY ITS ID, never by its name — a name changes and the rule would stop\n * resolving. The panel therefore collects columns, not text.\n */\nfunction formulaExpression(op: string, fieldIds: string[]): Record<string, unknown> {\n const args = fieldIds.filter((id) => id !== \"\").map((id) => ({ field: id }));\n if (args.length === 0) return { op, args: [{ const: \"\" }] };\n return { op, args };\n}\n\nfunction TypeQuestions(props: {\n type: PickableFieldType;\n editing: boolean;\n optionText: string;\n setOptionText: (value: string) => void;\n unit: string;\n setUnit: (value: string) => void;\n withTime: boolean;\n setWithTime: (value: boolean) => void;\n via: string;\n setVia: (value: string) => void;\n pick: string;\n setPick: (value: string) => void;\n agg: NonNullable<NewFieldDeclaration[\"agg\"]>;\n setAgg: (value: NonNullable<NewFieldDeclaration[\"agg\"]>) => void;\n of: string;\n setOf: (value: string) => void;\n formulaOp: string;\n setFormulaOp: (value: string) => void;\n formulaFields: string[];\n setFormulaFields: (value: string[]) => void;\n relations: Field[];\n manyRelations: Field[];\n others: Field[];\n existingOptionsTable: boolean;\n}) {\n const { type } = props;\n\n if (type === \"select\" || type === \"multi_select\") {\n return (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">The choices</Label>\n <BasicTextarea\n rows={4}\n className=\"text-xs\"\n aria-label=\"The choices\"\n placeholder={\"Open\\nIn progress\\nClosed\"}\n value={props.optionText}\n onChange={(e) => props.setOptionText(e.target.value)}\n />\n <p className=\"text-[11px] text-muted-foreground\">\n {props.editing\n ? props.existingOptionsTable\n ? \"One per line. Leave this empty to keep the choices as they are; type a list and it replaces them, keeping the ones that are still here.\"\n : \"One per line. These become this field's choices.\"\n : \"One per line. They are saved with the field — you do not have to make a table for them.\"}\n </p>\n </div>\n );\n }\n\n if (type === \"currency\") {\n return (\n <label className=\"flex max-w-[16rem] flex-col gap-1\">\n <Label className=\"text-xs\">The currency</Label>\n <BasicInput\n value={props.unit}\n aria-label=\"The currency\"\n placeholder=\"$\"\n onChange={(e) => props.setUnit(e.target.value)}\n />\n <p className=\"text-[11px] text-muted-foreground\">\n Shown with every amount, everywhere the value appears — including where an assistant reads it.\n </p>\n </label>\n );\n }\n\n if (type === \"datetime\") {\n return (\n <label className=\"flex items-center gap-1.5\">\n <Checkbox\n checked={props.withTime}\n aria-label=\"Include a time of day\"\n onCheckedChange={(v) => props.setWithTime(v === true)}\n />\n Include a time of day, not just the day\n </label>\n );\n }\n\n if (type === \"lookup\" || type === \"rollup\") {\n const usable = type === \"rollup\" ? props.manyRelations : props.relations;\n if (usable.length === 0) {\n // NEVER A DEAD CONTROL. The reason, and the thing to do about it.\n return (\n <p className=\"text-[11px] text-muted-foreground\">\n {type === \"rollup\"\n ? \"This kind of column works something out from records this one points at, and this table has no column yet that points at several records. Add a Person or File column that can hold more than one first.\"\n : \"This kind of column reads a value from a record this one points at, and this table has no column yet that points at another record. Add a Person or File column first.\"}\n </p>\n );\n }\n return (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">{type === \"rollup\" ? \"Across the records in\" : \"Read it from\"}</Label>\n <Select value={props.via} onValueChange={props.setVia}>\n <SelectTrigger size=\"sm\" aria-label={type === \"rollup\" ? \"Across the records in\" : \"Read it from\"}>\n <SelectValue placeholder=\"Choose a column\" />\n </SelectTrigger>\n <SelectContent>\n {usable.map((f) => (\n <SelectItem key={f.id} value={f.key}>\n {fieldName(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {type === \"lookup\" ? (\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">The value to read</Label>\n <BasicInput\n value={props.pick}\n aria-label=\"The value to read\"\n placeholder=\"name\"\n onChange={(e) => props.setPick(e.target.value)}\n />\n <p className=\"text-[11px] text-muted-foreground\">\n The column on the other record whose value is borrowed.\n </p>\n </label>\n ) : (\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">What to work out</Label>\n <Select value={props.agg} onValueChange={(v) => props.setAgg(v as never)}>\n <SelectTrigger size=\"sm\" aria-label=\"What to work out\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ROLLUP_OPERATIONS.map((row) => (\n <SelectItem key={row.value} value={row.value}>\n {row.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {props.agg !== \"count\" ? (\n <BasicInput\n className=\"mt-1\"\n value={props.of}\n aria-label=\"Of which value\"\n placeholder=\"amount\"\n onChange={(e) => props.setOf(e.target.value)}\n />\n ) : null}\n </div>\n )}\n </div>\n );\n }\n\n if (type === \"formula\") {\n if (props.others.length === 0) {\n return (\n <p className=\"text-[11px] text-muted-foreground\">\n A worked-out column needs other columns to work from, and this table has none yet.\n </p>\n );\n }\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">What to do</Label>\n <Select value={props.formulaOp} onValueChange={props.setFormulaOp}>\n <SelectTrigger size=\"sm\" className=\"max-w-[18rem]\" aria-label=\"What to do\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FORMULA_OPERATIONS.map((row) => (\n <SelectItem key={row.value} value={row.value}>\n {row.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label className=\"text-xs\">Which columns</Label>\n <div className=\"flex flex-wrap gap-1\">\n {props.others.map((f) => {\n const picked = props.formulaFields.includes(f.id);\n return (\n <Button\n key={f.id}\n type=\"button\"\n size=\"sm\"\n variant={picked ? \"default\" : \"outline\"}\n onClick={() =>\n props.setFormulaFields(\n picked\n ? props.formulaFields.filter((id) => id !== f.id)\n : [...props.formulaFields, f.id],\n )\n }\n >\n {fieldName(f)}\n </Button>\n );\n })}\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n In the order you pick them. Columns are remembered by which column they are, so renaming one\n never breaks this.\n </p>\n </div>\n </div>\n );\n }\n\n return null;\n}\n","\"use client\";\n\n// src/TableSettings.tsx — @ai-matrx/records-ui · SCR-3, SCR-4, SCR-5\n//\n// EVERY FIELD OF ONE TABLE, TO RENAME, REORDER, RETYPE AND DELETE, FROM ONE\n// PANEL — and the agent's pending field proposals in the SAME list, with the\n// same accept and reject on each (SCR-5), because a proposal is a field that\n// has not been agreed to yet, not a different kind of thing in a different\n// place.\n//\n// The panel does not exist at all for somebody who does not administer the\n// table (SCR-4). There is no read-only variant: what it would show, the grid\n// already shows.\n\nimport { useState } from \"react\";\nimport {\n useFieldMutation,\n useFields,\n useRecordMutation,\n useTable,\n type Field,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport { Badge, Button, Separator, cn } from \"@ai-matrx/design-system\";\nimport { FieldEditor } from \"./FieldEditor\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { fieldTypeLabel } from \"./parity\";\nimport { fieldName, tableName } from \"./names\";\n\nexport interface FieldProposalRow {\n id: string;\n /** What the agent proposed, in the Field shape the store would store. */\n field: Partial<Field> & { key: string; label?: string };\n why: string;\n proposed_by: string;\n}\n\nexport interface TableSettingsProps {\n tableId: Uuid;\n /**\n * SCR-5. Pending field proposals. The door that lists them\n * (`custom.field_propose`) does not exist yet — `@ai-matrx/records` answers\n * `door_absent` by name for it — so a host passes what it has, and when it\n * has nothing the section says so rather than pretending there is nothing to\n * approve.\n */\n proposals?: FieldProposalRow[] | undefined;\n onAcceptProposal?: ((proposal: FieldProposalRow) => void) | undefined;\n onRejectProposal?: ((proposal: FieldProposalRow) => void) | undefined;\n /**\n * SCR-3's fourth verb. Called after the store has accepted the delete, so the\n * host can leave a page that is now about a table nobody can open.\n */\n onDeleted?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TableSettings({\n tableId,\n proposals,\n onAcceptProposal,\n onRejectProposal,\n onDeleted,\n className,\n}: TableSettingsProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const mutation = useRecordMutation();\n // THE SHAPE OF THE TABLE goes through the store's own field doors, never\n // through the record writer: a field taken off with `record_delete` leaves the\n // TABLE still declaring a column that is gone, which is the same broken half\n // of \"one source of truth\" that made every \"Add field\" refuse.\n const shape = useFieldMutation();\n const [editing, setEditing] = useState<Field | \"new\" | null>(null);\n const [askingToDelete, setAskingToDelete] = useState(false);\n const [askingToRemove, setAskingToRemove] = useState<Field | null>(null);\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (!rights.admin) return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n\n const rows = [...(fields.data ?? [])].sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));\n\n const move = async (field: Field, direction: -1 | 1) => {\n const index = rows.findIndex((r) => r.id === field.id);\n const swap = rows[index + direction];\n if (!swap) return;\n // The order is the Field's own `sort`, so reordering is two ordinary writes\n // through the one write door, not a table-level layout blob.\n await mutation.update({ record_id: field.id, patch: { sort: swap.sort ?? index + direction } });\n await mutation.update({ record_id: swap.id, patch: { sort: field.sort ?? index } });\n fields.reload();\n };\n\n const remove = async (field: Field) => {\n const gone = await shape.retire({ field_id: field.id });\n setAskingToRemove(null);\n if (gone) {\n fields.reload();\n table.reload();\n }\n };\n\n /**\n * DELETING THE TABLE ITSELF — the verb this panel's own header has claimed\n * since SCR-3 and did not have. A walk of the real screens on 19 September\n * made a table and then could not get rid of it from anywhere in the product.\n * A Table is a record, so this is the same soft delete every record gets\n * (REC-23), through the same door, and the panel says exactly that before it\n * happens rather than after.\n */\n const deleteTable = async () => {\n const gone = await mutation.remove({ record_id: tableId });\n setAskingToDelete(false);\n if (gone !== null) onDeleted?.();\n };\n\n if (editing) {\n return (\n <FieldEditor\n tableId={tableId}\n {...(editing === \"new\" ? {} : { field: editing })}\n onSaved={() => {\n setEditing(null);\n fields.reload();\n table.reload();\n }}\n onCancel={() => setEditing(null)}\n className={className}\n />\n );\n }\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Fields</span>\n <span className=\"text-muted-foreground\">{rows.length}</span>\n <Button size=\"sm\" variant=\"outline\" className=\"ml-auto\" onClick={() => setEditing(\"new\")}>\n Add a field\n </Button>\n </div>\n\n {mutation.error ? <RefusalNotice error={mutation.error} /> : null}\n {shape.error ? <RefusalNotice error={shape.error} /> : null}\n\n {/* Destructive, so the consequence is named BEFORE it happens and takes a\n second press — the same shape the table's own delete has below. */}\n {askingToRemove ? (\n <div className=\"flex flex-wrap items-center gap-2 rounded border border-destructive/40 px-2 py-1.5\">\n <span className=\"text-destructive\">\n Removing {fieldName(askingToRemove)} takes it off every record of this table. The values stay in\n each record&apos;s history and nothing else is deleted.\n </span>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n disabled={shape.saving}\n onClick={() => void remove(askingToRemove)}\n >\n {shape.saving ? \"Removing…\" : \"Remove it\"}\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setAskingToRemove(null)}>\n Keep it\n </Button>\n </div>\n ) : null}\n\n <ul className=\"divide-y rounded border\">\n {rows.map((field, index) => (\n <li key={field.id} className=\"flex items-center gap-2 px-2 py-1.5\">\n <span className=\"min-w-0 flex-1 truncate\">{fieldName(field)}</span>\n <Badge variant=\"outline\" className=\"text-[10px] font-normal\">\n {fieldTypeLabel(field)}\n </Badge>\n {field.required ? <span className=\"text-[10px] text-destructive\">required</span> : null}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Move ${fieldName(field)} up`}\n disabled={index === 0}\n onClick={() => void move(field, -1)}\n >\n ↑\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Move ${fieldName(field)} down`}\n disabled={index === rows.length - 1}\n onClick={() => void move(field, 1)}\n >\n ↓\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setEditing(field)}>\n Edit\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"text-destructive\"\n aria-label={`Remove ${fieldName(field)}`}\n onClick={() => setAskingToRemove(field)}\n >\n Remove\n </Button>\n </li>\n ))}\n {rows.length === 0 ? <li className=\"px-2 py-2 text-muted-foreground\">This table has no fields yet.</li> : null}\n </ul>\n\n <Separator />\n\n {/* SCR-5: proposals are fields in the same list, with the same two verbs. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">Proposed</span>\n <span className=\"text-muted-foreground\">{proposals?.length ?? 0}</span>\n </div>\n {proposals === undefined ? (\n <p className=\"text-muted-foreground\">\n Nothing is listing proposals here yet: the store has no `custom.field_propose` door, so this panel would be\n inventing an empty queue. When the door lands, its rows appear in this list with the same accept and reject.\n </p>\n ) : proposals.length === 0 ? (\n <p className=\"text-muted-foreground\">No field is waiting for a decision.</p>\n ) : (\n <ul className=\"divide-y rounded border\">\n {proposals.map((proposal) => (\n <li key={proposal.id} className=\"flex items-center gap-2 px-2 py-1.5\">\n <span className=\"min-w-0 flex-1 truncate\">{proposal.field.label || proposal.field.key}</span>\n <span className=\"min-w-0 flex-1 truncate text-muted-foreground\">{proposal.why}</span>\n <Badge variant=\"secondary\" className=\"text-[10px] font-normal\">\n {proposal.proposed_by}\n </Badge>\n <Button size=\"sm\" variant=\"outline\" onClick={() => onAcceptProposal?.(proposal)}>\n Accept\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => onRejectProposal?.(proposal)}>\n Reject\n </Button>\n </li>\n ))}\n </ul>\n )}\n\n <Separator />\n\n {/* SCR-3. Destructive, so it names the consequence BEFORE it happens and\n takes a second press. There is no undo button here on purpose: the\n restore path is the store's own and it belongs with the record's\n history, not beside the control that did the delete. */}\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">This table</span>\n {askingToDelete ? (\n <>\n <p className=\"text-muted-foreground\">\n Deleting {table.data ? tableName(table.data) : \"this table\"} takes it out of everyone&apos;s list, with\n its {rows.length} field{rows.length === 1 ? \"\" : \"s\"} and every record in it.\n {table.data?.retention_days\n ? ` The store keeps them for ${table.data.retention_days} days, so it can still be restored.`\n : \" The store keeps them, so it can still be restored.\"}\n </p>\n <div className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"destructive\" disabled={mutation.saving} onClick={() => void deleteTable()}>\n {mutation.saving ? \"Deleting…\" : \"Delete this table\"}\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setAskingToDelete(false)}>\n Keep it\n </Button>\n </div>\n </>\n ) : (\n <div>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAskingToDelete(true)}>\n Delete this table\n </Button>\n </div>\n )}\n {mutation.error ? <RefusalNotice error={mutation.error} /> : null}\n </div>\n </div>\n );\n}\n","\"use client\";\n\n// src/Peek.tsx — @ai-matrx/records-ui · SCR-N-3\n//\n// THE GENERIC PEEK, DRIVEN BY THE FIELD RECORDS. There is no per-table peek in\n// this platform: before this, 21 hand-written peeks covered 19 registered\n// catalogue keys and every custom table — 100% of them — fell to \"Peek — coming\n// soon\".\n//\n// It reads the record through the read door, shows every applicable Field's\n// value the way that Field says to show it, and flips to the same\n// `RecordForm` for editing. It carries the Alchemy menu, so everything a person\n// can copy, hand to an agent or export from a record is in the one place it is\n// everywhere else on the platform.\n\nimport { useState } from \"react\";\nimport { useFields, useRecord, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport { AlchemyMenu } from \"@ai-matrx/alchemy/react\";\nimport { Button, Separator, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { ShareControl } from \"./ShareControl\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { ProvenanceBadge, RecordValue } from \"./values\";\nimport { fieldName, recordName } from \"./names\";\n\nexport interface PeekProps {\n tableId: Uuid;\n recordId: Uuid;\n onClose?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function Peek({ tableId, recordId, onClose, className }: PeekProps) {\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const record = useRecord(recordId, true);\n const rights = useTableRights(table.data);\n const host = useRecordsUi();\n const organizationId = useRecordsClient().config.organizationId;\n const [editing, setEditing] = useState(false);\n\n if (record.error) return <RefusalNotice error={record.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n\n const document = record.data?.document;\n // REC-2: the Table's own title field is what makes a record a chip. A record\n // with nothing readable says so — a truncated uuid tells a person nothing and\n // reads like a bug (`names.ts`).\n const title = document ? recordName(document, table.data?.title_field) : \"\";\n const href = host.hrefForRecord && table.data ? host.hrefForRecord({ table: table.data, recordId }) : undefined;\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-2 text-xs\", className)}>\n {/* ONE row of header: the title, the controls. Nothing repeats the name. */}\n <div className=\"flex items-center gap-2\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {record.loading && !document ? <Skeleton className=\"h-4 w-40\" /> : title}\n </h3>\n <AlchemyMenu\n label={title || \"Record\"}\n sourceId={`record:${recordId}`}\n size=\"xs\"\n human={() =>\n (fields.data ?? [])\n .map((field) => `${fieldName(field)}: ${String(document?.[field.key] ?? \"\")}`)\n .join(\"\\n\")\n }\n json={() => document ?? {}}\n />\n {href ? (\n <a className=\"text-primary underline-offset-2 hover:underline\" href={href}>\n Open\n </a>\n ) : null}\n {/* SCR-N-5. Beside Edit, where a person looks for it. */}\n <ShareControl kind=\"record\" organizationId={organizationId} subjectId={recordId} name={title} />\n {rights.write ? (\n <Button size=\"sm\" variant={editing ? \"ghost\" : \"outline\"} onClick={() => setEditing((e) => !e)}>\n {editing ? \"Stop editing\" : \"Edit\"}\n </Button>\n ) : null}\n {onClose ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={onClose} aria-label=\"Close\">\n ×\n </Button>\n ) : null}\n </div>\n\n <Separator />\n\n {editing ? (\n <RecordForm\n tableId={tableId}\n recordId={recordId}\n onSaved={() => {\n setEditing(false);\n record.reload();\n }}\n onCancel={() => setEditing(false)}\n />\n ) : (\n <dl className=\"grid grid-cols-[minmax(6rem,12rem)_1fr] gap-x-3 gap-y-1.5\">\n {(fields.data ?? []).map((field) => (\n <div key={field.id} className=\"contents\">\n <dt className=\"flex items-baseline gap-1 truncate text-muted-foreground\">\n {fieldName(field)}\n <ProvenanceBadge document={document} fieldKey={field.key} />\n </dt>\n <dd className=\"min-w-0\"><RecordValue field={field} value={document?.[field.key]} document={document} /></dd>\n </div>\n ))}\n </dl>\n )}\n\n {/* FLD-9: what the system worked out, and where it came from. */}\n {record.data?.computed?.length ? (\n <>\n <Separator />\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">Worked out by the system</span>\n {record.data.computed.map((row, i) => (\n <p key={i} className=\"text-muted-foreground\">\n {JSON.stringify(row)}\n </p>\n ))}\n </div>\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/ShareControl.tsx — @ai-matrx/records-ui · SCR-N-5\n//\n// THE SHARE BUTTON, on the record screen and on the table screen, in the row\n// where everything else a person does to a thing already is.\n//\n// WHAT IT IS NOT. It is not a share dialog. AI Matrx has exactly one of those\n// and it lives in the app (matrx-frontend `features/sharing`): a people picker\n// over the organization's members, the four levels, the list of who has access\n// with the REASON each one has it, and revoke. Building a second one in this\n// package would give the platform two answers to \"who can see this\", which is\n// the one question a platform may not have two answers to. So this component\n// draws the button, owns whether the dialog is open, and hands the subject to\n// the host's `share` port.\n//\n// ABSENT, NEVER DEAD. With no `share` port bound there is NO BUTTON — not a\n// greyed one, not one that opens an empty panel. `NO_SHARE_REASON` is exported\n// from `./host` and `reason` below hands it to anyone who asks why, which is\n// how every other unbound port in this package behaves.\n//\n// A TABLE IS A RECORD. In this store a Table is a `custom.record` row whose\n// table is the Table kernel, so the same button, the same door and the same\n// dialog serve both screens; `kind` only changes the noun in the sentences.\n\nimport { useState, type ReactNode } from \"react\";\nimport type { Uuid } from \"@ai-matrx/records\";\nimport { Button } from \"@ai-matrx/design-system\";\nimport { useRecordsUi, NO_SHARE_REASON, type ShareSubject } from \"./host\";\n\nexport interface ShareControlProps {\n kind: ShareSubject[\"kind\"];\n organizationId: Uuid;\n subjectId: Uuid;\n /** What to call it in the dialog's title. */\n name?: string | undefined;\n size?: \"sm\" | \"default\" | undefined;\n variant?: \"ghost\" | \"outline\" | \"default\" | undefined;\n className?: string | undefined;\n}\n\n/** True when a host has bound a share dialog — so a caller can lay out its row. */\nexport function useCanShare(): boolean {\n return typeof useRecordsUi().share === \"function\";\n}\n\n/** Why there is no Share button here, for anything that asks. */\nexport function shareUnavailableReason(): string {\n return NO_SHARE_REASON;\n}\n\nexport function ShareControl({\n kind,\n organizationId,\n subjectId,\n name,\n size = \"sm\",\n variant = \"ghost\",\n className,\n}: ShareControlProps): ReactNode {\n const host = useRecordsUi();\n const [open, setOpen] = useState(false);\n\n // No port, no button. The reason is exported rather than rendered as a dead\n // control, because a Share button that opens nothing is the screen lying.\n if (!host.share) return null;\n\n return (\n <>\n <Button\n size={size}\n variant={variant}\n className={className}\n onClick={() => setOpen(true)}\n aria-label={kind === \"table\" ? \"Share this table\" : \"Share this record\"}\n >\n Share\n </Button>\n {open\n ? host.share({\n kind,\n organizationId,\n subjectId,\n name: name && name.trim() !== \"\" ? name : subjectId.slice(0, 8),\n onClose: () => setOpen(false),\n })\n : null}\n </>\n );\n}\n","\"use client\";\n\n// src/views.ts — @ai-matrx/records-ui · SCR-6, SCR-7, SCR-N-6\n//\n// A SAVED VIEW IS ONE RECORD, and that record owns its layout and REFERENCES\n// its membership rule.\n//\n// The split matters. A view does not carry a filter predicate of its own that a\n// screen re-implements in JavaScript: it names a Rule, and the STORE answers\n// who is in it (`custom.rule_members`). So the same view means the same thing\n// to a grid, to an export, to an agent and to the server. What the view owns\n// itself is presentation — which of the four layouts, which Field the kanban\n// columns come from, which Field the calendar reads, which Field the gallery\n// shows — because that is not data, it is how this person wants to look at it.\n//\n// The whole view is also a plain declarative object (`SavedViewSpec`), which is\n// what makes \"an agent writes the view in 45 seconds\" true: one `record_write`\n// of one document, and the person only tweaks.\n\nimport type { ReadRow, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** The four ways one saved view can be looked at (SCR-6). */\nexport const VIEW_LAYOUTS = [\"grid\", \"kanban\", \"calendar\", \"gallery\"] as const;\nexport type ViewLayout = (typeof VIEW_LAYOUTS)[number];\n\nexport const LAYOUT_LABEL: Record<ViewLayout, string> = {\n grid: \"Grid\",\n kanban: \"Kanban\",\n calendar: \"Calendar\",\n gallery: \"Gallery\",\n};\n\n/**\n * What each layout needs before it can draw anything, in one sentence a screen\n * prints. A layout that is missing its Field says so instead of rendering an\n * empty board that looks like \"no records\".\n */\nexport const LAYOUT_NEEDS: Record<ViewLayout, string | null> = {\n grid: null,\n kanban: \"A kanban board needs a Field to make its columns from — pick one and the board appears.\",\n calendar: \"A calendar needs a date Field to place records on — pick one and the month appears.\",\n gallery: null,\n};\n\n/** One sort clause. The Field's key and a direction; nothing else is a sort. */\nexport interface ViewSort {\n field: string;\n direction: \"asc\" | \"desc\";\n}\n\n/**\n * THE DECLARATIVE SPEC. An agent writes this whole object; a person tweaks it.\n * Every builder component in this package takes one of these as a prop.\n */\nexport interface SavedViewSpec {\n name: string;\n /** The Table this view looks at. */\n subject: Uuid;\n layout: ViewLayout;\n /** Kanban: the Field whose value becomes a column. */\n groupField?: string | null;\n /** Calendar: the Field that places a record in the month. */\n dateField?: string | null;\n /** Gallery: the Field shown large on the card. */\n imageField?: string | null;\n sorts?: ViewSort[];\n /**\n * The membership Rule. The STORE decides who is in this view; this is a\n * reference to its Rule record, never a predicate this package evaluates.\n */\n ruleId?: Uuid | null;\n isDefault?: boolean;\n}\n\n/** A saved view as it comes back out of the store, with its record's own id. */\nexport interface SavedView extends SavedViewSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every saved view is a record of. */\nexport const VIEW_TABLE: SystemTableSpec = {\n slug: \"records_ui_view\",\n name: \"Saved views\",\n labelSingular: \"View\",\n labelPlural: \"Views\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"layout\", label: \"Layout\", type: \"text\", sort: 30, required: true },\n { key: \"group_field\", label: \"Group by\", type: \"text\", sort: 40 },\n { key: \"date_field\", label: \"Date field\", type: \"text\", sort: 50 },\n { key: \"image_field\", label: \"Image field\", type: \"text\", sort: 60 },\n { key: \"sorts\", label: \"Sorts\", type: \"text\", sort: 70, config: { multiline: true } },\n { key: \"rule_id\", label: \"Membership rule\", type: \"text\", sort: 80 },\n { key: \"is_default\", label: \"Default\", type: \"text\", sort: 90 },\n ],\n};\n\n/**\n * WHICH FIELD EACH LAYOUT CAN BE DRAWN FROM, decided from the FIELD'S OWN\n * DECLARATION and never from the values it happens to hold.\n *\n * A kanban makes columns from a choice: the Field whose value is one of a\n * closed set (FLD-5 / FLD-6 — a pick-list is a Table, and a select stores the\n * id of one of its records). Grouping by a free-text Field produces one column\n * per record, which is not a board. A calendar places a record in time, so it\n * needs a Field that holds a date.\n *\n * These two answers are here, beside the layouts, because the picker on the\n * screen and any agent writing a view spec must agree about what is offerable.\n */\nexport const LAYOUT_FIELD_KIND: Record<ViewLayout, \"choice\" | \"date\" | null> = {\n grid: null,\n kanban: \"choice\",\n calendar: \"date\",\n gallery: null,\n};\n\n/** The one sentence a layout says when the table holds no Field it could use. */\nexport const LAYOUT_NO_FIELD: Record<ViewLayout, string> = {\n grid: \"\",\n kanban:\n \"This table has no choice field yet, so there is nothing to make columns from. Add a field that \" +\n \"holds one of a set of choices — Add field, then Select — and it appears here.\",\n calendar:\n \"This table has no date field yet, so there is nothing to place records on. Add a field that holds \" +\n \"a date — Add field, then Date — and it appears here.\",\n gallery: \"\",\n};\n\n/** The spec as the one document the store holds. */\nexport function viewDocument(spec: SavedViewSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n layout: spec.layout,\n group_field: spec.groupField ?? null,\n date_field: spec.dateField ?? null,\n image_field: spec.imageField ?? null,\n sorts: JSON.stringify(spec.sorts ?? []),\n rule_id: spec.ruleId ?? null,\n is_default: spec.isDefault ? \"true\" : \"false\",\n };\n}\n\n/** One stored record back into the spec a screen and an agent both read. */\nexport function viewFromRecord(row: ReadRow): SavedView {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const layout = String(data[\"layout\"] ?? \"grid\");\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled view\"),\n subject: String(data[\"subject\"] ?? \"\"),\n layout: (VIEW_LAYOUTS as readonly string[]).includes(layout) ? (layout as ViewLayout) : \"grid\",\n groupField: (data[\"group_field\"] as string | null) ?? null,\n dateField: (data[\"date_field\"] as string | null) ?? null,\n imageField: (data[\"image_field\"] as string | null) ?? null,\n sorts: parseSorts(data[\"sorts\"]),\n ruleId: (data[\"rule_id\"] as string | null) ?? null,\n isDefault: data[\"is_default\"] === \"true\",\n };\n}\n\n/**\n * A PARTIAL change to a saved view, as the patch the store takes. Only the keys\n * the caller actually changed are written — a full document would re-write a\n * name or a rule the person edited in another tab.\n */\nexport function viewPatchDocument(patch: Partial<SavedViewSpec>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (patch.name !== undefined) out[\"name\"] = patch.name;\n if (patch.layout !== undefined) out[\"layout\"] = patch.layout;\n if (patch.groupField !== undefined) out[\"group_field\"] = patch.groupField ?? null;\n if (patch.dateField !== undefined) out[\"date_field\"] = patch.dateField ?? null;\n if (patch.imageField !== undefined) out[\"image_field\"] = patch.imageField ?? null;\n if (patch.sorts !== undefined) out[\"sorts\"] = JSON.stringify(patch.sorts ?? []);\n if (patch.ruleId !== undefined) out[\"rule_id\"] = patch.ruleId ?? null;\n if (patch.isDefault !== undefined) out[\"is_default\"] = patch.isDefault ? \"true\" : \"false\";\n return out;\n}\n\nfunction parseSorts(raw: unknown): ViewSort[] {\n if (Array.isArray(raw)) return raw as ViewSort[];\n if (typeof raw !== \"string\" || raw.trim() === \"\") return [];\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as ViewSort[]) : [];\n } catch {\n // A sort nobody can read is not silently dropped to \"no sort\": the view says\n // what it holds and the caller can see that it is not a sort list.\n return [];\n }\n}\n","\"use client\";\n\n// src/ViewSwitcher.tsx — @ai-matrx/records-ui · SCR-6\n//\n// ONE SAVED VIEW, FOUR WAYS TO LOOK AT IT: grid, kanban, calendar, gallery.\n//\n// The records are the SAME records in all four. Switching layout re-draws them;\n// it never re-queries something different and it never filters differently —\n// membership is the view's Rule and the STORE answers it (`custom.rule_members`),\n// so a card that disappears between two layouts would be a defect, not a\n// feature. A view with no Rule is the whole table, and the screen says which.\n//\n// A layout that cannot draw yet (a kanban with no Field to group by, a calendar\n// with no date Field) says the one sentence that fixes it. It never renders an\n// empty board that reads like \"there is nothing here\".\n\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { useFields, useRecords, useRecordsClient, type Field, type ReadRow, type StoredRecord, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { Grid } from \"./Grid\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { RecordValue, scalarText } from \"./values\";\nimport { useRecordLabels } from \"./labels\";\nimport { fieldName, rowName } from \"./names\";\nimport { editorKindFor } from \"./parity\";\nimport {\n LAYOUT_FIELD_KIND,\n LAYOUT_LABEL,\n LAYOUT_NEEDS,\n LAYOUT_NO_FIELD,\n VIEW_LAYOUTS,\n type SavedViewSpec,\n type ViewLayout,\n} from \"./views\";\n\nexport interface ViewSwitcherProps {\n /**\n * THE DECLARATIVE SPEC — an agent writes the whole thing, a person tweaks it.\n * `ViewBar` passes the saved view it loaded; a host with no saved views at all\n * can pass a literal here and the switcher works.\n */\n view: SavedViewSpec;\n /** Called when the person picks another layout, so the host can save it. */\n onLayoutChange?: ((layout: ViewLayout) => void) | undefined;\n /**\n * Called with whatever part of the view the person just changed — the layout,\n * the Field the kanban groups by, the Field the calendar reads. The HOST\n * saves it onto the view record, so the choice is remembered per saved view\n * rather than per page load. Unbound, the pickers still work for this visit\n * and the screen says the choice is not being kept.\n */\n onViewChange?: ((patch: Partial<SavedViewSpec>) => void) | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n /** The host's whole-record form, offered by the grid when an empty record is refused. */\n onNewRecordForm?: (() => void) | undefined;\n pageSize?: number | undefined;\n className?: string | undefined;\n}\n\n/** The records this view holds: its Rule's members when it names one, the table otherwise. */\nexport function useViewRecords(view: SavedViewSpec, pageSize = 200) {\n const client = useRecordsClient();\n const table = useRecords(view.ruleId ? null : view.subject, { pageSize });\n const [ruled, setRuled] = useState<{ rows: ReadRow[]; loading: boolean; error: RecordsError | null }>({\n rows: [],\n loading: Boolean(view.ruleId),\n error: null,\n });\n\n const ruleId = view.ruleId ?? null;\n useEffect(() => {\n if (!ruleId) return;\n let cancelled = false;\n setRuled({ rows: [], loading: true, error: null });\n void client.ruleMembers({ rule_id: ruleId }).then((result) => {\n if (cancelled) return;\n setRuled(\n result.ok\n ? { rows: (result.data ?? []).map(asReadRow), loading: false, error: null }\n : { rows: [], loading: false, error: result.error },\n );\n });\n return () => {\n cancelled = true;\n };\n }, [client, ruleId]);\n\n const rows = ruleId ? ruled.rows : (table.data?.rows ?? []);\n return {\n rows: sortRows(rows, view.sorts ?? []),\n loading: ruleId ? ruled.loading : table.loading,\n error: ruleId ? ruled.error : table.error,\n /** Where membership came from, in a sentence. A screen that hides this is hiding the view's meaning. */\n membership: ruleId\n ? \"Membership is this view's Rule, answered by the store.\"\n : \"This view has no Rule, so it holds the whole table.\",\n };\n}\n\n/**\n * `custom.rule_members` answers SETOF `custom.record` — it is the membership\n * door, not the read door, so its rows arrive in the row shape rather than the\n * masked-document shape. They are carried into the read door's shape HERE, at\n * the one seam, so a card is drawn by exactly one code path whichever door\n * produced it. What this cannot do is mask: a Rule's members come back as the\n * store stored them, which is the membership door's own gap, not this screen's.\n */\nfunction asReadRow(row: StoredRecord): ReadRow {\n return { id: row.id, document: (row.data ?? {}) as ReadRow[\"document\"], level: \"viewer\", hidden: {} };\n}\n\nfunction sortRows(rows: ReadRow[], sorts: { field: string; direction: \"asc\" | \"desc\" }[]): ReadRow[] {\n if (sorts.length === 0) return rows;\n return [...rows].sort((a, b) => {\n for (const sort of sorts) {\n const left = (a.document ?? {})[sort.field];\n const right = (b.document ?? {})[sort.field];\n if (left === right) continue;\n const order = (left ?? \"\") < (right ?? \"\") ? -1 : 1;\n return sort.direction === \"desc\" ? -order : order;\n }\n return 0;\n });\n}\n\nexport function ViewSwitcher({\n view,\n onLayoutChange,\n onViewChange,\n onOpenRecord,\n onNewRecordForm,\n pageSize = 200,\n className,\n}: ViewSwitcherProps) {\n const [layout, setLayout] = useState<ViewLayout>(view.layout);\n // The Fields the pickers below chose, so a host that binds no `onViewChange`\n // still gets a board rather than a sentence — and is TOLD it is not kept.\n const [local, setLocal] = useState<Partial<SavedViewSpec>>({});\n useEffect(() => {\n setLayout(view.layout);\n setLocal({});\n }, [view.layout, view.name, view.subject]);\n\n const pick = (next: ViewLayout) => {\n setLayout(next);\n onLayoutChange?.(next);\n onViewChange?.({ layout: next });\n };\n\n const change = (patch: Partial<SavedViewSpec>) => {\n setLocal((held) => ({ ...held, ...patch }));\n onViewChange?.(patch);\n };\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the view's name, the four layouts, nothing repeated. */}\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-sm font-medium\">{view.name}</span>\n <div className=\"ml-auto flex items-center gap-0.5\" role=\"group\" aria-label=\"Layout\">\n {VIEW_LAYOUTS.map((option) => (\n <Button\n key={option}\n size=\"sm\"\n variant={option === layout ? \"secondary\" : \"ghost\"}\n aria-pressed={option === layout}\n onClick={() => pick(option)}\n >\n {LAYOUT_LABEL[option]}\n </Button>\n ))}\n </div>\n </div>\n\n {layout === \"grid\" ? (\n <Grid\n tableId={view.subject}\n pageSize={pageSize}\n {...(onOpenRecord ? { onOpenRecord } : {})}\n {...(onNewRecordForm ? { onNewRecordForm } : {})}\n />\n ) : (\n <Board\n view={{ ...view, ...local, layout }}\n pageSize={pageSize}\n onChange={change}\n remembered={Boolean(onViewChange)}\n {...(onOpenRecord ? { onOpenRecord } : {})}\n />\n )}\n </div>\n );\n}\n\n/** Which Fields a kanban may group by, and which a calendar may read. */\nfunction offerableFields(all: Field[], want: \"choice\" | \"date\"): Field[] {\n return all.filter((field) => {\n const kind = editorKindFor(field);\n if (want === \"choice\") return kind === \"select\" || kind === \"multi_select\";\n return kind === \"datetime\" || kind === \"date\";\n });\n}\n\nfunction Board({\n view,\n pageSize,\n onChange,\n remembered,\n onOpenRecord,\n}: {\n view: SavedViewSpec;\n pageSize: number;\n onChange: (patch: Partial<SavedViewSpec>) => void;\n remembered: boolean;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n}) {\n const fields = useFields(view.subject);\n const records = useViewRecords(view, pageSize);\n\n if (fields.error) return <RefusalNotice error={fields.error} />;\n if (records.error) return <RefusalNotice error={records.error} />;\n if (fields.loading || records.loading) return <Skeleton className=\"h-40 w-full\" />;\n\n const all = fields.data ?? [];\n const byKey = (key: string | null | undefined) => all.find((f) => f.key === key);\n const titleField = byKey(view.groupField) ? all.find((f) => f.key !== view.groupField) ?? all[0] : all[0];\n\n if (view.layout === \"kanban\") {\n const groupField = byKey(view.groupField);\n const picker = (\n <FieldPicker\n layout=\"kanban\"\n label=\"Group by\"\n all={all}\n chosen={groupField?.key ?? null}\n remembered={remembered}\n onPick={(key) => onChange({ groupField: key })}\n />\n );\n if (!groupField) return <Needs layout=\"kanban\" picker={picker} />;\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n {picker}\n <Kanban rows={records.rows} groupField={groupField} titleField={titleField} onOpenRecord={onOpenRecord} note={records.membership} />\n </div>\n );\n }\n if (view.layout === \"calendar\") {\n const dateField = byKey(view.dateField);\n const picker = (\n <FieldPicker\n layout=\"calendar\"\n label=\"Dates from\"\n all={all}\n chosen={dateField?.key ?? null}\n remembered={remembered}\n onPick={(key) => onChange({ dateField: key })}\n />\n );\n if (!dateField) return <Needs layout=\"calendar\" picker={picker} />;\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n {picker}\n <Calendar rows={records.rows} dateField={dateField} titleField={titleField} onOpenRecord={onOpenRecord} note={records.membership} />\n </div>\n );\n }\n return <Gallery rows={records.rows} fields={all} imageKey={view.imageField ?? null} onOpenRecord={onOpenRecord} note={records.membership} />;\n}\n\n/**\n * THE PICKER THE SENTENCE ALWAYS PROMISED. Before this, a kanban said \"pick one\n * and the board appears\" and there was no picker anywhere on the page — the\n * verdict of 19 September found the same dead end on the calendar. A screen\n * that names a remedy and does not offer it is worse than one that says\n * nothing, so the sentence and the control are now the same component.\n */\nfunction FieldPicker({\n layout,\n label,\n all,\n chosen,\n remembered,\n onPick,\n}: {\n layout: ViewLayout;\n label: string;\n all: Field[];\n chosen: string | null;\n remembered: boolean;\n onPick: (key: string | null) => void;\n}) {\n const want = LAYOUT_FIELD_KIND[layout];\n const offerable = want ? offerableFields(all, want) : [];\n if (offerable.length === 0) {\n // Honest, and it names the fix: this is not \"pick one\", because there is\n // nothing to pick.\n return <p className=\"text-xs text-muted-foreground\">{LAYOUT_NO_FIELD[layout]}</p>;\n }\n return (\n <div className=\"flex items-center gap-1.5 text-xs\">\n <label className=\"text-muted-foreground\" htmlFor={`view-field-${layout}`}>\n {label}\n </label>\n <select\n id={`view-field-${layout}`}\n aria-label={`${label} which field`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={chosen ?? \"\"}\n onChange={(event) => onPick(event.target.value === \"\" ? null : event.target.value)}\n >\n <option value=\"\">Choose a field</option>\n {offerable.map((field) => (\n <option key={field.key} value={field.key}>\n {fieldName(field)}\n </option>\n ))}\n </select>\n {remembered ? null : (\n <span className=\"text-muted-foreground\">\n Kept for this visit only — this screen has nowhere to save it onto the view.\n </span>\n )}\n </div>\n );\n}\n\n/** The one sentence that fixes an un-drawable layout, WITH the control that fixes it. */\nfunction Needs({ layout, picker }: { layout: ViewLayout; picker: ReactNode }) {\n return (\n <div className=\"flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground\">\n <p>{LAYOUT_NEEDS[layout]}</p>\n {picker}\n </div>\n );\n}\n\nfunction Note({ children }: { children: string }) {\n return <p className=\"text-xs text-muted-foreground\">{children}</p>;\n}\n\nfunction Kanban({\n rows,\n groupField,\n titleField,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n groupField: Field;\n titleField: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const groupFields = useMemo(() => [groupField], [groupField]);\n // A BOARD IS GROUPED BY A CHOICE, AND A CHOICE IS STORED AS THE ID OF AN\n // OPTION RECORD (FLD-5 / FLD-6). Without the resolver every heading on this\n // board was a bare 36-character identifier — the single most visible line in\n // the 19 September verdict's \"machine identity is everywhere a person looks\".\n const labels = useRecordLabels(groupFields);\n const columns = useMemo(() => {\n const map = new Map<string, ReadRow[]>();\n for (const row of rows) {\n const raw = (row.document ?? {})[groupField.key];\n // A record with no value for the grouping Field is NOT dropped: it gets\n // its own column, named for the absence, because losing rows between two\n // layouts is the defect this board could most easily ship.\n const key = raw === null || raw === undefined || raw === \"\" ? \"No value\" : scalarText(groupField, raw, labels);\n map.set(key, [...(map.get(key) ?? []), row]);\n }\n return [...map.entries()].sort((a, b) => (a[0] === \"No value\" ? 1 : b[0] === \"No value\" ? -1 : a[0].localeCompare(b[0])));\n }, [rows, groupField, labels]);\n\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <div className=\"flex min-h-0 gap-2 overflow-x-auto pb-2\">\n {columns.map(([name, cards]) => (\n <section key={name} className=\"flex w-64 shrink-0 flex-col rounded border bg-muted/30\">\n <header className=\"flex items-center gap-2 border-b px-2 py-1 text-xs font-medium\">\n <span className=\"truncate\">{name}</span>\n <span className=\"ml-auto text-muted-foreground\">{cards.length}</span>\n </header>\n <ul className=\"flex flex-col gap-1 p-1\">\n {cards.map((card) => (\n <li key={card.id}>\n <Card record={card} field={titleField} onOpenRecord={onOpenRecord} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n </div>\n );\n}\n\nfunction Calendar({\n rows,\n dateField,\n titleField,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n dateField: Field;\n titleField: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const { days, undated } = useMemo(() => {\n const byDay = new Map<string, ReadRow[]>();\n const without: ReadRow[] = [];\n for (const row of rows) {\n const raw = (row.document ?? {})[dateField.key];\n const at = typeof raw === \"string\" || typeof raw === \"number\" ? new Date(raw) : null;\n if (!at || Number.isNaN(at.getTime())) {\n without.push(row);\n continue;\n }\n const key = at.toISOString().slice(0, 10);\n byDay.set(key, [...(byDay.get(key) ?? []), row]);\n }\n return { days: [...byDay.entries()].sort((a, b) => a[0].localeCompare(b[0])), undated: without };\n }, [rows, dateField]);\n\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <ol className=\"flex min-h-0 flex-col divide-y overflow-y-auto rounded border\">\n {days.map(([day, cards]) => (\n <li key={day} className=\"flex gap-3 p-2\">\n <span className=\"w-24 shrink-0 text-xs font-medium tabular-nums\">\n {new Date(`${day}T00:00:00Z`).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" })}\n </span>\n <ul className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {cards.map((card) => (\n <li key={card.id}>\n <Card record={card} field={titleField} onOpenRecord={onOpenRecord} />\n </li>\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {undated.length > 0 ? (\n // Nothing fails silently: records with no date are NOT missing from the\n // calendar, they are named as records the calendar cannot place.\n <p className=\"text-xs text-muted-foreground\">\n {undated.length} {undated.length === 1 ? \"record has\" : \"records have\"} no {fieldName(dateField)},\n so the calendar cannot place {undated.length === 1 ? \"it\" : \"them\"}.\n </p>\n ) : null}\n </div>\n );\n}\n\nfunction Gallery({\n rows,\n fields,\n imageKey,\n onOpenRecord,\n note,\n}: {\n rows: ReadRow[];\n fields: Field[];\n imageKey: string | null;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n note: string;\n}) {\n const shown = fields.slice(0, 4);\n return (\n <div className=\"flex min-h-0 flex-col gap-2\">\n <Note>{note}</Note>\n <ul className=\"grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-2 overflow-y-auto\">\n {rows.map((row) => {\n const image = imageKey ? (row.document ?? {})[imageKey] : null;\n return (\n <li key={row.id}>\n <button\n type=\"button\"\n className=\"flex w-full flex-col gap-1 rounded border p-2 text-left hover:bg-muted\"\n onClick={() => onOpenRecord?.(row.id)}\n >\n {typeof image === \"string\" && image !== \"\" ? (\n <img src={image} alt=\"\" className=\"h-28 w-full rounded object-cover\" />\n ) : null}\n {shown.map((field) => (\n <span key={field.key} className=\"flex min-w-0 items-baseline gap-1 text-xs\">\n <span className=\"shrink-0 text-muted-foreground\">{fieldName(field)}</span>\n <span className=\"min-w-0 truncate\"><RecordValue field={field} value={(row.document ?? {})[field.key]} document={row.document} /></span>\n </span>\n ))}\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\nfunction Card({\n record,\n field,\n onOpenRecord,\n}: {\n record: ReadRow;\n field: Field | undefined;\n onOpenRecord?: ((recordId: Uuid) => void) | undefined;\n}) {\n const host = useRecordsUi();\n // Never a bare identifier on a card: the Field's own value when there is one,\n // the record's name when there is not.\n const label = field\n ? scalarText(field, (record.document ?? {})[field.key])\n : rowName(record, null, \"Untitled\");\n return (\n <button\n type=\"button\"\n className={cn(\n \"w-full truncate rounded border bg-background px-2 py-1 text-left text-xs hover:bg-muted\",\n host.density === \"spacious\" ? \"py-2\" : \"\",\n )}\n onClick={() => onOpenRecord?.(record.id)}\n title={label}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\n// src/ViewBar.tsx — @ai-matrx/records-ui · SCR-7, SCR-N-6\n//\n// THE SAVED VIEWS OF ONE TABLE, AS RECORDS.\n//\n// Each view is ONE record in this organization's own `records_ui_view` Table,\n// declared through the store's doors the first time anything asks for it\n// (`systemTable.ts`). That is what makes a view shareable, exportable,\n// historied and agent-writable without a line of code per feature: it is a\n// record, so everything this package does to records it already does to views.\n//\n// A view owns its LAYOUT and references its MEMBERSHIP RULE. The bar never\n// evaluates a predicate — picking a view hands `ViewSwitcher` a spec, and the\n// store answers who is in it.\n//\n// `seed` is the declarative half: an agent writes a complete view spec, the bar\n// saves it as a record on first sight, and the person only tweaks it.\n//\n// ONE CONTROL FOR ONE THING. This bar used to carry a layout `select` of its\n// own beside `ViewSwitcher`'s layout buttons, and the two disagreed on screen:\n// the verdict of 19 September watched the dropdown keep saying \"Grid\" while\n// Calendar was drawn. The switcher owns the LAYOUT; this bar owns WHICH VIEW.\n// Saving a layout — or a kanban's grouping Field, or a calendar's date Field —\n// onto the view record belongs to whoever owns the switcher (`TablePage`).\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\nimport {\n VIEW_TABLE,\n viewDocument,\n viewFromRecord,\n type SavedView,\n type SavedViewSpec,\n} from \"./views\";\n\nexport interface ViewBarProps {\n /** The Table whose views these are. */\n tableId: Uuid;\n /** The view that is showing. Leave it out and the bar picks the default, then the first. */\n activeViewId?: Uuid | null | undefined;\n onActiveView?: ((view: SavedView) => void) | undefined;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these whose name this\n * table does not have yet is saved as a record the first time the bar loads.\n * The person tweaks them afterwards like any other view.\n */\n seed?: SavedViewSpec[] | undefined;\n className?: string | undefined;\n}\n\nexport function ViewBar({ tableId, activeViewId, onActiveView, seed, className }: ViewBarProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(VIEW_TABLE);\n const [views, setViews] = useState<SavedView[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [active, setActive] = useState<Uuid | null>(activeViewId ?? null);\n const [naming, setNaming] = useState(false);\n const [draftName, setDraftName] = useState(\"\");\n\n const viewTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!viewTableId) return;\n const result = await client.list({ table_id: viewTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n const mine = result.data.rows.map(viewFromRecord).filter((v) => v.subject === tableId);\n\n // The agent's specs, saved once. A seed whose name already exists is left\n // alone — an agent re-running never overwrites what a person has tweaked.\n const missing = (seed ?? []).filter((s) => !mine.some((v) => v.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: viewTableId,\n data: viewDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: viewTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n setViews(again.data.rows.map(viewFromRecord).filter((v) => v.subject === tableId));\n return;\n }\n setError(null);\n setViews(mine);\n }, [client, viewTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!views || views.length === 0) return;\n const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? views.find((v) => v.isDefault) ?? views[0]!;\n if (chosen.id !== active) setActive(chosen.id);\n onActiveView?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [views, activeViewId]);\n\n async function create(name: string) {\n if (!viewTableId || name.trim() === \"\") return;\n const written = await client.recordWrite({\n table_id: viewTableId,\n data: viewDocument({ name: name.trim(), subject: tableId, layout: \"grid\" }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setNaming(false);\n setDraftName(\"\");\n setActive(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (error) return <RefusalNotice error={error} className={className} actions={<Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>Try again</Button>} />;\n if (home.loading || views === null) return <Skeleton className={cn(\"h-7 w-64\", className)} />;\n\n return (\n <div className={cn(\"flex items-center gap-1 overflow-x-auto\", className)} role=\"group\" aria-label=\"Saved views\">\n {views.map((view) => (\n <Button\n key={view.id}\n size=\"sm\"\n variant={view.id === active ? \"secondary\" : \"ghost\"}\n aria-pressed={view.id === active}\n onClick={() => {\n setActive(view.id);\n onActiveView?.(view);\n }}\n title={view.ruleId ? \"Membership is this view's Rule\" : \"The whole table\"}\n >\n {view.name}\n {view.isDefault ? <span className=\"ml-1 text-[10px] text-muted-foreground\">default</span> : null}\n </Button>\n ))}\n\n {/* SCR-4 again: saving a view is administering the table, so a member does\n not get a dead \"New view\" button — there is no button. */}\n {rights.admin ? (\n naming ? (\n <form\n className=\"ml-1 flex items-center gap-1\"\n onSubmit={(e) => {\n e.preventDefault();\n void create(draftName);\n }}\n >\n <Input\n autoFocus\n aria-label=\"Name for the new view\"\n value={draftName}\n onChange={(e) => setDraftName(e.target.value)}\n className=\"h-7 w-40 text-xs\"\n placeholder=\"View name\"\n />\n <Button size=\"sm\" type=\"submit\">\n Save\n </Button>\n </form>\n ) : (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-1\" onClick={() => setNaming(true)}>\n New view\n </Button>\n )\n ) : null}\n\n {views.length === 0 && !rights.admin ? (\n <span className=\"text-xs text-muted-foreground\">{rights.reason}</span>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/seedOnce.ts — @ai-matrx/records-ui\n//\n// THE SEED IS WRITTEN ONCE, AND \"once\" MEANS ONCE PER MOUNT — NOT ONCE PER\n// LOAD THAT HAPPENED TO SEE IT MISSING.\n//\n// Every `seed`-taking component in this package had the same shape: a loader\n// that reads what exists, works out what is missing, writes it, and re-reads.\n// The loader is a `useCallback` whose identity changes when its inputs settle\n// (the Fields arriving is the common one), so the effect runs it again — and if\n// the FIRST run is still in flight, the second run reads a list that does not\n// yet contain what the first is writing, and writes it a second time.\n//\n// It looks harmless until the store is slow. Against the live store this\n// produced two identical \"Agreement\" templates and a screen with two buttons of\n// the same name; the same class had already produced two `signed_by` Fields in\n// the demo's own harness, fixed there the same way. The instance is a race; the\n// class is \"a check against the server's list is not a lock\", and the fix is a\n// claim that lives in the component instance rather than in the answer.\n//\n// CLAIMING IS NOT PERSISTENCE. This never stops a SECOND mount, another tab or\n// another person from seeding — nothing here pretends to be a distributed lock.\n// It stops one component from racing itself, which is the whole of what went\n// wrong. Two tabs seeding at once is the store's problem to answer, and it does.\n\nimport { useCallback, useRef } from \"react\";\n\n/**\n * A per-mount claim over seed names. `claim(\"Agreement\")` answers true exactly\n * once; every later ask for the same name answers false, including while the\n * first write is still in flight.\n */\nexport function useSeedGuard(): (name: string) => boolean {\n const claimed = useRef<Set<string>>(new Set());\n return useCallback((name: string) => {\n if (claimed.current.has(name)) return false;\n claimed.current.add(name);\n return true;\n }, []);\n}\n","\"use client\";\n\n// src/ProposalRow.tsx — @ai-matrx/records-ui · SCR-11\n//\n// ONE ROW PER PROPOSED CHANGE: what changes, why, Accept, Reject — and nothing\n// folded behind a disclosure, because a person deciding needs every line at\n// once. This is the SAME row whether it appears inline in a chat, in the action\n// inbox, or beside a grid; a second reviewer somewhere else is the defect.\n//\n// It refuses to fake three things, and they are worth naming because each one\n// is a way a queue lies:\n// 1. A control that would do nothing is ABSENT, with the reason in words —\n// never a greyed button nobody can explain.\n// 2. The store's answer is shown VERBATIM. \"Written\", \"already there\" and a\n// refusal are three different sentences.\n// 3. Accepting a removal DELETES the record, so the confirmation says that in\n// those words rather than \"this cannot be undone\".\n//\n// Every change is expressed against the record store, because in this platform\n// a field proposal, a table change and a list change are all the same act: a\n// record written, updated or deleted through one door.\n\nimport { useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport { Badge, Button, cn } from \"@ai-matrx/design-system\";\n\n/** One proposed change, in the proposer's words plus the exact act it asks for. */\nexport interface ProposedChange {\n id: string;\n act: \"add\" | \"update\" | \"remove\";\n /**\n * The Table a NEW record lands in. Required for `add` and unused by `update`\n * and `remove`, which name a record instead — and it is optional for exactly\n * that reason: it used to be required for all three, so a proposer wanting to\n * change an existing record had to supply the id of the kernel Table that\n * record lives in, which is a fact the client has no door to ask for. A\n * required field a caller cannot fill is a field that gets filled with\n * something untrue.\n */\n table?: Uuid | undefined;\n /** The record it changes. Required for `update` and `remove`. */\n record?: Uuid | undefined;\n /** The document for `add`, or the patch for `update`. */\n data?: Record<string, unknown> | undefined;\n /** What this change is, in one line a person reads. */\n label: string;\n /** Why the proposer asks for it. Optional, and shown when it is there. */\n why?: string | undefined;\n}\n\nexport type ProposalOutcome =\n | { settled: \"accepted\"; sentence: string }\n | { settled: \"rejected\"; sentence: string }\n | { settled: \"refused\"; sentence: string };\n\nexport interface ProposalRowProps {\n change: ProposedChange;\n /** What already happened to this change, when the host remembers decisions. */\n outcome?: ProposalOutcome | undefined;\n /**\n * The apply port. Left unbound, the row applies the change through the record\n * store itself — the default that makes the component plug and play. A host\n * whose proposals land somewhere else (a different store, a server lane)\n * binds this and keeps the SAME row.\n */\n onApply?: ((change: ProposedChange) => Promise<ProposalOutcome>) | undefined;\n onReject?: ((change: ProposedChange) => Promise<ProposalOutcome> | ProposalOutcome) | undefined;\n /** Absent controls with this reason, instead of dead ones. */\n readOnlyReason?: string | undefined;\n onSettled?: ((outcome: ProposalOutcome) => void) | undefined;\n className?: string | undefined;\n}\n\nconst ACT_WORD: Record<ProposedChange[\"act\"], string> = {\n add: \"Add\",\n update: \"Update\",\n remove: \"Remove\",\n};\n\nexport function ProposalRow({\n change,\n outcome,\n onApply,\n onReject,\n readOnlyReason,\n onSettled,\n className,\n}: ProposalRowProps) {\n const client = useRecordsClient();\n const [settled, setSettled] = useState<ProposalOutcome | null>(outcome ?? null);\n const [busy, setBusy] = useState(false);\n const [confirming, setConfirming] = useState(false);\n\n async function applyThroughTheStore(): Promise<ProposalOutcome> {\n if (change.act === \"add\") {\n if (!change.table) {\n // Not a silent no-op: the proposal is malformed and says which part.\n return {\n settled: \"refused\",\n sentence:\n \"This proposal asks to add a record but does not name the table it goes in, so nothing was written.\",\n };\n }\n const written = await client.recordWrite({ table_id: change.table, data: change.data ?? {} });\n return written.ok\n ? { settled: \"accepted\", sentence: \"Written.\" }\n : { settled: \"refused\", sentence: written.error.message };\n }\n if (!change.record) {\n // Not a silent no-op: the proposal is malformed and says which part.\n return {\n settled: \"refused\",\n sentence: `This proposal asks to ${change.act} a record but does not name one, so nothing was changed.`,\n };\n }\n if (change.act === \"update\") {\n const updated = await client.recordUpdate({ record_id: change.record, patch: change.data ?? {} });\n return updated.ok\n ? { settled: \"accepted\", sentence: \"Written.\" }\n : { settled: \"refused\", sentence: updated.error.message };\n }\n const removed = await client.recordDelete({ record_id: change.record });\n return removed.ok\n ? { settled: \"accepted\", sentence: \"Deleted. The store keeps it restorable for this table's retention.\" }\n : { settled: \"refused\", sentence: removed.error.message };\n }\n\n async function accept() {\n setBusy(true);\n const result = onApply ? await onApply(change) : await applyThroughTheStore();\n setBusy(false);\n setConfirming(false);\n setSettled(result);\n onSettled?.(result);\n }\n\n async function reject() {\n const result: ProposalOutcome = onReject\n ? await onReject(change)\n : { settled: \"rejected\", sentence: \"Rejected.\" };\n setSettled(result);\n onSettled?.(result);\n }\n\n return (\n <div className={cn(\"flex flex-col gap-1 rounded border p-2\", className)}>\n {/* One row: the act, what changes, and the decision. No second header. */}\n <div className=\"flex items-baseline gap-2\">\n <Badge variant={change.act === \"remove\" ? \"destructive\" : \"secondary\"} className=\"text-[10px]\">\n {ACT_WORD[change.act]}\n </Badge>\n <span className=\"min-w-0 flex-1 truncate text-xs\" title={change.label}>\n {change.label}\n </span>\n {settled ? (\n <span\n className={cn(\n \"shrink-0 text-xs\",\n settled.settled === \"refused\" ? \"text-destructive\" : \"text-muted-foreground\",\n )}\n >\n {settled.settled === \"accepted\" ? \"Accepted\" : settled.settled === \"rejected\" ? \"Rejected\" : \"Refused\"}\n </span>\n ) : readOnlyReason ? null : (\n <span className=\"flex shrink-0 items-center gap-1\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n disabled={busy}\n onClick={() => void reject()}\n >\n Reject\n </Button>\n <Button\n size=\"sm\"\n disabled={busy}\n onClick={() => (change.act === \"remove\" ? setConfirming(true) : void accept())}\n >\n Accept\n </Button>\n </span>\n )}\n </div>\n\n {change.why ? <p className=\"text-xs text-muted-foreground\">{change.why}</p> : null}\n\n {/* The store's own sentence, verbatim. */}\n {settled ? <p className=\"text-xs text-muted-foreground\">{settled.sentence}</p> : null}\n\n {/* A destructive accept names the consequence in those words. */}\n {confirming ? (\n <div className=\"flex items-center gap-2 rounded bg-destructive/10 p-2 text-xs\">\n <span className=\"min-w-0 flex-1\">\n Accepting this deletes the record. It stays restorable for this table&apos;s retention, and after\n that it is gone.\n </span>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setConfirming(false)}>\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"destructive\" disabled={busy} onClick={() => void accept()}>\n Delete it\n </Button>\n </div>\n ) : null}\n\n {readOnlyReason && !settled ? <p className=\"text-xs text-muted-foreground\">{readOnlyReason}</p> : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/ActionInbox.tsx — @ai-matrx/records-ui · SCR-11\n//\n// ONE QUEUE. Approvals, assignments and agent proposals — field, table and\n// list-change alike — arrive in the same place, in the same row shape, with the\n// same two verbs.\n//\n// That is the whole point of the component: a platform where an approval lives\n// in one screen, an assignment in another and an agent's suggestion inline in a\n// chat is a platform where people miss things. Every one of them is a record in\n// this organization's own `records_ui_action` Table, so an agent files work for\n// a person with ONE `record_write` and it appears here.\n//\n// THE ROW IS `ProposalRow`, not a variant of it. A change in how a decision is\n// presented happens once, and every surface that shows one inherits it.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\nimport { ProposalRow, type ProposalOutcome, type ProposedChange } from \"./ProposalRow\";\n\n/** The three things that land in the queue. One word each, closed. */\nexport const ACTION_KINDS = [\"approval\", \"assignment\", \"proposal\"] as const;\nexport type ActionKind = (typeof ACTION_KINDS)[number];\n\n/** The package-owned Table every queued action is a record of. */\nexport const ACTION_TABLE: SystemTableSpec = {\n slug: \"records_ui_action\",\n name: \"Action inbox\",\n labelSingular: \"Action\",\n labelPlural: \"Actions\",\n titleField: \"title\",\n fields: [\n { key: \"title\", label: \"What\", type: \"text\", sort: 10, required: true },\n { key: \"kind\", label: \"Kind\", type: \"text\", sort: 20, required: true },\n { key: \"why\", label: \"Why\", type: \"text\", sort: 30, config: { multiline: true } },\n { key: \"status\", label: \"Status\", type: \"text\", sort: 40 },\n { key: \"assignee\", label: \"For\", type: \"text\", sort: 50 },\n { key: \"subject_table\", label: \"In table\", type: \"text\", sort: 60 },\n { key: \"subject\", label: \"About\", type: \"text\", sort: 70 },\n { key: \"changes\", label: \"Proposed changes\", type: \"text\", sort: 80, config: { multiline: true } },\n { key: \"answer\", label: \"Answer\", type: \"text\", sort: 90, config: { multiline: true } },\n // The read door answers documents, not row metadata, so when an action was\n // filed is part of the action.\n { key: \"at\", label: \"Filed\", type: \"text\", sort: 100 },\n ],\n};\n\n/**\n * THE DECLARATIVE SPEC an agent writes. One `record_write` of this document puts\n * a decision in front of a person — there is no per-feature approval plumbing\n * anywhere in the platform.\n */\nexport interface QueuedActionSpec {\n kind: ActionKind;\n title: string;\n why?: string | undefined;\n assignee?: Uuid | null | undefined;\n subjectTable?: Uuid | null | undefined;\n subject?: Uuid | null | undefined;\n /** For a proposal: the exact acts being asked for. */\n changes?: ProposedChange[] | undefined;\n}\n\nexport interface QueuedAction extends QueuedActionSpec {\n id: Uuid;\n /**\n * The version this row was read at. The read door answers documents and not\n * versions, so a queue row carries null and settling it is the store's\n * ordinary last-writer-wins write — the row's own `status` is what a second\n * settler then sees.\n */\n version: number | null;\n status: \"open\" | \"accepted\" | \"rejected\" | \"refused\";\n answer: string | null;\n at: string;\n}\n\nexport function actionDocument(spec: QueuedActionSpec): Record<string, unknown> {\n return {\n title: spec.title,\n kind: spec.kind,\n why: spec.why ?? null,\n status: \"open\",\n assignee: spec.assignee ?? null,\n subject_table: spec.subjectTable ?? null,\n subject: spec.subject ?? null,\n changes: JSON.stringify(spec.changes ?? []),\n answer: null,\n // The queue sorts newest first and the read door answers no row metadata,\n // so the moment it was filed is part of the action itself.\n at: new Date().toISOString(),\n };\n}\n\nexport interface ActionInboxProps {\n /** Narrow the queue to one table's actions. Left out, it is everything waiting. */\n tableId?: Uuid | null | undefined;\n /** Show settled actions too. The default is what is still waiting. */\n includeSettled?: boolean | undefined;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these the queue does not\n * already hold (by title) is filed as a record on first load.\n */\n seed?: QueuedActionSpec[] | undefined;\n onOpenRecord?: ((recordId: Uuid, tableId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function ActionInbox({ tableId, includeSettled = false, seed, onOpenRecord, className }: ActionInboxProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const home = useSystemTable(ACTION_TABLE);\n const [actions, setActions] = useState<QueuedAction[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n const queueTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!queueTableId) return;\n const result = await client.list({ table_id: queueTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n const held = result.data.rows.map(toAction);\n const missing = (seed ?? []).filter((s) => !held.some((a) => a.title === s.title));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.title)) continue;\n const written = await client.recordWrite({ table_id: queueTableId, data: actionDocument(spec) });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: queueTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n setError(null);\n setActions(again.data.rows.map(toAction));\n return;\n }\n setError(null);\n setActions(held);\n }, [client, queueTableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const shown = useMemo(() => {\n const all = actions ?? [];\n return all\n .filter((a) => (tableId ? a.subjectTable === tableId : true))\n .filter((a) => (includeSettled ? true : a.status === \"open\"))\n .sort((a, b) => b.at.localeCompare(a.at));\n }, [actions, tableId, includeSettled]);\n\n /** Stamp the action record with what happened, in the store's own sentence. */\n async function settle(action: QueuedAction, outcome: ProposalOutcome) {\n const updated = await client.recordUpdate({\n record_id: action.id,\n patch: { status: outcome.settled, answer: outcome.sentence },\n ...(action.version === null ? {} : { expectedVersion: action.version }),\n });\n if (!updated.ok) {\n setError(updated.error);\n return;\n }\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (home.loading || actions === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">Inbox</h3>\n <span className=\"text-xs text-muted-foreground\">{shown.length}</span>\n <div className=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Refresh\n </Button>\n </div>\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {shown.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {includeSettled ? \"Nothing has come through this queue yet.\" : \"Nothing is waiting on you.\"}\n </p>\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\">\n {shown.map((action) => (\n <li key={action.id} className=\"flex flex-col gap-1 rounded border p-2\">\n {/* One row: kind, what it is, when — no repeated title below. */}\n <div className=\"flex items-baseline gap-2\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {action.kind}\n </Badge>\n <span className=\"min-w-0 flex-1 truncate text-xs font-medium\">{action.title}</span>\n {action.subject && action.subjectTable && onOpenRecord ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-5 px-1 text-[11px]\"\n onClick={() => onOpenRecord(action.subject!, action.subjectTable!)}\n >\n Open\n </Button>\n ) : null}\n <span className=\"shrink-0 text-[11px] tabular-nums text-muted-foreground\">\n {new Date(action.at).toLocaleDateString()}\n </span>\n </div>\n {action.why ? <p className=\"text-xs text-muted-foreground\">{action.why}</p> : null}\n\n {(action.changes ?? []).length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {(action.changes ?? []).map((change) => (\n <li key={change.id}>\n {/* THE SAME ROW an inline chat proposal uses. */}\n <ProposalRow\n change={change}\n {...(action.status === \"open\"\n ? {}\n : { outcome: { settled: action.status, sentence: action.answer ?? \"\" } as ProposalOutcome })}\n onSettled={(outcome) => void settle(action, outcome)}\n />\n </li>\n ))}\n </ul>\n ) : action.status === \"open\" ? (\n // An approval or an assignment carries no change set, so it gets\n // the same two verbs with nothing to apply: the decision itself\n // is the act, and it is recorded on the action.\n <div className=\"flex items-center gap-1\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() =>\n void settle(action, {\n settled: \"rejected\",\n sentence: action.kind === \"assignment\" ? \"Declined.\" : \"Not approved.\",\n })\n }\n >\n {action.kind === \"assignment\" ? \"Decline\" : \"Reject\"}\n </Button>\n <Button\n size=\"sm\"\n onClick={() =>\n void settle(action, {\n settled: \"accepted\",\n sentence: action.kind === \"assignment\" ? \"Taken.\" : \"Approved.\",\n })\n }\n >\n {action.kind === \"assignment\" ? \"Take it\" : \"Approve\"}\n </Button>\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">{action.answer}</p>\n )}\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n\nfunction toAction(row: ReadRow): QueuedAction {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const status = String(data[\"status\"] ?? \"open\");\n return {\n id: row.id,\n version: null,\n kind: (ACTION_KINDS as readonly string[]).includes(String(data[\"kind\"])) ? (data[\"kind\"] as ActionKind) : \"approval\",\n title: String(data[\"title\"] ?? \"Untitled\"),\n why: (data[\"why\"] as string | undefined) ?? undefined,\n assignee: (data[\"assignee\"] as string | null) ?? null,\n subjectTable: (data[\"subject_table\"] as string | null) ?? null,\n subject: (data[\"subject\"] as string | null) ?? null,\n changes: parseChanges(data[\"changes\"]),\n status: ([\"open\", \"accepted\", \"rejected\", \"refused\"] as string[]).includes(status)\n ? (status as QueuedAction[\"status\"])\n : \"open\",\n answer: (data[\"answer\"] as string | null) ?? null,\n at: String(data[\"at\"] ?? \"\"),\n };\n}\n\nfunction parseChanges(raw: unknown): ProposedChange[] {\n if (Array.isArray(raw)) return raw as ProposedChange[];\n if (typeof raw !== \"string\" || raw.trim() === \"\") return [];\n try {\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as ProposedChange[]) : [];\n } catch {\n return [];\n }\n}\n","\"use client\";\n\n// src/HistoryPanel.tsx — @ai-matrx/records-ui · SCR-17\n//\n// WHO CHANGED WHAT, WHEN — from the record's own values, not from a log this\n// package keeps.\n//\n// The store writes a version envelope per VALUE (`custom.record_values_versioned`\n// answers `value_version`, `actor`, `on_behalf_of`, `written_at` and the\n// interned `source` for every field key), so the timeline is the record itself\n// read honestly. There is no second history table to drift from the record.\n//\n// VAL-8 / AGT-N-4 are visible here and they matter: an agent carries the exact\n// authority of the person operating it, so a line written by an agent names\n// BOTH — \"agent, on behalf of <person>\" — and never hides the person behind the\n// machine.\n//\n// THE UNDO DOOR is the store's own soft delete: `record_delete` is reversible\n// within the Table's retention and `record_restore` is the reversal. A deleted\n// record's panel therefore offers Restore and says when the door closes; it\n// does not pretend the record is gone.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport {\n useFields,\n useRecordsClient,\n useTable,\n type ReadValue,\n type RecordRead,\n type Uuid,\n} from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { scalarText } from \"./values\";\n\nexport interface HistoryPanelProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface Entry {\n fieldKey: string;\n label: string;\n version: number;\n at: string | null;\n actor: string;\n onBehalfOf: string | null;\n text: string;\n source: string | null;\n}\n\nexport function HistoryPanel({ tableId, recordId, className }: HistoryPanelProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const [read, setRead] = useState<RecordRead | null>(null);\n const [version, setVersion] = useState<number | null>(null);\n /** The store said `02000` for this record: it is soft-deleted, and Restore is its verb. */\n const [gone, setGone] = useState(false);\n const [values, setValues] = useState<Record<string, ReadValue> | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const [said, setSaid] = useState<string | null>(null);\n\n // THE TIMELINE IS THE RECORD. `record_values_versioned` gives every value its\n // own version, writer, `on_behalf_of` and moment, so there is no second\n // history table to drift. The read door answers documents and deliberately\n // not row metadata, so the record's own version and whether it is deleted\n // come from its revisions (`custom.io_revisions`) — the store, either way.\n const load = useCallback(async () => {\n const [read, versioned, revisions] = await Promise.all([\n client.recordRead({ record_id: recordId }),\n client.recordValuesVersioned({ record_id: recordId }),\n client.revisions({ record_id: recordId }),\n ]);\n // A SOFT-DELETED RECORD IS NOT AN ERROR ON THIS SCREEN. The read door says\n // `02000 There is no record …` for a record the store has deleted — which\n // is exactly the state whose one verb is Restore, so it is read as that\n // state rather than shown as a refusal. Any other refusal is still shown.\n if (!read.ok && read.error.sqlstate !== \"02000\") {\n setError(read.error);\n return;\n }\n setGone(!read.ok);\n if (!versioned.ok) {\n setError(versioned.error);\n return;\n }\n setError(null);\n const byKey: Record<string, ReadValue> = {};\n for (const value of versioned.data) byKey[value.field_key] = value;\n setValues(byKey);\n setVersion(\n revisions.ok\n ? revisions.data.reduce<number | null>(\n (held: number | null, r: { version: number }) => (held === null || r.version > held ? r.version : held),\n null,\n )\n : null,\n );\n setRead(read.ok ? read.data : { record_id: recordId, document: {}, hidden: {}, computed: [] });\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n // NO COMPONENT ACTS BEFORE THE STORE HAS ANSWERED. The undo verb is decided by\n // the TABLE's rights, so a panel drawn while the Table is still loading would\n // show a timeline with no verb on it and no reason why — the same class the\n // grid and the import wizard already wait for.\n if (!read || !values || fields.loading || table.loading) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n const labels = new Map((fields.data ?? []).map((f) => [f.key, f] as const));\n const entries: Entry[] = Object.values(values)\n .map((value) => {\n const field = labels.get(value.field_key);\n return {\n fieldKey: value.field_key,\n label: field?.label || value.field_key,\n version: value.value_version ?? 1,\n at: value.written_at,\n actor: value.actor ?? \"unknown\",\n onBehalfOf: value.on_behalf_of,\n text: value.absent_reason\n ? `absent — ${value.absent_reason}`\n : field\n ? scalarText(field, value.value)\n : JSON.stringify(value.value),\n source: value.source ? Object.values(value.source).map(String).join(\" · \") : null,\n };\n })\n .sort((a, b) => (b.at ?? \"\").localeCompare(a.at ?? \"\"));\n\n const deleted = gone;\n const retention = table.data?.retention_days ?? null;\n\n async function undo(action: \"delete\" | \"restore\") {\n setBusy(true);\n const result =\n action === \"delete\"\n ? await client.recordDelete({ record_id: recordId })\n : await client.recordRestore({ record_id: recordId });\n setBusy(false);\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setSaid(\n action === \"delete\"\n ? retention === null\n ? \"Deleted. The store keeps it reversible; Restore brings it back.\"\n : `Deleted. Restore brings it back for the next ${retention} days.`\n : \"Restored.\",\n );\n await load();\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row. The record's state and its one reversible verb. */}\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">History</h3>\n {version === null ? null : <span className=\"text-xs text-muted-foreground\">v{version}</span>}\n {deleted ? <Badge variant=\"destructive\" className=\"text-[10px]\">Deleted</Badge> : null}\n <div className=\"ml-auto flex items-center gap-1\">\n {rights.write ? (\n <Button size=\"sm\" variant={deleted ? \"secondary\" : \"ghost\"} disabled={busy} onClick={() => void undo(deleted ? \"restore\" : \"delete\")}>\n {deleted ? \"Restore\" : \"Delete\"}\n </Button>\n ) : null}\n </div>\n </div>\n\n {said ? <p className=\"text-xs text-muted-foreground\">{said}</p> : null}\n {deleted && !said ? (\n <p className=\"text-xs text-muted-foreground\">\n {retention === null\n ? \"This record is soft-deleted and Restore brings it back.\"\n : `This record is soft-deleted and stays restorable for ${retention} days.`}\n </p>\n ) : null}\n\n {entries.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">This record has no values yet, so there is nothing to show a history of.</p>\n ) : (\n <ol className=\"flex min-h-0 flex-col divide-y overflow-y-auto rounded border\">\n {entries.map((entry) => (\n <li key={`${entry.fieldKey}-${entry.version}`} className=\"flex items-baseline gap-2 px-2 py-1 text-xs\">\n <span className=\"w-28 shrink-0 truncate font-medium\">{entry.label}</span>\n <span className=\"min-w-0 flex-1 truncate\" title={entry.text}>\n {entry.text}\n </span>\n <span className=\"shrink-0 tabular-nums text-muted-foreground\">v{entry.version}</span>\n <span className=\"shrink-0 text-muted-foreground\" title={entry.source ?? undefined}>\n {/* AGT-N-4: an agent never hides the person it acted for. */}\n {entry.onBehalfOf ? `${entry.actor}, for ${entry.onBehalfOf}` : entry.actor}\n </span>\n <span className=\"w-36 shrink-0 text-right tabular-nums text-muted-foreground\">\n {entry.at ? new Date(entry.at).toLocaleString() : \"—\"}\n </span>\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n","\"use client\";\n\n// src/CommentThread.tsx — @ai-matrx/records-ui · SCR-18\n//\n// A COMMENT IS A RECORD. It lives in this organization's own\n// `records_ui_comment` Table (declared on first use through the store's doors),\n// which is what makes a comment searchable, exportable, agent-readable and\n// subject to the same organization wall as everything else — with no per-feature\n// comment table anywhere.\n//\n// SCR-18's right is `commenter`: a person who may comment but not write records\n// gets the composer, and a person who may not comment gets no composer AND the\n// reason, never a dead box that swallows what they typed.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, useTable, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\n\n/** The package-owned Table every comment is a record of. */\nexport const COMMENT_TABLE: SystemTableSpec = {\n slug: \"records_ui_comment\",\n name: \"Comments\",\n labelSingular: \"Comment\",\n labelPlural: \"Comments\",\n titleField: \"body\",\n fields: [\n { key: \"body\", label: \"Comment\", type: \"text\", sort: 10, required: true, config: { multiline: true } },\n { key: \"subject\", label: \"About\", type: \"text\", sort: 20, required: true },\n { key: \"subject_table\", label: \"In table\", type: \"text\", sort: 30 },\n { key: \"reply_to\", label: \"Reply to\", type: \"text\", sort: 40 },\n { key: \"resolved\", label: \"Resolved\", type: \"text\", sort: 50 },\n // The read door answers documents, not row metadata: who said it and when\n // are part of the comment.\n { key: \"by\", label: \"By\", type: \"text\", sort: 60 },\n { key: \"at\", label: \"At\", type: \"text\", sort: 70 },\n ],\n};\n\nexport interface CommentThreadProps {\n /** The Table the commented-on record belongs to — its rights decide the composer. */\n tableId: Uuid;\n /** The record being discussed. */\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface Comment {\n id: Uuid;\n body: string;\n replyTo: string | null;\n resolved: boolean;\n by: string | null;\n at: string;\n}\n\nexport function CommentThread({ tableId, recordId, className }: CommentThreadProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(COMMENT_TABLE);\n const [comments, setComments] = useState<Comment[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [draft, setDraft] = useState(\"\");\n const [replyTo, setReplyTo] = useState<Uuid | null>(null);\n const [busy, setBusy] = useState(false);\n\n const commentTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!commentTableId) return;\n const result = await client.list({ table_id: commentTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setError(null);\n setComments(\n result.data.rows\n .filter((row) => (row.document as Record<string, unknown>)?.[\"subject\"] === recordId)\n .map(toComment)\n .sort((a, b) => a.at.localeCompare(b.at)),\n );\n }, [client, commentTableId, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function post() {\n if (!commentTableId || draft.trim() === \"\") return;\n setBusy(true);\n const written = await client.recordWrite({\n table_id: commentTableId,\n data: {\n body: draft.trim(),\n subject: recordId,\n subject_table: tableId,\n reply_to: replyTo,\n resolved: \"false\",\n by: client.config.actor.user_id ?? null,\n at: new Date().toISOString(),\n },\n });\n setBusy(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setDraft(\"\");\n setReplyTo(null);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (home.loading || comments === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n const threads = comments.filter((c) => !c.replyTo);\n const repliesOf = (id: string) => comments.filter((c) => c.replyTo === id);\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-sm font-medium\">Comments</h3>\n <span className=\"text-xs text-muted-foreground\">{comments.length}</span>\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {threads.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No comments on this record yet.</p>\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\">\n {threads.map((comment) => (\n <li key={comment.id} className=\"rounded border p-2\">\n <Line comment={comment} onReply={rights.comment ? () => setReplyTo(comment.id) : undefined} />\n {repliesOf(comment.id).length > 0 ? (\n <ol className=\"mt-1 flex flex-col gap-1 border-l pl-2\">\n {repliesOf(comment.id).map((reply) => (\n <li key={reply.id}>\n <Line comment={reply} />\n </li>\n ))}\n </ol>\n ) : null}\n </li>\n ))}\n </ol>\n )}\n\n {rights.comment ? (\n <form\n className=\"flex flex-col gap-1\"\n onSubmit={(e) => {\n e.preventDefault();\n void post();\n }}\n >\n {replyTo ? (\n <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n Replying\n <Button size=\"sm\" variant=\"ghost\" type=\"button\" onClick={() => setReplyTo(null)}>\n Cancel\n </Button>\n </span>\n ) : null}\n <Textarea\n aria-label=\"Write a comment\"\n rows={2}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n className=\"text-xs\"\n placeholder=\"Write a comment\"\n />\n <div className=\"flex\">\n <Button size=\"sm\" type=\"submit\" className=\"ml-auto\" disabled={busy || draft.trim() === \"\"}>\n Comment\n </Button>\n </div>\n </form>\n ) : (\n // No dead composer. The reason the store or the host gave, in full.\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n )}\n </section>\n );\n}\n\nfunction Line({ comment, onReply }: { comment: Comment; onReply?: (() => void) | undefined }) {\n return (\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-baseline gap-2 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">{comment.by ?? \"unknown\"}</span>\n <span className=\"tabular-nums\">{new Date(comment.at).toLocaleString()}</span>\n {onReply ? (\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-5 px-1 text-[11px]\" onClick={onReply}>\n Reply\n </Button>\n ) : null}\n </div>\n <p className=\"whitespace-pre-wrap text-xs\">{comment.body}</p>\n </div>\n );\n}\n\nfunction toComment(row: ReadRow): Comment {\n const data = (row.document ?? {}) as Record<string, unknown>;\n return {\n id: row.id,\n body: String(data[\"body\"] ?? \"\"),\n replyTo: (data[\"reply_to\"] as string | null) ?? null,\n resolved: data[\"resolved\"] === \"true\",\n by: (data[\"by\"] as string | null) ?? null,\n at: String(data[\"at\"] ?? \"\"),\n };\n}\n","\"use client\";\n\n// src/forms.ts — @ai-matrx/records-ui · SCR-13, SCR-14\n//\n// A FORM IS A VIEW ON A REAL TABLE.\n//\n// It is not a second data model with its own \"responses\" store that somebody\n// later has to reconcile with the records people actually work on. A form names\n// a Table, each of its questions names one of that Table's own Fields, and a\n// submission is an ORDINARY RECORD in that Table — so the moment it is sent it\n// is in the grid, in the views, in the exports, in History and in the agent's\n// context, with no plumbing in between.\n//\n// THE AI-FIRST LAW. We build a Typeform duplicate not because people will click\n// a form together one question at a time, but because an agent writes the WHOLE\n// thing in one `record_write` and the person only tweaks it. `FormSpec` below is\n// that complete declarative object: name, questions, conditional logic, theme,\n// thank-you screen. `FormBuilder` takes one as `seed`, exactly as `ViewBar` and\n// `ActionInbox` do.\n//\n// CONDITIONAL LOGIC IS A RULE, NOT AN `if`. `showIf` is a Rule expression the\n// STORE evaluates (`custom.rule_eval`), referencing Fields BY ID. So the same\n// form means the same thing to the runner, to the server and to an agent, and\n// nobody re-implements the predicate in JavaScript where it can drift.\n\nimport type { ReadRow, RuleExpression, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** How a form is put in front of a person. */\nexport const FORM_FLOWS = [\"one-at-a-time\", \"single-page\"] as const;\nexport type FormFlow = (typeof FORM_FLOWS)[number];\n\n/** One question. It ASKS FOR one Field of the subject Table — never its own column. */\nexport interface FormQuestionSpec {\n /** The Field's key on the subject Table. */\n field: string;\n /** Ask it in the form's own words. Left out, the Field's own label is the question. */\n ask?: string | null;\n /** One line under the question. */\n help?: string | null;\n /** Override the Field's own `required`. Left out, the Field decides. */\n required?: boolean | null;\n /**\n * CONDITIONAL LOGIC, AS A RULE. `{\"op\":\"eq\",\"args\":[{\"field\":\"<field id>\"},{\"const\":\"Yes\"}]}`\n * — the store answers it, this package never does. An UNDECIDED answer (the\n * store's `null`, which is what an unanswered question gives) SHOWS the\n * question: a person is never silently skipped past something.\n */\n showIf?: RuleExpression | null;\n}\n\n/** The look. Tokens, so light and dark both come out right without a second theme. */\nexport interface FormTheme {\n /** A design-system accent class or a CSS color. Left out, the app's own accent. */\n accent?: string | null;\n align?: \"left\" | \"center\" | null;\n}\n\n/** THE COMPLETE DECLARATIVE SPEC. One `record_write` and the form exists. */\nexport interface FormSpec {\n name: string;\n /** The Table a submission lands in. */\n subject: Uuid;\n intro?: string | null;\n questions: FormQuestionSpec[];\n flow?: FormFlow | null;\n theme?: FormTheme | null;\n thankYou?: { title: string; body?: string | null } | null;\n submitLabel?: string | null;\n /**\n * Is this form meant to be answerable by someone who is not signed in? The\n * runner does NOT make that true by itself — it needs the anonymous write\n * door, and until that door exists it says so BY NAME rather than writing as\n * whoever happens to be signed in and calling it public.\n */\n isPublic?: boolean;\n}\n\n/** A form as it comes back out of the store, with its record's own id and version. */\nexport interface SavedForm extends FormSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every form is a record of. */\nexport const FORM_TABLE: SystemTableSpec = {\n slug: \"records_ui_form\",\n name: \"Forms\",\n labelSingular: \"Form\",\n labelPlural: \"Forms\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"intro\", label: \"Intro\", type: \"text\", sort: 30, config: { multiline: true } },\n { key: \"questions\", label: \"Questions\", type: \"text\", sort: 40, config: { multiline: true } },\n { key: \"flow\", label: \"Flow\", type: \"text\", sort: 50 },\n { key: \"theme\", label: \"Theme\", type: \"text\", sort: 60, config: { multiline: true } },\n { key: \"thank_you\", label: \"Thank-you screen\", type: \"text\", sort: 70, config: { multiline: true } },\n { key: \"submit_label\", label: \"Submit button\", type: \"text\", sort: 80 },\n { key: \"is_public\", label: \"Public\", type: \"text\", sort: 90 },\n ],\n};\n\n/** The spec as the one document the store holds. */\nexport function formDocument(spec: FormSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n intro: spec.intro ?? null,\n questions: JSON.stringify(spec.questions ?? []),\n flow: spec.flow ?? \"one-at-a-time\",\n theme: JSON.stringify(spec.theme ?? {}),\n thank_you: JSON.stringify(spec.thankYou ?? null),\n submit_label: spec.submitLabel ?? null,\n is_public: spec.isPublic ? \"true\" : \"false\",\n };\n}\n\n/** One stored record back into the spec a screen and an agent both read. */\nexport function formFromRecord(row: ReadRow): SavedForm {\n const data = (row.document ?? {}) as Record<string, unknown>;\n const flow = String(data[\"flow\"] ?? \"one-at-a-time\");\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled form\"),\n subject: String(data[\"subject\"] ?? \"\"),\n intro: (data[\"intro\"] as string | null) ?? null,\n questions: parseJson<FormQuestionSpec[]>(data[\"questions\"], []),\n flow: (FORM_FLOWS as readonly string[]).includes(flow) ? (flow as FormFlow) : \"one-at-a-time\",\n theme: parseJson<FormTheme>(data[\"theme\"], {}),\n thankYou: parseJson<{ title: string; body?: string | null } | null>(data[\"thank_you\"], null) ?? null,\n submitLabel: (data[\"submit_label\"] as string | null) ?? null,\n isPublic: data[\"is_public\"] === \"true\",\n };\n}\n\nfunction parseJson<T>(raw: unknown, fallback: T): T {\n if (raw === null || raw === undefined) return fallback;\n if (typeof raw !== \"string\") return raw as T;\n if (raw.trim() === \"\") return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\n/**\n * THE SOURCE STAMP every submission carries. A record that arrived through a\n * form is not indistinguishable from one somebody typed into the grid: it says\n * which form, which version of it, when, and who was acting. `_source` is a\n * stamp on the document beside the answers, so it travels with the record\n * through export, History and the agent's context without a parallel table.\n */\nexport function submissionStamp(args: {\n formId: Uuid | null;\n formName: string;\n actor: string;\n onBehalfOf?: string | null;\n}): Record<string, unknown> {\n return {\n _source: {\n via: \"form\",\n form_id: args.formId,\n form_name: args.formName,\n at: new Date().toISOString(),\n actor: args.actor,\n ...(args.onBehalfOf ? { on_behalf_of: args.onBehalfOf } : {}),\n },\n };\n}\n","\"use client\";\n\n// src/FormBuilder.tsx — @ai-matrx/records-ui · SCR-13\n//\n// THE FORM BUILDER, BUILT FOR THE AGENT FIRST.\n//\n// `seed` takes COMPLETE declarative `FormSpec`s an agent wrote — the whole form\n// in one object, questions, conditions, theme and thank-you screen included —\n// and saves each one that is not there yet as a record. That is the 45 seconds\n// the law is about. Everything else on this screen is the TWEAK: a person\n// changes what the agent got wrong, one control at a time, and never has to\n// assemble a form field by field to have one.\n//\n// The questions a person can add are the subject Table's own Fields, because a\n// form is a view on a real Table — there is no way in this screen to invent a\n// question that lands nowhere, which is why a submission is a record and not a\n// \"response\" in a second store.\n//\n// A condition is written as the store's own Rule expression, pointing at a\n// Field BY ID (REC-17). The builder never writes a field NAME into a rule: the\n// store refuses that by name, and it is right to.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, RuleExpression } from \"@ai-matrx/records\";\nimport {\n BasicInput,\n BasicTextarea,\n Button,\n Checkbox,\n Label,\n Skeleton,\n cn,\n} from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useRecordVersion, useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { FormRunner } from \"./FormRunner\";\nimport { fieldName } from \"./names\";\nimport {\n FORM_FLOWS,\n FORM_TABLE,\n formDocument,\n formFromRecord,\n type FormFlow,\n type FormQuestionSpec,\n type FormSpec,\n type SavedForm,\n} from \"./forms\";\n\nexport interface FormBuilderProps {\n /** The Table this form collects into. A form is a view on a real Table. */\n tableId: Uuid;\n /**\n * COMPLETE DECLARATIVE SPECS an agent wrote. Any of these whose name this\n * table does not have yet is saved as a record the first time the builder\n * loads. A seed whose name exists is LEFT ALONE — an agent re-running never\n * overwrites what a person has since tweaked.\n */\n seed?: FormSpec[] | undefined;\n activeFormId?: Uuid | null | undefined;\n onActiveForm?: ((form: SavedForm) => void) | undefined;\n className?: string | undefined;\n}\n\n/** The comparisons a condition can make. The store's own operator names. */\nconst CONDITION_OPS: Array<{ op: string; label: string }> = [\n { op: \"eq\", label: \"is\" },\n { op: \"ne\", label: \"is not\" },\n { op: \"present\", label: \"has been answered\" },\n { op: \"gt\", label: \"is more than\" },\n { op: \"lt\", label: \"is less than\" },\n];\n\nexport function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }: FormBuilderProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const home = useSystemTable(FORM_TABLE);\n const [forms, setForms] = useState<SavedForm[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeFormId ?? null);\n const [draft, setDraft] = useState<SavedForm | null>(null);\n const [saving, setSaving] = useState(false);\n const [saved, setSaved] = useState<string | null>(null);\n // The version of the form record this screen LOADED, read for the one record\n // being edited. Null means the save is the store's last-writer-wins write.\n const loaded = useRecordVersion(activeId);\n\n const formTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!formTableId) return;\n const result = await client.list({ table_id: formTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n let mine = result.data.rows.map(formFromRecord).filter((f) => f.subject === tableId);\n const missing = (seed ?? []).filter((s) => !mine.some((f) => f.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: formTableId,\n data: formDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: formTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n mine = again.data.rows.map(formFromRecord).filter((f) => f.subject === tableId);\n }\n setError(null);\n setForms(mine);\n }, [client, formTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!forms || forms.length === 0) return;\n const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n setDraft(chosen);\n onActiveForm?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [forms, activeFormId]);\n\n const byKey = useMemo(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);\n\n function patch(change: Partial<FormSpec>) {\n setDraft((prev) => (prev ? { ...prev, ...change } : prev));\n setSaved(null);\n }\n\n function patchQuestion(index: number, change: Partial<FormQuestionSpec>) {\n setDraft((prev) => {\n if (!prev) return prev;\n const questions = prev.questions.map((q, i) => (i === index ? { ...q, ...change } : q));\n return { ...prev, questions };\n });\n setSaved(null);\n }\n\n async function save() {\n if (!draft || !formTableId) return;\n setSaving(true);\n const document = formDocument(draft);\n const written = await client.recordUpdate({\n record_id: draft.id,\n patch: document,\n // The form record's own version: two people editing one form are TOLD.\n ...(loaded.version === null ? {} : { expectedVersion: loaded.version }),\n });\n setSaving(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n // Saving twice in a row is two saves, never a conflict with yourself.\n loaded.note(written.data);\n setSaved(\"Saved.\");\n await load();\n }\n\n async function create(name: string) {\n if (!formTableId) return;\n const written = await client.recordWrite({\n table_id: formTableId,\n data: formDocument({ name, subject: tableId, questions: [] }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setActiveId(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (home.loading || fields.loading || forms === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!rights.admin) {\n // SCR-4 again: building a form is administering the table. There is no\n // greyed-out builder — there is no builder, and the reason is readable.\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n }\n\n return (\n <div className={cn(\"flex min-h-0 gap-3\", className)}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-2 overflow-auto\">\n {/* One row: the forms, the flow, the save. No repeated names. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Forms\">\n {forms.map((form) => (\n <Button\n key={form.id}\n size=\"sm\"\n variant={form.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={form.id === activeId}\n onClick={() => {\n setActiveId(form.id);\n setDraft(form);\n }}\n >\n {form.name}\n </Button>\n ))}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void create(`Form ${forms.length + 1}`)}>\n New form\n </Button>\n <span className=\"ml-auto flex items-center gap-2\">\n {saved ? <span className=\"text-xs text-muted-foreground\">{saved}</span> : null}\n <Button size=\"sm\" disabled={saving || !draft} onClick={() => void save()}>\n {saving ? \"Saving…\" : \"Save\"}\n </Button>\n </span>\n </div>\n\n {!draft ? (\n <p className=\"text-xs text-muted-foreground\">\n No form collects into this table yet. \"New form\" makes one, or an agent writes a whole one with a\n single record.\n </p>\n ) : (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Name</Label>\n <BasicInput value={draft.name} onChange={(e) => patch({ name: e.target.value })} />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Flow</Label>\n <select\n className=\"h-9 rounded border bg-background px-2 text-sm\"\n value={draft.flow ?? \"one-at-a-time\"}\n onChange={(e) => patch({ flow: e.target.value as FormFlow })}\n >\n {FORM_FLOWS.map((flow) => (\n <option key={flow} value={flow}>\n {flow === \"one-at-a-time\" ? \"One question at a time\" : \"All on one page\"}\n </option>\n ))}\n </select>\n </label>\n <label className=\"col-span-2 flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Intro</Label>\n <BasicTextarea\n rows={2}\n value={draft.intro ?? \"\"}\n onChange={(e) => patch({ intro: e.target.value || null })}\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Submit button</Label>\n <BasicInput\n value={draft.submitLabel ?? \"\"}\n placeholder=\"Submit\"\n onChange={(e) => patch({ submitLabel: e.target.value || null })}\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Thank-you title</Label>\n <BasicInput\n value={draft.thankYou?.title ?? \"\"}\n placeholder=\"Thank you\"\n onChange={(e) =>\n patch({\n thankYou: e.target.value\n ? { title: e.target.value, body: draft.thankYou?.body ?? null }\n : null,\n })\n }\n />\n </label>\n </div>\n\n {/* The questions. Each one asks for a Field this Table actually has. */}\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Questions</span>\n <span>{draft.questions.length} of this table's {fields.data?.length ?? 0} fields</span>\n </div>\n {(fields.data ?? []).map((field) => {\n const index = draft.questions.findIndex((q) => q.field === field.key);\n const asked = index >= 0;\n const question = asked ? draft.questions[index]! : null;\n return (\n <div key={field.id} className=\"rounded border px-2 py-1.5\">\n <div className=\"flex items-center gap-2\">\n <Checkbox\n checked={asked}\n aria-label={`Ask for ${fieldName(field)}`}\n onCheckedChange={(checked) =>\n patch({\n questions: checked\n ? [...draft.questions, { field: field.key }]\n : draft.questions.filter((q) => q.field !== field.key),\n })\n }\n />\n <span className=\"text-xs font-medium\">{fieldName(field)}</span>\n <span className=\"text-xs text-muted-foreground\">{field.key}</span>\n {field.required ? <span className=\"text-xs text-destructive\">required</span> : null}\n </div>\n {asked && question ? (\n <div className=\"mt-1.5 grid grid-cols-2 gap-2 pl-6\">\n <BasicInput\n className=\"h-8 text-xs\"\n placeholder={fieldName(field)}\n aria-label={`How to ask for ${field.key}`}\n value={question.ask ?? \"\"}\n onChange={(e) => patchQuestion(index, { ask: e.target.value || null })}\n />\n <BasicInput\n className=\"h-8 text-xs\"\n placeholder=\"Help text\"\n aria-label={`Help text for ${field.key}`}\n value={question.help ?? \"\"}\n onChange={(e) => patchQuestion(index, { help: e.target.value || null })}\n />\n <Condition\n question={question}\n fieldKeys={fields.data ?? []}\n onChange={(showIf) => patchQuestion(index, { showIf })}\n />\n </div>\n ) : null}\n </div>\n );\n })}\n {draft.questions\n .filter((q) => !byKey.has(q.field))\n .map((q) => (\n <p key={q.field} className=\"text-xs text-destructive\">\n This form asks for \"{q.field}\" and this table has no such Field. It is shown here rather\n than quietly dropped.\n </p>\n ))}\n </div>\n </>\n )}\n </div>\n\n {/* The preview is the RUNNER, not a picture of it: what a person will actually meet. */}\n {draft ? (\n <aside className=\"w-96 shrink-0 overflow-auto rounded border p-2\">\n <FormRunner form={draft} preview />\n </aside>\n ) : null}\n </div>\n );\n}\n\n/** The one condition row. It writes the store's own Rule expression, by Field id. */\nfunction Condition({\n question,\n fieldKeys,\n onChange,\n}: {\n question: FormQuestionSpec;\n fieldKeys: Array<{ id: string; key: string; label: string }>;\n onChange: (showIf: RuleExpression | null) => void;\n}) {\n const expr = question.showIf as { op?: string; args?: Array<{ field?: string; const?: unknown }> } | null;\n const op = expr?.op ?? \"\";\n const onField = expr?.args?.[0]?.field ?? \"\";\n const value = expr?.args?.[1]?.const ?? \"\";\n\n function write(next: { op?: string; field?: string; value?: unknown }) {\n const chosenOp = next.op ?? op;\n const chosenField = next.field ?? onField;\n const chosenValue = next.value ?? value;\n if (!chosenOp || !chosenField) {\n onChange(null);\n return;\n }\n onChange(\n chosenOp === \"present\"\n ? ({ op: \"present\", args: [{ field: chosenField }] } as RuleExpression)\n : ({ op: chosenOp, args: [{ field: chosenField }, { const: chosenValue }] } as RuleExpression),\n );\n }\n\n return (\n <div className=\"col-span-2 flex items-center gap-1 text-xs\">\n <span className=\"text-muted-foreground\">Ask only when</span>\n <select\n aria-label=\"Condition field\"\n className=\"h-8 rounded border bg-background px-1 text-xs\"\n value={onField}\n onChange={(e) => write({ field: e.target.value })}\n >\n <option value=\"\">always</option>\n {fieldKeys.map((f) => (\n <option key={f.id} value={f.id}>\n {f.label || f.key}\n </option>\n ))}\n </select>\n {onField ? (\n <>\n <select\n aria-label=\"Condition comparison\"\n className=\"h-8 rounded border bg-background px-1 text-xs\"\n value={op}\n onChange={(e) => write({ op: e.target.value })}\n >\n {CONDITION_OPS.map((c) => (\n <option key={c.op} value={c.op}>\n {c.label}\n </option>\n ))}\n </select>\n {op !== \"present\" ? (\n <BasicInput\n className=\"h-8 w-28 text-xs\"\n aria-label=\"Condition value\"\n value={String(value ?? \"\")}\n onChange={(e) => write({ value: e.target.value })}\n />\n ) : null}\n </>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/FormRunner.tsx — @ai-matrx/records-ui · SCR-14\n//\n// THE FORM, AS THE PERSON ANSWERING IT SEES IT. One question at a time, a\n// progress line that is honest about how many questions are actually left, the\n// keyboard doing what a keyboard does (Enter goes on, Shift+Enter goes back),\n// and a submission that is an ORDINARY RECORD in a real Table the moment it is\n// sent.\n//\n// FOUR THINGS THIS COMPONENT REFUSES TO DO:\n//\n// 1. It never evaluates a condition itself. `showIf` is a Rule and the STORE\n// answers it (`custom.rule_eval`), so the form branches the same way for a\n// person, for the server and for an agent. An UNDECIDED answer — which is\n// what the store returns for a question nobody has answered yet — SHOWS the\n// question. Undecided is not false, and silently skipping a person past\n// something is the exact failure the store's own null-handling avoids.\n// 2. It never draws a file chooser with nowhere to put the file. With no\n// `upload` port bound the attachment question says so in one sentence.\n// 3. It never calls itself public. `isPublic` needs the anonymous write door;\n// until that door exists the runner works SIGNED IN and says \"public link\n// pending\" naming `custom.anon_record_write` and the lane that owes it.\n// 4. It never invents its own editors. Every answer is taken with the same\n// `FieldControl` the record form uses, so a currency in a form and a\n// currency in the grid are the same control with the same unit.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useFields, useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport { doorExists, DOORS } from \"@ai-matrx/records/core\";\nimport type { Field, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Progress, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { FieldControl, FieldLabel } from \"./editors\";\nimport { editorKindFor } from \"./parity\";\nimport { NO_UPLOAD_REASON, useRecordsUi } from \"./host\";\nimport { submissionStamp, type FormSpec, type SavedForm } from \"./forms\";\n\nexport interface FormRunnerProps {\n /** The complete spec. An agent wrote it; `FormBuilder` saved it; this runs it. */\n form: FormSpec | SavedForm;\n /** Preview mode answers the questions but writes nothing, and says so. */\n preview?: boolean | undefined;\n onSubmitted?: ((recordId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\ntype Answers = Record<string, unknown>;\n\n/** One question resolved against the subject Table's own Fields. */\ninterface ResolvedQuestion {\n key: string;\n ask: string;\n help: string | null;\n required: boolean;\n /** Null when the Table has no such Field — named on screen, never dropped. */\n field: Field | null;\n showIf: unknown;\n}\n\nexport function FormRunner({ form, preview = false, onSubmitted, className }: FormRunnerProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const fields = useFields(form.subject);\n const [answers, setAnswers] = useState<Answers>({});\n const [at, setAt] = useState(0);\n const [error, setError] = useState<RecordsError | null>(null);\n const [writing, setWriting] = useState(false);\n const [done, setDone] = useState<Uuid | \"preview\" | null>(null);\n /** Which conditional questions the STORE said to hide. Keyed by field key. */\n const [hidden, setHidden] = useState<Record<string, boolean>>({});\n const stage = useRef<HTMLDivElement>(null);\n\n const questions: ResolvedQuestion[] = useMemo(() => {\n const byKey = new Map((fields.data ?? []).map((f) => [f.key, f]));\n return (form.questions ?? []).map((q) => {\n const field = byKey.get(q.field) ?? null;\n return {\n key: q.field,\n ask: q.ask ?? field?.label ?? q.field,\n help: q.help ?? null,\n required: q.required ?? field?.required ?? false,\n field,\n showIf: q.showIf ?? null,\n };\n });\n }, [fields.data, form.questions]);\n\n // ── the conditions, answered by the STORE ────────────────────────────────\n // Re-asked whenever an answer changes, because that is what a condition is\n // about. One call per conditional question; a form with no conditions makes\n // no calls at all.\n useEffect(() => {\n let cancelled = false;\n const conditional = questions.filter((q) => q.showIf);\n if (conditional.length === 0) return;\n void (async () => {\n const next: Record<string, boolean> = {};\n for (const q of conditional) {\n const answered = await client.ruleEval({ expr: q.showIf, values: answers });\n if (!answered.ok) {\n // A condition the store could not work out is NOT a silent hide: the\n // question stays, and the store's sentence is shown above the form.\n if (!cancelled) setError(answered.error);\n next[q.key] = false;\n continue;\n }\n // `null` is UNDECIDED. Undecided shows the question.\n next[q.key] = answered.data === false;\n }\n if (!cancelled) setHidden(next);\n })();\n return () => {\n cancelled = true;\n };\n }, [client, questions, answers]);\n\n const live = questions.filter((q) => !hidden[q.key]);\n const oneAtATime = (form.flow ?? \"one-at-a-time\") === \"one-at-a-time\";\n const index = Math.min(at, Math.max(live.length - 1, 0));\n const current = live[index];\n const centred = (form.theme?.align ?? \"center\") === \"center\";\n\n const answered = live.filter((q) => {\n const v = answers[q.key];\n return v !== undefined && v !== null && v !== \"\";\n }).length;\n\n const missing = live.filter((q) => {\n const v = answers[q.key];\n return q.required && (v === undefined || v === null || v === \"\");\n });\n\n const submit = useCallback(async () => {\n if (preview) {\n setDone(\"preview\");\n return;\n }\n setWriting(true);\n setError(null);\n const document = {\n ...Object.fromEntries(live.map((q) => [q.key, answers[q.key] ?? null])),\n ...submissionStamp({\n formId: (form as SavedForm).id ?? null,\n formName: form.name,\n actor: client.config.actor.actor,\n onBehalfOf: client.config.actor.on_behalf_of ?? null,\n }),\n };\n const written = await client.recordWrite({ table_id: form.subject, data: document });\n setWriting(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setDone(written.data);\n onSubmitted?.(written.data);\n }, [answers, client, form, live, onSubmitted, preview]);\n\n function advance() {\n if (!oneAtATime) return;\n if (index < live.length - 1) setAt(index + 1);\n else if (missing.length === 0) void submit();\n }\n\n function retreat() {\n if (oneAtATime && index > 0) setAt(index - 1);\n }\n\n // The keyboard flow. Enter goes on, Shift+Enter goes back — except inside a\n // long-text answer, where Enter is a new line and always has been.\n function onKeyDown(event: React.KeyboardEvent) {\n if (event.key !== \"Enter\") return;\n const target = event.target as HTMLElement;\n if (target.tagName === \"TEXTAREA\" && !event.metaKey && !event.ctrlKey) return;\n event.preventDefault();\n if (event.shiftKey) retreat();\n else advance();\n }\n\n useEffect(() => {\n // Moving to a question puts the caret in it: a person who is typing never\n // has to reach for the mouse to answer the next one.\n const input = stage.current?.querySelector<HTMLElement>(\"input, textarea, select, [role='combobox']\");\n input?.focus();\n }, [index, done]);\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (fields.loading) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n // ── the thank-you screen ─────────────────────────────────────────────────\n if (done) {\n return (\n <section className={cn(\"mx-auto max-w-xl py-10\", centred && \"text-center\", className)}>\n <h2 className=\"text-lg font-medium\">{form.thankYou?.title ?? \"Thank you\"}</h2>\n {form.thankYou?.body ? <p className=\"mt-1 text-sm text-muted-foreground\">{form.thankYou.body}</p> : null}\n <p className=\"mt-3 text-xs text-muted-foreground\">\n {done === \"preview\"\n ? \"This was a preview, so nothing was written.\"\n : `Saved as a record in ${form.name}. It is in the table now, with this form stamped on it.`}\n </p>\n </section>\n );\n }\n\n const unresolved = questions.filter((q) => !q.field);\n // W4-ANON LANDED, AND UNDER A DIFFERENT NAME THAN THIS PACKAGE GUESSED AT.\n // The lane is `custom.anon_write` behind `custom.anon_token_verify`, not one\n // door called `anon_record_write`, and while this file named the guess every\n // person answering a public form was told the feature was \"pending\" for\n // something that had shipped. A screen calling a live feature pending is the\n // same silent failure as a screen calling a missing one live.\n //\n // What is still true: a public answer is posted with an EMBED TOKEN, from an\n // allowed origin, into a PUBLISHED form — none of which a signed-in runner\n // has. So a public form mounted here still runs signed-in, and now says the\n // true reason and the exact thing to do about it.\n const publicPending = form.isPublic === true && !doorExists(DOORS.anonWrite);\n const publicNeedsEmbed = form.isPublic === true && doorExists(DOORS.anonWrite);\n\n return (\n <section\n className={cn(\"mx-auto flex max-w-xl flex-col gap-3 py-4\", centred && \"text-center\", className)}\n onKeyDown={onKeyDown}\n >\n {/* One row. The name, the progress, the count — no subtitle restating the name. */}\n <header className=\"flex items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{form.name}</span>\n <Progress value={live.length === 0 ? 0 : (answered / live.length) * 100} className=\"h-1 flex-1\" />\n <span className=\"tabular-nums\">\n {oneAtATime ? `${index + 1} of ${live.length}` : `${answered} of ${live.length}`}\n </span>\n </header>\n\n {publicPending ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-muted-foreground\">\n Public link pending: this store has no <code>custom.anon_write</code> door, so this form is being\n answered as the person signed in, and their name is what the record will carry.\n </p>\n ) : null}\n\n {publicNeedsEmbed ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-muted-foreground\">\n You are answering this signed in, so the record will carry your name. A stranger answers the same\n form through an embed: issue one with <code>EmbedFrame</code>, publish the form, and their answer\n arrives as a quarantined submission rather than a record written as whoever happened to be signed\n in here.\n </p>\n ) : null}\n\n {unresolved.length > 0 ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-left text-xs text-destructive\">\n {unresolved.map((q) => q.key).join(\", \")} {unresolved.length === 1 ? \"is a question\" : \"are questions\"} this\n form asks for and this table has no such Field. Add the Field, or take the question out — it is\n shown here rather than quietly dropped, because a dropped question is an answer nobody gave.\n </p>\n ) : null}\n\n {form.intro && index === 0 ? <p className=\"text-sm text-muted-foreground\">{form.intro}</p> : null}\n\n {error ? <RefusalNotice error={error} className=\"text-left\" /> : null}\n\n <div ref={stage} className=\"flex flex-col gap-4 text-left\">\n {(oneAtATime ? (current ? [current] : []) : live).map((q) => (\n <Question\n key={q.key}\n question={q}\n value={answers[q.key]}\n onChange={(v) => setAnswers((prev) => ({ ...prev, [q.key]: v }))}\n upload={host.upload}\n />\n ))}\n {live.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n Every question in this form is hidden by its own condition right now, so there is nothing to\n answer yet.\n </p>\n ) : null}\n </div>\n\n <footer className={cn(\"flex items-center gap-2\", centred && \"justify-center\")}>\n {oneAtATime && index > 0 ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={retreat}>\n Back\n </Button>\n ) : null}\n {oneAtATime && index < live.length - 1 ? (\n <Button size=\"sm\" onClick={advance}>\n Next\n </Button>\n ) : (\n <Button size=\"sm\" disabled={writing || missing.length > 0} onClick={() => void submit()}>\n {writing ? \"Sending…\" : (form.submitLabel ?? \"Submit\")}\n </Button>\n )}\n {missing.length > 0 && (!oneAtATime || index === live.length - 1) ? (\n <span className=\"text-xs text-muted-foreground\">\n {missing.map((q) => q.ask).join(\", \")} still {missing.length === 1 ? \"needs\" : \"need\"} an answer.\n </span>\n ) : null}\n {preview ? <span className=\"text-xs text-muted-foreground\">Preview — nothing is written.</span> : null}\n </footer>\n </section>\n );\n}\n\n/** One question: the Field's own editor, or the honest sentence when it cannot be drawn. */\nfunction Question({\n question,\n value,\n onChange,\n upload,\n}: {\n question: ResolvedQuestion;\n value: unknown;\n onChange: (value: unknown) => void;\n upload: ReturnType<typeof useRecordsUi>[\"upload\"];\n}) {\n const [uploadError, setUploadError] = useState<string | null>(null);\n const field = question.field;\n if (!field) return null;\n\n const id = `form-${field.key}`;\n const isAttachment = editorKindFor(field) === \"attachment\";\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel field={{ ...field, label: question.ask, required: question.required }} htmlFor={id} />\n {question.help ? <p className=\"text-xs text-muted-foreground\">{question.help}</p> : null}\n {isAttachment && !upload ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_UPLOAD_REASON}</p>\n ) : isAttachment ? (\n <>\n <input\n id={id}\n type=\"file\"\n className=\"text-xs\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploadError(null);\n void upload?.(file).then((result) => {\n if (!result) return;\n if (result.ok) onChange(result.fileId);\n else setUploadError(result.reason);\n });\n }}\n />\n {uploadError ? <p className=\"text-xs text-destructive\">{uploadError}</p> : null}\n </>\n ) : (\n <FieldControl field={field} value={value} onChange={onChange} id={id} />\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/charts.ts — @ai-matrx/records-ui · SCR-15, SCR-16\n//\n// A CHART IS A QUESTION THE STORE ANSWERS, NOT A PILE OF ROWS A BROWSER SUMS.\n//\n// Every block here is drawn from ONE call to `custom.record_aggregate` — the\n// eighth verb (AGT-N-8) — whose aggregate node sits ABOVE the join to the read\n// door's visibility set. Two consequences, and both of them are the reason this\n// file exists at all:\n//\n// · A chart shows exactly the records this person may see. Rows they may not\n// see are never fetched, so they cannot be summed and then hidden — and a\n// total that quietly included them would be a screen lying in the one place\n// nobody would ever check.\n// · A dashboard over a hundred thousand records is one round trip per block,\n// not a hundred thousand rows over the wire.\n//\n// AND A DASHBOARD IS ONE RECORD. `DashboardSpec` is the whole thing — every\n// block, its question and its shape — so an agent writes a finished dashboard\n// with ONE `record_write` and the person only tweaks it.\n\nimport type { AggregateBucket, AggregateMeasure, ReadRow, Uuid } from \"@ai-matrx/records\";\nimport type { SystemTableSpec } from \"./systemTable\";\n\n/** The shapes a block can take. Closed: a shape nobody drew is not offered. */\nexport const CHART_KINDS = [\"bar\", \"column\", \"line\", \"donut\", \"number\", \"table\"] as const;\nexport type ChartKind = (typeof CHART_KINDS)[number];\n\nexport const CHART_KIND_LABEL: Record<ChartKind, string> = {\n bar: \"Bars\",\n column: \"Columns\",\n line: \"Line\",\n donut: \"Donut\",\n number: \"Number\",\n table: \"Table\",\n};\n\n/** What each shape needs before it can draw, in one sentence a block prints. */\nexport const CHART_NEEDS: Record<ChartKind, string | null> = {\n bar: \"A bar chart needs something to group by — pick a Field and the bars appear.\",\n column: \"A column chart needs something to group by — pick a Field and the columns appear.\",\n line: \"A line needs a date Field to run along — pick one and the line appears.\",\n donut: \"A donut needs something to group by — pick a Field and the slices appear.\",\n number: null,\n table: null,\n};\n\n/** ONE BLOCK: the question and the shape, in one declarative object. */\nexport interface ChartSpec {\n title: string;\n /** The Table this block asks about. */\n subject: Uuid;\n kind: ChartKind;\n /** Field keys whose values become the groups. */\n groupBy?: string[];\n /** A date Field truncated to a period — what a line runs along. */\n bucket?: { key: string; by: AggregateBucket } | null;\n /** `count` needs no key; every other measure reads one Field. */\n measures?: AggregateMeasure[];\n /** Equality only, and the store puts it in the SAME WHERE as visibility. */\n filter?: Record<string, string>;\n limit?: number;\n /** How wide this block sits on the canvas, in twelfths. */\n span?: number;\n}\n\n/** THE WHOLE DASHBOARD, as one object an agent writes in one call. */\nexport interface DashboardSpec {\n name: string;\n /** The Table most of its blocks are about. A block may name another. */\n subject: Uuid;\n blocks: ChartSpec[];\n}\n\nexport interface SavedDashboard extends DashboardSpec {\n id: Uuid;\n /**\n * The record's version AT LOAD, read from `custom.io_revisions` for the one\n * record being edited. The read door answers documents and not versions, so\n * this is null until it has been read — and a save with a null version is an\n * ordinary last-writer-wins write, exactly as the store defines it.\n */\n version: number | null;\n}\n\n/** The package-owned Table every dashboard is a record of. */\nexport const DASHBOARD_TABLE: SystemTableSpec = {\n slug: \"records_ui_dashboard\",\n name: \"Dashboards\",\n labelSingular: \"Dashboard\",\n labelPlural: \"Dashboards\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"blocks\", label: \"Blocks\", type: \"text\", sort: 30, config: { multiline: true } },\n ],\n};\n\nexport function dashboardDocument(spec: DashboardSpec): Record<string, unknown> {\n return {\n name: spec.name,\n subject: spec.subject,\n blocks: JSON.stringify(spec.blocks ?? []),\n };\n}\n\nexport function dashboardFromRecord(row: ReadRow): SavedDashboard {\n const data = (row.document ?? {}) as Record<string, unknown>;\n let blocks: ChartSpec[] = [];\n const raw = data[\"blocks\"];\n if (Array.isArray(raw)) blocks = raw as ChartSpec[];\n else if (typeof raw === \"string\" && raw.trim() !== \"\") {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (Array.isArray(parsed)) blocks = parsed as ChartSpec[];\n } catch {\n blocks = [];\n }\n }\n return {\n id: row.id,\n version: null,\n name: String(data[\"name\"] ?? \"Untitled dashboard\"),\n subject: String(data[\"subject\"] ?? \"\"),\n blocks,\n };\n}\n\n/**\n * The series palette. Six SEMANTIC tokens the design system already flips for\n * dark mode, so a chart is correct in both themes without a second palette and\n * without a hex code anywhere in this package.\n */\nexport const SERIES_COLORS = [\n \"hsl(var(--primary))\",\n \"hsl(var(--info))\",\n \"hsl(var(--success))\",\n \"hsl(var(--warning))\",\n \"hsl(var(--destructive))\",\n \"hsl(var(--accent-foreground))\",\n] as const;\n\n/** The label one aggregate row carries — its groups, joined the way a person reads them. */\nexport function groupLabel(groups: Record<string, string | null>): string {\n const parts = Object.values(groups).map((v) => (v === null || v === \"\" ? \"—\" : v));\n return parts.length === 0 ? \"All records\" : parts.join(\" · \");\n}\n","\"use client\";\n\n// src/docs.ts — @ai-matrx/records-ui · SCR-20, SCR-21, SCR-22\n//\n// DOCUMENTS OVER RECORDS. A template is a body whose tokens point at Fields BY\n// ID; a render is written ONCE and frozen with the SHA-256 of its own text; a\n// signature seals that exact version and is immutable once made.\n//\n// Three things this package refuses to re-implement, because the store already\n// does them and doing them twice is how two answers appear:\n// · which tokens a body contains — `custom.doc_tokens`;\n// · which of them this Table cannot answer, and why — `custom.doc_unresolved_tokens`;\n// · whether a signature still holds — `custom.doc_signature_intact`.\n//\n// The token syntax is the store's own: `{{field:<the field's id>}}`. A name\n// would be a token that silently stops resolving the day somebody renames a\n// Field, which is the exact failure REC-17 exists to prevent.\n\nimport type { Field, Uuid } from \"@ai-matrx/records\";\n\n/** The one token form, written the way the store's own pattern reads it. */\nexport function fieldToken(fieldId: Uuid): string {\n return `{{field:${fieldId}}}`;\n}\n\n/** THE DECLARATIVE SPEC an agent writes. One template, whole, in one object. */\nexport interface DocTemplateSpec {\n name: string;\n /** The body, tokens and all. */\n body: string;\n}\n\n/**\n * A template written in terms of Field KEYS — which is how an agent thinks and\n * how a person reads — turned into the store's id-based tokens. The agent writes\n * `{{title}}`; what is stored points at the Field's id, so a rename never\n * silently empties the document.\n *\n * A key this Table does not have is LEFT EXACTLY AS IT IS, so\n * `custom.doc_unresolved_tokens` names it and the screen shows the store's own\n * reason — it is never quietly deleted from the body.\n */\nexport function bodyFromKeys(body: string, fields: Field[]): string {\n const byKey = new Map(fields.map((f) => [f.key, f.id]));\n return body.replace(/\\{\\{\\s*([a-zA-Z0-9_]+)\\s*\\}\\}/g, (whole, key: string) => {\n const id = byKey.get(key);\n return id ? fieldToken(id) : whole;\n });\n}\n\n/** The reverse, for a person reading a stored body: ids shown as the Field's label. */\nexport function bodyForReading(body: string, fields: Field[]): string {\n const byId = new Map(fields.map((f) => [f.id, f.label || f.key]));\n return body.replace(/\\{\\{\\s*field:([0-9a-fA-F-]{36})\\s*\\}\\}/g, (whole, id: string) => {\n const label = byId.get(id);\n return label ? `{{${label}}}` : whole;\n });\n}\n\n/** VAL-10: a signature is a Value on a text Field whose format is `signature`. */\nexport function isSignatureField(field: Field): boolean {\n return field.type === \"text\" && (field.format ?? \"\").toLowerCase() === \"signature\";\n}\n","\"use client\";\n\n// src/DocTemplate.tsx — @ai-matrx/records-ui · SCR-20\n//\n// THE TEMPLATE EDITOR. A body, a palette of this Table's own Fields, and the\n// STORE's verdict on which tokens it cannot answer — never this package's.\n//\n// `custom.doc_unresolved_tokens` is asked on every change and its sentence is\n// shown verbatim beside the token it is about. A template is still saveable\n// with an unresolved token, because half-written is a normal state; what is not\n// allowed is publishing one and letting a token reach a person's document\n// looking like text somebody typed.\n//\n// `seed` is the agent's half, as everywhere: complete templates written in\n// Field KEYS (`{{title}}`), converted to the store's id-based tokens on the way\n// in, so a rename never silently empties a contract.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocTemplateRow, DocUnresolvedToken, RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, BasicTextarea, Button, Label, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useTableRights } from \"./host\";\nimport { bodyFromKeys, fieldToken, type DocTemplateSpec } from \"./docs\";\nimport { fieldName } from \"./names\";\n\nexport interface DocTemplateProps {\n /** The Table these templates render. */\n tableId: Uuid;\n /** COMPLETE templates an agent wrote, in Field keys. Saved once, never overwritten. */\n seed?: DocTemplateSpec[] | undefined;\n activeTemplateId?: Uuid | null | undefined;\n onActiveTemplate?: ((template: DocTemplateRow) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }: DocTemplateProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const [templates, setTemplates] = useState<DocTemplateRow[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeTemplateId ?? null);\n const [draftName, setDraftName] = useState(\"\");\n const [draftBody, setDraftBody] = useState(\"\");\n const [unresolved, setUnresolved] = useState<DocUnresolvedToken[]>([]);\n const [saving, setSaving] = useState(false);\n\n const load = useCallback(async () => {\n const held = await client.docTemplates({ table_id: tableId });\n if (!held.ok) {\n setError(held.error);\n return;\n }\n let rows = held.data;\n const missing = (seed ?? []).filter((s) => !rows.some((t) => t.name === s.name));\n if (missing.length > 0 && (fields.data ?? []).length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const saved = await client.docTemplateSave({\n table_id: tableId,\n name: spec.name,\n body: bodyFromKeys(spec.body, fields.data ?? []),\n });\n if (!saved.ok) {\n setError(saved.error);\n return;\n }\n }\n const again = await client.docTemplates({ table_id: tableId });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n rows = again.data;\n }\n setError(null);\n setTemplates(rows);\n }, [client, tableId, seed, fields.data]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!templates || templates.length === 0) return;\n const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n setDraftName(chosen.name);\n setDraftBody(chosen.body);\n onActiveTemplate?.(chosen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [templates, activeTemplateId]);\n\n // The STORE's verdict on the body, re-asked as it is typed. Never this\n // package's own idea of which token resolves.\n useEffect(() => {\n let cancelled = false;\n if (draftBody.trim() === \"\") {\n setUnresolved([]);\n return;\n }\n void client.docUnresolvedTokens({ table_id: tableId, body: draftBody }).then((answered) => {\n if (cancelled) return;\n if (answered.ok) setUnresolved(answered.data);\n });\n return () => {\n cancelled = true;\n };\n }, [client, tableId, draftBody]);\n\n async function save() {\n setSaving(true);\n const saved = await client.docTemplateSave({\n table_id: tableId,\n name: draftName.trim() || \"Untitled template\",\n body: draftBody,\n template_id: activeId,\n });\n setSaving(false);\n if (!saved.ok) {\n setError(saved.error);\n return;\n }\n setActiveId(saved.data);\n await load();\n }\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (templates === null || fields.loading) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!rights.admin) {\n return <p className={cn(\"text-xs text-muted-foreground\", className)}>{rights.reason}</p>;\n }\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row: the templates, the version, the save. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Templates\">\n {templates.map((t) => (\n <Button\n key={t.id}\n size=\"sm\"\n variant={t.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={t.id === activeId}\n onClick={() => {\n setActiveId(t.id);\n setDraftName(t.name);\n setDraftBody(t.body);\n }}\n >\n {t.name}\n <span className=\"ml-1 text-[10px] text-muted-foreground\">v{t.template_version}</span>\n </Button>\n ))}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n setActiveId(null);\n setDraftName(\"\");\n setDraftBody(\"\");\n }}\n >\n New template\n </Button>\n <Button size=\"sm\" className=\"ml-auto\" disabled={saving} onClick={() => void save()}>\n {saving ? \"Saving…\" : \"Save\"}\n </Button>\n </div>\n\n <label className=\"flex flex-col gap-1\">\n <Label className=\"text-xs font-medium\">Name</Label>\n <BasicInput value={draftName} onChange={(e) => setDraftName(e.target.value)} placeholder=\"Agreement\" />\n </label>\n\n {/* The palette: this Table's own Fields, inserted as the store's own token. */}\n <div className=\"flex flex-wrap items-center gap-1\">\n <span className=\"text-xs text-muted-foreground\">Insert</span>\n {(fields.data ?? []).map((field) => (\n <Button\n key={field.id}\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 px-1.5 text-xs\"\n onClick={() => setDraftBody((body) => `${body}${fieldToken(field.id)}`)}\n >\n {fieldName(field)}\n </Button>\n ))}\n </div>\n\n <BasicTextarea\n rows={10}\n aria-label=\"Template body\"\n className=\"font-mono text-xs\"\n value={draftBody}\n onChange={(e) => setDraftBody(e.target.value)}\n />\n\n {/* The store's own sentence per token it cannot answer — verbatim. */}\n {unresolved.length > 0 ? (\n <ul className=\"flex flex-col gap-0.5 rounded border border-dashed px-2 py-1 text-xs\">\n {unresolved.map((token) => (\n <li key={token.raw} className=\"text-destructive\">\n <code>{token.raw}</code> — {token.why}\n </li>\n ))}\n </ul>\n ) : draftBody.trim() !== \"\" ? (\n <p className=\"text-xs text-muted-foreground\">\n Every token in this body points at a Field this table can answer.\n </p>\n ) : null}\n </div>\n );\n}\n","\"use client\";\n\n// src/DocRender.tsx — @ai-matrx/records-ui · SCR-21\n//\n// ONE TEMPLATE, ONE RECORD, ONE DOCUMENT — and the preview and the frozen\n// version are the SAME bytes, because both come from the store.\n//\n// `custom.doc_render_body` resolves the tokens without writing anything, which\n// is the preview. `custom.doc_render_document` writes the render: the text and\n// the SHA-256 of that text, frozen. Everything downstream — a signature, a PDF,\n// a link somebody sends — is about a VERSION, never about \"the document as it\n// happens to read today\". That is the whole reason a render is a row and not a\n// function call a screen repeats.\n//\n// The PDF is `@ai-matrx/print`'s, not a second renderer: the platform has one\n// answer to \"make this a PDF\" and this screen uses it.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocRenderRow, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\n\nexport interface DocRenderProps {\n templateId: Uuid;\n recordId: Uuid;\n /** A name for the file when somebody takes the PDF. */\n filename?: string | undefined;\n onRendered?: ((render: DocRenderRow) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function DocRender({ templateId, recordId, filename, onRendered, className }: DocRenderProps) {\n const client = useRecordsClient();\n const [preview, setPreview] = useState<string | null>(null);\n const [renders, setRenders] = useState<DocRenderRow[] | null>(null);\n const [showing, setShowing] = useState<Uuid | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const paper = useRef<HTMLDivElement>(null);\n\n const load = useCallback(async () => {\n const [body, held] = await Promise.all([\n client.docRenderBody({ template_id: templateId, record_id: recordId }),\n client.docRenders({ record_id: recordId }),\n ]);\n if (!body.ok) {\n setError(body.error);\n return;\n }\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setPreview(body.data);\n setRenders(held.data.filter((r) => r.template_id === templateId));\n }, [client, templateId, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function freeze() {\n setBusy(\"freeze\");\n const written = await client.docRenderDocument({ template_id: templateId, record_id: recordId });\n setBusy(null);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n await load();\n setShowing(written.data);\n const made = (await client.docRenders({ record_id: recordId }));\n if (made.ok) {\n const row = made.data.find((r) => r.id === written.data);\n if (row) onRendered?.(row);\n }\n }\n\n async function toPdf() {\n const element = paper.current;\n if (!element) return;\n setBusy(\"pdf\");\n try {\n // The platform's ONE answer to \"make this a PDF\". A second renderer here\n // would produce a document that does not match the printed one.\n const { captureToPDF } = await import(\"@ai-matrx/print/pdf\");\n await captureToPDF(element, { filename: filename ?? \"document\" });\n } catch (thrown) {\n setError({\n code: \"internal\",\n message: \"The PDF could not be made on this screen.\",\n hint: thrown instanceof Error ? thrown.message : String(thrown),\n });\n } finally {\n setBusy(null);\n }\n }\n\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (preview === null || renders === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const frozen = showing ? (renders.find((r) => r.id === showing) ?? null) : null;\n const text = frozen ? frozen.body : preview;\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row: which version is on screen, and the two verbs. */}\n <div className=\"flex items-center gap-1 text-xs\">\n <Button\n size=\"sm\"\n variant={frozen ? \"ghost\" : \"secondary\"}\n aria-pressed={!frozen}\n onClick={() => setShowing(null)}\n >\n As it reads now\n </Button>\n {renders.map((render) => (\n <Button\n key={render.id}\n size=\"sm\"\n variant={render.id === showing ? \"secondary\" : \"ghost\"}\n aria-pressed={render.id === showing}\n onClick={() => setShowing(render.id)}\n title={`Template v${render.template_version} · ${render.content_hash.slice(0, 12)}`}\n >\n {new Date(render.rendered_at).toLocaleString()}\n </Button>\n ))}\n <span className=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" disabled={busy !== null} onClick={() => void freeze()}>\n {busy === \"freeze\" ? \"Freezing…\" : \"Freeze this version\"}\n </Button>\n <Button size=\"sm\" variant=\"ghost\" disabled={busy !== null} onClick={() => void toPdf()}>\n {busy === \"pdf\" ? \"Making the PDF…\" : \"PDF\"}\n </Button>\n </span>\n </div>\n\n {/* The document. Frozen bytes when a version is chosen, the live resolution\n otherwise — and the screen says which, because they are not the same thing. */}\n <div ref={paper} className=\"whitespace-pre-wrap rounded border bg-background p-4 text-sm text-foreground\">\n {text}\n </div>\n\n <p className=\"text-xs text-muted-foreground\">\n {frozen\n ? `Frozen ${new Date(frozen.rendered_at).toLocaleString()} from template v${frozen.template_version}. Its text and its SHA-256 (${frozen.content_hash.slice(0, 12)}…) are what any signature seals.`\n : \"This is how the template reads against this record right now. Nothing has been frozen, so there is no version for anyone to sign yet.\"}\n </p>\n </div>\n );\n}\n","\"use client\";\n\n// src/SignBlock.tsx — @ai-matrx/records-ui · SCR-22\n//\n// A SIGNATURE IS A VALUE, AND THE STORE DECIDES WHETHER IT STILL HOLDS.\n//\n// VAL-10: a signature is written on a text Field whose format is `signature`,\n// on the record's own Table, through `custom.doc_sign` — which writes it as an\n// ordinary Value with the envelope law's stamp plus the document version and\n// hash it sealed. So a signature is in History, in the export and in the agent's\n// context like any other Value, and there is no signatures feature bolted on.\n//\n// THREE THINGS THIS SCREEN NEVER DOES:\n// · It never checks a seal itself. `custom.doc_signature_intact` answers, and\n// its verdict is shown as the store said it.\n// · It never offers to re-sign. The door refuses a second signature on a Field\n// already signed, and the screen says the same sentence rather than showing a\n// button that will be refused.\n// · It never signs anything unfrozen. A seal is over a document VERSION, so\n// with no render there is no Sign — and the reason is on screen.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { DocRenderRow, DocSignatureRow, Field, RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\nimport { isSignatureField } from \"./docs\";\nimport { fieldName } from \"./names\";\n\nexport interface SignBlockProps {\n tableId: Uuid;\n recordId: Uuid;\n /** The frozen version being signed. Without one there is nothing to seal. */\n render: DocRenderRow | null;\n className?: string | undefined;\n}\n\nexport function SignBlock({ tableId, recordId, render, className }: SignBlockProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const [signatures, setSignatures] = useState<DocSignatureRow[] | null>(null);\n const [verdicts, setVerdicts] = useState<Record<string, unknown>>({});\n const [error, setError] = useState<RecordsError | null>(null);\n const [name, setName] = useState(\"\");\n const [busy, setBusy] = useState(false);\n\n const load = useCallback(async () => {\n const held = await client.docSignatures({ record_id: recordId });\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setSignatures(held.data);\n // Whether each seal still holds is the STORE's answer, asked for each one.\n const answers: Record<string, unknown> = {};\n for (const signature of held.data) {\n const intact = await client.docSignatureIntact({ signature_id: signature.id });\n answers[signature.id] = intact.ok ? intact.data : intact.error.message;\n }\n setVerdicts(answers);\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n async function sign(field: Field) {\n if (!render) return;\n setBusy(true);\n const signed = await client.docSign({\n render_id: render.id,\n field_key: field.key,\n signer_name: name.trim(),\n signer_user_id: client.config.actor.user_id ?? null,\n });\n setBusy(false);\n if (!signed.ok) {\n setError(signed.error);\n return;\n }\n setName(\"\");\n await load();\n }\n\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (fields.loading || signatures === null) return <Skeleton className={cn(\"h-32 w-full\", className)} />;\n\n const signable = (fields.data ?? []).filter(isSignatureField);\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Signatures</span>\n <span>{signatures.length} on this record</span>\n </div>\n\n {signatures.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {signatures.map((signature) => {\n const verdict = verdicts[signature.id];\n const intact = typeof verdict === \"object\" && verdict !== null ? (verdict as { intact?: boolean }).intact : undefined;\n return (\n <li key={signature.id} className=\"rounded border px-2 py-1.5 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{signature.signer_name}</span>\n <span className=\"text-muted-foreground\">{signature.field_key}</span>\n <span className=\"text-muted-foreground\">{new Date(signature.signed_at).toLocaleString()}</span>\n <span className=\"ml-auto font-mono text-[10px] text-muted-foreground\">\n v{signature.document_version} · {signature.document_hash.slice(0, 12)}\n </span>\n </div>\n {/* The store's verdict, not a check this screen invented. */}\n <p className={cn(\"mt-0.5\", intact === false ? \"text-destructive\" : \"text-muted-foreground\")}>\n {intact === true\n ? \"The store says what was signed is still exactly what is there.\"\n : intact === false\n ? typeof verdict === \"object\" && verdict !== null && \"reason\" in verdict\n ? String((verdict as { reason?: unknown }).reason)\n : \"The store says what is there no longer matches what was signed.\"\n : String(verdict ?? \"\")}\n </p>\n </li>\n );\n })}\n </ul>\n ) : null}\n\n {/* A seal is over a VERSION, so with nothing frozen there is no Sign at\n all — and the reason is on screen rather than a dead button. */}\n {!render ? (\n <p className=\"text-xs text-muted-foreground\">\n Nothing has been frozen yet, so there is no version to sign. A signature seals one exact document\n version and its hash — \"the document as it reads today\" is not something anyone can agree to.\n </p>\n ) : signable.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This table has no signature Field, so there is nowhere to write a signature. A signature is a Value\n on a text Field whose format is <code>signature</code> — add one and the signing appears.\n </p>\n ) : !rights.write ? (\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n ) : (\n <div className=\"flex flex-col gap-1\">\n {signable.map((field) => {\n const already = signatures.find((s) => s.field_key === field.key);\n if (already) {\n return (\n <p key={field.id} className=\"text-xs text-muted-foreground\">\n {fieldName(field)} is signed, and a signature is immutable once made. A further\n agreement is a further Field with its own signature, or a further version with its own seal.\n </p>\n );\n }\n return (\n <form\n key={field.id}\n className=\"flex items-center gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n if (name.trim() !== \"\") void sign(field);\n }}\n >\n <BasicInput\n className=\"h-8 w-56 text-xs\"\n aria-label={`Sign ${fieldName(field)}`}\n placeholder=\"Type your full name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n <Button size=\"sm\" type=\"submit\" disabled={busy || name.trim() === \"\"}>\n Sign\n </Button>\n <span className=\"text-xs text-muted-foreground\">\n seals version {render.template_version} · {render.content_hash.slice(0, 12)}…\n </span>\n </form>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/NotifyRuleEditor.tsx — @ai-matrx/records-ui · SCR-19\n//\n// \"TELL ME WHEN SOMETHING IN THIS VIEW CHANGES\" — and that sentence is a RULE\n// RECORD, not a notifications table.\n//\n// DOOR-18: a subscription is an ordinary Rule carrying a `subscription` block\n// that names a saved view, a cadence, a channel and the person to tell. The\n// store answers `custom.agg_subscriptions`, fires `custom.agg_subscription_fire`\n// and delivers through `communication.notification`. So there is one notifier in\n// this platform, and a subscription is readable, historied, exportable and\n// agent-writable exactly like everything else this package touches.\n//\n// THE PART THAT MATTERS MOST IS NOT ON THIS SCREEN. `custom.agg_view_admits`\n// runs the admission test as the SUBSCRIBER, not as the writer: a change to a\n// record the subscriber may not see is not a notification they are entitled to,\n// because the notification's existence would leak the record. This editor never\n// re-implements that test and never offers to turn it off.\n//\n// `seed` is the agent's half, as everywhere else: complete declarative\n// subscriptions, written once, never overwriting one a person has since changed.\n//\n// WHAT DOES NOT WORK YET, AND WHY IT SAYS SO INSTEAD OF PRETENDING. A\n// subscription is a RULE record, and `custom.record_write` — the one write door\n// — inserts `data_class = 'record'`. A document written that way is not a Rule:\n// `custom.agg_subscriptions` never sees it, so a screen that wrote one and said\n// \"subscribed\" would have subscribed nobody to anything and left a stray record\n// behind. Declaring a Rule needs a door of its own (`custom.rule_declare`,\n// W1-RULE's), so this editor asks for that door BY NAME and shows the store's\n// refusal. Reading, listing and stopping a subscription all work today; the day\n// the door lands, so does subscribing, with no change on this screen.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, Subscription } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { NO_SAVED_VIEWS_REASON, useRecordsUi, useTableRights } from \"./host\";\n\n/** THE DECLARATIVE SPEC an agent writes. One declaration and a person is told. */\nexport interface NotifyRuleSpec {\n name: string;\n savedViewId: Uuid;\n /** `immediate` fires on the change; `digest` is collected and sent on a schedule. */\n cadence?: string;\n /** The digest's schedule, in the store's own words. Meaningless for `immediate`. */\n schedule?: string | null;\n channel?: string;\n /** Who is told. Left out, the person setting it up — \"tell ME\". */\n recipientUserId?: Uuid | null;\n eventKey?: string;\n}\n\nexport interface NotifyRuleEditorProps {\n /** The Table these subscriptions are about — the Rule's scope. */\n tableId: Uuid;\n /** COMPLETE declarative subscriptions an agent wrote. Saved once, never overwritten. */\n seed?: NotifyRuleSpec[] | undefined;\n className?: string | undefined;\n}\n\nexport function NotifyRuleEditor({ tableId, seed, className }: NotifyRuleEditorProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [subscriptions, setSubscriptions] = useState<Subscription[] | null>(null);\n const [cadences, setCadences] = useState<string[]>([]);\n const [views, setViews] = useState<Array<{ id: Uuid; name: string }> | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n\n const load = useCallback(async () => {\n const [held, offered] = await Promise.all([\n client.aggSubscriptions(),\n // The cadences are ASKED of the store, never a list typed into a picker\n // here that could drift from what the digest runner understands.\n client.aggSubscriptionCadences(),\n ]);\n if (!held.ok) {\n setError(held.error);\n return;\n }\n setError(null);\n setSubscriptions(held.data);\n if (offered.ok) setCadences(offered.data);\n if (host.savedViews) setViews(await host.savedViews());\n else setViews(null);\n }, [client, host]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const write = useCallback(\n async (spec: NotifyRuleSpec) => {\n const declared = await client.ruleDeclare({\n spec: {\n name: spec.name,\n // REC-15: a subscription answers yes-or-no about a record, so it is a\n // predicate, and what it decides is membership of the view.\n kind: \"predicate\",\n uses: [\"membership\"],\n scope_table_id: tableId,\n applies_to_types: [],\n expr: { const: true },\n subscription: {\n saved_view_id: spec.savedViewId,\n cadence: spec.cadence ?? \"immediate\",\n schedule: spec.schedule ?? null,\n channel: spec.channel ?? \"in_app\",\n // \"Tell me\" is the default, and the store fires at nobody when this\n // is null — which it says out loud rather than dropping quietly.\n recipient_user_id: spec.recipientUserId ?? client.config.actor.user_id ?? null,\n event_key: spec.eventKey ?? \"records.changed\",\n },\n },\n });\n if (!declared.ok) {\n setError(declared.error);\n return false;\n }\n return true;\n },\n [client, tableId],\n );\n\n // The agent's specs, saved once. A seed whose name is already subscribed is\n // left alone — an agent re-running never overwrites a person's tweak.\n useEffect(() => {\n if (!subscriptions || !seed || seed.length === 0) return;\n const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));\n if (missing.length === 0) return;\n void (async () => {\n for (const spec of missing) {\n if (!(await write(spec))) return;\n }\n await load();\n })();\n }, [subscriptions, seed, write, load]);\n\n async function subscribe(viewId: Uuid, viewName: string, cadence: string) {\n setBusy(true);\n const ok = await write({ name: `${viewName} — ${cadence}`, savedViewId: viewId, cadence });\n setBusy(false);\n if (ok) await load();\n }\n\n async function unsubscribe(ruleId: Uuid) {\n setBusy(true);\n const deleted = await client.recordDelete({ record_id: ruleId });\n setBusy(false);\n if (!deleted.ok) {\n setError(deleted.error);\n return;\n }\n await load();\n }\n\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (subscriptions === null) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {/* One row. What this is, and how many there are — no subtitle repeating it. */}\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Tell me when</span>\n <span>{subscriptions.length} subscription{subscriptions.length === 1 ? \"\" : \"s\"}</span>\n </div>\n\n {subscriptions.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n Nothing is telling anyone about this yet. A subscription is a Rule over a saved view, so what\n you are told about is exactly what that view holds.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {subscriptions.map((held) => (\n <li key={held.rule_id} className=\"flex items-center gap-2 rounded border px-2 py-1.5 text-xs\">\n <span className=\"truncate font-medium\">{held.name}</span>\n <span className=\"text-muted-foreground\">{held.cadence}</span>\n <span className=\"text-muted-foreground\">{held.channel}</span>\n {held.cadence === \"digest\" && held.schedule ? (\n <span className=\"text-muted-foreground\">{held.schedule}</span>\n ) : null}\n {/* Nothing fails silently: a subscription that fires at nobody\n says so, rather than looking like it is working. */}\n {held.recipient_user_id === null ? (\n <span className=\"text-destructive\">\n This one has nobody to tell, so it fires at nobody.\n </span>\n ) : null}\n {held.saved_view_id === null ? (\n <span className=\"text-destructive\">\n This one names no view, so the store never admits a record to it.\n </span>\n ) : null}\n {rights.write ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto\"\n disabled={busy}\n onClick={() => void unsubscribe(held.rule_id)}\n >\n Stop telling me\n </Button>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n\n {/* Subscribing to a view needs the views, and the store has no door onto\n them — so with no port bound this says that, rather than showing an\n empty picker that reads like \"you have no views\". */}\n {views === null ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {NO_SAVED_VIEWS_REASON}\n </p>\n ) : views.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This organization has no saved views yet, so there is nothing to subscribe to. Save a view first.\n </p>\n ) : rights.write ? (\n <form\n className=\"flex items-center gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n const form = event.currentTarget;\n const view = (form.elements.namedItem(\"view\") as HTMLSelectElement).value;\n const cadence = (form.elements.namedItem(\"cadence\") as HTMLSelectElement).value;\n const name = views.find((v) => v.id === view)?.name ?? \"View\";\n if (view) void subscribe(view, name, cadence);\n }}\n >\n <select name=\"view\" aria-label=\"View to be told about\" className=\"h-7 rounded border bg-background px-1 text-xs\">\n {views.map((view) => (\n <option key={view.id} value={view.id}>\n {view.name}\n </option>\n ))}\n </select>\n <select name=\"cadence\" aria-label=\"How often\" className=\"h-7 rounded border bg-background px-1 text-xs\">\n {(cadences.length > 0 ? cadences : [\"immediate\"]).map((cadence) => (\n <option key={cadence} value={cadence}>\n {cadence === \"immediate\" ? \"as it happens\" : cadence}\n </option>\n ))}\n </select>\n <Button size=\"sm\" type=\"submit\" disabled={busy}>\n Tell me\n </Button>\n </form>\n ) : (\n <p className=\"text-xs text-muted-foreground\">{rights.reason}</p>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/ChartBlock.tsx — @ai-matrx/records-ui · SCR-15\n//\n// ONE BLOCK, ONE CALL TO THE STORE. The grouping, the bucketing, the filter and\n// the measure are all `custom.record_aggregate`'s work, computed inside the\n// read door's own query — this file draws the answer and does not do any\n// arithmetic of its own beyond turning numbers into pixels.\n//\n// WHY NOT SUM IN THE BROWSER: the aggregate node sits above the visibility\n// join, so the total is over exactly the records this person may see. A browser\n// that fetched rows and summed them would either read rows it may not have or\n// under-count them silently, and a wrong total is the hardest lie to notice.\n//\n// A SHAPE THAT CANNOT BE DRAWN SAYS THE SENTENCE THAT FIXES IT. A donut with\n// nothing to group by and a line with no date Field print what they need; they\n// never draw an empty frame that reads like \"there is no data\".\n\nimport { useEffect, useState } from \"react\";\nimport { useRecordsClient } from \"@ai-matrx/records/react\";\nimport { measureKey, type AggregateRow, type RecordsError } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { CHART_NEEDS, SERIES_COLORS, groupLabel, type ChartSpec } from \"./charts\";\n\nexport interface ChartBlockProps {\n spec: ChartSpec;\n className?: string | undefined;\n}\n\nexport function ChartBlock({ spec, className }: ChartBlockProps) {\n const client = useRecordsClient();\n const [rows, setRows] = useState<AggregateRow[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n const measures = spec.measures && spec.measures.length > 0 ? spec.measures : [{ op: \"count\" as const }];\n const primary = measureKey(measures[0]!);\n const grouped = (spec.groupBy ?? []).length > 0 || !!spec.bucket;\n const needs = grouped ? null : CHART_NEEDS[spec.kind];\n\n const question = JSON.stringify({\n t: spec.subject,\n g: spec.groupBy ?? [],\n m: measures,\n b: spec.bucket ?? null,\n f: spec.filter ?? {},\n l: spec.limit ?? 50,\n });\n\n useEffect(() => {\n if (needs) return;\n let cancelled = false;\n setRows(null);\n setError(null);\n void client\n .recordAggregate({\n table_id: spec.subject,\n groupBy: spec.groupBy ?? [],\n measures,\n bucket: spec.bucket ?? null,\n filter: spec.filter ?? {},\n limit: spec.limit ?? 50,\n })\n .then((result) => {\n if (cancelled) return;\n if (result.ok) setRows(result.data);\n else setError(result.error);\n });\n return () => {\n cancelled = true;\n };\n // The QUESTION is the dependency, not the object identity: a parent that\n // rebuilds the same spec every render must not re-ask the store forever.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client, question, needs]);\n\n return (\n <figure className={cn(\"flex min-w-0 flex-col gap-1.5 rounded border p-2\", className)}>\n {/* One row. The title and what is being measured — no subtitle repeating the title. */}\n <figcaption className=\"flex items-baseline gap-2 text-xs\">\n <span className=\"truncate font-medium\">{spec.title}</span>\n <span className=\"ml-auto shrink-0 text-muted-foreground\">{primary.replace(\"_\", \" of \")}</span>\n </figcaption>\n\n {needs ? (\n <p className=\"px-1 py-3 text-xs text-muted-foreground\">{needs}</p>\n ) : error ? (\n <RefusalNotice error={error} />\n ) : rows === null ? (\n <Skeleton className=\"h-28 w-full\" />\n ) : rows.length === 0 ? (\n <p className=\"px-1 py-3 text-xs text-muted-foreground\">\n The store answered this question with no groups at all, so there is nothing to draw yet.\n </p>\n ) : (\n <Drawing kind={spec.kind} rows={rows} measure={primary} />\n )}\n </figure>\n );\n}\n\nfunction value(row: AggregateRow, measure: string): number {\n const held = row.measures?.[measure];\n return typeof held === \"number\" ? held : Number(held ?? 0);\n}\n\nfunction pretty(n: number): string {\n return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(undefined, { maximumFractionDigits: 2 });\n}\n\nfunction Drawing({ kind, rows, measure }: { kind: ChartSpec[\"kind\"]; rows: AggregateRow[]; measure: string }) {\n const points = rows.map((row) => ({ label: groupLabel(row.groups ?? {}), value: value(row, measure), n: row.row_count }));\n const top = Math.max(...points.map((p) => p.value), 0) || 1;\n\n if (kind === \"number\") {\n const total = points.reduce((sum, p) => sum + p.value, 0);\n return (\n <div className=\"flex items-baseline gap-2 px-1 py-2\">\n <span className=\"text-2xl font-semibold tabular-nums\">{pretty(total)}</span>\n <span className=\"text-xs text-muted-foreground\">\n from {points.reduce((sum, p) => sum + p.n, 0).toLocaleString()} records\n </span>\n </div>\n );\n }\n\n if (kind === \"table\") {\n return (\n <table className=\"w-full text-xs\">\n <tbody>\n {points.map((p) => (\n <tr key={p.label} className=\"border-t first:border-t-0\">\n <td className=\"py-0.5 pr-2 truncate\">{p.label}</td>\n <td className=\"py-0.5 text-right tabular-nums\">{pretty(p.value)}</td>\n <td className=\"py-0.5 pl-2 text-right tabular-nums text-muted-foreground\">{p.n}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n }\n\n if (kind === \"bar\") {\n // Horizontal bars, because a category label is words and words read across.\n return (\n <ul className=\"flex flex-col gap-1 px-1 py-1\">\n {points.map((p, i) => (\n <li key={p.label} className=\"flex items-center gap-2 text-xs\">\n <span className=\"w-28 shrink-0 truncate\" title={p.label}>\n {p.label}\n </span>\n <span className=\"h-3 min-w-0 flex-1 rounded-sm bg-muted\">\n <span\n className=\"block h-3 rounded-sm\"\n style={{ width: `${Math.max((p.value / top) * 100, 1)}%`, background: SERIES_COLORS[i % SERIES_COLORS.length] }}\n />\n </span>\n <span className=\"w-16 shrink-0 text-right tabular-nums\">{pretty(p.value)}</span>\n </li>\n ))}\n </ul>\n );\n }\n\n if (kind === \"column\" || kind === \"line\") {\n const width = 320;\n const height = 96;\n const step = points.length > 1 ? width / (points.length - 1) : width;\n const y = (v: number) => height - (v / top) * (height - 8) - 4;\n return (\n <div className=\"px-1 py-1\">\n <svg viewBox={`0 0 ${width} ${height}`} className=\"h-24 w-full\" role=\"img\" aria-label={`${measure} by group`}>\n {kind === \"line\" ? (\n <polyline\n fill=\"none\"\n stroke={SERIES_COLORS[0]}\n strokeWidth=\"2\"\n points={points.map((p, i) => `${i * step},${y(p.value)}`).join(\" \")}\n />\n ) : (\n points.map((p, i) => {\n const barWidth = Math.max(width / points.length - 4, 2);\n return (\n <rect\n key={p.label}\n x={(width / points.length) * i + 2}\n y={y(p.value)}\n width={barWidth}\n height={height - 4 - y(p.value)}\n rx=\"2\"\n fill={SERIES_COLORS[i % SERIES_COLORS.length]}\n />\n );\n })\n )}\n </svg>\n <ul className=\"mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-xs text-muted-foreground\">\n {points.map((p) => (\n <li key={p.label} className=\"tabular-nums\">\n {p.label} {pretty(p.value)}\n </li>\n ))}\n </ul>\n </div>\n );\n }\n\n // donut\n const total = points.reduce((sum, p) => sum + p.value, 0) || 1;\n let offset = 0;\n const radius = 34;\n const circumference = 2 * Math.PI * radius;\n return (\n <div className=\"flex items-center gap-3 px-1 py-1\">\n <svg viewBox=\"0 0 88 88\" className=\"h-24 w-24 shrink-0\" role=\"img\" aria-label={`${measure} by group`}>\n {points.map((p, i) => {\n const length = (p.value / total) * circumference;\n const dash = `${length} ${circumference - length}`;\n const node = (\n <circle\n key={p.label}\n cx=\"44\"\n cy=\"44\"\n r={radius}\n fill=\"none\"\n stroke={SERIES_COLORS[i % SERIES_COLORS.length]}\n strokeWidth=\"14\"\n strokeDasharray={dash}\n strokeDashoffset={-offset}\n transform=\"rotate(-90 44 44)\"\n />\n );\n offset += length;\n return node;\n })}\n </svg>\n <ul className=\"flex min-w-0 flex-col gap-0.5 text-xs\">\n {points.map((p, i) => (\n <li key={p.label} className=\"flex items-center gap-1.5\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-sm\"\n style={{ background: SERIES_COLORS[i % SERIES_COLORS.length] }}\n />\n <span className=\"truncate\">{p.label}</span>\n <span className=\"ml-auto shrink-0 tabular-nums\">{pretty(p.value)}</span>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","\"use client\";\n\n// src/DashboardCanvas.tsx — @ai-matrx/records-ui · SCR-16\n//\n// A DASHBOARD IS ONE RECORD, and its blocks are that record's own document. So\n// a dashboard is shareable, exportable, historied, commentable and\n// agent-writable for free — every one of those is something this package\n// already does to records, and none of it is written twice.\n//\n// `seed` is the agent's half: COMPLETE `DashboardSpec`s, each saved as a record\n// the first time the canvas loads and never overwritten afterwards. A person\n// adding a block, renaming one or changing its shape is the tweak.\n//\n// Every block is its own single call to `custom.record_aggregate`, so a canvas\n// of eight blocks is eight round trips over eight aggregates, never eight\n// downloads of the table.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useSeedGuard } from \"./seedOnce\";\nimport { useRecordVersion, useSystemTable } from \"./systemTable\";\nimport { useTableRights } from \"./host\";\nimport { ChartBlock } from \"./ChartBlock\";\nimport {\n CHART_KINDS,\n CHART_KIND_LABEL,\n DASHBOARD_TABLE,\n dashboardDocument,\n dashboardFromRecord,\n type ChartKind,\n type ChartSpec,\n type DashboardSpec,\n type SavedDashboard,\n} from \"./charts\";\n\nexport interface DashboardCanvasProps {\n /** The Table these blocks are about. */\n tableId: Uuid;\n /** COMPLETE declarative dashboards an agent wrote. Saved once, never overwritten. */\n seed?: DashboardSpec[] | undefined;\n activeDashboardId?: Uuid | null | undefined;\n className?: string | undefined;\n}\n\nexport function DashboardCanvas({ tableId, seed, activeDashboardId, className }: DashboardCanvasProps) {\n const client = useRecordsClient();\n // One claim per seed name, per mount: a check against the server's list is\n // not a lock, and a loader that re-runs mid-write would write it twice.\n const claimSeed = useSeedGuard();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const fields = useFields(tableId);\n const home = useSystemTable(DASHBOARD_TABLE);\n const [boards, setBoards] = useState<SavedDashboard[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(activeDashboardId ?? null);\n // The version of the board this canvas LOADED, for the one record being edited.\n const loaded = useRecordVersion(activeId);\n\n const boardTableId = home.tableId;\n\n const load = useCallback(async () => {\n if (!boardTableId) return;\n const result = await client.list({ table_id: boardTableId, limit: 500 });\n if (!result.ok) {\n setError(result.error);\n return;\n }\n let mine = result.data.rows.map(dashboardFromRecord).filter((d) => d.subject === tableId);\n const missing = (seed ?? []).filter((s) => !mine.some((d) => d.name === s.name));\n if (missing.length > 0) {\n for (const spec of missing) {\n if (!claimSeed(spec.name)) continue;\n const written = await client.recordWrite({\n table_id: boardTableId,\n data: dashboardDocument({ ...spec, subject: tableId }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n }\n const again = await client.list({ table_id: boardTableId, limit: 500 });\n if (!again.ok) {\n setError(again.error);\n return;\n }\n mine = again.data.rows.map(dashboardFromRecord).filter((d) => d.subject === tableId);\n }\n setError(null);\n setBoards(mine);\n }, [client, boardTableId, tableId, seed]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!boards || boards.length === 0) return;\n const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0]!;\n if (chosen.id !== activeId) setActiveId(chosen.id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boards, activeDashboardId]);\n\n async function writeBlocks(board: SavedDashboard, blocks: ChartSpec[]) {\n const updated = await client.recordUpdate({\n record_id: board.id,\n patch: dashboardDocument({ ...board, blocks }),\n // The dashboard record's own version: two tabs editing one board are TOLD.\n ...(loaded.version === null ? {} : { expectedVersion: loaded.version }),\n });\n if (!updated.ok) {\n setError(updated.error);\n return;\n }\n // The store's own new version, so the NEXT change to this board is a change\n // and not a conflict with the person who just made the last one.\n loaded.note(updated.data);\n await load();\n }\n\n async function create() {\n if (!boardTableId) return;\n const written = await client.recordWrite({\n table_id: boardTableId,\n data: dashboardDocument({ name: `Dashboard ${(boards?.length ?? 0) + 1}`, subject: tableId, blocks: [] }),\n });\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setActiveId(written.data);\n await load();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (error) {\n return (\n <RefusalNotice\n error={error}\n className={className}\n actions={\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void load()}>\n Try again\n </Button>\n }\n />\n );\n }\n if (home.loading || boards === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const board = boards.find((d) => d.id === activeId) ?? null;\n const groupable = (fields.data ?? []).filter((f) => f.type === \"text\" || f.type === \"list\");\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the boards, and the two verbs that change this one. */}\n <div className=\"flex items-center gap-1 overflow-x-auto\" role=\"group\" aria-label=\"Dashboards\">\n {boards.map((d) => (\n <Button\n key={d.id}\n size=\"sm\"\n variant={d.id === activeId ? \"secondary\" : \"ghost\"}\n aria-pressed={d.id === activeId}\n onClick={() => setActiveId(d.id)}\n >\n {d.name}\n </Button>\n ))}\n {/* SCR-4: making a dashboard is administering the table, so a member\n gets no dead button — there is no button. */}\n {rights.admin ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => void create()}>\n New dashboard\n </Button>\n ) : null}\n {board && rights.admin ? (\n <span className=\"ml-auto flex items-center gap-1\">\n <select\n aria-label=\"Add a block\"\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value=\"\"\n onChange={(e) => {\n const kind = e.target.value as ChartKind;\n if (!kind) return;\n const by = groupable[0]?.key;\n void writeBlocks(board, [\n ...board.blocks,\n {\n title: CHART_KIND_LABEL[kind],\n subject: tableId,\n kind,\n ...(by && kind !== \"number\" ? { groupBy: [by] } : {}),\n measures: [{ op: \"count\" }],\n },\n ]);\n }}\n >\n <option value=\"\">Add a block</option>\n {CHART_KINDS.map((kind) => (\n <option key={kind} value={kind}>\n {CHART_KIND_LABEL[kind]}\n </option>\n ))}\n </select>\n </span>\n ) : null}\n </div>\n\n {!board ? (\n <p className=\"text-xs text-muted-foreground\">\n {rights.admin\n ? \"No dashboard looks at this table yet. \\\"New dashboard\\\" makes one, or an agent writes a whole one with a single record.\"\n : rights.reason}\n </p>\n ) : board.blocks.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n This dashboard has no blocks yet. Each one is a single question the store answers — grouped,\n bucketed and measured inside the read door.\n </p>\n ) : (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-3\">\n {board.blocks.map((block, index) => (\n <div key={`${block.title}-${index}`} className=\"flex min-w-0 flex-col gap-1\">\n <ChartBlock spec={{ ...block, subject: block.subject || tableId }} />\n {rights.admin ? (\n <div className=\"flex items-center gap-1 text-xs\">\n <select\n aria-label={`Shape of ${block.title}`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={block.kind}\n onChange={(e) =>\n void writeBlocks(\n board,\n board.blocks.map((b, i) => (i === index ? { ...b, kind: e.target.value as ChartKind } : b)),\n )\n }\n >\n {CHART_KINDS.map((kind) => (\n <option key={kind} value={kind}>\n {CHART_KIND_LABEL[kind]}\n </option>\n ))}\n </select>\n <select\n aria-label={`Group ${block.title} by`}\n className=\"h-7 rounded border bg-background px-1 text-xs\"\n value={block.groupBy?.[0] ?? \"\"}\n onChange={(e) =>\n void writeBlocks(\n board,\n board.blocks.map((b, i) =>\n i === index ? { ...b, groupBy: e.target.value ? [e.target.value] : [] } : b,\n ),\n )\n }\n >\n <option value=\"\">no grouping</option>\n {groupable.map((f) => (\n <option key={f.id} value={f.key}>\n {f.label || f.key}\n </option>\n ))}\n </select>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => void writeBlocks(board, board.blocks.filter((_, i) => i !== index))}\n >\n Remove\n </Button>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\n// src/RecordChat.tsx — @ai-matrx/records-ui · SCR-26\n//\n// \"TALK TO THIS RECORD\" — AND THERE IS EXACTLY ONE CHAT SURFACE IN THIS\n// PLATFORM, WHICH IS NOT THIS ONE.\n//\n// The temptation here is to build a message list and a composer. Doing that\n// would give AI Matrx a second chat UI that streams differently, handles tool\n// asks differently, pages history differently and drifts from the real one\n// within a month — for the sake of a panel beside a record. So this component\n// builds NO chat UI at all.\n//\n// What it builds is the thing only the record store can build: the CONTEXT.\n// It reads the one record THROUGH THE READ DOOR (`custom.read_record`), turns\n// the Fields the store agreed this person may see into named context entries,\n// names the ones the store MASKED rather than pretending the record has fewer\n// fields than it has, and hands that to the host's chat port.\n//\n// WHAT matrx-frontend MUST PASS (the port, in its own words):\n//\n// <RecordsUiProvider value={{\n// chat: (ctx) => {\n// const { conversationId } = useAgentLauncher(agentId, {\n// surfaceKey: ctx.surfaceKey,\n// runtime: { context: Object.fromEntries(ctx.entries.map(e => [e.key, e.value])) },\n// });\n// return <AgentConversationColumn conversationId={conversationId} surfaceKey={ctx.surfaceKey} />;\n// },\n// }}>\n//\n// `AgentConversationColumn`\n// (matrx-frontend `features/agents/components/shared/AgentConversationColumn.tsx`)\n// is that one surface, and it cannot live in this package: it reads the app's\n// Redux store — conversations, messages, instance-context, surfaces — and a\n// package that imported those would stop being a package. The agent itself is\n// resolved through a Mandate on the host's side, never a UUID pinned here.\n//\n// UNBOUND, THIS COMPONENT IS ABSENT WITH ITS REASON. It never draws a dead\n// composer, and it never quietly renders a transcript that goes nowhere.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, HiddenFieldNotice, RecordsError } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi } from \"./host\";\nimport { scalarText } from \"./values\";\n\n/** One named piece of grounding, shaped the way the platform's context slice takes them. */\nexport interface RecordChatEntry {\n key: string;\n value: unknown;\n label: string;\n /** `text` for a scalar, `json` for a structure. The host maps this to its own vocabulary. */\n type: \"text\" | \"json\";\n}\n\n/** A Field the STORE masked for this reader, named rather than silently dropped. */\nexport interface RecordChatWithheld {\n key: string;\n label: string;\n /** The store's own reason. */\n reason: string;\n}\n\n/** Everything the host's chat surface needs, and nothing about how it should look. */\nexport interface RecordChatContext {\n /**\n * A unique key per mounted conversation. Two record panels open at once must\n * not fight over focus, so this is derived from the record and never a\n * constant.\n */\n surfaceKey: string;\n tableId: Uuid;\n recordId: Uuid;\n tableName: string;\n /** The record's own title, for the panel's one-row header and the chip. */\n title: string;\n /** The grounding, already read through the read door. */\n entries: RecordChatEntry[];\n /** What this reader is NOT being given, with the store's reason for each. */\n withheld: RecordChatWithheld[];\n}\n\nexport const NO_CHAT_REASON =\n \"No chat port is bound, so this panel is absent rather than showing a composer that goes nowhere. \" +\n \"Bind `chat` on <RecordsUiProvider> with your host's own chat surface — in AI Matrx that is \" +\n \"`AgentConversationColumn`, launched through a Mandate — and this panel becomes that surface with \" +\n \"this record as its context. This package deliberately ships no second chat UI.\";\n\nexport interface RecordChatProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\nexport function RecordChat({ tableId, recordId, className }: RecordChatProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [read, setRead] = useState<{\n document: Record<string, unknown>;\n hidden: Record<string, HiddenFieldNotice>;\n } | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setRead(null);\n setError(null);\n void client.recordRead({ record_id: recordId }).then((answered) => {\n if (cancelled) return;\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setRead({\n document: answered.data.document as Record<string, unknown>,\n hidden: answered.data.hidden ?? {},\n });\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId]);\n\n const context: RecordChatContext | null = useMemo(() => {\n if (!read || !table.data || !fields.data) return null;\n const titleKey = table.data.title_field ?? fields.data[0]?.key ?? \"\";\n const title = String(read.document[titleKey] ?? \"this record\");\n const withheld: RecordChatWithheld[] = Object.entries(read.hidden).map(([key, notice]) => ({\n key,\n label: fields.data?.find((f) => f.key === key)?.label ?? key,\n reason: noticeText(notice),\n }));\n return {\n surfaceKey: `records-ui:record-chat:${recordId}`,\n tableId,\n recordId,\n tableName: table.data.name,\n title,\n entries: entriesFor(fields.data, read.document, table.data.name, title, withheld),\n // Two different absences, both named: what the STORE masked for this\n // reader, and what the organization's own policy keeps out of a\n // conversation. Neither one silently shrinks the record.\n withheld,\n };\n }, [read, table.data, fields.data, recordId, tableId]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (!context) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!host.chat) {\n // ABSENT, WITH THE REASON — and with what was going to be sent, because a\n // person reading \"no chat port is bound\" should be able to see that the\n // record half of this actually works.\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{context.title}</span>\n <span>{context.entries.length} facts ready</span>\n </header>\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_CHAT_REASON}</p>\n <Withheld withheld={context.withheld} />\n </section>\n );\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the record, and what the agent is holding. No repeated names. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{context.title}</span>\n <span>{context.entries.length} facts in context</span>\n </header>\n <Withheld withheld={context.withheld} />\n <div className=\"flex min-h-0 flex-1 flex-col\">{host.chat(context)}</div>\n </section>\n );\n}\n\n/**\n * The store masked something, and the person is TOLD.\n *\n * An agent answering out of a record it was given nine of eleven fields from\n * will answer confidently and wrongly about the other two. A screen that hid\n * that would be the record store lying about what it handed over.\n */\nfunction Withheld({ withheld }: { withheld: RecordChatWithheld[] }) {\n if (withheld.length === 0) return null;\n return (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n Not in this conversation: {withheld.map((w) => w.label).join(\", \")}.{\" \"}\n {withheld[0]?.reason ? withheld[0].reason : \"The store masked it for this reader.\"} An answer here is\n an answer without {withheld.length === 1 ? \"that field\" : \"those fields\"}.\n </p>\n );\n}\n\n/**\n * THE GROUNDING, AND IT CARRIES THE FIELD'S MEANING.\n *\n * FLD-N-1: a unit and a format are on the Field because they change what the\n * value MEANS, so `48000` reaches the agent as `$48,000` exactly as it reaches\n * the screen. An agent given the bare number is an agent one currency away from\n * a confident mistake.\n */\nfunction entriesFor(\n fields: Field[],\n document: Record<string, unknown>,\n tableName: string,\n title: string,\n held: RecordChatWithheld[],\n): RecordChatEntry[] {\n const entries: RecordChatEntry[] = [\n {\n key: \"record_subject\",\n label: \"Record\",\n type: \"text\",\n value: `${title} — a ${tableName} record.`,\n },\n ];\n for (const field of fields) {\n // AGT-7 / VAL-6: a Field's sensitivity is a CEILING. The store's four words\n // are public · internal · confidential · restricted, and the top two are\n // ceilings no conversation rises through. Both these and FLD-12's `exclude`\n // and `on_request` are left out HERE and named in `held` below: a field\n // that quietly vanished would be a field the agent answers around.\n // FLD-12 is the FIELD'S OWN ANSWER to \"may an agent see this?\", in the\n // store's four words, and `exclude` means exactly that. AGT-7 adds a\n // ceiling on top: `confidential` and `restricted` values are not handed to\n // a conversation whatever the policy says.\n const guarded = field.sensitivity === \"confidential\" || field.sensitivity === \"restricted\";\n if (guarded || field.context_policy === \"exclude\" || field.context_policy === \"on_request\") {\n held.push({\n key: field.key,\n label: field.label,\n reason: guarded\n ? `This field is marked ${field.sensitivity}, so it is not handed to a conversation.`\n : field.context_policy === \"exclude\"\n ? \"This field says an agent may not see its values.\"\n : \"This field is given on request, so the agent asks for it rather than being handed it.\",\n });\n continue;\n }\n const raw = document[field.key];\n if (raw === undefined || raw === null || raw === \"\") continue;\n const structured = typeof raw === \"object\";\n entries.push({\n key: field.key,\n label: field.label,\n type: structured ? \"json\" : \"text\",\n value: structured ? raw : scalarText(field, raw),\n });\n }\n return entries;\n}\n\nfunction noticeText(notice: HiddenFieldNotice): string {\n const bag = notice as unknown as Record<string, unknown>;\n const said = bag[\"reason\"] ?? bag[\"message\"] ?? bag[\"why\"];\n return typeof said === \"string\" && said.length > 0 ? said : \"The store masked this field for this reader.\";\n}\n","\"use client\";\n\n// src/EnrichPanel.tsx — @ai-matrx/records-ui · SCR-27\n//\n// PER-FIELD AI FILL, AND THE THREE FACTS IT REFUSES TO FAKE.\n//\n// A Field whose `source` is `agent` is a Field the organization said an agent\n// keeps filled (FLD-7). `review_interval_days` is how often (AGT-6). Those two\n// live on the Field record, so this panel does not decide which fields are\n// agent-filled and it does not decide when they are stale — it READS both, and\n// a Table with no agent Fields says so instead of offering a Fill button over\n// nothing.\n//\n// 1. FRESHNESS IS THE VALUE'S OWN. `_values.<key>.at` is when it was written\n// and `.actor` is who wrote it; `review_interval_days` turns those into\n// \"due\" or \"fresh\". A screen that timed this off `updated_at` on the row\n// would call every field stale because one of them changed.\n//\n// 2. THE PROVENANCE BADGE IS NOT DECORATION. VAL-8: a value knows whether a\n// person or an agent wrote it, and which person the agent was acting for.\n// That is shown on every agent-filled value, always, because a number a\n// machine guessed and a number a person typed are different facts and the\n// difference must survive into the screen.\n//\n// 3. THE FILL GOES THROUGH THE SERVER, NEVER THROUGH THIS CLIENT. The write\n// has to be stamped actor `agent` on behalf of the person, and a browser\n// that stamped itself `agent` would be a browser claiming to be an agent.\n// The server's own `records` tool does it properly\n// (aidream `packages/matrx-records/matrx_records/agent/tool.py`:\n// `Actor.agent(principal)` → the reserved document keys `_actor` and\n// `_on_behalf_of`), so this panel asks the HOST to make that call.\n//\n// WHAT matrx-frontend MUST PASS:\n//\n// <RecordsUiProvider value={{\n// enrich: async (ask) =>\n// fetch(\"/api/ai/tools/execute\", { method: \"POST\", body: JSON.stringify({\n// tool_name: \"records\", surface: \"records-ui:enrich\",\n// arguments: { action: \"record_write\", record_id: ask.recordId,\n// values: Object.fromEntries(ask.fields.map(f => [f.key, null])) },\n// })}).then(...)\n//\n// TWO LIVE GATES SIT IN FRONT OF THAT CALL TODAY, and this panel names them\n// rather than spinning: the knob `custom/code_paths_enabled` resolves false\n// (the tool refuses every action while it does), and the `records` row in\n// `tool.binding` is `is_active = false`. Both are switches somebody flips on\n// purpose; neither is something a screen may work around.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, RecordDocument, RecordsError, ValueEnvelope } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { envelopeFor, RecordValue } from \"./values\";\n\n/** What the host is asked to have the server's `records` tool do. */\nexport interface EnrichAsk {\n tableId: Uuid;\n recordId: Uuid;\n /** The agent Fields to refill, each with why this panel thinks it is due. */\n fields: Array<{ key: string; label: string; because: string }>;\n}\n\nexport interface EnrichOutcome {\n ok: boolean;\n /** What happened, in a sentence — the server's own words when it has some. */\n message: string;\n}\n\nexport const NO_ENRICH_REASON =\n \"No enrich port is bound, so nothing here offers to fill a field it cannot fill. An AI fill is \" +\n \"written by the SERVER with actor `agent` on behalf of you — a browser that stamped itself `agent` \" +\n \"would be a browser claiming to be one — so bind `enrich` on <RecordsUiProvider> with a call to the \" +\n \"server's own `records` tool (action `record_write`). Two switches also sit in front of it today: \" +\n \"the knob `custom/code_paths_enabled` resolves false, and the `records` row in `tool.binding` is \" +\n \"`is_active = false`.\";\n\nexport interface EnrichPanelProps {\n tableId: Uuid;\n recordId: Uuid;\n className?: string | undefined;\n}\n\ninterface AgentField {\n field: Field;\n envelope: ValueEnvelope | undefined;\n value: unknown;\n /** Days since it was written, or null when it has never been written. */\n ageDays: number | null;\n /** The Field's own interval, null when the organization set none. */\n everyDays: number | null;\n due: boolean;\n /** Why it is due, or why it is not — said in words, never left to a colour. */\n because: string;\n}\n\nexport function EnrichPanel({ tableId, recordId, className }: EnrichPanelProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const rights = useTableRights(table.data);\n const [document, setDocument] = useState<RecordDocument | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [outcome, setOutcome] = useState<EnrichOutcome | null>(null);\n\n const load = useCallback(async () => {\n const answered = await client.recordRead({ record_id: recordId });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setError(null);\n setDocument(answered.data.document);\n }, [client, recordId]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const agentFields: AgentField[] | null = useMemo(() => {\n if (!fields.data || !document) return null;\n // FLD-7: the STORE says which fields an agent keeps filled. This panel has\n // no list of its own and no heuristic — a Field is here because its own\n // record says `source = 'agent'`.\n return fields.data.filter((f) => f.source === \"agent\").map((field) => describe(field, document));\n }, [fields.data, document]);\n\n const runFill = useCallback(\n async (targets: AgentField[]) => {\n if (!host.enrich || targets.length === 0) return;\n setBusy(targets.length === 1 ? (targets[0] as AgentField).field.key : \"*\");\n setOutcome(null);\n const answered = await host.enrich({\n tableId,\n recordId,\n fields: targets.map((t) => ({ key: t.field.key, label: t.field.label, because: t.because })),\n });\n setBusy(null);\n setOutcome(answered);\n // Re-read either way: a refused fill leaves the record exactly as it was,\n // and a screen that assumed so without looking would be guessing.\n await load();\n },\n [host, load, recordId, tableId],\n );\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (error) return <RefusalNotice error={error} className={className} />;\n if (!agentFields) return <Skeleton className={cn(\"h-40 w-full\", className)} />;\n\n if (agentFields.length === 0) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n No Field on {table.data?.name ?? \"this table\"} says an agent keeps it filled, so there is nothing\n here to enrich. A Field becomes agent-filled by carrying <code>source = agent</code> on its own\n record — set it in the field editor and it appears here with its review interval.\n </p>\n );\n }\n\n const due = agentFields.filter((f) => f.due);\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: the count, what is due, and the one verb. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">AI fill</span>\n <span>\n {agentFields.length} agent {agentFields.length === 1 ? \"field\" : \"fields\"}\n {due.length > 0 ? `, ${due.length} due` : \", all fresh\"}\n </span>\n {host.enrich && rights.write && due.length > 0 ? (\n <Button size=\"sm\" className=\"ml-auto\" disabled={busy !== null} onClick={() => void runFill(due)}>\n {busy === \"*\" ? \"Asking…\" : `Refill ${due.length}`}\n </Button>\n ) : null}\n </header>\n\n {/* The port is not bound: absent verb, stated reason. Never a dead button. */}\n {!host.enrich ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_ENRICH_REASON}</p>\n ) : null}\n {host.enrich && !rights.write ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{rights.reason}</p>\n ) : null}\n\n {outcome ? (\n <p\n className={cn(\n \"rounded border px-2 py-1 text-xs\",\n outcome.ok ? \"text-muted-foreground\" : \"border-destructive text-destructive\",\n )}\n >\n {outcome.message}\n </p>\n ) : null}\n\n <ul className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {agentFields.map((entry) => (\n <li key={entry.field.key} className=\"rounded border p-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-xs font-medium\">{entry.field.label}</span>\n <ProvenanceBadge envelope={entry.envelope} />\n <span className={cn(\"text-[11px]\", entry.due ? \"text-destructive\" : \"text-muted-foreground\")}>\n {entry.because}\n </span>\n {host.enrich && rights.write ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto h-6 px-2 text-[11px]\"\n disabled={busy !== null}\n onClick={() => void runFill([entry])}\n >\n {busy === entry.field.key ? \"Asking…\" : \"Fill\"}\n </Button>\n ) : null}\n </div>\n <div className=\"mt-1 text-xs\"><RecordValue field={entry.field} value={entry.value} document={document ?? undefined} /></div>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\n/**\n * VAL-8 ON SCREEN. Who wrote this value, and — when it was an agent — which\n * person they were acting for. AGT-N-4 is the whole reason the second half is\n * shown: an agent carries the exact authority of the person operating it, so\n * \"an agent, for Dana\" is the true sentence and \"an agent\" is not.\n */\nfunction ProvenanceBadge({ envelope }: { envelope: ValueEnvelope | undefined }) {\n if (!envelope) return null;\n if (envelope.actor !== \"agent\") {\n return (\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {envelope.actor === \"system\" ? \"written by the system\" : \"written by a person\"}\n </Badge>\n );\n }\n return (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {envelope.on_behalf_of ? `filled by an agent, for ${envelope.on_behalf_of}` : \"filled by an agent\"}\n </Badge>\n );\n}\n\n/**\n * IS THIS VALUE DUE? Read off the value's own envelope and the Field's own\n * interval, and said in a sentence.\n *\n * An interval nobody set is NOT silently \"never due\" and not silently \"always\n * due\": the Field has no review interval, that is stated, and the value is left\n * alone. A knob nobody turned is not a decision somebody made.\n */\nfunction describe(field: Field, document: RecordDocument): AgentField {\n const envelope = envelopeFor(document, field.key);\n const value = (document as Record<string, unknown>)[field.key];\n const everyDays = field.review_interval_days ?? null;\n const writtenAt = envelope?.at ? Date.parse(envelope.at) : Number.NaN;\n const ageDays = Number.isNaN(writtenAt) ? null : Math.floor((Date.now() - writtenAt) / 86_400_000);\n\n if (value === undefined || value === null || value === \"\") {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: true,\n because: \"never filled\",\n };\n }\n if (everyDays === null) {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: false,\n because:\n ageDays === null ? \"no review interval set\" : `filled ${ageDays}d ago, no review interval set`,\n };\n }\n if (ageDays === null) {\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: true,\n because: `every ${everyDays}d, and this value carries no date`,\n };\n }\n return {\n field,\n envelope,\n value,\n ageDays,\n everyDays,\n due: ageDays >= everyDays,\n because: ageDays >= everyDays ? `${ageDays}d old, due every ${everyDays}d` : `${ageDays}d old of ${everyDays}d`,\n };\n}\n","\"use client\";\n\n// src/ChecklistRunner.tsx — @ai-matrx/records-ui · SCR-28\n//\n// A CHECKLIST IS NOT A LIST OF STRINGS. Every step is a REAL RECORD in a real\n// Table, related to the others, so a step can be assigned, commented on,\n// exported, historied and read by an agent exactly like anything else in this\n// store — and \"step 3 of the onboarding\" is a row somebody can find six months\n// later rather than a line in a JSON blob.\n//\n// THE TEMPLATE IS INSTANTIATED IN ONE ACT (REC-70). `custom.work_template_instantiate`\n// judges the whole graph before writing any of it, so a half-made checklist is\n// not a state this store can be in — and this component does not loop writing\n// steps one at a time, which is exactly how half-made checklists happen.\n//\n// THE STORE OWNS THE ORDER, THE TURN AND THE STATES:\n// · `custom.work_states()` is the five states and what each may become. This\n// screen hardcodes none of them; a picker built from a hardcoded list is a\n// second source of truth waiting to disagree.\n// · `custom.work_whose_turn` says whose turn each step is and whether its\n// state is terminal.\n// · `custom.work_transition_refusal` says why a move is refused, ASKED FIRST,\n// so a person is told before they try rather than after.\n//\n// `seed` is the agent's half: a complete declarative template, saved the first\n// time it is seen, exactly as `ViewBar`, `FormBuilder` and `DashboardCanvas`\n// take theirs. An agent writes a twelve-step checklist in one object.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, useTable, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, WorkGraph, WorkState, WorkTurn } from \"@ai-matrx/records\";\nimport { Badge, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useTableRights } from \"./host\";\nimport { useSystemTable, type SystemTableSpec } from \"./systemTable\";\n\n/** THE COMPLETE DECLARATIVE SPEC — one object, one `record_write`, a whole checklist. */\nexport interface ChecklistSpec {\n name: string;\n /** The Table the steps become records in. */\n subject: Uuid;\n steps: ChecklistStepSpec[];\n}\n\nexport interface ChecklistStepSpec {\n /** The document this step's record starts life with. `title` is what a person reads. */\n title: string;\n /** Anything else the subject Table's Fields take. */\n data?: Record<string, unknown>;\n}\n\n/**\n * The package-owned Table a checklist RUN is recorded in. The steps are records\n * in the subject Table — this holds only which template was instantiated and\n * when, so re-opening a checklist finds the same steps rather than making new\n * ones. (Running the same checklist twice on purpose is two rows here, which is\n * the correct answer: they are two runs.)\n */\nexport const CHECKLIST_TABLE: SystemTableSpec = {\n slug: \"records_ui_checklist_run\",\n name: \"Checklist runs\",\n labelSingular: \"Checklist run\",\n labelPlural: \"Checklist runs\",\n titleField: \"name\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"text\", sort: 10, required: true },\n { key: \"subject\", label: \"Table\", type: \"text\", sort: 20, required: true },\n { key: \"template_id\", label: \"Template\", type: \"text\", sort: 30 },\n { key: \"instantiation_id\", label: \"Instantiation\", type: \"text\", sort: 40 },\n { key: \"step_ids\", label: \"Steps\", type: \"text\", sort: 50, config: { multiline: true } },\n { key: \"started_at\", label: \"Started\", type: \"text\", sort: 60 },\n ],\n};\n\nexport interface ChecklistRunnerProps {\n /** The Table the steps live in — normally the same Table the checklist is about. */\n tableId: Uuid;\n /** The agent's half. Each spec not already run is instantiated once. */\n seed?: ChecklistSpec[] | undefined;\n className?: string | undefined;\n}\n\ninterface Run {\n id: Uuid;\n name: string;\n subject: Uuid;\n templateId: Uuid | null;\n stepIds: Uuid[];\n startedAt: string;\n}\n\nexport function ChecklistRunner({ tableId, seed, className }: ChecklistRunnerProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const home = useSystemTable(CHECKLIST_TABLE);\n const [runs, setRuns] = useState<Run[] | null>(null);\n const [activeId, setActiveId] = useState<Uuid | null>(null);\n const [turns, setTurns] = useState<WorkTurn[] | null>(null);\n const [states, setStates] = useState<WorkState[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n const [note, setNote] = useState<string | null>(null);\n\n const runTableId = home.tableId;\n\n // The five states, from the store. Asked once, never typed out here.\n useEffect(() => {\n let cancelled = false;\n void client.workStates().then((answered) => {\n if (cancelled || !answered.ok) return;\n setStates([...answered.data].sort((a, b) => a.sort - b.sort));\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n const loadRuns = useCallback(async (): Promise<Run[] | null> => {\n if (!runTableId) return null;\n const listed = await client.list({ table_id: runTableId, limit: 200 });\n if (!listed.ok) {\n setError(listed.error);\n return null;\n }\n setError(null);\n const held = listed.data.rows.map(toRun).filter((r) => r.subject === tableId);\n setRuns(held);\n return held;\n }, [client, runTableId, tableId]);\n\n useEffect(() => {\n void loadRuns();\n }, [loadRuns]);\n\n // ── the seed: instantiated ONCE, never on top of a run that exists ────────\n useEffect(() => {\n let cancelled = false;\n if (!runTableId || !seed || seed.length === 0 || runs === null) return;\n const missing = seed.filter((spec) => !runs.some((run) => run.name === spec.name));\n if (missing.length === 0) return;\n void (async () => {\n for (const spec of missing) {\n if (cancelled) return;\n const started = await start(client, runTableId, spec);\n if (!started.ok) {\n setError(started.error);\n return;\n }\n }\n if (!cancelled) await loadRuns();\n })();\n return () => {\n cancelled = true;\n };\n }, [client, loadRuns, runTableId, runs, seed]);\n\n const active = useMemo(\n () => runs?.find((r) => r.id === activeId) ?? runs?.[0] ?? null,\n [runs, activeId],\n );\n\n // Whose turn each step is — the STORE's answer, over the whole subject Table,\n // narrowed here to this run's own steps.\n const loadTurns = useCallback(async () => {\n const answered = await client.workWhoseTurn({ table_id: tableId, includeFinished: true });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setTurns(answered.data);\n }, [client, tableId]);\n\n // Re-asked whenever the RUN changes, not only on mount: the seed instantiates\n // its steps AFTER the first read, so a screen that asked once would draw a\n // checklist whose every step said \"you cannot see this\" — records that had\n // been written a second earlier.\n useEffect(() => {\n void loadTurns();\n }, [loadTurns, active?.id, active?.stepIds.length]);\n\n async function move(step: Uuid, to: string) {\n setBusy(true);\n setNote(null);\n const written = await client.recordUpdate({ record_id: step, patch: { status: to } });\n setBusy(false);\n if (!written.ok) {\n setError(written.error);\n return;\n }\n setError(null);\n setNote(`Moved to ${to}.`);\n await loadTurns();\n }\n\n if (home.error) return <RefusalNotice error={home.error} className={className} />;\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (home.loading || runs === null) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n if (!active) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n No checklist has been run against {table.data?.name ?? \"this table\"} yet. Pass a complete template as{\" \"}\n <code>seed</code> — a name and its ordered steps — and it is instantiated once, as real records.\n </p>\n );\n }\n\n const steps = active.stepIds\n .map((id) => turns?.find((t) => t.record_id === id) ?? null)\n .map((turn, index) => ({ turn, index, id: active.stepIds[index] as Uuid }));\n const done = steps.filter((s) => s.turn?.terminal === true).length;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: which run, and how far through. No subtitle restating the name. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{active.name}</span>\n <span className=\"tabular-nums\">\n {done} of {steps.length} done\n </span>\n {runs.length > 1 ? (\n <select\n aria-label=\"Checklist run\"\n className=\"ml-auto h-7 rounded border bg-background px-1 text-xs\"\n value={active.id}\n onChange={(e) => setActiveId(e.target.value as Uuid)}\n >\n {runs.map((r) => (\n <option key={r.id} value={r.id}>\n {r.name}\n </option>\n ))}\n </select>\n ) : null}\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n {note ? <p className=\"text-xs text-muted-foreground\">{note}</p> : null}\n\n {turns === null ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : (\n <ol className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {steps.map(({ turn, index, id }) => (\n <li key={id} className=\"flex items-center gap-2 rounded border p-2\">\n <span className=\"w-5 shrink-0 text-right text-[11px] tabular-nums text-muted-foreground\">\n {index + 1}\n </span>\n <span className={cn(\"min-w-0 flex-1 truncate text-xs\", turn?.terminal && \"text-muted-foreground line-through\")}>\n {turn?.title ??\n // The step is a record the read door did not return. That is a\n // fact about visibility, not an empty row, so it says so.\n \"This step is a record you cannot see — it is in the run, and the store did not return it to you.\"}\n </span>\n {turn?.assignee_id ? (\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {turn.turn ?? \"assigned\"}\n </Badge>\n ) : null}\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {turn?.status ?? turn?.state ?? \"Not started\"}\n </Badge>\n {/* The next states are the STORE's `next` for the state this step\n is actually in. A move nobody may make is never offered. */}\n {rights.write && turn && states ? (\n <NextMove\n states={states}\n current={turn.status ?? turn.state ?? null}\n disabled={busy}\n onMove={(to) => void move(id, to)}\n />\n ) : null}\n </li>\n ))}\n </ol>\n )}\n\n {!rights.write ? <p className=\"text-xs text-muted-foreground\">{rights.reason}</p> : null}\n </section>\n );\n}\n\n/**\n * The moves this step may actually make, from `custom.work_states()`.\n *\n * A state the store does not list as `next` is not shown greyed out — it is not\n * there. Offering a move that will be refused, and only saying so afterwards,\n * is the screen making a person find out by failing.\n */\nfunction NextMove({\n states,\n current,\n disabled,\n onMove,\n}: {\n states: WorkState[];\n current: string | null;\n disabled: boolean;\n onMove: (to: string) => void;\n}) {\n const here = states.find((s) => s.name === current) ?? states[0];\n const next = here?.next ?? [];\n if (next.length === 0) {\n return <span className=\"text-[11px] text-muted-foreground\">finished</span>;\n }\n return (\n <span className=\"flex shrink-0 gap-1\">\n {next.map((to) => (\n <Button key={to} size=\"sm\" variant=\"ghost\" className=\"h-6 px-2 text-[11px]\" disabled={disabled} onClick={() => onMove(to)}>\n {to}\n </Button>\n ))}\n </span>\n );\n}\n\n/**\n * ONE ACT. The template is declared, judged and instantiated, and only then is\n * the run recorded — so a refused graph leaves nothing behind at all.\n */\nasync function start(\n client: ReturnType<typeof useRecordsClient>,\n runTableId: Uuid,\n spec: ChecklistSpec,\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const graph: WorkGraph = {\n // A ref is lower-case letters, digits and underscores — the store refuses\n // `step-1` by name (\"every record in a template needs a name made of\n // lower-case letters, digits and underscores\"). Refs are built here rather\n // than taken from a person's step title for exactly that reason.\n nodes: spec.steps.map((step, index) => ({\n ref: `step_${index + 1}`,\n table: spec.subject,\n data: { title: step.title, ...(step.data ?? {}) },\n })),\n // Each step owns the next, so the order is a fact in the store rather than\n // an array index a screen remembered.\n relations: spec.steps.slice(1).map((_, index) => ({ from: `step_${index + 1}`, to: `step_${index + 2}` })),\n };\n\n // ASKED BEFORE IT IS WRITTEN. The store says why a graph would be refused,\n // and a refusal here costs nothing rather than leaving a declared template\n // nobody can instantiate.\n const refusal = await client.workTemplateRefusal({ graph });\n if (!refusal.ok) return refusal;\n if (refusal.data) {\n return {\n ok: false,\n error: {\n code: \"refused_by_rule\",\n message: refusal.data,\n hint: \"The store judged the whole graph before anything was written, so nothing was — fix the template and run it again.\",\n },\n };\n }\n\n const declared = await client.workTemplateDeclare({ name: spec.name, graph });\n if (!declared.ok) return declared;\n const made = await client.workTemplateInstantiate({ template_id: declared.data });\n if (!made.ok) return made;\n\n return client.recordWrite({\n table_id: runTableId,\n data: {\n name: spec.name,\n subject: spec.subject,\n template_id: declared.data,\n instantiation_id: made.data.instantiation_id,\n step_ids: JSON.stringify(made.data.records),\n started_at: new Date().toISOString(),\n },\n });\n}\n\nfunction toRun(row: ReadRow): Run {\n const data = (row.document ?? {}) as Record<string, unknown>;\n let stepIds: Uuid[] = [];\n try {\n const raw = data[\"step_ids\"];\n stepIds = typeof raw === \"string\" ? (JSON.parse(raw) as Uuid[]) : Array.isArray(raw) ? (raw as Uuid[]) : [];\n } catch {\n stepIds = [];\n }\n return {\n id: row.id,\n name: String(data[\"name\"] ?? \"Checklist\"),\n subject: String(data[\"subject\"] ?? \"\"),\n templateId: (data[\"template_id\"] as Uuid | null) ?? null,\n stepIds,\n startedAt: String(data[\"started_at\"] ?? \"\"),\n };\n}\n","\"use client\";\n\n// src/BookingSlots.tsx — @ai-matrx/records-ui · SCR-29\n//\n// AVAILABILITY, A SLOT PICKER, AND THE ONE THING THAT MAKES BOOKING HARD:\n// TWO PEOPLE PICKING THE SAME SLOT AT THE SAME MOMENT.\n//\n// This screen does not decide that. `custom.work_slot_hold` does, under a\n// unique index, and the loser is TOLD — not shown a spinner, not silently given\n// the next slot, not left believing they have a booking that somebody else has.\n// A picker that filtered out taken slots client-side would be correct roughly\n// until two people used it.\n//\n// WHERE A HOLD LIVES, AND WHY IT IS NOT THE BOOKING TABLE. Measured against the\n// live store: `custom.work_slot_hold` WRITES a record for the hold, so pointing\n// it at the bookings Table is refused by that Table's own Rules (\"Title is\n// required\"), and `custom.work_slot_holds` then reads every booking back as a\n// hold with no slot key. A slot has to live in a Table declared for it, by\n// `custom.work_slots_declare`, which builds the UNIQUE INDEX that makes one\n// hold per slot true in the database rather than true in an application. So\n// this component declares that Table once, through the same doors everything\n// else uses, and holds against it.\n//\n// THE THREE PARTS, AND WHO OWNS EACH:\n// · AVAILABILITY is the organization's own: a start hour, an end hour, a slot\n// length, over N days. Those are knobs on this component with sensible\n// defaults, because they are an opinion and opinions are settings.\n// · WHAT IS TAKEN is the store's: `custom.work_slot_holds` lists every hold\n// with whether it has LAPSED, so a slot that came back says why rather than\n// reappearing mysteriously.\n// · WHAT A BOOKING *IS* is `FormRunner`'s: the person answers the form's own\n// questions and the submission is an ORDINARY RECORD in a real Table. There\n// is no bookings table, no second data model, and no reconciliation later.\n//\n// THE ORDER MATTERS AND IT IS THE STRICT ONE: hold the slot FIRST, then take\n// the details, then release the hold only if they abandon it. Taking details\n// first and holding after is how two people fill in a form and one of them\n// finds out at the end.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError, WorkSlotHold } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { FormRunner } from \"./FormRunner\";\nimport type { FormSpec } from \"./forms\";\n\nexport interface BookingSlotsProps {\n /** The Table holds are taken against, and the Table a booking lands in. */\n tableId: Uuid;\n /** The form a person fills in once they hold a slot. Its `subject` is the Table. */\n form: FormSpec;\n /** Availability — the organization's opinion, with a default rather than a question. */\n availability?: {\n /** First hour offered, 24h. Default 9. */\n fromHour?: number;\n /** Last hour offered, exclusive. Default 17. */\n toHour?: number;\n /** Minutes per slot. Default 60. */\n everyMinutes?: number;\n /** How many days ahead to offer. Default 5. */\n days?: number;\n };\n /** How long a hold lasts before the store lets the slot go. Default 15 minutes. */\n holdFor?: string;\n onBooked?: ((recordId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\ninterface Slot {\n /** The key the STORE holds. Stable, sortable, and the same string for everyone. */\n key: string;\n at: Date;\n taken: boolean;\n /** Set when the slot is taken: who by, so a person can see it is their own. */\n holder: string | null;\n}\n\nexport function BookingSlots({\n tableId,\n form,\n availability,\n holdFor = \"15 minutes\",\n onBooked,\n className,\n}: BookingSlotsProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const [slotTableId, setSlotTableId] = useState<Uuid | null>(null);\n const [holds, setHolds] = useState<WorkSlotHold[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [held, setHeld] = useState<{ slot: Slot; holdId: Uuid | null } | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [refused, setRefused] = useState<string | null>(null);\n\n const me = client.config.actor.user_id ?? \"anonymous\";\n const slug = `records_ui_slots_${tableId.replace(/-/g, \"\").slice(0, 16)}`;\n\n // ── the slots Table, declared once, through the store's own doors ─────────\n // A Home first (REC-1: a Table has to live somewhere), then the declaration\n // — the same sequence `ensureSystemTable` obeys, and for the same reason.\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n // FOUND BEFORE IT IS MADE. Two screens open on the same bookings Table\n // must hold against the SAME slots Table, or each one has its own\n // private idea of what is free and the unique index protects nothing.\n const tables = await client.tableList();\n if (!tables.ok) {\n if (!cancelled) setError(tables.error);\n return;\n }\n const already = tables.data.find((t) => t.slug === slug);\n if (already) {\n if (!cancelled) setSlotTableId(already.id);\n return;\n }\n const kernel = await client.personKernelId();\n if (!kernel.ok) {\n if (!cancelled) setError(kernel.error);\n return;\n }\n const home = await client.recordWrite({\n table_id: kernel.data,\n data: { name: `Slots for ${tableId}` },\n });\n if (!home.ok) {\n if (!cancelled) setError(home.error);\n return;\n }\n const declared = await client.workSlotsDeclare({\n name: `Slots for ${table.data?.name ?? \"bookings\"}`,\n slug,\n homeId: home.data,\n });\n if (cancelled) return;\n if (!declared.ok) {\n // THE STORE REFUSED TO MAKE SLOTS AT ALL — most often because it\n // cannot build the unique index that keeps one hold per slot. That is\n // shown verbatim and NO PICKER IS DRAWN: a booking screen over a store\n // that cannot decide a double-booking is a screen that will sell the\n // same hour twice and look fine doing it.\n setError(declared.error);\n return;\n }\n const made = (declared.data ?? {}) as Record<string, unknown>;\n setSlotTableId((made[\"table_id\"] as Uuid | undefined) ?? null);\n })();\n return () => {\n cancelled = true;\n };\n }, [client, slug, table.data, tableId]);\n\n const loadHolds = useCallback(async () => {\n if (!slotTableId) return;\n const answered = await client.workSlotHolds({ table_id: slotTableId });\n if (!answered.ok) {\n setError(answered.error);\n return;\n }\n setError(null);\n setHolds(answered.data);\n }, [client, slotTableId]);\n\n useEffect(() => {\n void loadHolds();\n }, [loadHolds]);\n\n const slots: Slot[] = useMemo(() => {\n const fromHour = availability?.fromHour ?? 9;\n const toHour = availability?.toHour ?? 17;\n const everyMinutes = availability?.everyMinutes ?? 60;\n const days = availability?.days ?? 5;\n // A LAPSED hold is not a taken slot. The store says which is which, so the\n // slot comes back on its own and nobody has to guess from a clock.\n const taken = new Map(\n (holds ?? []).filter((h) => !h.expired).map((h) => [h.slot_key, h.holder] as const),\n );\n const out: Slot[] = [];\n const first = new Date();\n first.setHours(0, 0, 0, 0);\n for (let day = 0; day < days; day += 1) {\n for (let minute = fromHour * 60; minute < toHour * 60; minute += everyMinutes) {\n const at = new Date(first);\n at.setDate(at.getDate() + day);\n at.setMinutes(minute);\n if (at.getTime() < Date.now()) continue;\n const key = at.toISOString();\n out.push({ key, at, taken: taken.has(key), holder: taken.get(key) ?? null });\n }\n }\n return out;\n }, [availability, holds]);\n\n async function take(slot: Slot) {\n if (!slotTableId) return;\n setBusy(slot.key);\n setRefused(null);\n setError(null);\n const answered = await client.workSlotHold({\n table_id: slotTableId,\n slotKey: slot.key,\n holder: me,\n ttl: holdFor,\n });\n setBusy(null);\n if (!answered.ok) {\n // THE LOSING HALF OF A RACE, AND IT IS THE DATABASE'S ANSWER.\n // `already_exists` is the unique index refusing a second hold on one\n // slot; the store's own sentence names the index that did it. Shown\n // verbatim, because \"the slot is already held\" is a fact a person can act\n // on and a spinner is not.\n if (answered.error.code === \"already_exists\") {\n setRefused(answered.error.message);\n } else {\n setError(answered.error);\n }\n await loadHolds();\n return;\n }\n const outcome = (answered.data ?? {}) as Record<string, unknown>;\n const holdId = (outcome[\"hold_id\"] as Uuid | undefined) ?? null;\n if (!holdId) {\n setRefused(\n \"The store did not hold that slot and did not say why, so nothing was booked. Pick another, and \" +\n \"report this — a hold that neither succeeds nor refuses is a defect, not a busy moment.\",\n );\n await loadHolds();\n return;\n }\n setHeld({ slot, holdId });\n }\n\n async function letGo() {\n if (held?.holdId) await client.workSlotRelease({ hold_id: held.holdId });\n setHeld(null);\n await loadHolds();\n }\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n // A refusal from the declaration is the END of this screen, not a banner over\n // a working picker.\n if (error && !slotTableId) return <RefusalNotice error={error} className={className} />;\n if (holds === null || !slotTableId) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n // ── the slot is held: now, and only now, the details ──────────────────────\n if (held) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{whenText(held.slot.at)}</span>\n <span>held for you for {holdFor}</span>\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-6 px-2 text-[11px]\" onClick={() => void letGo()}>\n Pick another\n </Button>\n </header>\n <FormRunner\n // The booking IS the submission: an ordinary record in a real Table,\n // carrying the slot it was made for, so it is in the grid and the\n // exports the moment it is sent.\n form={{\n ...form,\n questions: form.questions,\n }}\n onSubmitted={(recordId) => {\n void client\n .recordUpdate({ record_id: recordId, patch: { slot: held.slot.key } })\n .then(() => loadHolds());\n onBooked?.(recordId);\n }}\n />\n </section>\n );\n }\n\n const free = slots.filter((s) => !s.taken).length;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: what is on offer. No subtitle restating it. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Pick a time</span>\n <span className=\"tabular-nums\">\n {free} free of {slots.length}\n </span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n {refused ? <p className=\"rounded border border-destructive px-2 py-1 text-xs text-destructive\">{refused}</p> : null}\n\n {slots.length === 0 ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n There is no time left today inside the hours this is offered in. Tomorrow's slots appear here\n from midnight — this is empty because the day is over, not because something failed.\n </p>\n ) : (\n <ol className=\"flex flex-wrap gap-1\">\n {slots.map((slot) => (\n <li key={slot.key}>\n {/* A taken slot is not a dead button: it is not a button. */}\n {slot.taken ? (\n <span\n className=\"inline-flex h-8 items-center rounded border border-dashed px-2 text-[11px] text-muted-foreground\"\n title={slot.holder === me ? \"You are holding this one.\" : \"Somebody is holding this one.\"}\n >\n {whenText(slot.at)} · {slot.holder === me ? \"yours\" : \"taken\"}\n </span>\n ) : (\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-8 px-2 text-[11px]\"\n disabled={busy !== null}\n onClick={() => void take(slot)}\n >\n {busy === slot.key ? \"Holding…\" : whenText(slot.at)}\n </Button>\n )}\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n}\n\nfunction whenText(at: Date): string {\n return at.toLocaleString(undefined, { weekday: \"short\", hour: \"numeric\", minute: \"2-digit\" });\n}\n","\"use client\";\n\n// src/CaptureSheet.tsx — @ai-matrx/records-ui · SCR-30\n//\n// A PHONE, IN A BASEMENT, WITH NO SIGNAL — AND THE CAPTURE STILL COUNTS.\n//\n// Everything hard about offline capture is one question: when the phone comes\n// back and fires the same capture for the thirtieth time, does the store write\n// thirty records? The answer is the OFFLINE CAPTURE CONTRACT, and both halves\n// of it are load-bearing:\n//\n// 1. THE CLIENT MINTS THE ID, BEFORE THE FIRST ATTEMPT, OFFLINE. `clientKey`\n// is decided the moment a person hits Capture — not when the write lands,\n// because a key minted by the server is a key that does not exist while\n// there is no server. It is never re-minted on retry: re-minting is exactly\n// how a retry becomes a second capture.\n// 2. THE STORE DEDUPES ON IT. `custom.anon_capture` writes a replay-ledger row\n// `on conflict do nothing` under a unique index and returns the record id\n// the FIRST attempt produced. So the second, third and thirtieth replay all\n// take the same branch whatever this client believes, and a phone that\n// crashed mid-send loses nothing.\n//\n// THREE MORE THINGS THIS SHEET REFUSES TO FAKE:\n// · It never claims a capture is saved while it is queued. The queue is\n// visible, counted, and each waiting item says what the store last said.\n// · With no `captureQueue` port bound the queue is IN MEMORY for the life of\n// the page and SAYS SO — a queue that silently died with the tab is the\n// precise failure this component exists to prevent.\n// · A camera or a microphone this browser will not give it is named, not\n// rendered as a button that does nothing. Bytes go through the host's\n// `upload` port; with none bound, the photo and voice capture say so and\n// the reading capture — which is just a number and a note — still works.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useFields, useRecordsClient, useTable, type Uuid } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { NO_UPLOAD_REASON, useRecordsUi, type PendingCapture } from \"./host\";\n\n/** The three things a phone captures. Each one writes the SAME kind of record. */\nexport const CAPTURE_MODES = [\"reading\", \"photo\", \"voice\"] as const;\nexport type CaptureMode = (typeof CAPTURE_MODES)[number];\n\nexport const IN_MEMORY_QUEUE_REASON =\n \"No capture queue is bound, so anything that cannot be sent right now is held in this page's memory \" +\n \"and is lost if the page closes. Bind `captureQueue` on <RecordsUiProvider> with your host's own \" +\n \"durable store (IndexedDB in a browser) and a queued capture survives the tab, the reload and the \" +\n \"flight. It is said here rather than discovered later.\";\n\nexport interface CaptureSheetProps {\n /** The Table a capture becomes a record in. */\n tableId: Uuid;\n /** Which Field a reading's number goes in. Defaults to the first range Field. */\n readingField?: string | undefined;\n /** Which Field the note goes in. Defaults to the Table's title field. */\n noteField?: string | undefined;\n /** Which Field an attachment's file id goes in. */\n attachmentField?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * THE CLIENT-MINTED ID. `crypto.randomUUID` where there is one; a time-and-\n * randomness key where there is not. Either way it is decided HERE, offline,\n * before anything is attempted.\n */\nfunction mintClientKey(): string {\n const c = globalThis.crypto as { randomUUID?: () => string } | undefined;\n if (typeof c?.randomUUID === \"function\") return `capture:${c.randomUUID()}`;\n return `capture:${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;\n}\n\nfunction deviceName(): string {\n const nav = globalThis.navigator as { userAgent?: string } | undefined;\n return nav?.userAgent ? nav.userAgent.slice(0, 120) : \"unknown device\";\n}\n\nexport function CaptureSheet({\n tableId,\n readingField,\n noteField,\n attachmentField,\n className,\n}: CaptureSheetProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const fields = useFields(tableId);\n const [mode, setMode] = useState<CaptureMode>(\"reading\");\n const [reading, setReading] = useState(\"\");\n const [note, setNote] = useState(\"\");\n const [fileId, setFileId] = useState<Uuid | null>(null);\n const [pending, setPending] = useState<PendingCapture[] | null>(null);\n const [saved, setSaved] = useState<Uuid[]>([]);\n const [error, setError] = useState<RecordsError | null>(null);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [flushing, setFlushing] = useState(false);\n /** Kept in a ref as well so a flush never races the render that queued an item. */\n const queue = useRef<PendingCapture[]>([]);\n\n const keep = useCallback(\n async (next: PendingCapture[]) => {\n queue.current = next;\n setPending(next);\n if (host.captureQueue) await host.captureQueue.save(next);\n },\n [host],\n );\n\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n const held = host.captureQueue ? await host.captureQueue.load() : [];\n if (cancelled) return;\n queue.current = held;\n setPending(held);\n })();\n return () => {\n cancelled = true;\n };\n }, [host]);\n\n const resolved = useCallback(() => {\n const all = fields.data ?? [];\n return {\n reading: readingField ?? all.find((f) => f.type === \"range\")?.key ?? null,\n note: noteField ?? table.data?.title_field ?? all[0]?.key ?? null,\n attachment: attachmentField ?? all.find((f) => f.format === \"file\" || f.format === \"image\")?.key ?? null,\n };\n }, [attachmentField, fields.data, noteField, readingField, table.data]);\n\n /**\n * SEND EVERYTHING WAITING. Each item goes through `custom.anon_capture` with\n * the key it was minted with — so an item that actually landed last time\n * comes back with the same record id and leaves the queue, and an item that\n * did not is tried again. Nothing here decides \"this probably worked\".\n */\n const flush = useCallback(async () => {\n if (flushing || queue.current.length === 0) return;\n setFlushing(true);\n const left: PendingCapture[] = [];\n const landed: Uuid[] = [];\n for (const item of queue.current) {\n const answered = await client.anonCapture({\n table_id: item.tableId,\n clientKey: item.clientKey,\n payload: item.payload,\n device: item.device,\n capturedAt: item.capturedAt,\n });\n if (answered.ok) {\n landed.push(answered.data);\n continue;\n }\n left.push({ ...item, attempts: item.attempts + 1, lastRefusal: answered.error.message });\n setError(answered.error);\n }\n if (landed.length > 0) {\n setSaved((held) => [...held, ...landed]);\n setError(null);\n }\n await keep(left);\n setFlushing(false);\n }, [client, flushing, keep]);\n\n // A capture is queued first and sent immediately after, which is the same\n // path a reconnect takes. There is no \"online\" branch that skips the queue:\n // one path means the offline path is the one that is actually exercised.\n async function capture() {\n const keys = resolved();\n const payload: Record<string, unknown> = {};\n if (keys.note && note.trim() !== \"\") payload[keys.note] = note.trim();\n if (mode === \"reading\" && keys.reading && reading.trim() !== \"\") {\n payload[keys.reading] = Number(reading);\n }\n if (mode !== \"reading\" && keys.attachment && fileId) payload[keys.attachment] = fileId;\n if (Object.keys(payload).length === 0) return;\n\n const item: PendingCapture = {\n // MINTED HERE. Before the attempt, not after it.\n clientKey: mintClientKey(),\n tableId,\n payload,\n capturedAt: new Date().toISOString(),\n device: deviceName(),\n attempts: 0,\n lastRefusal: null,\n };\n setReading(\"\");\n setNote(\"\");\n setFileId(null);\n await keep([...queue.current, item]);\n await flush();\n }\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (fields.error) return <RefusalNotice error={fields.error} className={className} />;\n if (fields.loading || pending === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n const keys = resolved();\n\n return (\n <section className={cn(\"mx-auto flex w-full max-w-sm flex-col gap-2\", className)}>\n {/* One row, phone-first: the three modes and the queue count. */}\n <header className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {CAPTURE_MODES.map((m) => (\n <Button\n key={m}\n size=\"sm\"\n variant={m === mode ? \"default\" : \"ghost\"}\n className=\"h-8 px-3 text-[11px] capitalize\"\n onClick={() => setMode(m)}\n >\n {m}\n </Button>\n ))}\n <span className=\"ml-auto tabular-nums\">\n {pending.length > 0 ? `${pending.length} waiting` : `${saved.length} saved`}\n </span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {mode === \"reading\" ? (\n keys.reading ? (\n <Input\n aria-label=\"Reading\"\n inputMode=\"decimal\"\n // A phone keyboard, and a touch target a thumb can hit.\n className=\"h-12 text-lg\"\n placeholder=\"0\"\n value={reading}\n onChange={(e) => setReading(e.target.value)}\n />\n ) : (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {table.data?.name ?? \"This table\"} has no number Field for a reading to go in, so this mode\n would have nowhere to put what you typed. Add one, or name it with <code>readingField</code>.\n </p>\n )\n ) : null}\n\n {mode !== \"reading\" ? (\n !host.upload ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">{NO_UPLOAD_REASON}</p>\n ) : !keys.attachment ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n {table.data?.name ?? \"This table\"} has no Field a file id can go in, so a {mode} capture would\n upload the bytes and then have nowhere to record them. Add one, or name it with{\" \"}\n <code>attachmentField</code>.\n </p>\n ) : (\n <>\n <input\n aria-label={mode === \"photo\" ? \"Take a photo\" : \"Record a voice note\"}\n type=\"file\"\n className=\"text-xs\"\n // Phone-first: this is what opens the camera and the microphone\n // rather than a file browser.\n accept={mode === \"photo\" ? \"image/*\" : \"audio/*\"}\n capture={mode === \"photo\" ? \"environment\" : undefined}\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploadError(null);\n void host.upload?.(file).then((result) => {\n if (result.ok) setFileId(result.fileId);\n else setUploadError(result.reason);\n });\n }}\n />\n {fileId ? <p className=\"text-[11px] text-muted-foreground\">Attached.</p> : null}\n {uploadError ? <p className=\"text-xs text-destructive\">{uploadError}</p> : null}\n </>\n )\n ) : null}\n\n <Textarea\n aria-label=\"Note\"\n rows={2}\n className=\"text-sm\"\n placeholder=\"Note\"\n value={note}\n onChange={(e) => setNote(e.target.value)}\n />\n\n <Button className=\"h-12\" onClick={() => void capture()}>\n Capture\n </Button>\n\n {/* The queue, visible and honest. Never a capture that claims to be saved. */}\n {pending.length > 0 ? (\n <div className=\"flex flex-col gap-1 rounded border p-2\">\n <div className=\"flex items-center gap-2 text-xs\">\n <span className=\"font-medium\">Waiting to send</span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto h-6 px-2 text-[11px]\"\n disabled={flushing}\n onClick={() => void flush()}\n >\n {flushing ? \"Sending…\" : \"Try now\"}\n </Button>\n </div>\n <ul className=\"flex flex-col gap-0.5\">\n {pending.map((item) => (\n <li key={item.clientKey} className=\"text-[11px] text-muted-foreground\">\n {new Date(item.capturedAt).toLocaleTimeString()} · {item.attempts} tried\n {item.lastRefusal ? ` · ${item.lastRefusal}` : \"\"}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {!host.captureQueue ? (\n <p className=\"rounded border border-dashed px-2 py-1 text-[11px] text-muted-foreground\">\n {IN_MEMORY_QUEUE_REASON}\n </p>\n ) : null}\n </section>\n );\n}\n","\"use client\";\n\n// src/PortalShell.tsx — @ai-matrx/records-ui · SCR-23\n//\n// AN OUTSIDER'S WHOLE WORLD: their list, their record, their form — and NOTHING\n// ELSE, because they are not in the organization.\n//\n// VIS-31 is the fact this shell is built on, and it is subtle enough that the\n// store says it in one place so no screen can invent a second answer: \"no\n// organization\" cannot mean \"no row in the membership table\", because signup\n// mints every account a PERSONAL organization — under that reading nobody would\n// ever be external. `iam.is_external_principal` means no membership of a\n// NON-personal organization, and `iam.external_principal_card` says WHY in\n// plain English, which is what this shell shows instead of an empty page.\n//\n// WHAT AN OUTSIDER REACHES IS NOT \"THEIR ORGANIZATION'S RECORDS\". It is\n// `iam.external_principal_reach` — exactly the resource ids Visibility handed\n// them, one by one. A portal that listed a Table and relied on the read door to\n// filter would be a portal whose correctness depended on a filter running; this\n// one asks for the list of ids first and reads only those.\n//\n// AND THE SHELL IS HONEST ABOUT THE LANE. While `custom/external_principal_enabled`\n// is false the doors refuse BY NAME, which is the answer the platform gave\n// before this campaign, and this screen shows that sentence rather than an\n// empty list that reads like \"you have nothing\".\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { ExternalPrincipalCard, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { Peek } from \"./Peek\";\nimport { FormRunner } from \"./FormRunner\";\nimport type { FormSpec } from \"./forms\";\n\nexport interface PortalShellProps {\n /** The Table the outsider's records belong to. */\n tableId: Uuid;\n /** OPTIONAL. A form the outsider may send — their one way to put something in. */\n form?: FormSpec | undefined;\n /** What the resources are called in `iam`'s own vocabulary. Default `record`. */\n resourceType?: string;\n className?: string | undefined;\n}\n\nexport function PortalShell({ tableId, form, resourceType = \"record\", className }: PortalShellProps) {\n const client = useRecordsClient();\n const [card, setCard] = useState<ExternalPrincipalCard | null>(null);\n const [reach, setReach] = useState<Uuid[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [open, setOpen] = useState<Uuid | null>(null);\n const [sending, setSending] = useState(false);\n\n const load = useCallback(async () => {\n // WHO THEY ARE, FIRST. A portal that read records before it knew whose\n // portal it was would be a portal deciding that for itself.\n const who = await client.externalPrincipalCard();\n if (!who.ok) {\n setError(who.error);\n return;\n }\n setError(null);\n setCard(who.data);\n const reached = await client.externalPrincipalReach({ resourceType });\n if (!reached.ok) {\n setError(reached.error);\n return;\n }\n setReach(reached.data.map((row) => row.resource_id));\n }, [client, resourceType]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) {\n // The lane is closed, or the outsider is not one. Either way the sentence\n // is `iam`'s own, verbatim — never softened into \"nothing to show\".\n return <RefusalNotice error={error} className={className} />;\n }\n if (!card || reach === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (!card.external) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n {card.explanation ||\n \"You are a member of an organization here, so this portal is not yours — a portal is the scoped \" +\n \"view an OUTSIDER gets. You have the full application instead.\"}\n </p>\n );\n }\n\n if (sending && form) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{form.name}</span>\n <Button size=\"sm\" variant=\"ghost\" className=\"ml-auto h-6 px-2 text-[11px]\" onClick={() => setSending(false)}>\n Back\n </Button>\n </header>\n <FormRunner\n form={form}\n onSubmitted={() => {\n setSending(false);\n void load();\n }}\n />\n </section>\n );\n }\n\n if (open) {\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n <Peek tableId={tableId} recordId={open} onClose={() => setOpen(null)} />\n </section>\n );\n }\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: how many things are theirs, and the one thing they may do. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Shared with you</span>\n <span className=\"tabular-nums\">{reach.length}</span>\n {form ? (\n <Button size=\"sm\" className=\"ml-auto h-7 px-2 text-[11px]\" onClick={() => setSending(true)}>\n {form.submitLabel ?? form.name}\n </Button>\n ) : null}\n </header>\n\n {reach.length === 0 ? (\n // EMPTY, AND IT SAYS WHICH EMPTY. \"Nobody has shared anything with you\"\n // and \"the store would not tell us\" are different sentences, and a\n // person acts on them differently.\n <p className=\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\">\n Nothing has been shared with you yet. {card.explanation} When somebody shares a record with you it\n appears here — this list is exactly what Visibility gave you, one record at a time, never an\n organization's list.\n </p>\n ) : (\n <ul className=\"flex min-h-0 flex-col gap-1 overflow-y-auto\">\n {reach.map((id) => (\n <li key={id}>\n <button\n type=\"button\"\n className=\"w-full truncate rounded border px-2 py-1.5 text-left text-xs hover:bg-muted\"\n onClick={() => setOpen(id)}\n >\n <PortalRow tableId={tableId} recordId={id} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n );\n}\n\n/**\n * One line for one record the outsider may see. It reads through the SAME read\n * door as everything else — there is no portal read path, because a second read\n * path is a second place for a visibility bug to live.\n */\nfunction PortalRow({ tableId, recordId }: { tableId: Uuid; recordId: Uuid }) {\n const client = useRecordsClient();\n const [title, setTitle] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void client.recordRead({ record_id: recordId }).then((answered) => {\n if (cancelled) return;\n if (!answered.ok) {\n setTitle(answered.error.message);\n return;\n }\n const document = answered.data.document as Record<string, unknown>;\n const first = Object.values(document).find((v) => typeof v === \"string\" && v !== \"\");\n setTitle(typeof first === \"string\" ? first : recordId);\n });\n return () => {\n cancelled = true;\n };\n }, [client, recordId, tableId]);\n\n return <span>{title ?? \"…\"}</span>;\n}\n","\"use client\";\n\n// src/PublicViewPage.tsx — @ai-matrx/records-ui · SCR-24\n//\n// THE PUBLIC PAGE A SIGNED-OUT VISITOR LANDS ON, AND THE NOTE IT REFUSES TO\n// LEAVE OFF.\n//\n// VIS-32: a share, however generous, produces NO public address. A public\n// address exists only because somebody made a publish binding on purpose, and\n// the binding carries its own RENDER MODE — this page does not choose between\n// a list and a detail, it is TOLD.\n//\n// `iam.resolve_publish_binding` is the whole of the resolution, and three\n// different-looking situations deliberately resolve identically to NOTHING: an\n// address nobody ever made, an address that was revoked, and an address whose\n// lane was closed again. They are one 404, because an address that answered\n// differently for a revoked binding would be an existence oracle — \"this used\n// to be something\" is information a stranger should not get for free.\n//\n// D-15, AND IT IS NOT DECORATION. Nothing was scanned before this was listed:\n// there is no pre-listing scan, no quarantine, no report-and-takedown ranking.\n// `iam.world_publish_gap_notice()` is ONE function so the screen, the API, the\n// admission row and this page cannot drift into four different admissions of\n// the same gap — or into none. The note is carried on EVERY read and is shown\n// here every time, including when everything worked.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type ReadRow, type Uuid } from \"@ai-matrx/records/react\";\nimport type { Field, RecordsError, ResolvedPublishBinding } from \"@ai-matrx/records\";\nimport { Skeleton, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { RecordValue } from \"./values\";\n\nexport interface PublicViewPageProps {\n /** The public address, exactly as it appears in the URL. */\n slug: string;\n className?: string | undefined;\n}\n\nexport function PublicViewPage({ slug, className }: PublicViewPageProps) {\n const client = useRecordsClient();\n const [binding, setBinding] = useState<ResolvedPublishBinding | null | \"none\">(null);\n const [rows, setRows] = useState<ReadRow[] | null>(null);\n const [fields, setFields] = useState<Field[] | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n /** D-15's sentence, read from the store even when a binding did not resolve. */\n const [gap, setGap] = useState<string | null>(null);\n\n const load = useCallback(async () => {\n // The gap notice is read FIRST and unconditionally: a page that only\n // admitted the gap on the happy path would be a page that stops admitting\n // it exactly when something is wrong.\n const notice = await client.worldPublishGapNotice();\n if (notice.ok) setGap(notice.data);\n\n const resolved = await client.resolvePublishBinding({ slug });\n if (!resolved.ok) {\n setError(resolved.error);\n return;\n }\n setError(null);\n const found = resolved.data[0];\n if (!found) {\n setBinding(\"none\");\n return;\n }\n setBinding(found);\n\n // The render mode says which read to do. It is the BINDING's decision, made\n // when it was published, not a guess this page makes from the shape of the\n // answer.\n if (found.render_mode === \"list\") {\n const listed = await client.list({ table_id: found.resource_id, limit: 100 });\n if (!listed.ok) {\n setError(listed.error);\n return;\n }\n setRows(listed.data.rows);\n const held = await client.fields({ table_id: found.resource_id });\n if (held.ok) setFields(held.data);\n return;\n }\n const read = await client.recordRead({ record_id: found.resource_id });\n if (!read.ok) {\n setError(read.error);\n return;\n }\n setRows([{ id: found.resource_id, document: read.data.document, level: \"viewer\", hidden: read.data.hidden } as ReadRow]);\n }, [client, slug]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n if (error) return <RefusalNotice error={error} className={className} />;\n if (binding === null) return <Skeleton className={cn(\"h-64 w-full\", className)} />;\n\n if (binding === \"none\") {\n // THE 404, AND IT IS THE SAME 404 FOR ALL THREE CAUSES. Nothing here hints\n // that this address ever existed.\n return (\n <main className={cn(\"mx-auto max-w-2xl py-16 text-center\", className)}>\n <h1 className=\"text-lg font-medium\">Nothing here</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n There is no public page at this address.\n </p>\n {gap ? <p className=\"mt-6 text-xs text-muted-foreground\">{gap}</p> : null}\n </main>\n );\n }\n\n return (\n <main className={cn(\"mx-auto flex max-w-2xl flex-col gap-3 py-8\", className)}>\n {/* One row. The namespace it was published under, and nothing restating it. */}\n <header className=\"flex items-baseline gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{binding.namespace ?? \"Published\"}</span>\n <span>{binding.render_mode === \"list\" ? `${rows?.length ?? 0} items` : \"Shared publicly\"}</span>\n </header>\n\n {rows === null ? (\n <Skeleton className=\"h-40 w-full\" />\n ) : rows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">This page has nothing on it yet.</p>\n ) : (\n <ol className=\"flex flex-col gap-2\">\n {rows.map((row) => (\n <li key={row.id} className=\"rounded border p-3\">\n <PublicRow row={row} fields={fields} />\n </li>\n ))}\n </ol>\n )}\n\n {/* D-15, ON EVERY READ, INCLUDING THE HAPPY ONE. */}\n <footer className=\"mt-4 border-t pt-3 text-xs text-muted-foreground\">\n {binding.notice || gap || \"Nothing was scanned before this was listed.\"}\n </footer>\n </main>\n );\n}\n\n/**\n * One public row. It draws through the same `renderValue` as every other screen\n * in this package, so a unit and a format mean the same thing to a stranger as\n * they do to the person who typed the value.\n */\nfunction PublicRow({ row, fields }: { row: ReadRow; fields: Field[] | null }) {\n const document = (row.document ?? {}) as Record<string, unknown>;\n if (!fields) {\n const first = Object.entries(document).filter(([key]) => !key.startsWith(\"_\"));\n return (\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm\">\n {first.map(([key, value]) => (\n <div key={key} className=\"contents\">\n <dt className=\"text-xs text-muted-foreground\">{key}</dt>\n <dd className=\"text-sm\">{String(value ?? \"\")}</dd>\n </div>\n ))}\n </dl>\n );\n }\n return (\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1\">\n {fields.map((field) => (\n <div key={field.key} className=\"contents\">\n <dt className=\"text-xs text-muted-foreground\">{field.label}</dt>\n <dd className=\"text-sm\"><RecordValue field={field} value={document[field.key]} document={row.document} /></dd>\n </div>\n ))}\n </dl>\n );\n}\n","\"use client\";\n\n// src/EmbedFrame.tsx — @ai-matrx/records-ui · SCR-25\n//\n// PUTTING ONE OF OUR FORMS OR VIEWS ON SOMEBODY ELSE'S WEBSITE, WITHOUT HANDING\n// THEM A WAY INTO EVERYTHING ELSE.\n//\n// This component is two halves that must not be confused:\n//\n// · THE ISSUING HALF (`EmbedFrame`) runs on OUR side, signed in, for the\n// person who owns the form. It mints a token through\n// `custom.anon_token_issue` and shows the snippet to paste. The secret comes\n// back ONCE — only its digest is stored, so a database read, a backup or a\n// leaked dump cannot produce a working token — which is why this screen says\n// so out loud and offers to mint a new one rather than pretending it can\n// show the old one again.\n//\n// · THE HANDSHAKE (`useEmbedHandshake`) runs on THEIR page, inside the iframe.\n// It calls `custom.anon_token_verify` with the secret and the ORIGIN, and\n// the store decides. It is the store that decides, and the check is EXACT —\n// `https://example.com.evil.test` passes a suffix match and fails this one.\n//\n// THE THREE THINGS THE STORE REFUSES, AND THIS SCREEN NAMES BEFORE IT ASKS:\n// 1. A token with no origin list. An empty list does not mean \"everywhere\" —\n// it is refused at issue, because a token that works from any page on the\n// internet includes an attacker's.\n// 2. A token carrying both read and write. One credential, one decision; the\n// second is always the one nobody meant to grant.\n// 3. A write token for a form nobody published. Closed by default.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useRecordsClient, type Uuid } from \"@ai-matrx/records/react\";\nimport type { AnonTokenBinding, RecordsError } from \"@ai-matrx/records\";\nimport { Button, Input, Skeleton, Textarea, cn } from \"@ai-matrx/design-system\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { useRecordsUi, useTableRights } from \"./host\";\nimport { useTable } from \"@ai-matrx/records/react\";\n\nexport interface EmbedFrameProps {\n /** The Table whose rights decide whether an embed may be issued at all. */\n tableId: Uuid;\n /** A write embed names the form it writes into. */\n formId?: Uuid | null | undefined;\n /** A read embed names the saved view or the record it shows. */\n savedViewId?: Uuid | null | undefined;\n recordId?: Uuid | null | undefined;\n /** Where the embedded page is served from — the `src` of the iframe. */\n embedUrl: string;\n className?: string | undefined;\n}\n\nexport function EmbedFrame({\n tableId,\n formId,\n savedViewId,\n recordId,\n embedUrl,\n className,\n}: EmbedFrameProps) {\n const client = useRecordsClient();\n const host = useRecordsUi();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const [origins, setOrigins] = useState(\"\");\n const [secret, setSecret] = useState<string | null>(null);\n const [tokenId, setTokenId] = useState<Uuid | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [busy, setBusy] = useState(false);\n\n // A write embed needs a form; a read embed needs a view or a record. The mode\n // is therefore a FACT about what was passed, never a toggle somebody can set\n // to a value the store will refuse.\n const mode: \"read\" | \"write\" = formId ? \"write\" : \"read\";\n\n const parsed = origins\n .split(/[\\s,]+/)\n .map((o) => o.trim())\n .filter((o) => o.length > 0);\n\n const issue = useCallback(async () => {\n setBusy(true);\n setError(null);\n const minted = await client.anonTokenIssue({\n mode,\n allowedOrigins: parsed,\n formId: formId ?? null,\n savedViewId: savedViewId ?? null,\n recordId: recordId ?? null,\n });\n setBusy(false);\n if (!minted.ok) {\n setError(minted.error);\n return;\n }\n setSecret(minted.data.secret);\n setTokenId(minted.data.token_id);\n host.notify?.success(\"Embed token issued. Copy it now — it is never shown again.\");\n }, [client, formId, host, mode, parsed, recordId, savedViewId]);\n\n const revoke = useCallback(async () => {\n if (!tokenId) return;\n setBusy(true);\n const done = await client.anonTokenRevoke({ token_id: tokenId });\n setBusy(false);\n if (!done.ok) {\n setError(done.error);\n return;\n }\n setSecret(null);\n setTokenId(null);\n }, [client, tokenId]);\n\n if (table.error) return <RefusalNotice error={table.error} className={className} />;\n if (table.loading) return <Skeleton className={cn(\"h-48 w-full\", className)} />;\n\n // Issuing an embed hands a stranger a way in, so the store asks for `admin`\n // on the Table. Without it there is no control here at all — not a greyed\n // one — and the reason is shown.\n if (!rights.admin) {\n return (\n <p className={cn(\"rounded border border-dashed px-2 py-1 text-xs text-muted-foreground\", className)}>\n {rights.reason} Issuing an embed opens a way in from somebody else's website, so the store asks for\n the admin level on this table before it will mint one.\n </p>\n );\n }\n\n const snippet = secret\n ? `<iframe src=\"${embedUrl}#t=${secret}\" style=\"width:100%;height:640px;border:0\" loading=\"lazy\"></iframe>`\n : null;\n\n return (\n <section className={cn(\"flex min-h-0 flex-col gap-2\", className)}>\n {/* One row: what kind of embed this is, and where it may run. */}\n <header className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Embed</span>\n <span>{mode === \"write\" ? \"a form people can send\" : \"a read-only view\"}</span>\n </header>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n <label className=\"flex flex-col gap-1 text-xs\">\n <span className=\"text-muted-foreground\">Sites this embed works on</span>\n <Input\n aria-label=\"Allowed origins\"\n className=\"h-8 text-xs\"\n placeholder=\"https://example.com\"\n value={origins}\n onChange={(e) => setOrigins(e.target.value)}\n />\n {/* Said BEFORE the refusal, because a person should not have to be\n refused to learn the rule. */}\n <span className=\"text-[11px] text-muted-foreground\">\n Name every site, scheme and host and port. An empty list is refused rather than quietly meaning\n \"anywhere\": a token that works from any page on the internet includes an attacker's. The match is\n exact, so <code>example.com.evil.test</code> will not pass.\n </span>\n </label>\n\n {!secret ? (\n <Button size=\"sm\" className=\"self-start\" disabled={busy || parsed.length === 0} onClick={() => void issue()}>\n {busy ? \"Issuing…\" : \"Issue embed\"}\n </Button>\n ) : (\n <>\n <p className=\"rounded border px-2 py-1 text-xs text-muted-foreground\">\n Copy this now. Only its digest is stored, so nobody — including us — can show it to you again;\n if it is lost, issue a new one and replace the old.\n </p>\n <Textarea aria-label=\"Embed snippet\" readOnly rows={3} className=\"font-mono text-[11px]\" value={snippet ?? \"\"} />\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void navigator.clipboard?.writeText(snippet ?? \"\")}\n >\n Copy\n </Button>\n <Button size=\"sm\" variant=\"ghost\" disabled={busy} onClick={() => void revoke()}>\n Revoke\n </Button>\n </div>\n </>\n )}\n </section>\n );\n}\n\n/**\n * THE OTHER HALF, RUNNING INSIDE THE IFRAME ON SOMEBODY ELSE'S PAGE.\n *\n * It hands the secret and this page's own origin to the store and uses whatever\n * comes back. It decides nothing itself: a handshake that checked the origin in\n * JavaScript would be a handshake an attacker can edit.\n *\n * `origin` is taken from `window.location.origin` by default rather than from a\n * prop, because a prop is a value the embedding page controls and the origin\n * must not be.\n */\nexport function useEmbedHandshake(args: { secret: string; requiredMode?: \"read\" | \"write\"; origin?: string }): {\n binding: AnonTokenBinding | null;\n error: RecordsError | null;\n loading: boolean;\n} {\n const client = useRecordsClient();\n const [binding, setBinding] = useState<AnonTokenBinding | null>(null);\n const [error, setError] = useState<RecordsError | null>(null);\n const [loading, setLoading] = useState(true);\n const origin = args.origin ?? (typeof location === \"undefined\" ? \"\" : location.origin);\n const { secret, requiredMode } = args;\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(null);\n void client\n .anonTokenVerify({ secret, origin, requiredMode: requiredMode ?? null })\n .then((answered) => {\n if (cancelled) return;\n setLoading(false);\n if (!answered.ok) {\n setError(answered.error);\n setBinding(null);\n return;\n }\n setBinding(answered.data);\n });\n return () => {\n cancelled = true;\n };\n }, [client, origin, requiredMode, secret]);\n\n return { binding, error, loading };\n}\n","\"use client\";\n\n// src/RecordsMount.tsx — @ai-matrx/records-ui\n//\n// THE ONE LINE A HOST ROUTE WRITES. `<RecordsProvider>` from @ai-matrx/records\n// and `<RecordsUiProvider>` from this package are two providers that must be\n// nested in one order, every time — so a route that got the order wrong would\n// fail with \"useRecordsClient was called outside <RecordsProvider>\" at the\n// bottom of a screen nobody was looking at. This mounts both, in the one order\n// that is correct, so a route file stays a mount and nothing more.\n//\n// THE RIGHTS QUESTION, ANSWERED HONESTLY BY DEFAULT.\n// `TableRights` is a port because this package refuses to guess who may\n// administer a table. But a host that binds nothing gets `NO_RIGHTS` — every\n// administering control ABSENT — which is the safe default and a poor product\n// for a host whose authority IS the store's. `storeDecidesRights` is the other\n// honest answer and it is opt-in: offer the control, let the doors decide, and\n// show the store's own refusal verbatim when they refuse. It never claims a\n// right; it says, in its reason, that the store is the authority.\n//\n// Kernel Tables (REC-27) are excluded from it outright: the nine Tables the\n// platform ships are not administered from a person's screen.\n\nimport type { ReactNode } from \"react\";\nimport type { RecordsActor, RecordsConfig, RecordsDataSource, Table, Uuid } from \"@ai-matrx/records\";\nimport { RecordsProvider } from \"@ai-matrx/records/react\";\nimport { RecordLabelProvider } from \"./labels\";\n\nimport { RecordsUiProvider, type RecordsUiHost, type TableRights } from \"./host\";\n\nexport const STORE_DECIDES_REASON =\n \"This host offers the control and lets the record store decide: the doors are the authority here, \" +\n \"and a door that refuses you says so in its own words on this screen. Kernel tables are not \" +\n \"administered from a screen at all.\";\n\nexport const KERNEL_REASON =\n \"This is one of the Tables the platform ships, so it is not administered from a screen. Make your \" +\n \"own table to change fields.\";\n\n/**\n * The rights answer for a host whose authority IS the record store's doors.\n * Offers the control; the store refuses with its own sentence if it must.\n */\nexport function storeDecidesRights(table: Table): TableRights {\n if (table.is_kernel) {\n return { admin: false, comment: true, write: false, reason: KERNEL_REASON };\n }\n return { admin: true, comment: true, write: true, reason: STORE_DECIDES_REASON };\n}\n\nexport interface RecordsMountProps {\n /** The store config: the host's session-carrying client, the actor, the organization. */\n config: RecordsConfig;\n /** What this host binds on top — links, toasts, uploads, rights. */\n host?: RecordsUiHost | undefined;\n /**\n * Use `storeDecidesRights` when the host binds no `rights` of its own. Left\n * off, an unbound host gets `NO_RIGHTS` and every administering control is\n * absent with its reason.\n */\n letTheStoreDecideRights?: boolean | undefined;\n children: ReactNode;\n}\n\nexport function RecordsMount({\n config,\n host,\n letTheStoreDecideRights,\n children,\n}: RecordsMountProps) {\n const bound: RecordsUiHost = {\n ...(host ?? {}),\n ...(host?.rights\n ? {}\n : letTheStoreDecideRights\n ? { rights: storeDecidesRights }\n : {}),\n };\n return (\n <RecordsProvider config={config}>\n <RecordsUiProvider value={bound}>\n {/* WHAT AN ID IS CALLED. A choice and a relation are stored as the id of\n another record, so every read-only surface needs the same answer to\n \"what is that record called\" — resolved once here rather than once\n per cell, and never drawn as the id itself. */}\n <RecordLabelProvider>{children}</RecordLabelProvider>\n </RecordsUiProvider>\n </RecordsProvider>\n );\n}\n\n/**\n * The actor a signed-in person is. `user` is the store's own word (the closed\n * ACTOR_VOCABULARY is `user` · `agent` · `system`), and AGT-N-4 means an agent\n * acting for this person carries exactly this authority and no other.\n */\nexport function personActor(userId: Uuid | null | undefined): RecordsActor {\n return userId ? { actor: \"user\", user_id: userId } : { actor: \"user\" };\n}\n\n/**\n * A supabase-js client AS this package's data seam.\n *\n * `RecordsDataSource` is deliberately a small structural subset of\n * `SupabaseClient` — the package holds no key and opens no connection, the host\n * hands it a client that already carries the person's session.\n *\n * IT IS NOT AN IDENTITY CAST, and it cost a live screen to learn why\n * (2026-09-19, /data-v2's first load): the port's `rpc(fn, args, { schema })`\n * says the schema OUT LOUD, because every door of this store is `custom.<name>`\n * and every door of the trust layer is `iam.<name>`. supabase-js's own\n * `rpc(fn, args, options)` has no `schema` option at all — its third argument is\n * `{ head, get, count }` — so a client passed straight through silently asked\n * its default PostgREST profile and the store answered, correctly and uselessly,\n * \"Could not find the function public.table_kernel_id ... PGRST202\". The schema\n * is chosen the one way supabase-js offers: `client.schema(name).rpc(...)`.\n *\n * `schema(name).from(table)` already agrees structurally and is passed through.\n *\n * `fallbackSchema` is the profile a call that says NOTHING is sent to. No caller\n * in `@ai-matrx/records` omits the option — `callDoor` always says `custom` and\n * `trustDoor` always says `iam` — so it never fires today; it exists so that a\n * call which one day forgets lands on the store rather than silently on\n * `public`. It is a FALLBACK and not the answer: a version of this adapter that\n * sent EVERY door to one fixed schema would route the `iam` trust doors (the\n * external principal, the publish binding) into `custom` and get a PGRST202\n * naming the wrong schema.\n *\n * The cast itself stays HERE, once, where it is explained: a generated\n * `Database` type makes `schema().from().select()` enormous, and a host app that\n * passes its client straight into `config` gets `TS2589: Type instantiation is\n * excessively deep and possibly infinite` in its own build (matrx-frontend,\n * 2026-09-18, on all three campaign routes at once).\n */\nexport function recordsDataSource(client: object, fallbackSchema = \"custom\"): RecordsDataSource {\n const supabase = client as unknown as {\n rpc: (fn: string, args: Record<string, unknown>) => PromiseLike<unknown>;\n schema: (name: string) => {\n rpc: (fn: string, args: Record<string, unknown>) => PromiseLike<unknown>;\n from: (table: string) => unknown;\n };\n };\n return {\n rpc(fn, args, options) {\n const on = supabase.schema(options?.schema ?? fallbackSchema);\n return on.rpc(fn, args) as ReturnType<RecordsDataSource[\"rpc\"]>;\n },\n schema(name) {\n return supabase.schema(name) as ReturnType<RecordsDataSource[\"schema\"]>;\n },\n };\n}\n","\"use client\";\n\n// src/TablesHome.tsx — @ai-matrx/records-ui\n//\n// THE LIST OF A PERSON'S TABLES — AND IT IS NEVER A FLAT PILE.\n//\n// Four lanes, always, in this order: mine · my organization · system ·\n// community. The lane a Table is in is read off the Table record itself and is\n// not a guess:\n//\n// · mine — `visibility = 'personal'` (the store's own enum word)\n// · organization — `visibility = 'internal'`\n// · system — `is_kernel` (REC-27: the Tables the platform ships)\n// · community — `visibility` is `link` or `public`\n//\n// A lane with nothing in it SAYS SO in one sentence that tells a person how it\n// fills up. An empty heading with nothing under it reads as \"broken\"; this\n// reads as \"nothing here yet, and here is what puts something here\".\n//\n// Creating and importing are both here, because both make a Table, and they go\n// through the store's own doors — `declareTable` walks Home → table_declare →\n// Fields, and the import mounts `ImportWizard` on the Table it just declared.\n\nimport { useCallback, useState } from \"react\";\nimport type { Table, Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient, useTables } from \"@ai-matrx/records/react\";\nimport type { RecordsError } from \"@ai-matrx/records\";\nimport { BasicInput, Button, Skeleton, cn } from \"@ai-matrx/design-system\";\n\nimport { RefusalNotice } from \"./Refusal\";\nimport { ImportWizard } from \"./ImportWizard\";\nimport { declareTable, tokenFor } from \"./createTable\";\nimport { tableName } from \"./names\";\n\nexport type TableLane = \"mine\" | \"organization\" | \"system\" | \"community\" | \"app\";\n\n/** The five lanes, in the order a person reads them. Never a flat list. */\nexport const TABLE_LANES: readonly TableLane[] = [\"mine\", \"organization\", \"system\", \"community\", \"app\"];\n\nexport const LANE_TITLE: Record<TableLane, string> = {\n mine: \"Mine\",\n organization: \"My organization\",\n system: \"System\",\n community: \"Community\",\n app: \"Kept by the app\",\n};\n\n/**\n * THE APP'S OWN BOOKKEEPING, MARKED AS SUCH.\n *\n * A saved view, a comment, a queued action and a form are records in Tables\n * this package declares in the organization's own store (`systemTable.ts`) —\n * which is what makes them shareable, historied and agent-writable. The price\n * is that using the product creates Tables in the person's own list: the\n * verdict of 19 September watched \"Saved views · 9 fields · records_ui_view\"\n * appear among somebody's data, and then \"Comments\" appear beside it the\n * moment a record was opened.\n *\n * They are not hidden — hiding a real Table from the person who owns it is its\n * own lie, and they hold that person's comments. They get their own lane,\n * last, with a sentence that says what they are.\n */\nconst APP_TABLE_PREFIX = \"records_ui_\";\n\n/** What fills an empty lane. A heading with nothing under it must still teach. */\nexport const LANE_EMPTY: Record<TableLane, string> = {\n mine: \"Nothing of your own yet. New table makes one that only you can see.\",\n organization:\n \"No tables shared across your organization yet. A table you make is yours until you change its visibility to internal.\",\n system: \"The platform's own tables are not in this organization's store.\",\n community: \"Nothing shared beyond your organization. A table published by link or to the world lands here.\",\n app:\n \"The app has not needed a table of its own in this organization yet. Saving a view, writing a \" +\n \"comment or building a form makes one, and it appears here rather than among your own data.\",\n};\n\n/** Which lane one Table belongs to, from the record's own columns. */\nexport function laneFor(table: Table): TableLane {\n if (table.is_kernel) return \"system\";\n if ((table.slug ?? \"\").startsWith(APP_TABLE_PREFIX)) return \"app\";\n if (table.visibility === \"public\" || table.visibility === \"link\") return \"community\";\n if (table.visibility === \"personal\") return \"mine\";\n return \"organization\";\n}\n\nexport interface TablesHomeProps {\n /** Where a table opens. Absent and the card is a plain row with no pretend link. */\n onOpenTable?: ((tableId: Uuid) => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TablesHome({ onOpenTable, className }: TablesHomeProps) {\n const client = useRecordsClient();\n const tables = useTables();\n const [creating, setCreating] = useState(false);\n const [name, setName] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<RecordsError | null>(null);\n const [importInto, setImportInto] = useState<Uuid | null>(null);\n\n const create = useCallback(\n async (mode: \"open\" | \"import\") => {\n const trimmed = name.trim();\n if (!trimmed) return;\n setBusy(true);\n setError(null);\n const result = await declareTable(client, { name: trimmed, slug: tokenFor(trimmed) });\n setBusy(false);\n if (!result.ok) {\n setError(result.error);\n return;\n }\n setName(\"\");\n setCreating(false);\n tables.reload();\n if (mode === \"import\") setImportInto(result.data);\n else onOpenTable?.(result.data);\n },\n [client, name, onOpenTable, tables],\n );\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-4\", className)}>\n {/* One row. The page's own header already says where you are. */}\n <div className=\"flex items-center gap-2\">\n {creating ? (\n <>\n <BasicInput\n autoFocus\n value={name}\n placeholder=\"Table name\"\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") void create(\"open\");\n if (e.key === \"Escape\") setCreating(false);\n }}\n className=\"h-8 max-w-xs\"\n />\n <Button size=\"sm\" disabled={busy || name.trim().length === 0} onClick={() => void create(\"open\")}>\n {busy ? \"Declaring…\" : \"Create\"}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={busy || name.trim().length === 0}\n onClick={() => void create(\"import\")}\n >\n Create and import a file\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setCreating(false)}>\n Cancel\n </Button>\n </>\n ) : (\n <Button size=\"sm\" onClick={() => setCreating(true)}>\n New table\n </Button>\n )}\n </div>\n\n {error ? <RefusalNotice error={error} /> : null}\n\n {importInto ? (\n <div className=\"rounded-md border p-3\">\n <ImportWizard tableId={importInto} onDone={() => setImportInto(null)} />\n <Button size=\"sm\" variant=\"ghost\" className=\"mt-2\" onClick={() => onOpenTable?.(importInto)}>\n Open the table\n </Button>\n </div>\n ) : null}\n\n {tables.error ? <RefusalNotice error={tables.error} /> : null}\n {tables.loading && !tables.data ? (\n <div className=\"space-y-2\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n ) : null}\n\n {tables.data\n ? TABLE_LANES.map((lane) => {\n const rows = tables.data!.filter((t) => laneFor(t) === lane);\n return (\n <section key={lane} className=\"space-y-1.5\">\n <div className=\"flex items-baseline gap-2\">\n <h2 className=\"text-sm font-medium\">{LANE_TITLE[lane]}</h2>\n <span className=\"text-xs opacity-60\">{rows.length}</span>\n </div>\n {rows.length === 0 ? (\n <p className=\"text-xs opacity-70\">{LANE_EMPTY[lane]}</p>\n ) : (\n <ul className=\"grid gap-1.5 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((table) => (\n <li key={table.id}>\n <button\n type=\"button\"\n onClick={() => onOpenTable?.(table.id)}\n className={cn(\n \"w-full rounded-md border px-3 py-2 text-left transition-colors\",\n onOpenTable ? \"hover:bg-accent\" : \"cursor-default\",\n )}\n >\n {/* The Table's NAME, never its token: `records_ui_view`\n and `v78_widget2` are machine names and no product\n a person judges puts one on a card. */}\n <span className=\"block truncate text-sm\">{tableName(table)}</span>\n <span className=\"block truncate text-xs opacity-60\">\n {table.fields.length} field{table.fields.length === 1 ? \"\" : \"s\"}\n {table.label_plural && table.label_plural !== table.name\n ? ` · ${table.label_plural}`\n : \"\"}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n );\n })\n : null}\n </div>\n );\n}\n","// src/createTable.ts — @ai-matrx/records-ui\n//\n// DECLARING A TABLE, THE WAY THE STORE MAKES YOU DECLARE ONE.\n//\n// REC-1: a Table has to live somewhere. `custom._table_shape_guard` refuses a\n// Table with no Home in those words (\"a table has to live somewhere - give it a\n// home\"), so the sequence is fixed and this module is the one place that walks\n// it for a person-made table:\n//\n// 1. `personKernelId()` — the kernel Table a Home record lives in.\n// 2. `record_write` — the Home record.\n// 3. `table_declare` — the Table, under that Home.\n// 4. one `record_write` per Field, into the field kernel.\n//\n// Nothing here works around a guard; every step is a door. A Field the store\n// refused stops the sequence and hands back the store's own sentence, because a\n// Table that quietly lost a column is the silent failure this package exists to\n// prevent.\n\nimport type { RecordsClient } from \"@ai-matrx/records/core\";\nimport type { RecordsError, Uuid } from \"@ai-matrx/records\";\n\n/** One Field a person asked for, in the store's own behaviour words (FLD-1). */\nexport interface NewFieldSpec {\n key: string;\n label: string;\n /** A parity type — the thirteen come from the store, see `PARITY_FIELD_TYPES`. */\n type: string;\n sort?: number;\n required?: boolean;\n multi?: boolean;\n config?: Record<string, unknown>;\n}\n\nexport interface NewTableSpec {\n name: string;\n /** The token the Table is addressed by. Derived from the name when absent. */\n slug?: string;\n labelSingular?: string;\n labelPlural?: string;\n /** The Field whose value is the record's title (REC-2). Defaults to the first Field. */\n titleField?: string;\n fields?: NewFieldSpec[];\n}\n\nexport type DeclareResult =\n | { ok: true; data: Uuid }\n | { ok: false; error: RecordsError };\n\n/** `My Sales Pipeline` → `my_sales_pipeline`. A token, never a sentence. */\nexport function tokenFor(name: string): string {\n return (\n name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 48) || \"table\"\n );\n}\n\n/** The one Field a Table cannot be declared without: something to call a record. */\n/**\n * WHY THE FIRST FIELD IS NOT REQUIRED.\n *\n * It was, and the cost showed up the moment the grid could add a row: \"New\n * record\" writes an empty record and puts you in the first cell, and the store\n * correctly refused every one of them — `REC-51: Title is required` — so the\n * one gesture that makes a grid feel like a grid never worked on a table a\n * person had just made. A title is what makes a record a CHIP (REC-2), which is\n * a fact about how it is shown, not a promise it can never be written without;\n * an organization that wants it demanded says so in the field editor, and the\n * store then enforces it for everyone.\n */\nexport const DEFAULT_FIELDS: NewFieldSpec[] = [\n { key: \"title\", label: \"Title\", type: \"text\", sort: 10, required: false },\n];\n\nexport async function declareTable(\n client: RecordsClient,\n spec: NewTableSpec,\n): Promise<DeclareResult> {\n const fields = spec.fields && spec.fields.length > 0 ? spec.fields : DEFAULT_FIELDS;\n const slug = spec.slug ?? tokenFor(spec.name);\n const titleField = spec.titleField ?? fields[0]!.key;\n\n const personKernel = await client.personKernelId();\n if (!personKernel.ok) return personKernel;\n\n const home = await client.recordWrite({\n table_id: personKernel.data,\n data: { name: `${spec.name} Home` },\n });\n if (!home.ok) return home;\n\n const table = await client.tableDeclare({\n homeId: home.data,\n spec: {\n name: spec.name,\n slug,\n type: \"entity\",\n label_singular: spec.labelSingular ?? spec.name,\n label_plural: spec.labelPlural ?? spec.name,\n display: \"list\",\n weight: \"light\",\n ordered: false,\n row_order: \"manual\",\n title_field: titleField,\n retention_days: 365,\n // AGT-1: a table a person made is agent-writable by declaration; the\n // organization turns it off, never this package.\n agent_writable: true,\n default_sort: [{ field: titleField, direction: \"asc\" }],\n fields: fields.map((f) => ({ name: f.key })),\n },\n });\n if (!table.ok) return table;\n\n const written = await addFields(client, table.data, fields);\n if (!written.ok) return written;\n return { ok: true, data: table.data };\n}\n\n/** Write Field records for an existing Table. Used by the create path and by import. */\nexport async function addFields(\n client: RecordsClient,\n tableId: Uuid,\n fields: NewFieldSpec[],\n): Promise<{ ok: true; data: Uuid } | { ok: false; error: RecordsError }> {\n const fieldKernel = await client.fieldKernelId();\n if (!fieldKernel.ok) return fieldKernel;\n\n for (const field of fields) {\n const result = await client.recordWrite({\n table_id: fieldKernel.data,\n data: {\n key: field.key,\n label: field.label,\n type: field.type,\n sort: field.sort ?? 100,\n required: field.required ?? false,\n multi: field.multi ?? false,\n dated: false,\n rules: [],\n config: field.config ?? {},\n source: \"manual\",\n depends_on: [],\n sensitivity: \"internal\",\n source_config: {},\n context_policy: \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n },\n });\n if (!result.ok) return result;\n }\n return { ok: true, data: tableId };\n}\n","\"use client\";\n\n// src/TablePage.tsx — @ai-matrx/records-ui\n//\n// ONE TABLE'S WHOLE PAGE, assembled from this package's own components and\n// nothing else. A host route mounts this and passes the table token; every\n// screen below it is the canonical one, so a table reached from /data, from a\n// portal or from an agent's link looks and behaves identically.\n//\n// WHAT IS ON IT, and which contract row each part answers:\n// ViewBar (SCR-7) the saved views, and saving a new one\n// ViewSwitcher (SCR-6) grid · kanban · calendar · gallery over the SAME records\n// RecordForm (SCR-N-1) adding a record\n// FieldEditor (SCR-9) adding or retyping a field\n// TableSettings (SCR-3/4/5) rename, reorder, retype, delete, proposals\n// ActionInbox (SCR-11) approvals, assignments and agent proposals\n// Peek (SCR-N-3) a record, opened in place\n// HistoryPanel (SCR-17) that record's own versioned timeline\n// CommentThread (SCR-18) that record's comments\n// ExportMenu (SCR-31) the same bytes a script would produce\n// ImportWizard (SCR-10) rows in through the one write door\n//\n// ONE PANEL AT A TIME. The right-hand rail shows exactly one of settings,\n// inbox, import, the new-field editor or the opened record — a page that opens\n// four rails at once is a page nobody can read.\n\nimport { useCallback, useState } from \"react\";\nimport { viewPatchDocument, type SavedView, type SavedViewSpec } from \"./views\";\nimport type { Uuid } from \"@ai-matrx/records\";\nimport { useRecordsClient, useTable } from \"@ai-matrx/records/react\";\nimport { Button, Separator, Skeleton, cn } from \"@ai-matrx/design-system\";\n\nimport { ActionInbox } from \"./ActionInbox\";\nimport { CommentThread } from \"./CommentThread\";\nimport { ExportMenu } from \"./ExportMenu\";\nimport { FieldEditor } from \"./FieldEditor\";\nimport { HistoryPanel } from \"./HistoryPanel\";\nimport { ImportWizard } from \"./ImportWizard\";\nimport { Peek } from \"./Peek\";\nimport { RecordForm } from \"./RecordForm\";\nimport { RefusalNotice } from \"./Refusal\";\nimport { ShareControl } from \"./ShareControl\";\nimport { TableSettings } from \"./TableSettings\";\nimport { ViewBar } from \"./ViewBar\";\nimport { ViewSwitcher } from \"./ViewSwitcher\";\nimport { useTableRights } from \"./host\";\nimport { tableName } from \"./names\";\nimport { useRecordVersion } from \"./systemTable\";\n\ntype Rail = \"none\" | \"settings\" | \"inbox\" | \"import\" | \"field\" | \"record\" | \"new-record\";\n\nexport interface TablePageProps {\n tableId: Uuid;\n /** Rows per page for every layout. */\n pageSize?: number | undefined;\n /**\n * The views this table should have. Each one whose NAME the table does not\n * hold yet is saved the first time the bar loads, and a name a person has\n * since tweaked is never overwritten. Left out, `DEFAULT_VIEW_NAME` below is\n * used — see why that default is not optional.\n */\n seedViews?: SavedViewSpec[] | undefined;\n /**\n * What a person does when the table is not theirs to see — switch\n * organization, go back to the list. Absent, the screen still SAYS what\n * happened; it just has no button to offer, which is honest and is never a\n * blank frame.\n */\n onLeave?: (() => void) | undefined;\n /** The word on that button. Defaults to \"Back to your tables\". */\n leaveLabel?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * THE SENTENCE A TABLE YOU CANNOT SEE SAYS.\n *\n * Measured on the real screen (independent verdict, 19 September): opening a\n * table's page while another organization was active left the main area's text\n * \"literally the empty string\" after eighteen seconds — no sentence, no\n * spinner, no console error. A made-up id did the same. The cause is exactly\n * one line of this file: `custom.table_list` correctly answers the tables this\n * person can see in THIS organization, the table is not among them, so\n * `useTable` answers `{ data: null, error: null }` — not a refusal, just\n * absence — and the page rendered a skeleton for ever.\n *\n * Absence is an ANSWER and it gets a sentence. It deliberately does not say\n * whether the table exists: this person cannot see it, and which of the two it\n * is is not theirs to learn.\n */\nexport const TABLE_NOT_REACHABLE =\n \"This table is not in the organization you are working in, so there is nothing here to show. \" +\n \"Switch to the organization that owns it and open it again — or it may have been deleted.\";\n\n/**\n * THE VIEW EVERY TABLE HAS, AND WHY IT IS NOT OPTIONAL.\n *\n * A view is a record, so a table nobody has saved a view for has none — and\n * this page then renders its own honest sentence (\"Waiting for this table's\n * views\") and NO RECORDS AT ALL. Measured on 2026-09-19 by walking the real\n * product: declare a table, write a record, open the table — and the record is\n * not on the screen, with the only remedy being a control the person has no\n * reason to press. That is a dead end on the first table anybody makes.\n *\n * So the page seeds one: every record, newest work first, as a grid. It is an\n * ordinary saved view record like any other — renamable, re-sortable,\n * deletable — not a hidden built-in mode, because a \"special\" default view is a\n * second kind of view that every feature after it has to know about.\n */\nexport const DEFAULT_VIEW_NAME = \"All records\";\n\nfunction defaultView(tableId: Uuid): SavedViewSpec {\n return { name: DEFAULT_VIEW_NAME, subject: tableId, layout: \"grid\", isDefault: true };\n}\n\nexport function TablePage({\n tableId,\n pageSize = 100,\n seedViews,\n onLeave,\n leaveLabel = \"Back to your tables\",\n className,\n}: TablePageProps) {\n const client = useRecordsClient();\n const table = useTable(tableId);\n const rights = useTableRights(table.data);\n const organizationId = useRecordsClient().config.organizationId;\n const [view, setView] = useState<SavedView | null>(null);\n const [rail, setRail] = useState<Rail>(\"none\");\n const [openRecord, setOpenRecord] = useState<Uuid | null>(null);\n // The view record's own version at load, so two tabs tweaking one view are\n // TOLD — and moved forward after every save, so ONE person switching layout\n // twice is not told they conflicted with themselves.\n const viewVersion = useRecordVersion(view?.id ?? null);\n\n const show = (next: Rail) => setRail((current) => (current === next ? \"none\" : next));\n\n /**\n * A change the switcher made — the layout, the kanban's grouping Field, the\n * calendar's date Field — saved onto the VIEW RECORD, which is what makes it\n * remembered per saved view rather than per page load. The local copy moves\n * first so the board redraws at once; the store is the one that keeps it.\n */\n const patchView = useCallback(\n async (patch: Partial<SavedViewSpec>) => {\n const current = view;\n if (!current) return;\n setView({ ...current, ...patch });\n const document = viewPatchDocument(patch);\n if (Object.keys(document).length === 0) return;\n const written = await client.recordUpdate({\n record_id: current.id,\n patch: document,\n ...(viewVersion.version === null ? {} : { expectedVersion: viewVersion.version }),\n });\n if (written.ok) viewVersion.note(written.data);\n },\n [client, view, viewVersion],\n );\n\n if (table.error) return <RefusalNotice error={table.error} />;\n if (table.loading) return <Skeleton className=\"h-40 w-full\" />;\n if (!table.data) {\n // NOT a blank frame, and not a spinner that never ends.\n return (\n <div className={cn(\"flex flex-col items-start gap-2 rounded-md border border-dashed p-6\", className)}>\n <p className=\"text-sm font-medium\">This table is not here</p>\n <p className=\"max-w-prose text-xs text-muted-foreground\">{TABLE_NOT_REACHABLE}</p>\n {onLeave ? (\n <Button size=\"sm\" variant=\"outline\" onClick={onLeave}>\n {leaveLabel}\n </Button>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className={cn(\"flex min-h-0 gap-4\", className)}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n {/* One row of controls. The route's own header already carries the name. */}\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <ViewBar\n tableId={tableId}\n onActiveView={setView}\n seed={seedViews ?? [defaultView(tableId)]}\n className=\"min-w-0 flex-1\"\n />\n {/* ONE \"New record\" ON SCREEN, EVER. The grid carries its own — it\n adds a row and puts you straight into the first cell, which is the\n gesture a person expects — so this page's button would be a second\n control for one thing (and was: the walk found two buttons of the\n same name in one header). It exists for the layouts that have no\n cells to type into. */}\n {rights.write && view && view.layout !== \"grid\" ? (\n <Button size=\"sm\" onClick={() => show(\"new-record\")}>\n New record\n </Button>\n ) : null}\n {rights.admin ? (\n <>\n <Button size=\"sm\" variant=\"outline\" onClick={() => show(\"field\")}>\n Add field\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"settings\")}>\n Settings\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"import\")}>\n Import\n </Button>\n </>\n ) : null}\n <Button size=\"sm\" variant=\"ghost\" onClick={() => show(\"inbox\")}>\n Inbox\n </Button>\n {/* SCR-N-5. A Table is a record, so the table screen shares through the\n same door and the same dialog a record does. */}\n <ShareControl\n kind=\"table\"\n organizationId={organizationId}\n subjectId={tableId}\n name={table.data?.name}\n />\n <ExportMenu tableId={tableId} />\n </div>\n\n {view ? (\n <ViewSwitcher\n view={view}\n pageSize={pageSize}\n onViewChange={(patch) => void patchView(patch)}\n {...(rights.write ? { onNewRecordForm: () => setRail(\"new-record\") } : {})}\n onOpenRecord={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n />\n ) : (\n <p className=\"text-xs opacity-70\">\n Waiting for {tableName(table.data)}&apos;s views. The bar above saves the first one.\n </p>\n )}\n </div>\n\n {rail === \"none\" ? null : (\n <aside className=\"w-[26rem] shrink-0 overflow-y-auto rounded-md border p-3\">\n {rail === \"settings\" ? (\n <TableSettings\n tableId={tableId}\n {...(onLeave ? { onDeleted: onLeave } : {})}\n />\n ) : null}\n {rail === \"inbox\" ? (\n <ActionInbox\n tableId={tableId}\n onOpenRecord={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n />\n ) : null}\n {rail === \"import\" ? <ImportWizard tableId={tableId} onDone={() => setRail(\"none\")} /> : null}\n {rail === \"field\" ? (\n <FieldEditor tableId={tableId} onSaved={() => setRail(\"none\")} onCancel={() => setRail(\"none\")} />\n ) : null}\n {rail === \"new-record\" ? (\n <RecordForm\n tableId={tableId}\n onSaved={(recordId) => {\n setOpenRecord(recordId);\n setRail(\"record\");\n }}\n onCancel={() => setRail(\"none\")}\n />\n ) : null}\n {rail === \"record\" && openRecord ? (\n <div className=\"space-y-3\">\n <Peek tableId={tableId} recordId={openRecord} onClose={() => setRail(\"none\")} />\n <Separator />\n <HistoryPanel tableId={tableId} recordId={openRecord} />\n <Separator />\n <CommentThread tableId={tableId} recordId={openRecord} />\n </div>\n ) : null}\n </aside>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["value","document","value","import_react","import_design_system","import_react","import_design_system","import_records","import_react","import_jsx_runtime","value","import_jsx_runtime","value","import_jsx_runtime","value","id","import_react","import_design_system","import_design_system","import_jsx_runtime","import_design_system","import_react","import_jsx_runtime","value","result","import_jsx_runtime","document","value","import_jsx_runtime","value","import_react","import_design_system","import_jsx_runtime","import_react","import_core","import_design_system","import_jsx_runtime","document","import_react","import_core","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_core","import_design_system","import_react","import_jsx_runtime","document","value","import_jsx_runtime","document","import_react","import_design_system","import_jsx_runtime","written","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_design_system","import_jsx_runtime","import_jsx_runtime","document","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","read","value","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_core","import_design_system","import_jsx_runtime","answered","document","value","import_jsx_runtime","document","value","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_records","import_design_system","import_jsx_runtime","total","step","import_react","import_design_system","import_jsx_runtime","board","import_react","import_design_system","import_jsx_runtime","document","tableName","import_react","import_design_system","import_jsx_runtime","document","ProvenanceBadge","value","import_react","import_design_system","import_jsx_runtime","step","import_react","import_design_system","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","keys","import_react","import_design_system","import_jsx_runtime","document","import_react","import_design_system","import_jsx_runtime","document","value","import_react","import_design_system","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_design_system","import_jsx_runtime","import_react","import_react","import_design_system","import_jsx_runtime","document"]}