@ai-matrx/records 0.57.2 → 0.58.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.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { p as Uuid, T as Timestamp, u as ReadRow, q as RecordDocument, aT as TableType, aR as TableDisplay, aL as StorageMode, aS as TableOrigin, S as StoredRecord, v as Field, aq as ParityFieldType, aG as RuleUse, aF as RuleNodeKind, D as RecordsError, U as UseCase, aD as RelationFlavor, am as OnDelete, aA as RelationBinding, aB as RelationCardinality, aj as MergeFieldSource, ai as MergeFieldSemanticType, ah as MergeFieldModifier, an as OverridePolicy, _ as Delivery, aa as Freshness, L as Actor, E as PgError } from './types-BpBSMhYq.cjs';
2
- export { I as ABSENCE_REASONS, J as ACTOR_VOCABULARY, K as AbsenceReason, M as COMPUTE_ON, O as CONTEXT_POLICIES, Q as ComputeOn, V as ContextPolicy, X as DECLARABLE_FIELD_KINDS, Y as DELIVERIES, Z as DeclarableFieldKind, $ as ENTITY_TOKENS, a0 as EntityToken, a1 as FIELD_SENSITIVITIES, a2 as FIELD_SOURCES, a3 as FRESHNESS, a4 as FieldBehavior, x as FieldPatch, A as FieldProposal, a5 as FieldRule, a6 as FieldSensitivity, a7 as FieldSource, a8 as FieldTypeWord, a9 as ForbiddenEnvelopeWord, ab as HiddenFieldNotice, ac as KERNEL_TABLES, ad as KernelTableName, ae as MERGE_FIELD_MODIFIERS, af as MERGE_FIELD_SEMANTIC_TYPES, ag as MERGE_FIELD_SOURCES, w as NewFieldDeclaration, ak as ON_DELETE, al as OVERRIDE_POLICIES, ao as PARITY_FIELD_TYPES, ap as PER_VALUE_ACCESS_WORDS, ar as ParityFieldTypeDescriptor, as as PerValueAccessWord, H as PredictedRefusal, at as ProvenancePointer, au as RELATION_BINDINGS, av as RELATION_CARDINALITIES, aw as RELATION_FLAVORS, ax as RETIRED_ACTOR_WORDS, ay as RULE_NODE_KINDS, az as RULE_USES, z as ReadValue, s as RecordGraphWritten, t as RecordRead, y as RecordRevision, R as RecordsErrorCode, r as RecordsResult, aC as RelationDisplay, aE as RetiredActorWord, aH as STORAGE_MODES, aI as STORE_DOORS, aJ as STORE_KNOBS, aK as STORE_REFUSAL_CODES, G as StaleWriteDetail, aM as StoreDoorName, aN as StoreRefusalCode, aO as TABLE_DISPLAYS, aP as TABLE_ORIGINS, aQ as TABLE_TYPES, C as TableProposal, aU as VALUE_ALTERNATE_KEYS, aV as VALUE_ENVELOPE_KEYS, aW as ValueAlternate, aX as ValueAlternateKey, aY as ValueEnvelope, aZ as ValueEnvelopeKey, a_ as ValueSource, W as WriteConflict, a$ as allowsOtherValues, b0 as err, b1 as isRecordsErr, b2 as ok } from './types-BpBSMhYq.cjs';
1
+ import { p as Uuid, T as Timestamp, u as ReadRow, q as RecordDocument, aT as TableType, aR as TableDisplay, aL as StorageMode, aS as TableOrigin, S as StoredRecord, v as Field, aq as ParityFieldType, aF as RuleNodeKind, aG as RuleUse, D as RecordsError, U as UseCase, M as Actor, G as PgError, aD as RelationFlavor, am as OnDelete, aA as RelationBinding, aB as RelationCardinality, r as RecordsResult, aj as MergeFieldSource, ai as MergeFieldSemanticType, ah as MergeFieldModifier, an as OverridePolicy, $ as Delivery, aa as Freshness } from './types-NKSc_jZq.cjs';
2
+ export { J as ABSENCE_REASONS, K as ACTOR_VOCABULARY, L as AbsenceReason, O as COMPUTE_ON, Q as CONTEXT_POLICIES, V as ComputeOn, X as ContextPolicy, Y as DECLARABLE_FIELD_KINDS, Z as DELIVERIES, _ as DeclarableFieldKind, a0 as ENTITY_TOKENS, a1 as EntityToken, a2 as FIELD_SENSITIVITIES, a3 as FIELD_SOURCES, a4 as FRESHNESS, a5 as FieldBehavior, x as FieldPatch, A as FieldProposal, a6 as FieldRule, a7 as FieldSensitivity, a8 as FieldSource, E as FieldTypeWord, a9 as ForbiddenEnvelopeWord, ab as HiddenFieldNotice, ac as KERNEL_TABLES, ad as KernelTableName, ae as MERGE_FIELD_MODIFIERS, af as MERGE_FIELD_SEMANTIC_TYPES, ag as MERGE_FIELD_SOURCES, w as NewFieldDeclaration, ak as ON_DELETE, al as OVERRIDE_POLICIES, ao as PARITY_FIELD_TYPES, ap as PER_VALUE_ACCESS_WORDS, ar as ParityFieldTypeDescriptor, as as PerValueAccessWord, I as PredictedRefusal, at as ProvenancePointer, au as RELATION_BINDINGS, av as RELATION_CARDINALITIES, aw as RELATION_FLAVORS, ax as RETIRED_ACTOR_WORDS, ay as RULE_NODE_KINDS, az as RULE_USES, z as ReadValue, s as RecordGraphWritten, t as RecordRead, y as RecordRevision, R as RecordsErrorCode, aC as RelationDisplay, aE as RetiredActorWord, aH as STORAGE_MODES, aI as STORE_DOORS, aJ as STORE_KNOBS, aK as STORE_REFUSAL_CODES, H as StaleWriteDetail, aM as StoreDoorName, aN as StoreRefusalCode, aO as TABLE_DISPLAYS, aP as TABLE_ORIGINS, aQ as TABLE_TYPES, C as TableProposal, aU as VALUE_ALTERNATE_KEYS, aV as VALUE_ENVELOPE_KEYS, aW as ValueAlternate, aX as ValueAlternateKey, aY as ValueEnvelope, aZ as ValueEnvelopeKey, a_ as ValueSource, W as WriteConflict, a$ as allowsOtherValues, b0 as err, b1 as isRecordsErr, b2 as ok } from './types-NKSc_jZq.cjs';
3
3
 
4
4
  /**
5
5
  * THE TWO LANES THE ARCHIVED-ITEMS LAW NAMES (Arman, 2026-09-09) — the same
@@ -298,7 +298,7 @@ interface CoercibleField {
298
298
  * `plain_text`, `long_text`, `number` and `boolean` are behaviours that carry
299
299
  * no parity type of their own; every other word here is a parity type.
300
300
  */
301
- declare const FIELD_KINDS: readonly ["attachment", "checkbox", "currency", "datetime", "email", "formula", "json", "long_text", "lookup", "member", "multi_select", "number", "percent", "phone", "relation", "rollup", "select", "text", "url"];
301
+ declare const FIELD_KINDS: readonly ["attachment", "checkbox", "currency", "datetime", "email", "entity_reference", "formula", "json", "long_text", "lookup", "member", "multi_select", "number", "percent", "phone", "relation", "rollup", "select", "text", "url"];
302
302
  /**
303
303
  * 🚨 THE UNION IS DERIVED FROM THE LIST ABOVE, and the list is what the
304
304
  * coverage test walks. Add a kind here and the test drives it; give it no arm
@@ -352,6 +352,13 @@ interface CoerceOptions {
352
352
  */
353
353
  label?: string | undefined;
354
354
  }
355
+ /**
356
+ * SC-R / P12. Whether a relation's config makes it an ENTITY REFERENCE: target
357
+ * mode `any` (REL-8) restricted by a non-empty `allowed_types`.
358
+ */
359
+ declare function isEntityReferenceConfig(config: Record<string, unknown> | null | undefined): boolean;
360
+ /** The platform kinds an entity-reference Field may name, lower-cased, in its own order. */
361
+ declare function entityReferenceKindsOf(field: Pick<CoercibleField, "config">): string[];
355
362
  /** The Field's name in plain words — never its key on a screen. */
