Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .changeset/console-2e818d0b51ec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
"@objectstack/console": minor
---

Console (objectui) refreshed to `2e818d0b51ec`. Frontend changes in this range:

Derived from the changesets objectui declared over the range — 17 releasing of 18 changesets added across 22 non-merge commits; omitted: 1 release-nothing changeset, 6 commits carrying no changeset (they ship no package code).

- **minor** — `FlexBlockNode`, the TypeScript type of an authored `flex` node, types its bag's child list as nodes: `properties.children` is `SchemaNode | SchemaNode[]`, where it was `unknown[]… (objectui `b10c68e58`)
- **minor** — The dashboards' metric card node, `plugin-dashboard:metric`, is a declared node type, and both dashboard surfaces hand `SchemaRenderer` declared nodes with no cast (objectui#11466… (objectui `83e3f8377`)
- **minor** — **BREAKING** — **An `object-metric` node in a dashboard widget's legacy `component` envelope now draws the retired-format prompt instead of its number (objectui#11466).** This follows the mainta… (objectui `83e3f8377`)
- **minor** — **BREAKING** — A node slot and `SchemaRenderer`'s `schema` prop take the union of the declared node types, `DeclaredNode` (objectui#11466). (objectui `83e3f8377`)
- **minor** — `safeValidateSchema`, and so `objectui validate`, accepts `record:line_items`, the last ADR-0080 public block it refused at `type` (objectui#10872). `@objectstack/spec` 17.6.0 car… (objectui `8d0ca9183`)
- **minor** — `ObjectKanbanSchema.grouping` is declared on both faces, as `@objectstack/spec`'s `GroupingConfig`, by reference (objectui#11216). (objectui `a7557a7d4`)
- **patch** — The dashboard surfaces read every `widgets[]` entry without leaning on `BaseSchema`'s index signature: a widget key is read on the widget arm alone, and the `chart` node is built… (objectui `2e818d0b5`)
- **patch** — A refused save, pin, reorder, view setting, report save, publish or discard in the console is now said to the user, and the view-config panel no longer reports a refused save as s… (objectui `e8c0b9614`)
- **patch** — The `object-grid` summary footer reads `currency`, `defaultCurrency`, `precision` and `scale` from the object field only. A column that carries one of these keys no longer changes… (objectui `d768c3178`)
- **patch** — fix(types): `AnyComponentSchema`'s declaration prints every category union by name, so `@object-ui/types` no longer sits at the edge of TypeScript's serialization ceiling (objectu… (objectui `bdc9049ed`)
- **patch** — "Save as view" now saves a Kanban view the platform accepts, and both Create View doors save the same view from the same dialog choices (objectui#11581). (objectui `b65aa5e65`)
- **patch** — The console and runner stylesheets compile only from their declared `@source` lines. Tailwind's automatic source detection is now off (`source(none)`), as it already was for `@obj… (objectui `5a2ca6b12`)
- **patch** — A refused view save is now said to the user, and the Create View dialog no longer closes as if the view were saved (objectui#11578). (objectui `f1c937966`)
- **patch** — The console's Create View dialog now creates chart views the platform accepts (objectui#11576). (objectui `d0097af2e`)
- **patch** — fix(plugin-grid): switching a server-grouped grid's grouping field shows exactly the new field's groups (objectui `2f54dca53`)
- **patch** — fix(app-shell): an interface page relays its source view's `tree` and `chart` blocks, and its own `allowPrinting` (objectui#11572) (objectui `09036173c`)
- **patch** — A stored list view now renders the same on an interface page and on the object page when it carries a legacy `options` bag (objectui#10380). (objectui `068564691`)

⚠️ 2 of these carry a breaking change: 2 by the author's own breaking annotation in the changeset body — objectui declares no `major` inside a launch window (`scripts/check-changeset-no-major.mjs`). Each is marked **BREAKING** in the list above — read them before compiling the release record.

**In this console build, declared nowhere** — objectui merged 6 commits in this range with no `.changeset/*.md`. The code is inside the pin above and ships here, but nothing upstream declared them, so they appear 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.

- _(no changeset)_ fix(release): the publish lane pushes the version's git tags and creates its GitHub Releases itself — changesets/action@v1 finds no `New tag:` line under CLI v3 (objectui#11596) (… (objectui `973fc20f3`)
- _(no changeset)_ docs(skills): `schema-expressions.md` states `{ condition, style }` as the only authorable conditional-formatting rule on every list carrier (objectui#11534) (#11595) (objectui `94985a92b`)
- _(no changeset)_ chore: release packages (#5400) (objectui `b493919c7`)
- _(no changeset)_ docs(plugin-detail): the reference-rail README says `entries` go in the `properties` bag, and that the validator refuses a flat one (objectui#10872) (#11584) (objectui `7a7660c65`)
- _(no changeset)_ docs(skills): the page-builder guide's object-form example names its fields; a per-form override goes on a section entry (objectui#11550) (#11561) (objectui `0a53c67f9`)
- _(no changeset)_ docs(skills): type three marked fences' schema as SchemaRendererProps['schema'] (objectui#11543) (#11558) (objectui `5cde2c6fe`)

<!-- adr-0087: not-required (no-migration-prescription)
This diff moves `.objectui-sha` and the artefacts that travel with it: this console
changeset, `scripts/sdui-manifest.record.json` (the regenerated `sdui.manifest.json` is
byte-identical: 107 components, sha256 `0ead67c1111d…` at both pins), the re-recorded
`packages/sdui-parser/objectui-lockstep.json` and the re-measured pin citations in
`packages/spec/src`, which carry their own `@objectstack/spec` patch changeset. It adds,
removes or renames no ObjectStack-authorable key: no Zod schema, no spec declaration and
no stored `sys_metadata` shape moves in it, so `objectstack migrate meta` has nothing here
to rewrite, and this body carries no FROM/TO prescription of its own.
The 2 declared-breaking entries listed above are both objectui#11466 (`83e3f8377`, the
range's one `!` commit, measured with `git log ab1879721595..2e818d0b51ec`) and both are
objectui's OWN package surfaces, each already carrying its upstream record: (1) a node
slot and `SchemaRenderer`'s `schema` prop take objectui's `DeclaredNode` union, a
TypeScript type of `@object-ui/types` / `@object-ui/react` that no ObjectStack schema
declares or references; (2) an `object-metric` node inside a dashboard widget's legacy
`component` envelope draws objectui's retired-format prompt instead of its number. That
envelope is not ObjectStack-authorable: `ui/dashboard.zod.ts` refuses a widget's
`component` key by name as an objectui-internal renderer capability, so no stored
ObjectStack dashboard can carry the form being retired, and no example in this repo
authors one (the showcase's `object-metric` tiles are page blocks, which this entry
leaves drawing). Where an entry mirrors an ObjectStack key, the ledger entry belongs to
the `packages/spec` PR that lands the retirement, never to the pin bump.
Scope of the claim, stated rather than implied: it is a claim about THIS diff, not a
per-entry re-measurement of the 2 upstream declared-breaking entries.
-->

objectui range: `ab1879721595...2e818d0b51ec`
18 changes: 18 additions & 0 deletions .changeset/objectui-pin-citations-2e818d0b51ec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@objectstack/spec': patch
---

The spec's objectui citations, and the shipped description text that names the `.objectui-sha` pin (the `FormField.span` describe and six migration-entry descriptions), are re-measured against the new console pin, objectui `2e818d0b51ec`.

Clause-②: no

Every anchor was mapped through the objectui diff `ab1879721595..2e818d0b51ec`. Every file a current anchor cites is byte-identical across the hop except four, and in those the cited text is byte-identical too:

- `plugin-dashboard/src/index.tsx`: objectui#11466 added lines above the `object-metric` registration, so the `object-metric` icon input record moves from `:269` to `:281`. It is still `{ name: 'icon', type: 'string' }`.
- `packages/types/src/objectql.ts`: objectui#11216 declared `grouping` on `ObjectKanbanSchema` below the cited `limit` member.
- `plugin-kanban.mdx`: objectui#11216 added a `grouping` row below the cited `limit` row.
- `SchemaRenderer.tsx`: objectui#11466 changed the type of `schema`. Its `properties.*` hoist and `createElement` spread are unchanged.

The six migration entries' corpus counts were re-taken with `git grep -o -F`, the method that reproduces the previous pin's numbers. objectui's 17.7.0 release removed 2726 consumed changesets, so the corpus is now 7579 tracked files. Every zero still reads zero.

No key, default, enum member or export moves.
2 changes: 1 addition & 1 deletion .objectui-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ab187972159583b595facdcae3c73b50f6f312e9
2e818d0b51ecdf8fdd9fcbf4b916bcd7fe9a9cf6
4 changes: 2 additions & 2 deletions content/docs/references/ui/view.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Column footer summary configuration
| **required** | `boolean` | optional | Required override |
| **hidden** | `boolean` | optional | Hidden override |
| **colSpan** | `integer` | optional | Absolute column span (1-4). The renderer clamps it to the form grid's current column count, so the cell starts at a real column boundary at every surface width and never overflows (`colSpan: 4` in a 3-column grid renders as 3); a `colSpan` within the column count renders as authored, and `colSpan: 1` emits no span class at all. |
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `ab1879721595`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `2e818d0b51ec`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
| **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) |
| **language** | `string` | optional | Code editor language (for type=code) |
| **keyField** | `{ field?: string; label?: string \| Record<string, string>; placeholder?: string \| Record<string, string>; helpText?: string \| Record<string, string>; … }` | optional | Key column config for record-typed fields |
Expand Down Expand Up @@ -343,7 +343,7 @@ Form-view select option — the object-field option shape minus the per-option `
| **required** | `boolean` | optional | Required override |
| **hidden** | `boolean` | optional | Hidden override |
| **colSpan** | `integer` | optional | Absolute column span (1-4). The renderer clamps it to the form grid's current column count, so the cell starts at a real column boundary at every surface width and never overflows (`colSpan: 4` in a 3-column grid renders as 3); a `colSpan` within the column count renders as authored, and `colSpan: 1` emits no span class at all. |
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `ab1879721595`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
| **span** | `Enum<'auto' \| 'full'>` | optional (default: `"auto"`) | Relative field width. 'auto' (default — omit it): the renderer sizes the field from its widget type × the current column count — at the pin this repo builds against (`.objectui-sha` = `2e818d0b51ec`), only textarea, markdown, html, richtext and repeater resolve to the full column count (repeater reaches it through the wide `field:grid` widget it maps to). 'full': resolves to the form grid's full column count. How far down the container-query tiers that span is emitted is the renderer's, not this key's: at that same pin the renderer emits one clamped col-span class per multi-column tier (`@md:col-span-2 @2xl:col-span-3` for a 3-column grid), so the field takes the whole row at every multi-column tier, not just the widest. |
| **widget** | `string` | optional | Custom widget/component name (overrides type-based inference) |
| **language** | `string` | optional | Code editor language (for type=code) |
| **keyField** | `{ field?: string; label?: string \| Record<string, string>; placeholder?: string \| Record<string, string>; helpText?: string \| Record<string, string>; … }` | optional | Key column config for record-typed fields |
Expand Down
6 changes: 3 additions & 3 deletions packages/sdui-parser/objectui-lockstep.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
],
"objectui": {
"repo": "https://github.com/objectstack-ai/objectui.git",
"rev": "ab187972159583b595facdcae3c73b50f6f312e9",
"revDate": "2026-10-03T17:12:55+00:00",
"rev": "2e818d0b51ecdf8fdd9fcbf4b916bcd7fe9a9cf6",
"revDate": "2026-10-04T07:05:00+00:00",
"source": "packages/sdui-parser/src",
"files": [
"packages/sdui-parser/src/body-dialect.ts",
Expand All @@ -21,7 +21,7 @@
"packages/sdui-parser/src/validate.ts"
]
},
"recordedAgainstPin": "ab187972159583b595facdcae3c73b50f6f312e9",
"recordedAgainstPin": "2e818d0b51ecdf8fdd9fcbf4b916bcd7fe9a9cf6",
"grammarRegion": {
"file": "packages/sdui-parser/src/parse.ts",
"delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */",
Expand Down
7 changes: 5 additions & 2 deletions packages/spec/src/data/api-methods-batch-conformance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ const SINGLE_RECORD_WRITE_ONLY: Record<string, string> = {
// `revoked` on ONE key. The multi-select surface this rule protects does not
// exist for API keys, and the shape a future one would take does not need
// `bulk` either — both read off the console build this release pins
// (`.objectui-sha` = `ab1879721`, `packages/plugin-grid`; re-measured at
// that pin, 2026-10-03. On the hop off `89cad75d5`, `ObjectGrid.tsx` changed
// (`.objectui-sha` = `2e818d0b5`, `packages/plugin-grid`; re-measured at
// that pin, 2026-10-04: `ObjectGrid.tsx` and `hooks/useBulkExecutor.ts` are
// byte-identical across the hop off `ab1879721` (`git diff --quiet`), so
// every anchor held unmoved. Re-measured at `ab1879721`, 2026-10-03. On the
// hop off `89cad75d5`, `ObjectGrid.tsx` changed
// again (74 insertions, 11 deletions: objectui#11544's group-header labels
// read from the object field's `options` only, objectui#11475's percent
// storage `max` copied onto the cell's field meta on three paths and one
Expand Down
19 changes: 14 additions & 5 deletions packages/spec/src/kernel/functional-completeness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] {
* English sentence. So the loss is total rather than partial — every
* record, on every object — and the author is told at render time as well
* as here. Both reads hold at the pin this repo builds against
* (`.objectui-sha` = `ab1879721`, re-read 2026-10-03: on the hop off
* (`.objectui-sha` = `2e818d0b5`, re-read 2026-10-04: `ObjectCalendar.tsx`
* and `ListView.tsx` are byte-identical across the hop off `ab1879721`
* (`git diff --quiet`), so every anchor held unmoved; re-read at
* `ab1879721` 2026-10-03: on the hop off
* `89cad75d5` `ObjectCalendar.tsx` changed in one comment line only, line
* for line (`:1250`, objectui#11438 re-citing the installed spec as
* 17.6.0), so `getCalendarConfig` `:294`, the `if (!calendarConfig)` arm
Expand Down Expand Up @@ -344,8 +347,10 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] {
* This repo already records the same deletion one door over: the #13817
* check in `../ui/view.zod.ts` names objectui#7029 as its runtime half.
* - `gantt` → NO fallback, and no silence [#19630]. Measured at the pin
* this repo builds against (`.objectui-sha` = `ab1879721`, re-read
* 2026-10-03; on the hop off `89cad75d5` `ObjectGantt.tsx` changed (8
* this repo builds against (`.objectui-sha` = `2e818d0b5`, re-read
* 2026-10-04: `ObjectGantt.tsx` and `ListView.tsx` are byte-identical across
* the hop off `ab1879721`, so every anchor held unmoved; re-read at
* `ab1879721` 2026-10-03; on the hop off `89cad75d5` `ObjectGantt.tsx` changed (8
* insertions, 0 deletions: one import line and objectui#11475's storage
* argument on the tooltip's `percent` row), none of it in `getGanttConfig`
* or the refusal arm, which are byte-identical and moved `:608` → `:609`
Expand Down Expand Up @@ -398,7 +403,9 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] {
* requires. So the view does not draw a blank chart: it refuses, by name.
* - `timeline` → date axis: NO fallback [#19630]; title: `titleField || 'name'`,
* which still stands. Measured at the same pin (`.objectui-sha` =
* `ab1879721`; on the hop off `89cad75d5` `ObjectTimeline.tsx` is
* `2e818d0b5`; `ObjectTimeline.tsx` and `ListView.tsx` are byte-identical
* across the hop off `ab1879721`, so every anchor held unmoved; on the hop
* off `89cad75d5` `ObjectTimeline.tsx` is
* byte-identical, so the start-date chain `:574-576` and the refusal arm
* `:911` did not move, and `ListView.tsx`'s `case 'timeline'` and
* `resolveTimelineDateBinding` are byte-identical, moved by 14 and by 9
Expand Down Expand Up @@ -444,7 +451,9 @@ export function checkFieldCompleteness(def: unknown): CompletenessFinding[] {
* block does render; the warning still fires there, because the block the
* view TYPE names is the one that is missing. Unchanged by this row.
* - `map` → NO fallback, and no silence [#19630]. Measured at the same
* pin (`.objectui-sha` = `ab1879721`; on the hop off `89cad75d5`
* pin (`.objectui-sha` = `2e818d0b5`; `ObjectMap.tsx` and `ListView.tsx`
* are byte-identical across the hop off `ab1879721`, so every anchor held
* unmoved; on the hop off `89cad75d5`
* `ObjectMap.tsx` is byte-identical, so `getMapConfig` `:387`,
* `hasCoordinateBinding` `:493` and the refusal arm `:1291` did not move,
* and `ListView.tsx`'s `case 'map'` is byte-identical, moved by 14, with
Expand Down
Loading
Loading