Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d6a0f7b
chore(objectui): bump the console pin to 62597c588072 (carries object…
claude Sep 23, 2026
1e9f2b8
chore(objectui): re-record the sdui manifest at pin 62597c588072
claude Sep 23, 2026
bb9b7e6
chore(sdui-parser): re-record the objectui lockstep at pin 62597c588072
claude Sep 23, 2026
5e01897
chore(spec): re-count the six pin-cited objectui corpus readings at 6…
claude Sep 23, 2026
75a0f8c
chore(spec): re-measure the component.test.ts objectui pin citations …
claude Sep 23, 2026
73c0465
chore(spec): re-measure the component.zod.ts icon, kanban, calendar a…
claude Sep 23, 2026
d7d3ab6
chore(spec): re-measure the gantt, tree, timeline and map-row pin cit…
claude Sep 23, 2026
613c778
chore(spec): re-measure the grid, completeness-table, dataset and vie…
claude Sep 23, 2026
d3ff597
Merge remote-tracking branch 'origin/main' into claude/issue-19503-ob…
claude Sep 23, 2026
32a60d6
chore(spec): keep both readings of the health-check entry's lit controls
claude Sep 23, 2026
f9558e7
chore(spec): restate the calendar-row copy claim and re-point the For…
claude Sep 23, 2026
72650da
chore(spec): regenerate view.mdx and add the FormField.span describe-…
claude Sep 23, 2026
1632905
Merge remote-tracking branch 'origin/main' into claude/issue-19503-ob…
claude Sep 23, 2026
3fd40be
chore(spec): regenerate view.mdx from the merged tree
claude Sep 23, 2026
557f561
Merge remote-tracking branch 'origin/main' into claude/issue-19503-ob…
claude Sep 23, 2026
2a76807
chore(spec): regenerate view.mdx from the merged tree
claude Sep 23, 2026
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
11 changes: 11 additions & 0 deletions .changeset/19503-pin-bump-describe-corrections.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@objectstack/spec': patch
---

One published `describe` sentence that dates itself to the `.objectui-sha` pin is re-pointed to the pin this release builds against, objectui `62597c588072`, after being re-read there (#19503).

`Clause-②: no`

- `FormField.span`: the `'auto'` clause says that at the pin this repo builds against, only textarea, markdown, html, richtext and repeater resolve to the full column count. It named `87af769e9`. Re-read at `62597c588`, the claim still holds: `plugin-form`'s `WIDE_FIELD_TYPES` is unchanged (it shifted one line when an import was added above it; repeater still reaches it through `field:grid`), and `form.tsx`'s `spanLadderFor` is byte-identical, so `'full'` is still the whole row at every multi-column tier. Only the pin the sentence names moves.

No key, default, enum member or export moves: the same authored metadata is accepted and refused as before, and `content/docs/references/ui/view.mdx` is regenerated from the sentence.
47 changes: 47 additions & 0 deletions .changeset/console-62597c588072.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
"@objectstack/console": minor
---

Console (objectui) refreshed to `62597c588072`. Frontend changes in this range:

Derived from the changesets objectui declared over the range — 27 releasing of 30 changesets added across 37 non-merge commits; omitted: 3 release-nothing changesets, 7 commits carrying no changeset (they ship no package code).

- **minor** — fix(plugin-grid): `object-grid`'s `pagination` and `selection` now read their own presence by the SAME rule — presence enables, an explicit off wins (objectui `62597c588`)
- **minor** — A render-time filter refusal now renders a named "this view's filter is malformed" state instead of throwing out of render (objectui#9050). (objectui `804831c2a`)
- **minor** — `record:related_list` `add.picker.filter` is declared as the contract's rule array on the authoring face, not as `unknown` (objectui#9964). (objectui `9a9780072`)
- **minor** — feat(core): `object-tree` joins the curated public tier — the spec declared the block, the roster withheld it (objectui `c131d9e69`)
- **minor** — A signed-in user's language has one source of truth: `sys_user.locale`. (objectui `63f4f928f`)
- **minor** — A record form can no longer be saved while an upload is still in flight (objectui#10166). (objectui `e686f4d9a`)
- **minor** — Nav `visible`: an ancestor's predicate now reaches the whole subtree, and a group no longer outlives its children (objectui#10119) (objectui `73a3c89af`)
- **minor** — A field-backed action param reaches its record picker, and a param whose backing field cannot be read is refused instead of rendered as an empty text box (objectui#10129). (objectui `6cc910b6d`)
- **patch** — fix(react): the refused-`data` dev warning can be reset between tests (objectui `befd40ccd`)
- **patch** — fix(components): a half-typed `between` range in the filter builder shows itself as incomplete instead of being dropped with no signal (objectui#10061) (objectui `777fca22f`)
- **patch** — fix(plugin-detail): a related list resolves `user` columns to names, like every other list (objectui `0d379f571`)
- **patch** — fix(core): a date-only value renders the calendar day it names, in every viewer timezone (objectui `516583b54`)
- **patch** — fix(plugin-detail): the record-grained write verdict is memoised PER PRINCIPAL (objectui#10107). (objectui `b06c3de2a`)
- **patch** — fix(console): a `file` field on a FormView renders the shared upload control, not a text box (objectui `7725c10a0`)
- **patch** — Stop the Studio permission matrix' Delegated Admin Scope editor authoring an `adminScope` the framework spec refuses, and make the section's collapsed badge report a scope it is c… (objectui `2d7fff3b8`)
- **patch** — fix(console): mint a `sys_file` id for files picked in the global action dialogs (objectui `98178b206`)
- **patch** — fix(plugin-detail): `requiredPermissions` on `record:details`, `record:highlights` and `record:related_list` is an ADR-0066 capability set, read fail-closed — it used to pass for… (objectui `c2dabf032`)
- **patch** — A form no longer submits — nor offers — a field the CALLER may read but not edit (objectui#10120). (objectui `80c54122e`)
- **patch** — fix(components): `page:header` resolves a lookup title candidate instead of handing its expanded object to JSX (objectui#10117) (objectui `4c6f549ef`)
- **patch** — `ObjectCalendar`'s user-visible copy now reaches the locale packs. The component was already i18n-aware — it imports and calls both translation hooks — and a set of English senten… (objectui `afb228418`)
- **patch** — `useSettledSchema` no longer republishes an EQUAL definition as a new object, so swapping the adapter on a record-bound view costs ONE record query instead of two. (objectui `162621b6a`)
- **patch** — A form no longer emits the columns the server owns, and a master-detail batch sends only the cells the user changed (objectui#10108). (objectui `e026e15f9`)
- **patch** — fix(plugin-calendar): the month gridcell's accessible name follows the resolved locale (objectui `708f2711b`)
- **patch** — The AI build bar, the Studio workbench and the chat transcript's draft cards report the runtime authoring gate's per-draft advisories (objectui#10039) (objectui `e16f504d9`)
- **patch** — fix(plugin-detail): `record:quick_actions.requiredPermissions` is an ADR-0066 capability set, read fail-closed — it used to pass for every reader of the object (objectui `28b065800`)
- **patch** — fix(plugin-map): the top-level-`style` warning now prescribes a spelling the runtime reads (objectui `2252653d0`)
- **patch** — `record:history` refuses a row cap the contract rejects instead of repairing it (objectui#10005). (objectui `cd2cb4183`)

**In this console build, declared nowhere** — objectui merged 7 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)_ docs(agents): 一次派发跑出来的 PR 停在 draft —— 给自行合并条款加第二条例外 (#10213) (objectui `87a0ed8cf`)
- _(no changeset)_ docs(agents): state the attribution-footer append as conditional on absence (#10212) (objectui `2ec310198`)
- _(no changeset)_ docs(skills): the console guide names the resolver `/` actually has (objectui#10140) (#10215) (objectui `8d7915ed2`)
- _(no changeset)_ ci(pm): adopt the board-snapshot archiver — route B, and the five files this repo's own gates demanded (objectui#9387) (#10203) (objectui `0cf2d6644`)
- _(no changeset)_ ci: compile objectui against @objectstack/spec@main as the shape gate (objectui#9860) (#9877) (objectui `6cae9a0b3`)
- _(no changeset)_ perf(console): move the `types` zod validators off the eager budgeted line (#10082) (objectui `64d250c8a`)
- _(no changeset)_ ci(bundle-analysis): retire the exhausted-headroom leg, keep every ceiling (#10151) (objectui `cbda340f0`)

objectui range: `87af769e9a3e...62597c588072`
2 changes: 1 addition & 1 deletion .objectui-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
87af769e9a3ee28ace099fdd653d3ebd79fe82e2
62597c588072636e9c30ea35b3d89b1e46fd765d
4 changes: 2 additions & 2 deletions content/docs/references/ui/view.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,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` = `87af769e9`), 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` = `62597c588`), 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 @@ -364,7 +364,7 @@ View filter rule
| **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` = `87af769e9`), 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` = `62597c588`), 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": "87af769e9a3ee28ace099fdd653d3ebd79fe82e2",
"revDate": "2026-09-20T15:03:40+00:00",
"rev": "62597c588072636e9c30ea35b3d89b1e46fd765d",
"revDate": "2026-09-23T02:43:52+00:00",
"source": "packages/sdui-parser/src",
"files": [
"packages/sdui-parser/src/body-dialect.ts",
Expand All @@ -22,7 +22,7 @@
"packages/sdui-parser/src/validate.ts"
]
},
"recordedAgainstPin": "87af769e9a3ee28ace099fdd653d3ebd79fe82e2",
"recordedAgainstPin": "62597c588072636e9c30ea35b3d89b1e46fd765d",
"grammarRegion": {
"file": "packages/sdui-parser/src/parse.ts",
"delimiter": "/* ---------------------- the JS literal subset (#6614) ---------------------- */",
Expand Down
41 changes: 24 additions & 17 deletions packages/spec/src/data/api-methods-batch-conformance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,36 @@ 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` = `87af769e9`, `packages/plugin-grid`; re-measured at
// that pin, 2026-09-20 — previously measured at `53ded82bf`, `a472b0716`,
// `00d3f09c5`, `67dadd602`, before that at `d8ec8d6d4`, `9602dc820`,
// `190fbd01d`, `9a3daf8d3`, originally at `6314e87f2`. `ObjectGrid.tsx` DID
// change again across the move off `53ded82bf` (721 insertions, 159
// deletions), so the selection block this record means was re-READ rather
// than carried: it is `ObjectGrid.tsx:3940-3955` here, was `3538-3553` at
// `53ded82bf` and `3544-3559` at `a472b0716`, and the sixteen lines are
// BYTE-IDENTICAL across the hop — `git hash-object` on both spans returns
// `6133933199230670e29d8c7f51c558d86a0af1d2`, the same id the previous two
// hops recorded, so the block only shifted 402 lines DOWN and none of its
// substance moved. The earlier hop off
// (`.objectui-sha` = `62597c588`, `packages/plugin-grid`; re-measured at
// that pin, 2026-09-23 — previously measured at `87af769e9`, `53ded82bf`,
// `a472b0716`, `00d3f09c5`, `67dadd602`, before that at `d8ec8d6d4`,
// `9602dc820`, `190fbd01d`, `9a3daf8d3`, originally at `6314e87f2`.
// `ObjectGrid.tsx` changed again across the move off `87af769e9` (119
// insertions, 9 deletions), and THIS time the selection block's CONTENT
// moved, not only its position: objectui#10218 (`62597c588` itself)
// rewrote the `selection` arm to "presence enables; an explicit off wins",
// so an authored `selection` object with no `type` now selects
// (`DEFAULT_SELECTION_TYPE`, `'multiple'`) where it used to fall through.
// The block is `ObjectGrid.tsx:4024-4051` here — `3940-3955` at `87af769e9`,
// `3538-3553` at `53ded82bf` — and no longer hashes to the
// `6133933199230670e29d8c7f51c558d86a0af1d2` the previous three hops
// recorded (`c88443302d40c2db739ddb235470bafa29056e2e` now). Re-READ, the
// arm this record relies on is unchanged: with neither `selection` nor
// `selectable` authored, multi-select is still enabled only by
// `hasBulkActions`, and the rewritten arm is reachable only by a view that
// declares `selection` — which none of these four does. The earlier hop off
// `00d3f09c5` is the one that caught the previous record's OWN grid anchor as
// wrong rather than merely shifted: `3790-3805` there is
// `runBulkActionAggregate` and says nothing about selection. That is the
// #10274 class, and the reason a citation refresh re-READS instead of moving
// numbers — arithmetic on a wrong anchor produces a fresh-looking span still
// describing the wrong function. The second claim,
// `hooks/useBulkExecutor.ts:298-303`, sits in a file that is NO LONGER
// byte-identical across this hop (36 insertions, 22 deletions), so it was
// re-READ rather than carried on file identity: the six lines are themselves
// byte-identical (`git hash-object` on both spans returns
// `01083348330f10a201cdf1078b4c21c236402b6a`) and still end on
// `hooks/useBulkExecutor.ts:298-303`, sits in a file that is byte-identical
// to `87af769e9` on this hop (it last changed on the hop off `53ded82bf`, 36
// insertions, 22 deletions, when it was re-READ rather than carried on file
// identity): the six lines hash to
// `01083348330f10a201cdf1078b4c21c236402b6a` at every one of those pins and
// still end on
// `label = 'bulk delete'`, the line the `284-288` span cited six
// pins ago stopped short of, truncating the second of the two branches it
// names (byte-identity is never taken as proof an anchor is right):
Expand Down
Loading
Loading