356
363
  declare function coercionLabel(field: CoercibleField): string;
357
364
  /**
@@ -765,6 +772,48 @@ interface PipelineMoveResult {
765
772
  }[];
766
773
  what_happens?: string;
767
774
  }
775
+ /** One card of a batch move (`custom.pipeline_move_many`). The version is REQUIRED: it is the
776
+ * version the board loaded, and a card that changed since answers `changed_since_loaded`. */
777
+ interface PipelineMoveManyItem {
778
+ record_id: Uuid;
779
+ stage: string;
780
+ expected_version: number;
781
+ /** Columns the stage asks for, filled in on the way in. */
782
+ also?: Record<string, unknown>;
783
+ }
784
+ /** What one card of a batch move came to. The sentence is always the store's own. */
785
+ type PipelineMoveVerdict = "moved" | "needs_approval" | "needs_fields" | "changed_since_loaded" | "no_right" | "refused";
786
+ interface PipelineMoveManyResult {
787
+ index: number;
788
+ record_id: Uuid;
789
+ stage: string;
790
+ verdict: PipelineMoveVerdict;
791
+ sentence: string;
792
+ /** Set on `needs_fields`: the empty columns the stage asks for. */
793
+ needs?: PipelineMissingField[];
794
+ /** Set on `moved` / `needs_approval`: the card's version now. */
795
+ version?: number;
796
+ /** Set on `changed_since_loaded`: the version that won. */
797
+ current_version?: number;
798
+ expected_version?: number;
799
+ approval_id?: Uuid;
800
+ approvers?: {
801
+ user_id: Uuid;
802
+ name: string | null;
803
+ why: string;
804
+ }[];
805
+ warnings?: StageRuleWarning[];
806
+ rule?: string;
807
+ code?: string;
808
+ }
809
+ /** What `custom.pipeline_move_many` answers: the counts, then one verdict per card in order. */
810
+ interface PipelineMoveMany {
811
+ asked: number;
812
+ moved: number;
813
+ needs_approval: number;
814
+ not_moved: number;
815
+ results: PipelineMoveManyResult[];
816
+ }
768
817
  /**
769
818
  * ONE GATE ON A STAGE, as the condition builder on the stage settings screen writes it.
770
819
  * `requires`, `who` and `limits` are sugar over this shape; this is the general form, and
@@ -1312,6 +1361,124 @@ interface PortalCard {
1312
1361
  * decides whether they can sign in at all.
1313
1362
  */
1314
1363
  external_lane_open: boolean;
1364
+ /** S6 — the look and forms exactly as the owner stored them (`{}` when none). */
1365
+ config: PortalConfig;
1366
+ /** S6 — the look as a client sees it: the portal's own values over the organization's brand. */
1367
+ style: PortalStyle;
1368
+ /** S6 — every form on the portal, in its order, with its title, Table and state. */
1369
+ forms: PortalFormRef[];
1370
+ /** S6 — the accent names a portal may carry (the design system's `STYLE_COLORS`). */
1371
+ accents: PortalAccent[];
1372
+ /**
1373
+ * S6 — the pictures that could be this portal's logo: the organization's own PUBLIC pictures in
1374
+ * Files, newest first. A private file is never offered, because the store would refuse it.
1375
+ */
1376
+ logo_candidates: Array<{
1377
+ file_id: Uuid;
1378
+ name: string;
1379
+ url: string | null;
1380
+ }>;
1381
+ }
1382
+ /** The design system's colour names (`STYLE_COLORS`), which is all an accent may be. */
1383
+ declare const PORTAL_ACCENTS: readonly ["slate", "green", "amber", "red", "blue", "violet", "teal"];
1384
+ type PortalAccent = (typeof PORTAL_ACCENTS)[number];
1385
+ declare function isPortalAccent(word: unknown): word is PortalAccent;
1386
+ /** One link in a portal's footer. The store takes only `https://`, `mailto:` and `tel:`. */
1387
+ interface PortalFooterLink {
1388
+ label: string;
1389
+ url: string;
1390
+ }
1391
+ /** A portal's look as the owner sets it. Every key is optional; absent means "the organization's". */
1392
+ interface PortalStyleInput {
1393
+ display_name?: string | null;
1394
+ welcome?: string | null;
1395
+ logo_file_id?: Uuid | null;
1396
+ accent?: PortalAccent | null;
1397
+ footer_links?: PortalFooterLink[] | null;
1398
+ }
1399
+ /** One form on a portal, as the owner sets it. `order` is the position; `label` overrides the title. */
1400
+ interface PortalFormInput {
1401
+ form_id: Uuid;
1402
+ label?: string | null;
1403
+ order?: number | null;
1404
+ }
1405
+ /**
1406
+ * What `portalDeclare({ config })` sends. A key given REPLACES that key; a key not given is KEPT;
1407
+ * `style: null` puts the organization's brand back and `forms: []` takes every form off.
1408
+ */
1409
+ interface PortalConfigInput {
1410
+ style?: PortalStyleInput | null;
1411
+ forms?: PortalFormInput[] | null;
1412
+ }
1413
+ /** The look and forms as the store holds them (normalized by the store). */
1414
+ interface PortalConfig {
1415
+ style?: PortalStyleInput;
1416
+ forms?: Array<{
1417
+ form_id: Uuid;
1418
+ label?: string;
1419
+ order: number;
1420
+ }>;
1421
+ }
1422
+ /** The look a client is shown — resolved by the store, never computed by a screen. */
1423
+ interface PortalStyle {
1424
+ display_name: string;
1425
+ welcome: string | null;
1426
+ logo_file_id: Uuid | null;
1427
+ /** The logo's PUBLIC address, or null. Readable by anybody the portal is shown to. */
1428
+ logo_url: string | null;
1429
+ /** Null means the app's own colour. */
1430
+ accent: PortalAccent | null;
1431
+ footer_links: PortalFooterLink[];
1432
+ /** Which of the values above came from the organization rather than the portal. */
1433
+ from_organization: Array<"display_name" | "logo">;
1434
+ }
1435
+ /** One form on a portal, with what the owner needs to see about it. */
1436
+ interface PortalFormRef {
1437
+ form_id: Uuid;
1438
+ /** What the portal calls it (the owner's label, else the form's title). */
1439
+ label: string;
1440
+ order: number;
1441
+ title: string;
1442
+ table_id: Uuid | null;
1443
+ table: string;
1444
+ /** `gone` is a form that was removed; the outsider's list only ever carries `open`. */
1445
+ state: "open" | "closed" | "full" | "gone";
1446
+ }
1447
+ /** A Table's stages as a portal client may be told them (`custom.portal_me` → tables[].stage). */
1448
+ interface PortalStage {
1449
+ /** The stage Field's key on the record. */
1450
+ field: string;
1451
+ label: string;
1452
+ /** In the order they were declared. A record stores the stage's `key`. */
1453
+ stages: Array<{
1454
+ key: string;
1455
+ label: string;
1456
+ retired: boolean;
1457
+ }>;
1458
+ }
1459
+ /** What `custom.portal_form` answers: one form on the caller's own portal. */
1460
+ interface PortalFormSpec {
1461
+ form_id: Uuid;
1462
+ portal_id: Uuid;
1463
+ table_id: Uuid;
1464
+ title: string;
1465
+ label: string;
1466
+ presentation: Record<string, unknown>;
1467
+ /** The form's exposed Fields as the store holds them — never the one naming the client. */
1468
+ fields: Array<Record<string, unknown> & {
1469
+ id: Uuid;
1470
+ key: string;
1471
+ }>;
1472
+ required: string[];
1473
+ state: "open" | "closed" | "full";
1474
+ message: string | null;
1475
+ }
1476
+ /** What `custom.portal_form_submit` answers. `held` waits for the office; `message` says so. */
1477
+ interface PortalFormAnswer {
1478
+ submission_id: Uuid | null;
1479
+ record_id: Uuid | null;
1480
+ state: "accepted" | "held" | "rejected" | "closed" | "full" | "too_many";
1481
+ message: string | null;
1315
1482
  }
