Skip to content

Commit a69a40a

Browse files
feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places (#23708)
Part of #23610 Clause-②: yes (narrowing) Executes ruling `6190536588` items 1, 2 and 3 (Q1 A · Q2 A, plus half 1) under claim `6194235384`. Item 4 (`skills/objectstack-ui/rules/pages.md`) is a separate Tier H PR (claim `6204703954`). That PR carries the card's closing keyword, so this one is `Part of` and the card closes with its last piece; item 5's follow-ups (the objectui card, the hotcrm memo) belong to the director seat. One PR, not split: +1055/−100 across 33 files after patch round 2 (pin bump included), generated artifacts included, about two of precedent #23331's size for two refusals, as the ruling's workload line estimated. ## What changes **Q1 — `isDefault: true` off a record page bound to an object is refused at every door.** One sentence, `misplacedDefaultPageRefusal` (`packages/spec/src/ui/default-record-page.ts`, next to `defaultRecordPageObject`, whose reading it reuses — no second judge). It names where a landing is really set: the app's first navigation item, and the app's own `isDefault` for the root landing. A record page with no `object` gets the bind-the-object variant. **Q2 — `template` closes and each template declares its slots.** `PageTemplateSchema` = `default`, `header-sidebar-main`, `three-column`, `dashboard`; `full-width` is retired by name through `enumWithRetiredValues` (prescription: use `default`, renders the same). `PAGE_TEMPLATE_SLOTS` declares the slots per the ruling; `PAGE_TEMPLATE_OPEN_GRID` = `dashboard`. `checkPageRegionPlacement` refuses, at `regions.N.name`, a region the template does not place, naming the template's slots and a rename hint (`left_sidebar` to `sidebar`, `right_sidebar` to `aside`, `content` to `main`). Judged on `kind: 'full'` pages only (a `slotted` page renders its `slots`, `html` / `react` their `source`) and case-insensitively, as the renderer's `findRegion` is. A second region that fills a slot an earlier region already fills is refused the same way, naming the region that fills it, because `findRegion` places the first match only. This came in the seat's patch round (record `6199121442` item 2). On `dashboard`, a second `header` or `footer` is refused; two regions of any other name stay two grid cells. **Half 1 — the text says what runs.** `PageTypeSchema`'s docblock and enum comments: `home`, `app` and `utility` are one region layout at three content widths; `home` is not a landing declaration; `utility` is an ordinary inline page with no floating or docked shell slot, and stays a type because the print door and the page-type width read it. The `print`-on-`utility` refusal no longer says "floating panel" (its pin in `page-print.test.ts` now also asserts the word is gone). `content/docs/ui/pages.mdx` (page types, a Templates table, the `isDefault` row, the region snippet's `content` to `main`), and the liveness `type`, `template`, `regions`, `isDefault` rows (re-read at objectui `0656b0e3c0`). ## Door by door (PM mechanism assumption 1, measured) | Door | Goes through `PageSchema`? | What this PR does there | Reading | | :--- | :--- | :--- | :--- | | `definePage` / `defineStack` (`stack.zod.ts`, `pages: z.array(PageSchema)`), so `os validate` / `os build` | yes | nothing — the two new `superRefine`s refuse | `STACK_SCHEMA_INVALID` 422 at `pages.N.isDefault` / `pages.N.template` / `pages.N.regions.M.name` (`page-default-and-region-placement.test.ts`, `stack-default-record-page.test.ts`) | | metadata save door (`saveMetaItem`, `getMetadataTypeSchema('page')`) | yes | nothing | `422 INVALID_METADATA`, nothing stored, both topologies (`default-record-page-save-door.test.ts`) | | package registration, package door (`SchemaRegistry.installPackage`) | **no** — the registry parses only object / app / package / plugin bodies | `refuseDefaultRecordPageConflicts` first refuses misplaced defaults (`misplacedDefaultPages`, same sources as `declaredDefaultRecordPages`, nested `plugins[]` included), ahead of every mutation | `MisplacedDefaultPageError`, `INVALID_METADATA` 422 (existing code, no new one), no package record left (`registry-default-record-page.test.ts`) | | package registration, item seam (`registerItem` with a `packageId`) | **no** | refuses before the holder check | same envelope | | bare slot (`registerItem` with no package: `sys_metadata` hydration) | — | not judged, by the door's existing design | pinned as a control | | `core` `stack-organization-record-page.ts` | n/a — a reader of `defaultRecordPageObject`, not a door | unchanged | `core` suite green | Q2's refusals are parse-only (the ruling names `os validate` and save), so the registry carries no template or region judgement. ## Stored metadata (assumption 4, measured) No D2 conversion touches these shapes and the read path does not refuse them: a `sys_metadata` page row laid in the store with a non-record `isDefault: true`, `template: 'full-width'` or a `left_sidebar` region is served by `getMetaItem` unchanged, on both the environment-scoped and the host-config kernel; saving it again answers 422. `applyConversionsToStoredItem` returns each row byte-equal with zero notices, and the parse still refuses it. The changeset's "Stored metadata keeps loading" paragraph states exactly this. ## First-party writers (assumption 5) - `examples/app-showcase/src/ui/pages/capability-map.page.ts` drops `isDefault: true`; it stays the landing as the first `ShowcaseApp.navigation` item. - `content/docs/protocol/objectui/layout-dsl.mdx`: three `os:check-yaml` pages named `template: standard` / `console` (with `left` / `right` regions), red under `check:yaml-examples` — now `default` and `header-sidebar-main` with `sidebar` / `main`; the callouts that called `template` a free-form string are corrected. - `examples/app-showcase/src/ui/pages/task-visualizations.pages.ts`: its shared base held `template: 'default'` as a widened `string` and stopped type-checking against the closed set (+7 root-program errors under `check:type-check-debt`); now `as const`. The changeset carries the same one-line migration for consumers. - No first-party page wrote `full-width` or an unplaced region in source. Census: `full-width` in two test fixtures only; every `regions` entry in `examples/**`, `packages/**`, `content/docs/**` read by name (main 226, header 40, sidebar 9, footer 4, aside 1, the rest test-only). Fixture triage (rule's consumption radius, not the edited package): - **Replaced** (pinned exactly the removed branch): `stack-default-record-page.test.ts` "an isDefault page that is not a record page is outside the rule", `registry-default-record-page.test.ts` same, `default-record-page-save-door.test.ts` same — each now asserts the refusal, with a no-flag control beside it. `page.test.ts` "should accept page with custom template" (`three-column-layout`) and "should accept default page" (no `object`). - **Respelled**: the two `buildDefaultPageSchema` seed fixtures (`spec` and `lint` `*-22537.test.ts`) from `full-width` to `default`, with a note. - **Re-anchored**: `expression-scope-app-root.pin.test.ts`'s LIT control quoted the old page-type sentence. - **Extended**: `object-refinement-check-exports.test.ts` catalogues the two new checks (bijection, attached-by-identifier, barrel identity). ## Renderer premise (assumption 3, re-read) objectui `main` at `0656b0e3c0` (and the sparse read at `2bacbf08b4`): `TEMPLATE_REGISTRY` still holds `default`, `full-width`, `header-sidebar-main`, `three-column`, `dashboard`; `default` and `full-width` are the same `FullWidthTemplate`, so **no rendering fork** and nothing was posted on the card for it. Slots match the ruling's table; `findRegion` is case-insensitive, which this PR follows. **One premise did not hold — "zero first-party writers" of `full-width`.** objectui's `packages/plugin-detail/src/synth/buildDefaultPageSchema.ts` returns `template: 'full-width'`, and Studio's record-page create seed (`app-shell/src/views/metadata-admin/anchors.ts`, `createSeed`) copies it into the page it saves. Retirement proceeds as ruled (identical rendering, no alias window), but that seed must say `default` before or with the pin bump that ships this, or a Studio "new record page" save answers 422. objectui's `PageNodeSchema` also redeclared `template` as `string` over the spec member, which is TS2430 against this spec (measured on a mirror, report `6200739195`). Both are fixed in objectstack-ai/objectui#12585, the sibling fix that AGENTS.md (Post-Task Checklist step 4) ships with this PR. ## Ledger Two D3 entries, `page-is-default-off-record-page-refused` and `page-template-closed-region-unplaced-refused`; no D2 conversion (ruling: no grace or alias window); no tombstone (no key removed). No `STEP18_RATIONALE` fragment was added: neither precedent entry for `isDefault` carried one, and draft PR #23418 is editing `registry.ts.template`. BREAKING changeset `.changeset/23610-page-isdefault-template-slots.md`: `@objectstack/spec` minor, `@objectstack/objectql` patch, ADR-0087 marker `registered` naming both ids. New exports regenerate `api-surface/`, `export-origins/`, `declaration-map/` and `content/docs/references/`. The template block sits after `PageComponentSchema` on purpose, so `skills/objectstack-ui/references/_index.md` (first five exports of the file) stays byte-identical and no `skills/**` path enters this PR. ## Verification (final head `4815bfa99`, after merging `origin/main` `f77ba411e`) - `@objectstack/spec`: 742 files / 21,868 tests passed. `check:generated`: all 14 artifacts current. - Downstream consumers of the narrowed schema, all green: `objectql` 8,157, `metadata-protocol` 20,560 (19 skipped), `core` 2,586, `lint` 6,771, `metadata-core` 728, `platform-objects` 1,091, `plugin-approvals` 1,080, `cloud-connection` 555, `mcp` 467, `downstream-contract` 31, `example-showcase` 411, `example-crm` 46, `cli` unit 4,354 (integration layer declared to CI). `objectql`, `metadata-protocol`, `example-showcase` re-run on the final head after the merge. - `typecheck` green for spec, objectql, metadata-protocol, core, lint, cli, platform-objects, plugin-approvals, cloud-connection, mcp, downstream-contract, example-showcase, example-crm; root program back to its ledger's 26. - Derived gates (`dispatch-gates --commands`, 119 families) on the final head: all exit 0; `--ran` reconciliation "119 derived, 119 run, 0 NOT-MEASURED (a DERIVED zero)". Two families first refused on the shallow clone (`check-engine-split-ratio`, `check-plugin-teardown-shape --self-test`) and passed after the deepening they prescribe. Local-only: `check:dev-prereqs` 0, `check:skill-frame-freshness` 0. - Ablations (each through `ablation-replace.mjs`, mutation proven on disk, restore proven by an empty `git diff HEAD`): drop `checkPageDefaultPlacement` 8 red; drop `checkPageRegionPlacement` 4 red; `template` back to `z.string()` 5 red; drop the package-door throw 1 red (the item seam still catches the top-level pages; the nested-plugin and no-record pin goes red); drop the item-seam throw 1 red. - Reverse type verification: `template: 'full-width'` in a showcase page gives `TS2322 … not assignable to type '"dashboard" | "default" | "header-sidebar-main" | "three-column"'`, so the rebuilt `.d.ts` was read. ## Landing order 1. Done: objectstack-ai/objectui#12585 merged on objectui `main` as `daeb77fc84dd`. The Studio record-page seed says `default`, and `PageNodeSchema.template` takes the spec's type in both the TS and zod faces. 2. Done (patch round 2, head `d36a804054`): - The branch merged `main` at `140238a47b`, after #23738 had moved the pin to `f96f771140f1`. - `scripts/bump-objectui.sh` moved `.objectui-sha` forward to `daeb77fc84dd`, which carries #12585, and wrote `.changeset/console-daeb77fc84dd.md` (`@objectstack/console`: minor). - `scripts/sdui-manifest.record.json` and `packages/sdui-parser/objectui-lockstep.json` are re-recorded at the new pin. `sdui.manifest.json` is byte-unchanged, and the lockstep needs no port. 3. Done: the new head has its delta contract-review record, PASS `6206263948` (the full PASS `6204434889` on `c2b9935b4` stands for everything it judged). The seat then marks this PR ready. 4. After this PR merges, the Tier H PR #23758 (ruling item 4, `Fixes #23610`) is marked ready, and #23776 (#23710) merges `main` and lands after it (landing-operations D). ## Patch round (head `c2b9935b4`, `origin/main` `8c85141c5` merged) - `@objectstack/spec`: 742 files / 21,876 tests passed. The downstream consumer set is unchanged and green. The duplicate-slot ablation (the branch never fires) gives 6 red of 285; restored. - `dispatch-gates --commands`: 119 families, 119 exit 0 (two `PREREQUISITE NOT MET` exits on a fresh worktree passed after the full build). `check:generated` 14/14. CI on `c2b9935b4`: 41 check-runs, 36 success, 5 skipped. ## Acceptance notes - Two regions filling the same slot (two `main`) were accepted and the second was dropped by the renderer. They are now refused in this PR (patch round, `c2b9935b4`). - `skills/objectstack-ui/rules/pages.md` rows for the Tier H follow-up are listed in the dispatch report on #23610. --- _Generated by [Claude Code](https://claude.ai/code/session_01TC6DKN349m4i7okGWPe4RG)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0b1179f commit a69a40a

33 files changed

Lines changed: 1055 additions & 100 deletions
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@objectstack/objectql': patch
4+
---
5+
6+
feat(spec)!: a page declares nothing the console does not honour — `isDefault: true` is refused off a record page bound to an object, `template` closes to the registered layouts, and a region the template does not place is refused
7+
8+
Clause-②: yes (narrowing)
9+
10+
**BREAKING (authoring):** two accept sets of `PageSchema` narrow to what the console runs, and the `PageTypeSchema` text stops promising what it does not.
11+
12+
| Writing | Before | Now |
13+
| :--- | :--- | :--- |
14+
| `isDefault: true` on a `home`, `app`, `utility` or `list` page, or on a record page with no `object` | accepted, stored and served; nothing read it | refused at `isDefault` — by `definePage`, `defineStack` (so `os validate` and `os build`, `STACK_SCHEMA_INVALID` 422), the metadata save door (`422 INVALID_METADATA`) and package registration (`SchemaRegistry.installPackage` / `registerItem`, `422 INVALID_METADATA`) |
15+
| `template: 'full-width'` | accepted; drawn exactly as `default` | refused by name: "Page `template: 'full-width'` was removed in @objectstack/spec 18 … Use `template: 'default'`" |
16+
| any other `template` outside `default`, `header-sidebar-main`, `three-column`, `dashboard` (`two-column`, `single-column`, …) | accepted; drawn as the page type's default layout | refused at `template` |
17+
| on a `kind: 'full'` page, a region its template does not place (`left_sidebar`, `right_sidebar`, `content`, …) | accepted; stacked under `main` at full width, its `width` ignored | refused at `regions.N.name`, naming the template's slots and the rename |
18+
| on a `kind: 'full'` page, a second region filling a slot an earlier one fills (two `main` regions; on `dashboard`, a second `header` or `footer`) | accepted; not drawn at all — the console draws the first region of a name and leaves that name out of the rest | refused at `regions.N.name`, naming the region that already fills the slot |
19+
20+
Migration:
21+
22+
- **`isDefault` on a non-record page** → delete it. A page does not choose where an app opens: an app's landing page is its **first navigation item** (by `order`), so to land on the page put its entry first in the app's `navigation`; the root landing follows the app's own `isDefault`. A record page meant as an object's default record page binds that object with `object`.
23+
- **`template: 'full-width'`** → `template: 'default'` (or delete the key — `default` is the default). The page renders exactly as before.
24+
- **A `template` held in a widened `string`** (a shared base object, `{ template: 'default' }` spread into `definePage`) no longer type-checks against the closed set → `template: 'default' as const`.
25+
- **An unregistered template** → one of `default` (header, sidebar, main, aside, footer), `header-sidebar-main` (header, sidebar, main), `three-column` (header, sidebar, main, aside, footer) or `dashboard` (header, footer, and every other region a grid cell).
26+
- **An unplaced region** → name it for the slot it fills: `left_sidebar` → `sidebar`, `right_sidebar` → `aside`, `content` → `main`; or choose `dashboard` when the regions are a grid. Names match case-insensitively, as the console's do. `slotted`, `html` and `react` pages are not judged on region names.
27+
- **A second region for a filled slot** → move its components into the first region of that name, or name it for an unfilled slot. On `dashboard`, two regions of any other one name stay two grid cells and are accepted.
28+
29+
The template set and each template's slots are now published: `PageTemplateSchema`, `PAGE_TEMPLATE_SLOTS` and `PAGE_TEMPLATE_OPEN_GRID` (`@objectstack/spec/ui`), with the two checks `checkPageDefaultPlacement` and `checkPageRegionPlacement` and the one refusal sentence `misplacedDefaultPageRefusal` that the parse and the registry share.
30+
31+
`os migrate meta` lists both as hand edits — the D3 entries `page-is-default-off-record-page-refused` and `page-template-closed-region-unplaced-refused`. No D2 conversion rewrites them: where an app opens, and which slot a region fills, are the author's calls.
32+
33+
**Stored metadata keeps loading.** No conversion touches these shapes and the read path does not refuse them, so a `sys_metadata` page row already stored with a non-record `isDefault: true`, `template: 'full-width'` or an unplaced region is served unchanged and renders as before (a stored row hydrates into the registry without a package, so the registry does not judge it either). Saving such a row again through the metadata API is refused until it is fixed.
34+
35+
The text, without a contract change: `PageTypeSchema`'s docblock and enum comments now say that `home`, `app` and `utility` are the same region layout at three content widths — `home` is not a landing declaration, and `utility` is an ordinary inline page (the console has no floating or docked shell slot for it); `utility` stays a page type, read by the print door and the page-type width. The `print`-on-`utility` refusal no longer calls a utility page "a floating panel".
36+
37+
`@objectstack/objectql`: the registry refuses `isDefault: true` on a non-record page a package registers (`MisplacedDefaultPageError`, `INVALID_METADATA` 422), at the package door and at the package-bound item seam, with the page parse's sentence.
38+
39+
<!-- adr-0087: registered page-is-default-off-record-page-refused, page-template-closed-region-unplaced-refused -->

‎.changeset/console-daeb77fc84dd.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@objectstack/console": minor
3+
---
4+
5+
Console (objectui) refreshed to `daeb77fc84dd`. Frontend changes in this range:
6+
7+
Derived from the changesets objectui declared over the range — 4 releasing of 4 changesets added across 5 non-merge commits; omitted: 1 commit carrying no changeset (they ship no package code).
8+
9+
- **minor** — Studio, Interfaces pillar: an html or react page reads like a code page. The source editor's plain-text fallback numbers its lines and wraps long ones as the code editor does, and… (objectui `830eb1f2d`)
10+
- **patch** — A new record page seeded in Studio is saved with the `default` layout template instead of `full-width`, and the page node's `template` member is typed by reference to the spec's (… (objectui `daeb77fc8`)
11+
- **patch** — Two Studio pickers are named by the labels shown beside them (objectui#12510). Nothing changes on screen. (objectui `3e09c1e8d`)
12+
- **patch** — Studio's empty surfaces now carry the action that fills them (objectui#12514). (objectui `f23eb01cb`)
13+
14+
**In this console build, declared nowhere** — objectui merged 1 commit in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared it, so it appears in no objectui CHANGELOG and in no entry above. Listed by subject rather than counted, because a count cannot tell a dependency bump from a form-behaviour change (objectstack#6174); the upstream gate that would prevent this is objectui#3387.
15+
16+
- _(no changeset)_ docs(studio-redesign): move the 61 PR screenshots under after/ to an evidence branch and remove them from main (#12583) (objectui `7066dae53`)
17+
18+
objectui range: `f96f771140f1...daeb77fc84dd`

‎.objectui-sha‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f96f771140f1ba488245e0d0d3e7420d720bff9a
1+
daeb77fc84dd824e74c95b87cdede85afdb248e7

‎content/docs/protocol/objectui/layout-dsl.mdx‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,15 @@ Page
7272

7373
## Page Templates
7474

75-
Top-level layout structures that define macro organization.
75+
Top-level layout structures that define macro organization. `template` is one of the
76+
layouts the console registers — `default` (`header`, `sidebar`, `main`, `aside`,
77+
`footer`), `header-sidebar-main` (`header`, `sidebar`, `main`), `three-column` (the same
78+
five as `default`) or `dashboard` (`header`, `footer`, and every other region a grid cell)
79+
— and each region's `name` is a slot that template places. Any other template name, and
80+
on a `kind: 'full'` page any region name the template does not place, is refused when the
81+
page is parsed (`os validate`, `os build`, the metadata save door): the console would draw
82+
an unregistered template as the default layout, and stack an unplaced region under `main`
83+
at full width with its `width` ignored.
7684

7785
### Standard Template
7886

@@ -102,7 +110,7 @@ name: account_record
102110
label: Account Record Page
103111
type: record
104112
object: account
105-
template: standard
113+
template: default
106114
regions:
107115
- name: header
108116
components:
@@ -150,22 +158,23 @@ regions:
150158

151159
High-density layout for power users (like Salesforce Service Console).
152160

161+
It is the `header-sidebar-main` template: the list in `sidebar`, the record in `main`.
162+
153163
{/* os:check-yaml page */}
154164
```yaml
155165
name: service_console
156166
label: Service Console
157167
type: app
158-
template: console
168+
template: header-sidebar-main
159169
regions:
160-
- name: left
170+
- name: sidebar
161171
width: small
162172
components:
163173
- type: object-grid
164174
properties:
165175
objectName: case
166176

167-
- name: right
168-
width: full
177+
- name: main
169178
components:
170179
- type: page:tabs
171180
properties:
@@ -218,9 +227,8 @@ regions:
218227
a matching `Multi-Step Onboarding Wizard` example further down. **`steps` exists
219228
on no schema.** `PageSchema` is `.strict()`, so it is refused by name
220229
(`Unrecognized key(s) on this page: steps`), and no other shape in the spec
221-
declares it either. `template: wizard` compounds it quietly: `template` is a
222-
free-form string, so that half *parses* while naming a layout template no
223-
renderer provides.
230+
declares it either. `template: wizard` is refused as well: `template` names
231+
one of the layouts the console registers, and no renderer provides a wizard.
224232

225233
Both are **removed rather than implemented** — multi-step authoring is an
226234
implementation card first, exactly like the deferred tab loading and the
@@ -757,7 +765,7 @@ properties:
757765
**There is no page-level `layout:` block.** Earlier revisions of this page
758766
described three advanced layouts as a top-level `layout:` mapping —
759767
`split_view`, `card_grid` and `kanban`. On `PageSchema`, `layout` is an
760-
**alias for `template`**, a plain string naming a layout template, so a mapping
768+
**alias for `template`**, which names one of the registered layout templates, so a mapping
761769
written there is refused with exactly that rename hint (`Did you mean layout →
762770
template?`). None of `split_view`, `card_grid`, `list_view` or `detail_view` is
763771
a type on any schema.
@@ -843,12 +851,12 @@ interface Page {
843851
// ever shipped). They live in PAGE_TYPE_ROADMAP; authoring one now fails
844852
// validation. See page.zod.ts (PageTypeSchema / PAGE_TYPE_ROADMAP).
845853
object?: string; // bound object for record pages
846-
template?: string; // layout template name, default 'default'
854+
template?: 'default' | 'header-sidebar-main' | 'three-column' | 'dashboard'; // default 'default'
847855
regions?: PageRegion[]; // named regions, each holding components (optional; defaults to [])
848856
}
849857
850858
interface PageRegion {
851-
name: string; // e.g. "header", "main", "sidebar"
859+
name: string; // a slot the page's template places: header, sidebar, main, aside, footer
852860
width?: 'small' | 'medium' | 'large' | 'full';
853861
components: PageComponent[];
854862
}
@@ -1016,7 +1024,7 @@ name: customer_360
10161024
label: Customer 360
10171025
type: record
10181026
object: customer
1019-
template: standard
1027+
template: default
10201028
regions:
10211029
- name: header
10221030
components:

‎content/docs/references/index.mdx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Protocol reference — every schema by module
33
navTitle: Protocol Reference
4-
description: Every schema published by @objectstack/spec — 1535 schemas across 14 protocol modules
4+
description: Every schema published by @objectstack/spec — 1536 schemas across 14 protocol modules
55
---
66

77
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -33,8 +33,8 @@ counts are sums of the rows they head. Regenerate with
3333
| [Shared Protocol](/docs/references/shared) | 10 | 31 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
3434
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
3535
| [System Protocol](/docs/references/system) | 36 | 284 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
36-
| [UI Protocol](/docs/references/ui) | 16 | 167 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
37-
| **Total** | **197** | **1535** | 14 protocol modules |
36+
| [UI Protocol](/docs/references/ui) | 16 | 168 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
37+
| **Total** | **197** | **1536** | 14 protocol modules |
3838

3939
---
4040

@@ -364,7 +364,7 @@ The runtime environment — logging, jobs, cache, metrics, notifications, i18n a
364364

365365
## UI Protocol
366366

367-
**Source:** `packages/spec/src/ui/` · **Import:** `@objectstack/spec/ui` · **16 pages, 167 schemas**
367+
**Source:** `packages/spec/src/ui/` · **Import:** `@objectstack/spec/ui` · **16 pages, 168 schemas**
368368

369369
Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer.
370370

@@ -381,7 +381,7 @@ Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI lay
381381
| [`expression-bindable-text-keys.zod.ts`](/docs/references/ui/expression-bindable-text-keys) | `ExpressionBindableTextKey` |
382382
| [`i18n.zod.ts`](/docs/references/ui/i18n) | `AriaProps`, `I18nLabel`, `InlineLocaleMap` |
383383
| [`notification.zod.ts`](/docs/references/ui/notification) | `NotificationPosition`, `NotificationSeverity`, `NotificationType` |
384-
| [`page.zod.ts`](/docs/references/ui/page) | `ElementApiDataSource`, `ElementDataSource`, `InterfacePageConfig`, `Page`, `PageComponent`, `PageComponentType`, `PagePrint`, `PageRegion`, `PageType`, `PageVariable` |
384+
| [`page.zod.ts`](/docs/references/ui/page) | `ElementApiDataSource`, `ElementDataSource`, `InterfacePageConfig`, `Page`, `PageComponent`, `PageComponentType`, `PagePrint`, `PageRegion`, `PageTemplate`, `PageType`, `PageVariable` |
385385
| [`report.zod.ts`](/docs/references/ui/report) | `JoinedReportBlock`, `Report`, `ReportChart`, `ReportSort`, `ReportType` |
386386
| [`responsive.zod.ts`](/docs/references/ui/responsive) | `ResponsiveStyles`, `StyleMap` |
387387
| [`sharing.zod.ts`](/docs/references/ui/sharing) | `SharingConfig` |

0 commit comments

Comments
 (0)