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
29 changes: 29 additions & 0 deletions .changeset/console-9646e2ed2bf3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"@objectstack/console": minor
---

Console (objectui) refreshed to `9646e2ed2bf3`. Frontend changes in this range:

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

- **minor** — The FilterBuilder's row and group types are exported as `FilterBuilderRow` and `FilterBuilderRowGroup` instead of `FilterBuilderCondition` and `FilterGroup` (objectui#6349, batch… (objectui `26b0bd2d1`)
- **minor** — `FilterBuilderOperator` is no longer exported from this package (objectui#6349, batch 12). It was `@objectstack/spec`'s `ViewFilterOperator`, the protocol's canonical view-filter… (objectui `26b0bd2d1`)
- **minor** — The result type of this package's `toDomProps` is declared and exported as `FieldDomProps` instead of `DomProps` (objectui#6349, batch 11). `@object-ui/core` publishes a different… (objectui `35a2b59a5`)
- **minor** — The node type of the tree this package's parser produces is declared and exported as `ParsedSchemaNode` instead of `SchemaNode` (objectui#6349, batch 11). `@object-ui/types` publi… (objectui `35a2b59a5`)
- **patch** — The Studio fallback form for an email template no longer offers `category` or `isSystem`, and the fallback skill form no longer offers `triggerPhrases` (objectstack-ai/objectstack… (objectui `9646e2ed2`)
- **patch** — A gallery card whose title field is a lookup now shows the referenced record's name, not `[object Object]` (objectui#12188). (objectui `5dd583f5e`)
- **patch** — The list view's URL filter state reads the FilterBuilder's group by `@object-ui/components`' new name for it, `FilterBuilderRowGroup` (it was exported as `FilterGroup`; objectui#6… (objectui `26b0bd2d1`)
- **patch** — `ListViewProps.onFilterChange` and `ListViewProps.initialFilters` now name the advanced-filter group by `@object-ui/components`' new name for it, `FilterBuilderRowGroup` (it was e… (objectui `26b0bd2d1`)
- **patch** — `toFilterGroup` now declares its return type by `@object-ui/components`' new name for the FilterBuilder's group, `FilterBuilderRowGroup` (it was exported as `FilterGroup`; objectu… (objectui `26b0bd2d1`)
- **patch** — Under a tenancy wall (`isolated` or `group`), the security catalog's pages are read-only for everyone but the platform operator, and say why (objectui#12183). (objectui `d928c8394`)
- **patch** — `DataSource` inside this package is now a re-export of `@object-ui/types`' `DataSource`, the one adapter contract, instead of an older and looser second declaration of it (objectu… (objectui `35a2b59a5`)
- **patch** — On a metadata type the `OS_METADATA_WRITABLE` hatch elevates, an item a package ships now opens read-only in the metadata editor and in the permission matrix, and an item no packa… (objectui `5b20aed39`)
- **patch** — Studio's landing page and the permission matrix name the overlay that exists: an environment overlay, not an org overlay (objectui#12171). (objectui `b0c5f9ddf`)

**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.

- _(no changeset)_ ci(site): deploy the docs from a GitHub Actions workflow every 6 hours, and turn Vercel's Git-triggered builds off (objectui#12178) (#12182) (objectui `7e30d0b6e`)

Clause-②: no

objectui range: `088e0f705520...9646e2ed2bf3`
20 changes: 20 additions & 0 deletions .changeset/objectui-pin-citations-9646e2ed2bf3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@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 `9646e2ed2bf3`.

Clause-②: no

Every anchor was mapped through the objectui diff `088e0f705520..9646e2ed2bf3`: 64 paths over 9 commits. One file that any record cites changed on the hop: `plugin-list/src/ListView.tsx` (+9/-9, objectui#12189, objectui `26b0bd2d1`, which renames the FilterBuilder group type to `FilterBuilderRowGroup`). All nine lines were replaced in place, the last at `:1558`, so no line in the file moved and no cited range contains a changed line:

- the `kanban` / `calendar` / `gantt` / `timeline` / `map` / `tree` arms of its per-type props builder held at `3762` / `3813` / `3959` / `3902` / `4079` / `4120-4144`;
- `resolveListMapConfig` (`:209-214`) and `resolveTimelineDateBinding` (`:695-699`) held, and each ends before the next changed line below it (`:324`, `:756`).

That file is cited by the four view-type rows of the functional-completeness table (`calendar`, `gantt`, `timeline`, `map`) and by the `object-gantt` and flat-`TreeConfig` records. Each of those gains a hop sentence naming it. The `kanban` row-cap record names `ListView.tsx` only as an earlier re-read's record, and its sentence says so.

Every other record cites only files that are byte-identical across the hop (`git diff --quiet`, checked file by file), and each gains a hop sentence that says so. That covers `form.tsx`, so `FormField.span: 'full'` still takes the whole row at every multi-column tier.

The six migration entries' corpus counts were re-taken with `git grep -o -F`, the method that reproduces every `088e0f705520` number. The corpus is now 8540 tracked files, and every retired name each entry counts still reads 0. The lit controls moved with the corpus, for example `objectstack` from 18400 to 18438, `tenant` from 1365 to 1393 and `useState` from 2661 to 2662.

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 @@
088e0f705520e82bee1d65a5fa3c1f7a26672dde
9646e2ed2bf315a6ae99b2a1633bc7c7d162f7b9
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` = `088e0f705520`), 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` = `9646e2ed2bf3`), 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` = `088e0f705520`), 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` = `9646e2ed2bf3`), 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": "088e0f705520e82bee1d65a5fa3c1f7a26672dde",
"revDate": "2026-10-12T03:19:24+00:00",
"rev": "9646e2ed2bf315a6ae99b2a1633bc7c7d162f7b9",
"revDate": "2026-10-12T08:01:27+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": "088e0f705520e82bee1d65a5fa3c1f7a26672dde",
"recordedAgainstPin": "9646e2ed2bf315a6ae99b2a1633bc7c7d162f7b9",
"grammarRegion": {
"file": "packages/sdui-parser/src/parse.ts",
"delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */",
Expand Down
5 changes: 4 additions & 1 deletion packages/spec/src/data/api-methods-batch-conformance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ 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` = `088e0f705`, re-read there 2026-10-12:
// (`.objectui-sha` = `9646e2ed2`, re-read there 2026-10-12:
// every objectui file this record cites is byte-identical across the hop from
// `088e0f705` (`git diff --quiet`), so every anchor held unmoved. At
// `088e0f705`, re-read there 2026-10-12:
// every objectui file this record cites is byte-identical across the hop from
// `e5311165a` (`git diff --quiet`), so every anchor held unmoved. At
// `e5311165a`, re-read there 2026-10-12:
Expand Down
36 changes: 32 additions & 4 deletions packages/spec/src/kernel/functional-completeness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,15 @@ 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` = `088e0f705`, re-read there 2026-10-12:
* (`.objectui-sha` = `9646e2ed2`, re-read there 2026-10-12:
* on the hop off `088e0f705` `ObjectCalendar.tsx` and the `en` / `zh` / `de`
* packs are byte-identical (`git diff --quiet`), so `getCalendarConfig` `:311`,
* the `if (!calendarConfig)` arm `:1354` with its `tt(…)` lines `:1361-1362`
* and the packs' `calendar.configRequired` strings did not move; and
* `ListView.tsx` changed (+9/-9, objectui#12189, objectui `26b0bd2d1`: the
* FilterBuilder group type's rename, nine lines replaced in place, the last at
* `:1558`), so its `case 'calendar'` held at `3813`. At `088e0f705`, re-read
* there 2026-10-12:
* on the hop off `e5311165a` `ObjectCalendar.tsx` and `ListView.tsx` are
* byte-identical (`git diff --quiet`), so `getCalendarConfig` `:311`, the
* `if (!calendarConfig)` arm `:1354` with its `tt(…)` lines `:1361-1362` and
Expand Down Expand Up @@ -440,7 +448,13 @@ 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` = `088e0f705`, re-read there 2026-10-12:
* this repo builds against (`.objectui-sha` = `9646e2ed2`, re-read there 2026-10-12:
* on the hop off `088e0f705` `ObjectGantt.tsx` is byte-identical (`git diff
* --quiet`), so `getGanttConfig` `:612` and the `if (!ganttConfig)` arm `:2330`
* did not move, and `ListView.tsx` changed (+9/-9, objectui#12189, objectui
* `26b0bd2d1`: the FilterBuilder group type's rename, nine lines replaced in
* place, the last at `:1558`), so its `case 'gantt'` held at `3959`. At
* `088e0f705`, re-read there 2026-10-12:
* every objectui file this record cites is byte-identical across the hop from
* `e5311165a` (`git diff --quiet`), so every anchor held unmoved. At
* `e5311165a`, re-read there 2026-10-12:
Expand Down Expand Up @@ -545,7 +559,14 @@ 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` =
* `088e0f705`, re-read there 2026-10-12:
* `9646e2ed2`, re-read there 2026-10-12:
* on the hop off `088e0f705` `ObjectTimeline.tsx` is byte-identical (`git diff
* --quiet`), so its start-date chain `:589-591` and its `if (!hasAuthoredItems
* && !startDateField)` refusal arm `:974` did not move, and `ListView.tsx`
* changed (+9/-9, objectui#12189, objectui `26b0bd2d1`: the FilterBuilder group
* type's rename, nine lines replaced in place, the last at `:1558`), so its
* `case 'timeline'` held at `3902` and `resolveTimelineDateBinding` at `695`.
* At `088e0f705`, re-read there 2026-10-12:
* every objectui file this record cites is byte-identical across the hop from
* `e5311165a` (`git diff --quiet`), so every anchor held unmoved. At
* `e5311165a`, re-read there 2026-10-12:
Expand Down Expand Up @@ -647,7 +668,14 @@ 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` = `088e0f705`, re-read there 2026-10-12:
* pin (`.objectui-sha` = `9646e2ed2`, re-read there 2026-10-12:
* on the hop off `088e0f705` `ObjectMap.tsx` is byte-identical (`git diff
* --quiet`), so `getMapConfig` `:421`, `hasCoordinateBinding` `:527` and the
* refusal arm `:1337` did not move; and `ListView.tsx` changed (+9/-9,
* objectui#12189, objectui `26b0bd2d1`: the FilterBuilder group type's rename,
* nine lines replaced in place, the last at `:1558`), so its `case 'map'` held
* at `4079` and `resolveListMapConfig` at `:209`. At `088e0f705`, re-read there
* 2026-10-12:
* every objectui file this record cites is byte-identical across the hop from
* `e5311165a` (`git diff --quiet`), so every anchor held unmoved. At
* `e5311165a`, re-read there 2026-10-12:
Expand Down
Loading
Loading