1316
1483
  /** What `custom.portal_invite` answers. `say` is the door's own sentence. */
1317
1484
  interface PortalInvitation {
@@ -1438,6 +1605,22 @@ type AggregateFilter = string | number | boolean | null | AggregateWindow;
1438
1605
  * lands somewhere else, which is the only way a drill-through can lie.
1439
1606
  */
1440
1607
  type RecordFilter = Record<string, AggregateFilter>;
1608
+ /**
1609
+ * S2-PRIME FILTER-GROUPS — A READ DOOR'S QUESTION, IN EITHER OF ITS TWO SHAPES.
1610
+ *
1611
+ * The flat `RecordFilter` above (field key → scalar / `null` / window, AND only) is what
1612
+ * dashboards, drill-throughs and the notifier carry. A `RuleExpression` — `{op, args}`, ALL / ANY /
1613
+ * NOT groups nested to any depth, fields by id — is what the condition builder, a view's own
1614
+ * filter and every membership Rule speak. `custom.record_filter_sql(org, table, filter)` turns
1615
+ * EITHER into the one WHERE clause the grid (`list`), the aggregate and the board all use, so the
1616
+ * three can never disagree about which records a view holds.
1617
+ */
1618
+ type StoreFilter = RecordFilter | RuleExpression;
1619
+ /**
1620
+ * Is this filter a Rule expression? The store's own test (`custom.filter_is_rule`): an object
1621
+ * whose `op` is a word and which carries `args`.
1622
+ */
1623
+ declare function isRuleFilter(filter: unknown): filter is RuleExpression;
1441
1624
  /** One measure. `count` counts rows and needs no Field; the rest read one. */
1442
1625
  interface AggregateMeasure {
1443
1626
  op: AggregateOperation;
@@ -1453,6 +1636,90 @@ interface AggregateRow {
1453
1636
  groups: Record<string, string | null>;
1454
1637
  measures: Record<string, number | null>;
1455
1638
  row_count: number;
1639
+ /**
1640
+ * S3 — present only when the question carried a comparison. The same group
1641
+ * in the PRIOR window: a bucket is matched by its position in its own window
1642
+ * (week 1 of September beside week 1 of August), so `prior_groups` names the
1643
+ * prior bucket's own date. `null` when the prior window had no such group.
1644
+ */
1645
+ prior_groups?: Record<string, string | null> | null;
1646
+ /** The prior window's measures, keyed exactly like `measures`. */
1647
+ prior_measures?: Record<string, number | null> | null;
1648
+ prior_row_count?: number | null;
1649
+ /** Every measure now and before, the change, and the change as a percent of before. */
1650
+ delta?: Record<string, AggregateDelta> | null;
1651
+ /** The two windows this row was worked out over, and the calendar that cut them. */
1652
+ compare?: AggregateCompareWindows | null;
1653
+ /**
1654
+ * S3 — a compared, bucketed row's POSITION in its window (0 = the first
1655
+ * bucket). A row the current window has not reached yet has a position and
1656
+ * no current bucket, so a chart names it "Week 6" rather than inventing a date.
1657
+ */
1658
+ position?: number | null;
1659
+ }
1660
+ /**
1661
+ * S3 — WHAT A PERIOD IS COMPARED AGAINST (`custom.agg_compare_kinds()`).
1662
+ * `previous_period` is the period before, of the same length (August before
1663
+ * September; an explicit window shifted back by its own length);
1664
+ * `same_period_last_year`; `range` is a fixed `baseline`.
1665
+ */
1666
+ type AggregateCompareKind = "previous_period" | "same_period_last_year" | "range";
1667
+ /**
1668
+ * S3 — ONE COMPARISON, as `custom.record_aggregate(p_compare)` and a
1669
+ * dashboard block's `compare` both take it. The current window is either the
1670
+ * calendar `period` holding `at` (default: now, in the organization's time
1671
+ * zone) or an explicit `from`/`to`. A date alone ("2026-09-01") is that local
1672
+ * day in the organization's time zone.
1673
+ */
1674
+ interface AggregateCompare {
1675
+ against?: AggregateCompareKind;
1676
+ /** The date Field the period runs along. Defaults to the bucket's key. */
1677
+ key?: string;
1678
+ period?: AggregateBucket;
1679
+ at?: string;
1680
+ from?: string;
1681
+ to?: string;
1682
+ /** Compare the part of the period that has happened ("month to date"). */
1683
+ to_date?: boolean;
1684
+ /** The fixed period `range` compares against. Half-open: `to` is excluded. */
1685
+ baseline?: {
1686
+ from: string;
1687
+ to: string;
1688
+ };
1689
+ }
1690
+ /** One measure now and before. `change_pct` is null when before was nothing or zero. */
1691
+ interface AggregateDelta {
1692
+ current: number | null;
1693
+ prior: number | null;
1694
+ change: number | null;
1695
+ change_pct: number | null;
1696
+ }
1697
+ /**
1698
+ * S3 — THE TWO WINDOWS the store actually ran, as local ISO moments with the
1699
+ * organization's offset ("2026-09-01T00:00:00-07:00"), and the calendar that
1700
+ * cut them. A screen labels the comparison from THIS, never from its own clock.
1701
+ */
1702
+ interface AggregateCompareWindows {
1703
+ key: string;
1704
+ against: AggregateCompareKind;
1705
+ period: AggregateBucket | null;
1706
+ to_date: boolean;
1707
+ time_zone: string;
1708
+ week_start: string;
1709
+ /** The bucket grain the windows were counted in, when the question had a bucket. */
1710
+ grain: AggregateBucket | null;
1711
+ /** How many buckets the current window holds — what a target's pace is shared over. */
1712
+ bucket_count: number | null;
1713
+ window: {
1714
+ from: string;
1715
+ to: string;
1716
+ };
1717
+ prior_window: {
1718
+ from: string;
1719
+ to: string;
1720
+ };
1721
+ /** On a row from `recordAggregate`: that row's bucket position (see `AggregateRow.position`). */
1722
+ position?: number | null;
1456
1723
  }
1457
1724
  /** The measure key the store answers with, so a chart can find its own series. */
1458
1725
  declare function measureKey(measure: AggregateMeasure): string;
@@ -1468,7 +1735,7 @@ declare function measureKey(measure: AggregateMeasure): string;
1468
1735
  * one question. `undefined` and an empty filter are both `"{}"` — the caller
1469
1736
  * asked nothing, and there is only one way to ask nothing.
1470
1737
  */
1471
- declare function stableFilterKey(filter: RecordFilter | null | undefined): string;
1738
+ declare function stableFilterKey(filter: StoreFilter | null | undefined): string;
1472
1739
 
1473
1740
  /** `custom.decoration_colors()` — the palette, in the order an uncolored choice takes. */
1474
1741
  type DecorationColor = "slate" | "green" | "amber" | "red" | "blue" | "violet" | "teal";
@@ -1702,6 +1969,187 @@ declare function recordChangeTrigger(tableId: Uuid, options?: {
1702
1969
  actions?: RecordChangeAction[];
1703
1970
  changed_fields?: string[];
1704
1971
  };
1972
+ /**
1973
+ * One entry of `custom.table_list_everywhere` — `public.get_user_tables`' own shape plus
1974
+ * `store`, so a picker swaps one call and keeps its code. `store` says which home opens it.
1975
+ */
1976
+ interface TableListEntry {
1977
+ id: Uuid;
1978
+ table_name: string;
1979
+ description: string | null;
1980
+ version: number | null;
1981
+ user_id: Uuid | null;
1982
+ is_public: boolean | null;
1983
+ visibility: string | null;
1984
+ organization_id: Uuid;
1985
+ created_at: string;
1986
+ updated_at: string | null;
1987
+ last_activity_at: string | null;
1988
+ row_count: number;
1989
+ field_count: number;
1990
+ store: "older" | "records";
1991
+ }
1992
+ /** Where a synced table comes from. `external_id` is the source's own id (a spreadsheet id). */
1993
+ interface TableSyncSource {
1994
+ provider: string;
1995
+ external_id: string;
1996
+ tab_id?: string | null;
1997
+ synced_at?: string | null;
1998
+ }
1999
+ /** What `custom.table_sync` takes: the source, its columns, and every row it has NOW. */
2000
+ interface TableSyncSpec {
2001
+ source: TableSyncSource;
2002
+ table_name: string;
2003
+ columns: string[];
2004
+ rows: {
2005
+ ref: string;
2006
+ values: Record<string, string | number | boolean | null>;
2007
+ }[];
2008
+ }
2009
+ interface TableSyncResult {
2010
+ table_id: Uuid;
2011
+ created: boolean;
2012
+ fields_added: number;
2013
+ rows_inserted: number;
2014
+ rows_updated: number;
2015
+ rows_archived: number;
2016
+ source_system: string;
2017
+ }
2018
+ /**
2019
+ * A sheet tab's cells (header row first) → the spec `custom.table_sync` takes. Every row is
2020
+ * named by its sheet row number (`row-2` is the first row under the header) unless
2021
+ * `refColumn` names a column holding a stable id; a blank or repeated ref is refused here, so
2022
+ * the store never sees two rows claiming to be the same source row. Wholly blank rows are
2023
+ * skipped. Pure.
2024
+ */
2025
+ declare function sheetSyncSpec(args: {
2026
+ source: TableSyncSource;
2027
+ tableName: string;
2028
+ cells: readonly (readonly (string | number | boolean | null | undefined)[])[];
2029
+ refColumn?: string;
2030
+ }): TableSyncSpec;
2031
+ /** One row of `custom.table_row_counts`: the rows of that Table this reader may see. */
2032
+ interface TableRowCount {
2033
+ table_id: Uuid;
2034
+ visible_rows: number;
2035
+ }
2036
+ /**
2037
+ * One row of `custom.record_headers`: the row's own columns the document door does not answer.
2038
+ * `created_by` is the caller's own id on rows the caller made and null on every other; `mine`
2039
+ * says which.
2040
+ */
2041
+ interface RecordHeader {
2042
+ id: Uuid;
2043
+ table_id: Uuid;
2044
+ created_at: string;
2045
+ updated_at: string;
2046
+ version: number;
2047
+ deleted_at: string | null;
2048
+ mine: boolean;
2049
+ created_by: Uuid | null;
2050
+ }
2051
+ /**
2052
+ * Fold `table_row_counts` onto a table list: `row_count` set on every Table the counts name.
2053
+ * A Table the counts do not name keeps what it had — the store answers no row for a Table this
2054
+ * reader may not know, and that is never turned into a zero. Pure.
2055
+ */
2056
+ declare function withRowCounts<T extends {
2057
+ id: Uuid;
2058
+ row_count?: number | null;
2059
+ }>(tables: readonly T[], counts: readonly TableRowCount[] | null | undefined): T[];
2060
+ /** What `custom.view_record_order_set` answers. */
2061
+ interface ViewOrderSet {
2062
+ view_id: Uuid;
2063
+ table_id: Uuid;
2064
+ order: "manual";
2065
+ named: number;
2066
+ positioned: number;
2067
+ }
2068
+ /**
2069
+ * The order to send after a drag: `order` with `moved` taken out and put at `toIndex` (clamped).
2070
+ * The store keeps every row the call does not name in its old place after the named ones, so a
2071
+ * screen may send only the rows it shows. Pure.
2072
+ */
2073
+ declare function moveInOrder(order: readonly Uuid[], moved: Uuid, toIndex: number): Uuid[];
2074
+ /**
2075
+ * What `custom.table_share_outside_grant` answers. `person` says which path ran:
2076
+ * `outside_account` (granted at once and notified — never made a member), `member` (a plain
2077
+ * share), `no_account` (the invitation door's own answer, with its link and delivery).
2078
+ */
2079
+ interface OutsideShareAnswer {
2080
+ granted: boolean;
2081
+ invited: boolean;
2082
+ joined: boolean;
2083
+ person: "outside_account" | "member" | "no_account";
2084
+ email: string;
2085
+ table: string;
2086
+ level: string;
2087
+ level_label: string;
2088
+ say: string;
2089
+ user_id?: Uuid;
2090
+ permission_id?: Uuid;
2091
+ invitation_id?: Uuid | null;
2092
+ accept_path?: string | null;
2093
+ delivery_say?: string | null;
2094
+ }
2095
+
2096
+ /** The three placement facts, as the Table document or `custom.table` carries them. */
2097
+ interface TablePlacement {
2098
+ kept_by_the_app?: boolean | null;
2099
+ kept_for?: string | null;
2100
+ offered_as_context?: boolean | null;
2101
+ }
2102
+ /**
2103
+ * One row of `custom.table_facts` since SC-1 — the two lane facts it always answered
2104
+ * (`visibility`, `mine`) and the placement, with the sentence a person reads and where the
2105
+ * table is used. A store without the SC-1 door answers the first three columns only; every
2106
+ * placement column is then `undefined`, and the readers below treat the table as the
2107
+ * organization's own — exactly what that store's older screens did.
2108
+ */
2109
+ interface TablePlacementFact extends TablePlacement {
2110
+ table_id: Uuid;
2111
+ visibility: string;
2112
+ mine: boolean;
2113
+ /** The heading a kept table is listed under: "The context system", "The choices behind your columns", … */
2114
+ keeper_group?: string | null;
2115
+ /** One plain sentence: who keeps it and where it opens from. Null for the organization's own. */
2116
+ keeper_says?: string | null;
2117
+ /** Where the table is used: `table` (another Table, or itself) or `scope` (a context scope). */
2118
+ used_in_kind?: "table" | "scope" | null;
2119
+ used_in_id?: Uuid | null;
2120
+ /** The Table that page belongs to, when `used_in_kind` is `table`. */
2121
+ used_in_table_id?: Uuid | null;
2122
+ }
2123
+ /** Whether a person's list of tables keeps this one out of sight until "Show everything". */
2124
+ declare function keptOutOfSight(placement: TablePlacement | null | undefined): boolean;
2125
+ /** Whether the context picker may offer this Table. Absent is no. */
2126
+ declare function offeredAsContext(placement: TablePlacement | null | undefined): boolean;
2127
+ /**
2128
+ * The placement facts folded onto a table list, by id. Pure — returns new objects and leaves
2129
+ * the list it was given alone. A table the facts do not name is returned unchanged.
2130
+ */
2131
+ declare function withTablePlacement<T extends {
2132
+ id: Uuid;
2133
+ }>(tables: readonly T[], facts: readonly TablePlacementFact[] | null | undefined): Array<T & Partial<TablePlacementFact>>;
2134
+ /**
2135
+ * THE KEPT TABLES, GROUPED UNDER THEIR KEEPER, in the order each group first appears. A kept
2136
+ * table the store gave no heading goes under "Kept by the app" — never dropped.
2137
+ */
2138
+ declare function keptGroups<T extends TablePlacement & Partial<TablePlacementFact>>(tables: readonly T[]): Array<{
2139
+ group: string;
2140
+ tables: T[];
2141
+ }>;
2142
+ /**
2143
+ * WHERE A KEPT TABLE OPENS FROM (THE DOOR LAW): the host's own addresses for a table and for a
2144
+ * context scope, chosen by what the store said the table is used in. With nothing said, the
2145
+ * table's own page — a kept table is never a row with nowhere to go.
2146
+ */
2147
+ declare function keptTableHref(fact: {
2148
+ table_id: Uuid;
2149
+ } & Partial<TablePlacementFact>, hrefs: {
2150
+ table: (tableId: Uuid) => string;
2151
+ scope: (scopeId: Uuid) => string;
2152
+ }): string;
1705
2153
 
1706
2154
  /** The seven shapes a block can take, exactly as `custom.dashboard_kinds()` answers. */
1707
2155
  type DashboardBlockKind = "number" | "bar" | "column" | "line" | "donut" | "table" | "stuck";
@@ -1734,6 +2182,43 @@ interface DashboardBlock {
1734
2182
  state_key?: string;
1735
2183
  /** `stuck` only: how long a record may sit on the same value. Defaults to 14. */
1736
2184
  days?: number;
2185
+ /**
2186
+ * S3 — the comparison this block makes (this month against last month).
2187
+ * The door fills `key` from the bucket when it is left out, and refuses a
2188
+ * comparison along a Field the Table does not have, by name.
2189
+ */
2190
+ compare?: AggregateCompare | null;
2191
+ /** S3 — the number this block is aiming for. */
2192
+ target?: DashboardTarget | null;
2193
+ }
2194
+ /**
2195
+ * S3 — A BLOCK'S TARGET. `measure` is one of the block's own measure keys
2196
+ * (default: the first). `per: "period"` is a target for the whole window (a
2197
+ * monthly target — a bucketed chart draws its even share per bucket as the
2198
+ * pace); `per: "bucket"` is a target for every bar or point.
2199
+ *
2200
+ * A target is a FIXED NUMBER (`value`) or A GOAL COLUMN (`field`, a Field key of
2201
+ * the block's Table): the store adds that column up (`op`, default `sum`) over
2202
+ * exactly the records the block's own number read — same filter, same window,
2203
+ * same reader — so "invoiced against quoted" is about the same jobs. Exactly
2204
+ * one of the two; a goal column is always `per: "period"`.
2205
+ */
2206
+ type DashboardTarget = DashboardTargetBase & ({
2207
+ value: number;
2208
+ field?: never;
2209
+ op?: never;
2210
+ } | {
2211
+ field: string;
2212
+ op?: DashboardTargetOp;
2213
+ value?: never;
2214
+ });
2215
+ /** How a goal column is added up across the block's records. */
2216
+ type DashboardTargetOp = "sum" | "avg" | "min" | "max";
2217
+ /** What every target carries, whichever kind it is. */
2218
+ interface DashboardTargetBase {
2219
+ label?: string;
2220
+ measure?: string;
2221
+ per?: "period" | "bucket";
1737
2222
  }
1738
2223
  /** One dashboard as `custom.dashboards` reports it to its organization. */
1739
2224
  interface DashboardSummary {
@@ -1792,6 +2277,56 @@ interface DashboardBlockResult {
1792
2277
  refused?: string;
1793
2278
  /** The SQLSTATE that refusal carried. */
1794
2279
  sqlstate?: string;
2280
+ /**
2281
+ * S3 — the windows this block was actually compared over; `null` when it was
2282
+ * not compared. (The comparison it was ASKED to make is the saved block's.)
2283
+ */
2284
+ compare?: AggregateCompareWindows | null;
2285
+ /** S3 — why a canvas comparison was not applied to this block (it has no date). */
2286
+ compare_refused?: string;
2287
+ /**
2288
+ * S3 — the block's first (or target) measure added up across its rows, now
2289
+ * and before, when the measure adds up (count, sum, filled, empty) or the
2290
+ * block has one row. Worked out by the store from the rows it answered, so
2291
+ * a tile, a chart and a ring cannot disagree.
2292
+ */
2293
+ totals?: DashboardTotals;
2294
+ /** S3 — the target, with how far the current total has come and its pace per bucket. */
2295
+ target?: DashboardTargetResult;
2296
+ }
2297
+ /** S3 — one block's total, now and before. */
2298
+ interface DashboardTotals {
2299
+ measure: string;
2300
+ current: number | null;
2301
+ prior: number | null;
2302
+ change: number | null;
2303
+ change_pct: number | null;
2304
+ }
2305
+ /** S3 — a target as the run answers it. */
2306
+ interface DashboardTargetResult {
2307
+ /**
2308
+ * The number aimed at: the fixed value, or the goal column added up over this
2309
+ * block's records. `null` when a goal column had nothing to add up, or was refused.
2310
+ */
2311
+ value: number | null;
2312
+ /** A goal column's key, when the target is read from one. */
2313
+ field?: string;
2314
+ /** How that column was added up. */
2315
+ op?: DashboardTargetOp;
2316
+ /**
2317
+ * The store's own sentence when THIS reader may not read the goal column — the
2318
+ * block still answers its number; only the target is withheld.
2319
+ */
2320
+ refused?: string;
2321
+ label: string;
2322
+ measure: string;
2323
+ per: "period" | "bucket";
2324
+ /** The current total the target is measured against. */
2325
+ current: number | null;
2326
+ /** current ÷ value, 4 decimals. */
2327
+ progress: number | null;
2328
+ /** The line a bucketed chart draws: the target's even share of one bucket, or the target itself per bucket. */
2329
+ pace: number | null;
1795
2330
  }
1796
2331
  /** What `custom.dashboard_run` answers: the canvas, and every block's own result. */
1797
2332
  interface DashboardRunResult {
@@ -1801,6 +2336,15 @@ interface DashboardRunResult {
1801
2336
  presentation: Record<string, unknown>;
1802
2337
  /** The one filter bar this run was asked with. */
1803
2338
  filter: Record<string, AggregateFilter>;
2339
+ /** S3 — the date grain the canvas re-cut every bucketed block to, or null. */
2340
+ grain?: AggregateBucket | null;
2341
+ /** S3 — the canvas comparison this run was asked with, or null. */
2342
+ compare?: AggregateCompare | null;
2343
+ /** S3 — the organization's calendar every date on this canvas was cut with. */
2344
+ calendar?: {
2345
+ time_zone: string;
2346
+ week_start: string;
2347
+ };
1804
2348
  blocks: DashboardBlockResult[];
1805
2349
  }
1806
2350
 
@@ -2532,11 +3076,22 @@ interface SavedViewRow {
2532
3076
  name: string;
2533
3077
  table_id: Uuid | null;
2534
3078
  filters: RecordFilter;
3079
+ /**
3080
+ * THE WHOLE VIEW (S0 ONE-SAVED-VIEW, 2026-09-23): `platform.saved_view` is the ONE saved-view
3081
+ * store, so this is what the view bar, the board, the calendar and the gallery draw from —
3082
+ * `layout` (the kind), `group_field`, `measure`, `date_field`, `image_field`, `sorts`, `rule_id`,
3083
+ * `is_default`, `presentation`, G7's `grid`, G13's `order`, the mover's `moved_from`.
3084
+ */
3085
+ definition: Record<string, unknown>;
2535
3086
  created_at: string;
2536
3087
  }
2537
- /** What `custom.view_declare` is asked for. `view_id` re-states rather than doubling. */
3088
+ /**
3089
+ * What `custom.view_declare` is asked for. With `view_id` the door MERGES: `name` changes only
3090
+ * when sent, `filters` only when the key is sent, each `definition` key replaces that one key and
3091
+ * a key sent as `null` is removed — so a screen sends only what it changed.
3092
+ */
2538
3093
  interface SavedViewSpecIn {
2539
- name: string;
3094
+ name?: string;
2540
3095
  filters?: RecordFilter | null;
2541
3096
  definition?: Record<string, unknown> | null;
2542
3097
  view_id?: Uuid | null;
@@ -2567,38 +3122,199 @@ interface SubscriptionBlock {
2567
3122
  }
2568
3123
 
2569
3124
  /**
2570
- * REL-6. Whether Visibility flows along this relation and the MAXIMUM access
2571
- * level it carries. Default off on `referenced`, on for `owned`.
3125
+ * The data seam: a structural subset of `SupabaseClient`. The package never
3126
+ * opens a database connection of its own and never holds a key — the HOST
3127
+ * supplies a client that already carries the operating person's session, which
3128
+ * is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
2572
3129
  */
2573
- interface RelationCarries {
2574
- carries: boolean;
2575
- /** The ceiling — a relation never carries more access than this. */
2576
- max_access: string | null;
3130
+ interface RecordsDataSource {
3131
+ /**
3132
+ * Call a door. The name is always a door the live catalogue has; `/core`
3133
+ * refuses `door_absent` before it ever reaches here for one that does not.
3134
+ */
3135
+ rpc(fn: string, args: Record<string, unknown>,
3136
+ /**
3137
+ * THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
3138
+ * own doors, `iam` for the trust doors (the external principal and the
3139
+ * publish binding, which are the PLATFORM's). A host binding supabase-js
3140
+ * routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
3141
+ * ignores it calls its own default PostgREST profile — `public` — and is
3142
+ * refused by name, which is the failure we want rather than a silent answer
3143
+ * from the wrong system. (Before 2026-09-18 this was described as "only ever
3144
+ * `iam`" and the store's doors went unqualified; the extension's first real
3145
+ * turn proved that asks `public.store_is_open` and finds nothing.)
3146
+ */
3147
+ options?: {
3148
+ schema?: string;
3149
+ }): PromiseLike<{
3150
+ data: unknown;
3151
+ error: PgError | null;
3152
+ }>;
3153
+ /** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
3154
+ schema(name: string): {
3155
+ from(table: string): RecordsTableQuery;
3156
+ };
2577
3157
  }
2578
- /** The seven properties, each its own question. */
2579
- interface RelationProperties {
2580
- /** REL-1. Stored once on the contained table, read from the field's side. */
2581
- flavor: RelationFlavor;
2582
- /** REL-2. Separate from flavour. */
2583
- on_delete: OnDelete;
2584
- /** REL-3. A snapshot is a frozen copy in the relation's payload — never a pointer into History. */
2585
- binding: RelationBinding;
2586
- /** REL-4. */
2587
- ordered: boolean;
2588
- /** REL-5. */
2589
- loops: "allowed" | "refused";
2590
- /** REL-6. */
2591
- carries: RelationCarries;
2592
- /** REL-7. */
2593
- cardinality: RelationCardinality;
3158
+ /** The read surface the list and query paths use. A real supabase-js client satisfies it. */
3159
+ interface RecordsTableQuery {
3160
+ select(columns: string, options?: {
3161
+ count?: "exact" | "planned" | "estimated";
3162
+ head?: boolean;
3163
+ }): RecordsFilter;
3164
+ }
3165
+ interface RecordsFilter extends PromiseLike<RecordsResponse> {
3166
+ eq(column: string, value: unknown): RecordsFilter;
3167
+ neq(column: string, value: unknown): RecordsFilter;
3168
+ in(column: string, values: readonly unknown[]): RecordsFilter;
3169
+ is(column: string, value: null | boolean): RecordsFilter;
3170
+ gte(column: string, value: unknown): RecordsFilter;
3171
+ lte(column: string, value: unknown): RecordsFilter;
3172
+ order(column: string, options?: {
3173
+ ascending?: boolean;
3174
+ }): RecordsFilter;
3175
+ range(from: number, to: number): RecordsFilter;
3176
+ limit(count: number): RecordsFilter;
3177
+ }
3178
+ interface RecordsResponse {
3179
+ data: unknown;
3180
+ error: PgError | null;
3181
+ count?: number | null;
2594
3182
  }
2595
3183
  /**
2596
- * REL-8 / REL-N-1. A target is a REFERENCE, written that way from the first
2597
- * line of code, because it may name a row outside our database. One Table,
2598
- * several, or any — polymorphic without restriction. External targets are
2599
- * read-only in v1.
3184
+ * WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
3185
+ * operating it — there is no agent identity and there are no service roles. So
3186
+ * the actor word and the person are two separate facts, and `on_behalf_of` is
3187
+ * meaningful only when the actor is `agent`.
2600
3188
  */
2601
- type RelationTarget = {
3189
+ interface RecordsActor {
3190
+ actor: Actor;
3191
+ /** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
3192
+ user_id?: Uuid;
3193
+ /** Only an agent acts on behalf of a person (the store refuses it otherwise). */
3194
+ on_behalf_of?: Uuid;
3195
+ }
3196
+ /**
3197
+ * OPTIONAL. A live-updates seam. The default degradation is stated rather than
3198
+ * silent: with no port bound, `useRecords` reports `live: false` and the screen
3199
+ * can say "not live" instead of quietly going stale.
3200
+ *
3201
+ * A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
3202
+ * deliberately does NOT depend on it, so the headless core stays free of a
3203
+ * realtime client and a host that has one keeps using the one it already has.
3204
+ */
3205
+ interface RecordsRealtimePort {
3206
+ /**
3207
+ * Watch one organization's records of one table. Returns an unsubscribe.
3208
+ *
3209
+ * THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
3210
+ * was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
3211
+ * imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
3212
+ * which worked, and which meant the port contract did not describe half of what a port
3213
+ * actually does. A column appearing is not a row changing, and the package owns the
3214
+ * difference.
3215
+ *
3216
+ * NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
3217
+ * re-reads — by id set when the nudge names ids, whole-page when it cannot.
3218
+ */
3219
+ subscribeRecords(args: {
3220
+ organization_id: Uuid;
3221
+ table_id: Uuid;
3222
+ }, sink: RecordsChangeSink): () => void;
3223
+ }
3224
+ /** What a realtime port may tell the package. Two calls, because a column is not a row. */
3225
+ interface RecordsChangeSink {
3226
+ /**
3227
+ * THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
3228
+ * a change above the store's own id cap — and is the one case that costs a whole-page read.
3229
+ * An EMPTY array is not the same thing and is not a nudge at all.
3230
+ */
3231
+ records(ids: readonly Uuid[] | null): void;
3232
+ /**
3233
+ * THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
3234
+ * redraw the same table without the new column in it, which is a screen that is out of date
3235
+ * while looking healthy.
3236
+ */
3237
+ shape(): void;
3238
+ }
3239
+ /**
3240
+ * OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
3241
+ * Default degradation: `console.error` with the store's own words, never
3242
+ * silence.
3243
+ */
3244
+ type RecordsErrorSink = (error: {
3245
+ code: string;
3246
+ message: string;
3247
+ hint?: string;
3248
+ where: string;
3249
+ }) => void;
3250
+ /**
3251
+ * OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
3252
+ * not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
3253
+ * never a literal placeholder left in the text (DYN-14).
3254
+ */
3255
+ interface RecordsResolverPort {
3256
+ resolve(args: {
3257
+ organization_id: Uuid;
3258
+ merge_field_keys: string[];
3259
+ /** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
3260
+ state?: Record<string, unknown>;
3261
+ }): Promise<unknown>;
3262
+ }
3263
+ /** The one config a host binds. */
3264
+ interface RecordsConfig {
3265
+ /** REQUIRED. */
3266
+ dataSource: RecordsDataSource;
3267
+ /** REQUIRED. */
3268
+ actor: RecordsActor;
3269
+ /**
3270
+ * REQUIRED. REC-29: organizations are hard walls, and the store is keyed
3271
+ * `(organization_id, id)`. There is no "current organization" this package
3272
+ * discovers for itself — the host says which one, every time.
3273
+ */
3274
+ organizationId: Uuid;
3275
+ realtime?: RecordsRealtimePort;
3276
+ onError?: RecordsErrorSink;
3277
+ resolver?: RecordsResolverPort;
3278
+ /**
3279
+ * The schema the record store lives in. Exists so a rehearsal branch and
3280
+ * production can differ without a fork; it is `custom` everywhere today.
3281
+ */
3282
+ schema?: string;
3283
+ }
3284
+
3285
+ /**
3286
+ * REL-6. Whether Visibility flows along this relation and the MAXIMUM access
3287
+ * level it carries. Default off on `referenced`, on for `owned`.
3288
+ */
3289
+ interface RelationCarries {
3290
+ carries: boolean;
3291
+ /** The ceiling — a relation never carries more access than this. */
3292
+ max_access: string | null;
3293
+ }
3294
+ /** The seven properties, each its own question. */
3295
+ interface RelationProperties {
3296
+ /** REL-1. Stored once on the contained table, read from the field's side. */
3297
+ flavor: RelationFlavor;
3298
+ /** REL-2. Separate from flavour. */
3299
+ on_delete: OnDelete;
3300
+ /** REL-3. A snapshot is a frozen copy in the relation's payload — never a pointer into History. */
3301
+ binding: RelationBinding;
3302
+ /** REL-4. */
3303
+ ordered: boolean;
3304
+ /** REL-5. */
3305
+ loops: "allowed" | "refused";
3306
+ /** REL-6. */
3307
+ carries: RelationCarries;
3308
+ /** REL-7. */
3309
+ cardinality: RelationCardinality;
3310
+ }
3311
+ /**
3312
+ * REL-8 / REL-N-1. A target is a REFERENCE, written that way from the first
3313
+ * line of code, because it may name a row outside our database. One Table,
3314
+ * several, or any — polymorphic without restriction. External targets are
3315
+ * read-only in v1.
3316
+ */
3317
+ type RelationTarget = {
2602
3318
  kind: "ours";
2603
3319
  entity_token: string;
2604
3320
  row_id: Uuid;
@@ -2673,6 +3389,53 @@ type RelationWordsManyArgs = {
2673
3389
  display?: RelationDisplaySpec | null;
2674
3390
  record_ids: Uuid[];
2675
3391
  };
3392
+ /** One reference as the store keeps it. */
3393
+ interface EntityRef {
3394
+ /** The `platform.entity_types` token: `note`, `web_site`, `agent` … */
3395
+ token: string;
3396
+ id: Uuid;
3397
+ }
3398
+ /** One reference as a read door answers it. */
3399
+ interface EntityRefWithWords extends EntityRef {
3400
+ /**
3401
+ * The thing's own title — or the store's withheld sentence when the reader
3402
+ * may not open it; `null` when the kind names no title.
3403
+ */
3404
+ label: string | null;
3405
+ }
3406
+ /** One kind of platform thing a record may point at (`custom.entity_reference_kinds`). */
3407
+ interface EntityReferenceKind {
3408
+ token: string;
3409
+ /** What a person reads: "Note", "Site", "Agent". */
3410
+ label: string;
3411
+ /** The picker's grouping: the admin-assigned reference category, else the schema. */
3412
+ category: string;
3413
+ }
3414
+ /**
3415
+ * The references a cell holds, whichever shape it arrived in — one object, a
3416
+ * list, or what a read door rendered (with labels). Anything that is not a
3417
+ * reference is left out, never guessed at.
3418
+ */
3419
+ declare function entityRefsOf(value: unknown): EntityRefWithWords[];
3420
+ /**
3421
+ * What to WRITE for an entity-reference cell: `{token, id}` only, each thing
3422
+ * once, first mention first — the label a read door added is dropped, because
3423
+ * the store reads it and never keeps it (REL-14). A single-valued column gets
3424
+ * the one object (or `null`), a multi-valued one the list.
3425
+ */
3426
+ declare function entityRefsToWrite(value: unknown, multi: boolean): EntityRef | EntityRef[] | null;
3427
+ /**
3428
+ * The kinds of platform thing a record may point at — what the field editor's
3429
+ * kind picker lists. `custom.entity_reference_kinds()`.
3430
+ */
3431
+ declare function entityReferenceKinds(source: RecordsDataSource): Promise<RecordsResult<EntityReferenceKind[]>>;
3432
+ /**
3433
+ * THE WORDS HELPER. The words of each `{token, id}` for a picker or a chip
3434
+ * before anything is saved — each label read by the store for THIS person and
3435
+ * withheld when they may not open the thing. `custom.entity_reference_words`.
3436
+ * A saved cell needs no call: every read door already answers its labels.
3437
+ */
3438
+ declare function entityReferenceWords(source: RecordsDataSource, organizationId: Uuid, refs: readonly EntityRef[]): Promise<RecordsResult<EntityRefWithWords[]>>;
2676
3439
 
2677
3440
  /**
2678
3441
  * DYN-14 / DYN-15. An ordered list of merge fields ENDING IN A LITERAL, or the
@@ -2980,6 +3743,34 @@ interface WorkApprovalDecision {
2980
3743
  version: number | null;
2981
3744
  message: string;
2982
3745
  }
3746
+ /** One inbox decision of a batch (`custom.work_decide_many`). */
3747
+ interface WorkDecideManyItem {
3748
+ /** The inbox item — a `work_approval` record's id (`WorkInboxItem.item_id`). */
3749
+ item: Uuid;
3750
+ decision: "approve" | "decline";
3751
+ note?: string | null;
3752
+ }
3753
+ type WorkDecideVerdict = "approved" | "declined" | "already_decided" | "no_right" | "refused";
3754
+ interface WorkDecideManyResult {
3755
+ index: number;
3756
+ item: Uuid;
3757
+ decision: "approve" | "decline";
3758
+ verdict: WorkDecideVerdict;
3759
+ /** The store's own sentence: what was applied, or why it was not. */
3760
+ sentence: string;
3761
+ subject_id?: Uuid;
3762
+ version?: number | null;
3763
+ record_ids?: Uuid[];
3764
+ code?: string;
3765
+ }
3766
+ /** What `custom.work_decide_many` answers: the counts, then one verdict per item in order. */
3767
+ interface WorkDecideMany {
3768
+ asked: number;
3769
+ approved: number;
3770
+ declined: number;
3771
+ not_decided: number;
3772
+ results: WorkDecideManyResult[];
3773
+ }
2983
3774
  /** What `custom.work_assign` answers: the value, the access, and who holds it now. */
2984
3775
  interface WorkAssignment {
2985
3776
  record_id: Uuid;
@@ -3228,167 +4019,6 @@ interface ResolvedPublishBinding {
3228
4019
  notice: string;
3229
4020
  }
3230
4021
 
3231
- /**
3232
- * The data seam: a structural subset of `SupabaseClient`. The package never
3233
- * opens a database connection of its own and never holds a key — the HOST
3234
- * supplies a client that already carries the operating person's session, which
3235
- * is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
3236
- */
3237
- interface RecordsDataSource {
3238
- /**
3239
- * Call a door. The name is always a door the live catalogue has; `/core`
3240
- * refuses `door_absent` before it ever reaches here for one that does not.
3241
- */
3242
- rpc(fn: string, args: Record<string, unknown>,
3243
- /**
3244
- * THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
3245
- * own doors, `iam` for the trust doors (the external principal and the
3246
- * publish binding, which are the PLATFORM's). A host binding supabase-js
3247
- * routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
3248
- * ignores it calls its own default PostgREST profile — `public` — and is
3249
- * refused by name, which is the failure we want rather than a silent answer
3250
- * from the wrong system. (Before 2026-09-18 this was described as "only ever
3251
- * `iam`" and the store's doors went unqualified; the extension's first real
3252
- * turn proved that asks `public.store_is_open` and finds nothing.)
3253
- */
3254
- options?: {
3255
- schema?: string;
3256
- }): PromiseLike<{
3257
- data: unknown;
3258
- error: PgError | null;
3259
- }>;
3260
- /** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
3261
- schema(name: string): {
3262
- from(table: string): RecordsTableQuery;
3263
- };
3264
- }
3265
- /** The read surface the list and query paths use. A real supabase-js client satisfies it. */
3266
- interface RecordsTableQuery {
3267
- select(columns: string, options?: {
3268
- count?: "exact" | "planned" | "estimated";
3269
- head?: boolean;
3270
- }): RecordsFilter;
3271
- }
3272
- interface RecordsFilter extends PromiseLike<RecordsResponse> {
3273
- eq(column: string, value: unknown): RecordsFilter;
3274
- neq(column: string, value: unknown): RecordsFilter;
3275
- in(column: string, values: readonly unknown[]): RecordsFilter;
3276
- is(column: string, value: null | boolean): RecordsFilter;
3277
- gte(column: string, value: unknown): RecordsFilter;
3278
- lte(column: string, value: unknown): RecordsFilter;
3279
- order(column: string, options?: {
3280
- ascending?: boolean;
3281
- }): RecordsFilter;
3282
- range(from: number, to: number): RecordsFilter;
3283
- limit(count: number): RecordsFilter;
3284
- }
3285
- interface RecordsResponse {
3286
- data: unknown;
3287
- error: PgError | null;
3288
- count?: number | null;
3289
- }
3290
- /**
3291
- * WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
3292
- * operating it — there is no agent identity and there are no service roles. So
3293
- * the actor word and the person are two separate facts, and `on_behalf_of` is
3294
- * meaningful only when the actor is `agent`.
3295
- */
3296
- interface RecordsActor {
3297
- actor: Actor;
3298
- /** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
3299
- user_id?: Uuid;
3300
- /** Only an agent acts on behalf of a person (the store refuses it otherwise). */
3301
- on_behalf_of?: Uuid;
3302
- }
3303
- /**
3304
- * OPTIONAL. A live-updates seam. The default degradation is stated rather than
3305
- * silent: with no port bound, `useRecords` reports `live: false` and the screen
3306
- * can say "not live" instead of quietly going stale.
3307
- *
3308
- * A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
3309
- * deliberately does NOT depend on it, so the headless core stays free of a
3310
- * realtime client and a host that has one keeps using the one it already has.
3311
- */
3312
- interface RecordsRealtimePort {
3313
- /**
3314
- * Watch one organization's records of one table. Returns an unsubscribe.
3315
- *
3316
- * THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
3317
- * was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
3318
- * imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
3319
- * which worked, and which meant the port contract did not describe half of what a port
3320
- * actually does. A column appearing is not a row changing, and the package owns the
3321
- * difference.
3322
- *
3323
- * NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
3324
- * re-reads — by id set when the nudge names ids, whole-page when it cannot.
3325
- */
3326
- subscribeRecords(args: {
3327
- organization_id: Uuid;
3328
- table_id: Uuid;
3329
- }, sink: RecordsChangeSink): () => void;
3330
- }
3331
- /** What a realtime port may tell the package. Two calls, because a column is not a row. */
3332
- interface RecordsChangeSink {
3333
- /**
3334
- * THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
3335
- * a change above the store's own id cap — and is the one case that costs a whole-page read.
3336
- * An EMPTY array is not the same thing and is not a nudge at all.
3337
- */
3338
- records(ids: readonly Uuid[] | null): void;
3339
- /**
3340
- * THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
3341
- * redraw the same table without the new column in it, which is a screen that is out of date
3342
- * while looking healthy.
3343
- */
3344
- shape(): void;
3345
- }
3346
- /**
3347
- * OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
3348
- * Default degradation: `console.error` with the store's own words, never
3349
- * silence.
3350
- */
3351
- type RecordsErrorSink = (error: {
3352
- code: string;
3353
- message: string;
3354
- hint?: string;
3355
- where: string;
3356
- }) => void;
3357
- /**
3358
- * OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
3359
- * not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
3360
- * never a literal placeholder left in the text (DYN-14).
3361
- */
3362
- interface RecordsResolverPort {
3363
- resolve(args: {
3364
- organization_id: Uuid;
3365
- merge_field_keys: string[];
3366
- /** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
3367
- state?: Record<string, unknown>;
3368
- }): Promise<unknown>;
3369
- }
3370
- /** The one config a host binds. */
3371
- interface RecordsConfig {
3372
- /** REQUIRED. */
3373
- dataSource: RecordsDataSource;
3374
- /** REQUIRED. */
3375
- actor: RecordsActor;
3376
- /**
3377
- * REQUIRED. REC-29: organizations are hard walls, and the store is keyed
3378
- * `(organization_id, id)`. There is no "current organization" this package
3379
- * discovers for itself — the host says which one, every time.
3380
- */
3381
- organizationId: Uuid;
3382
- realtime?: RecordsRealtimePort;
3383
- onError?: RecordsErrorSink;
3384
- resolver?: RecordsResolverPort;
3385
- /**
3386
- * The schema the record store lives in. Exists so a rehearsal branch and
3387
- * production can differ without a fork; it is `custom` everywhere today.
3388
- */
3389
- schema?: string;
3390
- }
3391
-
3392
4022
  /**
3393
4023
  * THE CLIENT OPERATION LEDGER — how a browser recognises the echo of its own write.
3394
4024
  *
@@ -3542,4 +4172,4 @@ interface ConversationScopeContext {
3542
4172
  /** `About: Acme Industrial` — the chip a bound chat wears. */
3543
4173
  declare function scopeChip(scope: ConversationScope): string;
3544
4174
 
3545
- export { ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type ActionRefusal, type ActionRunResult, Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DecorationColor, type DecorationPath, type DecorationRule, type DecorationRuleOp, type DecorationTarget, Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type ExampleBuilt, type ExampleSpec, type ExternalPrincipalCard, FIELD_KINDS, Field, type FieldHistoryEntry, type FieldKind, type FormSummary, type FormulaParse, Freshness, type GridLayout, type GridLayoutMode, type GridRowHeight, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, type IoExportPage, type KernelTargets, type MergeField, MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, MergeFieldSemanticType, MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, OnDelete, OverridePolicy, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, ParityFieldType, type PermissionLevel, PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, ReadRow, type RecordChangeAction, type RecordComment, RecordDocument, type RecordEvent, type RecordFilter, type RecordHistoryEntry, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, RecordsError, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsTableQuery, type RegisteredTable, type Relation, RelationBinding, RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplaySpec, RelationFlavor, type RelationProperties, type RelationStore, type RelationTarget, type RelationWordsManyArgs, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RowAction, type RowActionStep, type Rule, type RuleAnswer, type RuleExpression, RuleNodeKind, RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, StorageMode, StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, type Table, type TableArchiveProgress, type TableCapacity, type TableDecorations, TableDisplay, TableOrigin, TableType, type TableWebhook, type TableWebhookDeclared, Timestamp, Uuid, type ViewLayout, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, actionRefusals, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, exampleSpec, exportPageXlsx, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, recordChangeTrigger, rememberedOpCount, sameDocument, scopeChip, stableFilterKey };
4175
+ export { ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type ActionRefusal, type ActionRunResult, Actor, type AggregateBucket, type AggregateCompare, type AggregateCompareKind, type AggregateCompareWindows, type AggregateDelta, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DashboardTarget, type DashboardTargetBase, type DashboardTargetOp, type DashboardTargetResult, type DashboardTotals, type DecorationColor, type DecorationPath, type DecorationRule, type DecorationRuleOp, type DecorationTarget, Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityRef, type EntityRefWithWords, type EntityReferenceKind, type EntityTableFacts, type ExampleBuilt, type ExampleSpec, type ExternalPrincipalCard, FIELD_KINDS, Field, type FieldHistoryEntry, type FieldKind, type FormSummary, type FormulaParse, Freshness, type GridLayout, type GridLayoutMode, type GridRowHeight, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, type IoExportPage, type KernelTargets, type MergeField, MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, MergeFieldSemanticType, MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, OnDelete, type OutsideShareAnswer, OverridePolicy, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PORTAL_ACCENTS, PORTAL_ARCHIVE_FILTERS, ParityFieldType, type PermissionLevel, PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveMany, type PipelineMoveManyItem, type PipelineMoveManyResult, type PipelineMoveResult, type PipelineMoveVerdict, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalAccent, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalConfig, type PortalConfigInput, type PortalFooterLink, type PortalFormAnswer, type PortalFormInput, type PortalFormRef, type PortalFormSpec, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalStage, type PortalStyle, type PortalStyleInput, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, ReadRow, type RecordChangeAction, type RecordComment, RecordDocument, type RecordEvent, type RecordFilter, type RecordHeader, type RecordHistoryEntry, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, RecordsError, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, RelationBinding, RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplaySpec, RelationFlavor, type RelationProperties, type RelationStore, type RelationTarget, type RelationWordsManyArgs, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RowAction, type RowActionStep, type Rule, type RuleAnswer, type RuleExpression, RuleNodeKind, RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, StorageMode, type StoreFilter, StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, type Table, type TableArchiveProgress, type TableCapacity, type TableDecorations, TableDisplay, type TableListEntry, TableOrigin, type TablePlacement, type TablePlacementFact, type TableRowCount, type TableSyncResult, type TableSyncSource, type TableSyncSpec, TableType, type TableWebhook, type TableWebhookDeclared, Timestamp, Uuid, type ViewLayout, type ViewOrderSet, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDecideMany, type WorkDecideManyItem, type WorkDecideManyResult, type WorkDecideVerdict, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, actionRefusals, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, entityReferenceKinds, entityReferenceKindsOf, entityReferenceWords, entityRefsOf, entityRefsToWrite, exampleSpec, exportPageXlsx, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isEntityReferenceConfig, isOwnOp, isPortalAccent, isPortalArchiveFilter, isRuleFilter, isTheChosen, keptGroups, keptOutOfSight, keptTableHref, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, moveInOrder, offeredAsContext, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, recordChangeTrigger, rememberedOpCount, sameDocument, scopeChip, sheetSyncSpec, stableFilterKey, withRowCounts, withTablePlacement };