Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
60ed1ad
chore(deps): resolve @objectstack/* 17.7.0 in pnpm-lock.yaml (objectu…
claude Oct 6, 2026
c62fd61
test(tooling): re-key the lockfile-integrity samples and the live-e2e…
claude Oct 6, 2026
a116437
types,plugin-dashboard: re-attach the spec's 17.7.0 object-level chec…
claude Oct 6, 2026
7f05f8e
docs(spec-pin): re-measure and restamp the installed-pin claims on 17…
claude Oct 6, 2026
7b220cf
app-shell: ai:chat_window is retired upstream; its palette exclusion …
claude Oct 6, 2026
5d6c2a6
components: element:text drops the retired heading / subheading varia…
claude Oct 6, 2026
622e461
fields,i18n: label view_all_audit_log, the capability 17.7.0 adds (ob…
claude Oct 6, 2026
fc0d45d
test(app-shell): follow 17.7.0's approval node contract in three flow…
claude Oct 6, 2026
4eca34d
data-objectstack: the choice-without-options door shipped in 17.7.0; …
claude Oct 6, 2026
b10c5f4
types: the 17.7.0 import-boundary readings — three rows now carry spe…
claude Oct 6, 2026
616920f
types,plugin-calendar: 17.7.0 types the object-calendar calendar slot…
claude Oct 6, 2026
6c5baf9
plugin-gantt,plugin-timeline: open three descriptions with the 17.7.0…
claude Oct 6, 2026
58062fd
core: inventory requiresMembershipReach, the ActionSchema key 17.7.0 …
claude Oct 6, 2026
c7d4420
test(console): three registry parity rows 17.7.0 moves — ai:chat_wind…
claude Oct 6, 2026
9586d0e
plugin-form,types: sortField on a master-detail details entry is refu…
claude Oct 6, 2026
25251a8
Merge origin/main into claude/issue-11717-objectstack-17-7-0
claude Oct 6, 2026
47b0ff9
test(plugin-dashboard): type the collecting context off the spec chec…
claude Oct 6, 2026
50ed869
docs(console): the preview-samples note stops naming the retired head…
claude Oct 6, 2026
c7bbce4
test(types,app-shell): two rows the 17.7.0 moves reach in CI shard 7 …
claude Oct 6, 2026
c1e32e9
Merge origin/main into claude/issue-11717-objectstack-17-7-0
claude Oct 7, 2026
b680973
chore(console): raise the eager-closure line a fourth time for @objec…
claude Oct 7, 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
5 changes: 5 additions & 0 deletions .changeset/11717-action-key-requires-membership-reach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@object-ui/core': patch
---

The action key inventory lists `requiresMembershipReach`, the key `@objectstack/spec` 17.7.0 adds to `ActionSchema` (objectui#11717), so an action carrying it is no longer reported as having an unknown key. The spec's parse lowers it into `visible`; the action runner does not read it.
4 changes: 4 additions & 0 deletions .changeset/11717-bump-prose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

objectui#11717: test re-pins, ledgers and source comments that the `@objectstack/*` 17.7.0 bump made stale. Each measured fact was re-read on 17.7.0 before its stamp moved, and nothing that ships changes behaviour here.
6 changes: 6 additions & 0 deletions .changeset/11717-capability-view-all-audit-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@object-ui/fields': patch
'@object-ui/i18n': patch
---

The capability picker labels `view_all_audit_log`, the platform capability `@objectstack/spec` 17.7.0 adds to `PLATFORM_CAPABILITIES` (objectui#11717). Without the label it showed the registry's English text in every locale. All ten locale packs carry the label.
10 changes: 10 additions & 0 deletions .changeset/11717-dashboard-widget-chart-measure-arity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@object-ui/types': minor
---

`DashboardWidgetSchema` chains `@objectstack/spec`'s `checkDashboardWidgetChartMeasureArity` after the metric-family check (objectui#11334, objectui#11417), so `safeValidateSchema` and `objectui validate` now refuse what the spec refuses since 17.7.0. The refusal is one `custom` issue at `values`, with the spec's own message:

- two or more measures with no `dimensions` on a chart type that has no rendering for them without a dimension (`pie`, `donut`, `funnel`, `scatter`, `radar`, `treemap`, `sankey`);
- two or more measures on `pie`, `donut`, `funnel`, `treemap` or `sankey`, even with a dimension. These draw one series and dropped every measure after the first.

This narrows the accepted documents (breaking for a document of either shape). The fix: use `table` or a bar-family type for several measures, or give each measure its own widget. A widget stored before the refusal still renders, and the dashboard's dropped-measure warning still names what it drops. The widget editor's measure picker asks the same door, so it stops offering a second measure on these widgets.
5 changes: 5 additions & 0 deletions .changeset/11717-element-text-retired-variants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@object-ui/components': minor
---

`element:text` drops the two pre-convergence `variant` spellings `heading` and `subheading`, which `@objectstack/spec` 17.7.0 retires (objectstack#21015, objectui#11717). The registry `inputs` enum is the contract's nine values again: `h1` to `h6`, `body`, `caption` and `overline`. The html tier therefore refuses `heading` / `subheading` with `invalid-enum`, as `objectui validate` and the spec do. A stored node that still carries one renders as `body`, the renderer's answer for any value outside the contract. Migration: `heading` -> `h2`, `subheading` -> `h3`. `os migrate meta --from 17` lists the edits.
5 changes: 5 additions & 0 deletions .changeset/11717-master-detail-sort-field-refused.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@object-ui/plugin-form': patch
---

`@objectstack/spec` 17.7.0 retires `sortField` on an `object-master-detail-form` `details` entry (objectstack-ai/objectstack#21589), so `objectui validate` now refuses an entry that writes it, at that member, with the spec's retired-key message (objectui#11717). The form never read it: the line-position field is derived from the child object (objectui#11070). The `details` registration description and the `MasterDetailDetailConfig` docblock now say so. The type is unchanged: it already left the key off.
14 changes: 14 additions & 0 deletions .changeset/11717-objectstack-17-7-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@object-ui/types': patch
'@object-ui/plugin-dashboard': patch
'@object-ui/console': patch
---

objectui now resolves `@objectstack/*` 17.7.0 (objectui#11717). Two declared `@objectstack/spec` floors move, each because the package's published code now imports something an older release does not export:

- `@object-ui/types`: `^17.6.0` to `^17.7.0`. Its zod mirrors chain `checkDashboardWidgetChartMeasureArity` and `checkPageRequiresKind`, which the spec first exports in 17.7.0.
- `@object-ui/plugin-dashboard`: `^17.5.0` to `^17.6.0`. `DatasetWidget` reads `DASHBOARD_WIDGET_MULTI_MEASURE_TYPES`, which the spec first exports in 17.6.0, instead of restating it. What the widget draws does not change.

No other declared range moves.

- `@object-ui/console`: the bundle inlines the 17.7.0 packages, so its client-side validation answers as a 17.7.0 server does, refusals included. The first screen is heavier: the eager closure grows by 183,008 gzipped bytes against a `main` build, nearly all of it in the `vendor-objectstack` chunk, and the bundle budget is re-pinned over the new reading on a maintainer ruling. It comes down again by whatever objectstack#22044 recovers.
5 changes: 5 additions & 0 deletions .changeset/11717-page-requires-kind.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@object-ui/types': minor
---

The `page` node and the spec page-kind nodes (`record` / `home` / `utility`) chain `@objectstack/spec`'s `checkPageRequiresKind` (objectui#11717), as they already chain `checkPageSourceCompleteness`. A page that writes `requires` on a kind the platform does not compile at save is now refused at `requires` with the spec's own message, as the spec refuses it since 17.7.0. That covers `react`, `full` and `slotted` pages, and a page with no `kind`, an empty list included. `requires` stays legal on `html` and `jsx` pages, where the platform derives it from the compiled source. This narrows the accepted documents. The fix: delete the key.
6 changes: 6 additions & 0 deletions .changeset/11717-spec-row-describes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@object-ui/plugin-gantt': patch
'@object-ui/plugin-timeline': patch
---

The `object-gantt` `markers` input and the `object-timeline` `items` and `mapping` inputs open their descriptions with the `@objectstack/spec` 17.7.0 row's own describe text, which is true of these renderers (objectui#11168's rule, followed at objectui#11717). The renderer-specific sentences after it are unchanged.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* is therefore perfectly valid metadata. `{ type: 'heading' }` parsed clean
* through every spec release while resolving to nothing: `heading` has never
* been registered in this repo (the nearest real things are `element:text`
* with `variant: 'heading'`, which renders an h2, and the `ui/typography`
* with a heading `variant` such as `h2` (`heading` until 17.7.0 retired it), and the `ui/typography`
* primitives, which never go through the registry at all). Both `heading`
* nodes in the `page` sample fell through to the ComponentRegistry fallback,
* so the gallery's page card — the worked example of a composed page — showed
Expand Down
36 changes: 26 additions & 10 deletions apps/console/src/__tests__/registry-inputs-spec-parity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ const OBJECTUI_11111_LEDGER_CAPS = {
*/
const UNJUDGED_SPEC_BLOCKS: Record<string, string> = {
'ai:chat_window':
'NOT REGISTERED, DELIBERATELY. `packages/components/src/renderers/placeholders.tsx` omits it from `PROTOCOL_COMPONENTS` in so many words — the floating chat overlay (plugin-chatbot) is the canonical entry point, an inline page-level chat window is not a supported surface, and a page schema referencing it should raise a loud unknown-type error rather than draw a placeholder. `app-shell/src/views/metadata-admin/previews/block-types.ts` records the same refusal. objectui#8176.',
'RETIRED UPSTREAM. `@objectstack/spec` 17.7.0 retired it by name (objectstack#21504, landed by objectstack#21531): out of `PageComponentType`, named in `RETIRED_PAGE_COMPONENT_TYPES`, and its row `retiredComponentProps` — a `never` that refuses every props bag, `{}` included, with a message that names the floating chat overlay as the AI chat entry point — so there is no authoring surface for either direction to judge. Until that release it stood here as NOT REGISTERED, DELIBERATELY: `PROTOCOL_COMPONENTS` in `@object-ui/components` `renderers/placeholders.tsx` omits it in so many words, which the retirement now says upstream too. objectui#11717, ledger objectui#8176.',
'app:launcher':
'EMPTY SPEC SHAPE. `ComponentPropsMap[app:launcher]` declares no props at all, so there is nothing for either direction to judge. It IS registered — `app-shell/src/views/app-launcher-renderer.tsx` registers it propless for exactly this reason, and says so — but by `@object-ui/app-shell`, which this file does not import; the empty shape is the load-bearing half either way. objectui#8176.',
'cloud-connection:panel':
Expand Down Expand Up @@ -1285,7 +1285,7 @@ const UNPUBLISHED_EXEMPTIONS: Record<string, string> = {
// five extra (`showPagination`, `defaultSort`, `defaultFilters`,
// `resizableColumns`, `title`) are the same class by the same test, so they are
// carved out with it. `defaultSort` has since been harvested — spec 17.3.0
// tombstoned it (see the note below), leaving nine. Trimming back to exactly five is a one-line reversal
// tombstoned it (see the note below), and `resizableColumns` followed at 17.7.0, leaving eight. Trimming back to exactly five is a one-line reversal
// (delete the entry, declare the input); publishing first and withdrawing later
// is not, which is why the exemption is the direction taken while the card is
// open.
Expand Down Expand Up @@ -1324,8 +1324,22 @@ const UNPUBLISHED_EXEMPTIONS: Record<string, string> = {
*/
'object-grid.defaultFilters':
'@deprecated in ObjectGridSchema ("Use filter instead"); GA describes it as the "Legacy base-filter fallback, read only when `filter` is absent. Prefer `filter`". Read as back-compat, deliberately not published — the canonical `filter` IS declared. Same ruled carve-out class as the five the ruling enumerated, measured on this branch — objectui#4648 (maintainer 2026-08-16).',
'object-grid.resizableColumns':
'@deprecated in ObjectGridSchema ("Moved to top-level resizable"); GA describes it as the "Alternate spelling of `resizable`". Read as back-compat, deliberately not published — the canonical `resizable` IS declared. Same ruled carve-out class as the five the ruling enumerated, measured on this branch — objectui#4648 (maintainer 2026-08-16).',
/*
* `object-grid.resizableColumns` WAS THE TENTH TOMBSTONE HARVESTED HERE —
* `@objectstack/spec` 17.7.0 (objectstack#21445, PR objectstack#21463), the way
* `defaultSort` above was at 17.3.0.
*
* 17.7.0 converted the key to a tombstone: `safeParse` of
* `{ resizableColumns: true }` fails `invalid_type` `expected: 'never'` at that
* path, with a message that opens "`object-grid` property `resizableColumns`
* was removed in @objectstack/spec 17.7.0 (ADR-0049) — it was the legacy
* second spelling of `resizable`", and `{ resizable: true }` parses. So the
* key left the AUTHORABLE set while staying listed, and the dangling and
* stale checks reported it exactly as designed; deleting the entry is the only
* way to green (objectui#11717). ⛔ Not resolved by declaring the input:
* `resizable`, the canonical spelling, is declared already. Retiring the
* renderer's own read of the old spelling is objectui#6152's.
*/
'object-grid.title':
'@deprecated in ObjectGridSchema ("Use label instead"); GA describes it as the "Fallback for `label` (the renderer reads `label || title`)". Read as back-compat, deliberately not published — the canonical `label` IS declared. Same ruled carve-out class as the five the ruling enumerated, measured on this branch — objectui#4648 (maintainer 2026-08-16).',

Expand Down Expand Up @@ -1671,7 +1685,6 @@ const GA_PENDING_UNPUBLISHED_KEYS = [
'object-grid.showSearch',
'object-grid.showPagination',
'object-grid.defaultFilters',
'object-grid.resizableColumns',
'object-grid.title',
];

Expand Down Expand Up @@ -3034,7 +3047,7 @@ const MEMBER_PINS: Record<string, MemberPin> = {
},
'object-master-detail-form.details': {
file: 'packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx',
pins: 'Members are detail-collection OBJECTS (`MasterDetailDetailConfig`), and unlike this block\'s parent keys the read site is THIS block: `MasterDetailForm` is the key\'s only reader. Each member renders as its own section in AUTHORED order, headed by `title` (fallback `Line Items`), with `columns` reaching the line grid in authored order. ⭐ The sharp row: four members reach the grid through ONE hand-written object under the grid\'s camelCase keys (objectui#11610): `minRows`, `maxRows` and `addLabel` by the same name, and `amountField` RENAMED to the grid\'s `totalField` (the CHILD column summed; the detail\'s own `totalField`, the PARENT field, is not forwarded), beside `columns` and the DERIVED `sortField` (objectui#11070 round 9 retired the detail\'s `sortField` member; row 2c pins that a written one is read by nothing). That object is pinned as a SORTED KEY SET of exactly six, with two off-list members (one in the grid\'s own spelling, `allowAdd`) asserted not forwarded and an all-empty control beside it. `inlineMode: \'form\'` makes a list whose Add opens the full form (labelled `Add` when unset), and in grid mode `formFields` wider than `columns` offers the row form; each arm is the other\'s control. `childObject` and `relationshipField` address the atomic batch (each line a create on the child, linked by `{ $ref: 0 }`) and the edit-mode read (`{ $filter: { FK: recordId }, $top: 500 }` per collection). `totalField` receives the sum of the lines\' `amountField` on the PARENT leg, and a collection without one puts nothing there. With `{ childObject }` alone the FK and the columns are DERIVED from the child object, the one member behaviour the spec\'s description promises, and the batch writes the derived FK. `details: []` is the non-vacuity control: no section, no grid, a one-leg batch. The line grid is the REAL `LineItemsField`, wrapped only to record the props it is handed. Since `@objectstack/spec` 17.6.0 (objectstack-ai/objectstack#21215) the spec row is an array of CLOSED entries — `childObject` required, `columns` the spec\'s inline grid column, an undeclared member key refused by name — and `@object-ui/types` takes that row by reference, so both published faces give the spec\'s verdict on an entry (`packages/types/src/__tests__/object-master-detail-form-details-entry-11396.test.ts`). `MasterDetailDetailConfig` is DERIVED from that entry (objectui#11396) and held `Equal` to it at compile time in the pinned file, with ONE stated fork: 17.6.0 declares `sortField`, which this block does not read (row 2c); objectstack `main` has since retired it (objectstack-ai/objectstack#21589, unreleased after 17.6.0), and the fork closes at the bump to the first release carrying that. The registration declares `of: \'object\'`, derived from the now single-kind member contract. A declaration fixes an entry\'s SHAPE, not what this block DOES with a member, so the read site is still the whole member contract. New file (objectui#8071 slice 18).',
pins: 'Members are detail-collection OBJECTS (`MasterDetailDetailConfig`), and unlike this block\'s parent keys the read site is THIS block: `MasterDetailForm` is the key\'s only reader. Each member renders as its own section in AUTHORED order, headed by `title` (fallback `Line Items`), with `columns` reaching the line grid in authored order. ⭐ The sharp row: four members reach the grid through ONE hand-written object under the grid\'s camelCase keys (objectui#11610): `minRows`, `maxRows` and `addLabel` by the same name, and `amountField` RENAMED to the grid\'s `totalField` (the CHILD column summed; the detail\'s own `totalField`, the PARENT field, is not forwarded), beside `columns` and the DERIVED `sortField` (objectui#11070 round 9 retired the detail\'s `sortField` member; row 2c pins that a written one is read by nothing). That object is pinned as a SORTED KEY SET of exactly six, with two off-list members (one in the grid\'s own spelling, `allowAdd`) asserted not forwarded and an all-empty control beside it. `inlineMode: \'form\'` makes a list whose Add opens the full form (labelled `Add` when unset), and in grid mode `formFields` wider than `columns` offers the row form; each arm is the other\'s control. `childObject` and `relationshipField` address the atomic batch (each line a create on the child, linked by `{ $ref: 0 }`) and the edit-mode read (`{ $filter: { FK: recordId }, $top: 500 }` per collection). `totalField` receives the sum of the lines\' `amountField` on the PARENT leg, and a collection without one puts nothing there. With `{ childObject }` alone the FK and the columns are DERIVED from the child object, the one member behaviour the spec\'s description promises, and the batch writes the derived FK. `details: []` is the non-vacuity control: no section, no grid, a one-leg batch. The line grid is the REAL `LineItemsField`, wrapped only to record the props it is handed. Since `@objectstack/spec` 17.6.0 (objectstack-ai/objectstack#21215) the spec row is an array of CLOSED entries — `childObject` required, `columns` the spec\'s inline grid column, an undeclared member key refused by name — and `@object-ui/types` takes that row by reference, so both published faces give the spec\'s verdict on an entry (`packages/types/src/__tests__/object-master-detail-form-details-entry-11396.test.ts`). `MasterDetailDetailConfig` is DERIVED from that entry (objectui#11396) and held `Equal` to it at compile time in the pinned file, minus ONE key, `sortField`, which this block does not read (row 2c): a fork through 17.6.0, closed by `@objectstack/spec` 17.7.0, whose entry refuses an authored `sortField` with its retired-key message (objectstack-ai/objectstack#21589, objectui#11717). The registration declares `of: \'object\'`, derived from the now single-kind member contract. A declaration fixes an entry\'s SHAPE, not what this block DOES with a member, so the read site is still the whole member contract. New file (objectui#8071 slice 18).',
},
'object-master-detail-form.fields': {
file: 'packages/plugin-form/src/__tests__/topLevelFieldsWarnCoverage-8847.test.tsx',
Expand Down Expand Up @@ -4929,7 +4942,6 @@ describe('registry `inputs` vs `@objectstack/spec` ComponentPropsMap (repo-wide)
'defaultFilters',
'fields',
'pageSize',
'resizableColumns',
'selectable',
'showPagination',
'showSearch',
Expand Down Expand Up @@ -5182,7 +5194,7 @@ describe('registry `inputs` vs `@objectstack/spec` ComponentPropsMap (repo-wide)
}
});

it('the nine tombstoned keys are recognised, not exempted — and not published either', () => {
it('the ten tombstoned keys are recognised, not exempted — and not published either', () => {
// The pin the harvest leaves behind (objectui#3809). Deleting eight
// exemptions is only half the change: the derived assertions above would go
// green just as readily if a future edit RE-EXEMPTED one of these keys, or
Expand All @@ -5192,8 +5204,9 @@ describe('registry `inputs` vs `@objectstack/spec` ComponentPropsMap (repo-wide)
// the same reason the `#3808 / #3830` and `rc.6 record_picker` pins next door
// are written by name.
//
// Six upstream retirements, nine keys, several facts each (eight through
// 17.4.0; `object-kanban.quickAdd` joined at 17.5.0). The list is
// Seven upstream retirements, ten keys, several facts each (eight through
// 17.4.0; `object-kanban.quickAdd` joined at 17.5.0, and
// `object-grid.resizableColumns` at 17.7.0). The list is
// pin-dependent by construction and that is the point: it is the measurement
// (`@objectstack/spec@17.0.0`, and the same eight on the rc.6 that preceded
// it — this change was verified on both), so a pin that un-retires one of
Expand All @@ -5212,6 +5225,9 @@ describe('registry `inputs` vs `@objectstack/spec` ComponentPropsMap (repo-wide)
// (objectui#11073): objectui#8285's ruled retirement, which emptied
// `LAZY_BLOCK_RULED_CARVE_OUTS` in the same change.
['object-kanban', 'quickAdd'],
// The tenth, harvested at the 17.7.0 bump (objectui#11717):
// objectstack#21445 retired the legacy second spelling of `resizable`.
['object-grid', 'resizableColumns'],
];

for (const [type, key] of HARVESTED) {
Expand Down
Loading
Loading