Skip to content

Commit 134015d

Browse files
authored
Merge branch 'main' into claude/issue-10899-hosted-console-ux-defects
2 parents d8969d4 + 29c76e5 commit 134015d

36 files changed

Lines changed: 1288 additions & 287 deletions

‎.changeset/10321-named-view-kanban-groupby-refused.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ bag. The issue is `custom` at `listViews.KEY.kanban.groupBy` or
2121
`groupBy`. Did you mean `groupBy` → `groupByField`?", followed by the same
2222
explanation. Write `groupByField` (or the deprecated `groupField`).
2323

24+
⚠️ **Dated note, 2026-09-28 — `listViews` has since been mirrored, and the
25+
`options.kanban` bag is refused whole — objectui#7928.** Later in this same release
26+
`ObjectViewSchema.listViews` became the protocol's strict `ObjectListViewSchema` record,
27+
by reference, so "`ObjectViewSchema.listViews` is unmirrored" above no longer holds. The
28+
protocol now refuses `listViews.KEY.kanban.groupBy` itself (`unrecognized_keys` at
29+
`listViews.KEY.kanban`), and this check still adds its `custom` issue at
30+
`listViews.KEY.kanban.groupBy`, with the same message. It no longer judges the legacy
31+
bag: the record refuses a named view's `options` whole (`unrecognized_keys` at
32+
`listViews.KEY`, naming `options`), so nothing reports
33+
`listViews.KEY.options.kanban.groupBy`. `.changeset/7928-listviews-by-reference-fold.md`
34+
(PR objectui#10821) states what ships; the text above is kept as the reading of this change.
35+
2436
The protocol agrees on this route too. Measured on `@objectstack/spec` 17.4.0
2537
when this change was made, `ViewSchema` refuses `listViews.KEY.kanban.groupBy`
2638
as an unrecognized key exactly as `ListViewSchema` refuses `kanban.groupBy`,
@@ -43,3 +55,16 @@ an undeclared sibling in the kanban block nor the legacy `options` bag itself;
4355
the value type `listViews` should enforce is objectui#7928's. `groupBy` is not
4456
honoured as an alias (the ruling rules that out), and `groupBy` on the generated
4557
`object-kanban` node, the lane key `ObjectKanban` reads, is untouched.
58+
59+
⚠️ **Dated note, 2026-09-28 — what a written key now reports, and what the record now
60+
refuses — objectui#7928.** Later in this same release the named-view record became the
61+
protocol's own, by reference. A `groupBy` in a named view's `kanban` block now reports
62+
two issues, the protocol's `unrecognized_keys` and this entry's pointer; one in the
63+
`options.kanban` bag reports only the refusal of `options`, which names neither `groupBy`
64+
nor `groupByField`. So "one issue per written key, naming the key and the replacement"
65+
no longer holds. `ObjectViewSchema` now declares the value type the paragraph above
66+
defers to objectui#7928: `listViews` is in its shape, a named view needs `columns`, and
67+
the record refuses an undeclared sibling in the kanban block and the `options` bag. This
68+
entry's check now adds its message to a document the record already refuses.
69+
`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships;
70+
the text above is kept as the reading of this change.

‎.changeset/10584-object-chart-series-describe.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,16 @@ The TypeScript docblock on the same member now says the omission is deliberate
1515
rather than a lag: taking `type` up would widen a published accept set, and
1616
that waits for a named producer that writes it on an `object-chart` node.
1717

18+
⚠️ **Dated note, 2026-09-28 — `series` has since become two arms — objectui#10770.** Later
19+
in this same release each `ObjectChartSchema.series` entry became ONE of two arms, on
20+
both faces: the spec's `ChartSeriesSchema` (`{ name }`, by reference, the AUTHOR arm) or
21+
the internal `{ dataKey }` arm. The `.describe()` and the docblock now describe both. So
22+
"the copy is that `{ dataKey }` arm minus its per-series `type`" holds for the internal
23+
arm only, and `chartType` is the per-series family override on that arm only: on a
24+
`{ name }` entry the override is the spec's `type`, which an `object-chart` node now
25+
accepts. The deliberate omission of `type` stands on the `{ dataKey }` arm, where the
26+
zod mirror still strips it. `.changeset/10770-object-chart-react-tier-node.md` (PR
27+
objectui#10802) states what ships; the text above is kept as the reading of this change.
28+
1829
Wording only. The accepted shape does not move on either face: the element
1930
type, its members and the mirror's parse result are what they were.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@object-ui/auth': minor
3+
'@object-ui/console': patch
4+
---
5+
6+
fix(auth, console): a registration started from an invitation link comes back to the invitation after email verification
7+
8+
better-auth builds the verification mail's link server-side from the
9+
`/sign-up/email` request's `callbackURL`, defaulting it to `/`. The console kept
10+
`?redirect=/accept-invitation/ID` from the login page through `/register` to the
11+
"check your inbox" screen, but `createAuthClient().signUp` never sent a
12+
`callbackURL`, so the mail read `callbackURL=/` and the invitee verified onto the
13+
workspace picker ("Create workspace") instead of the invitation.
14+
15+
`@object-ui/auth` (additive):
16+
17+
- `SignUpData.callbackURL` is forwarded verbatim to `/sign-up/email`. Absent, the
18+
key stays off the wire and the server default is untouched.
19+
- `useAuth().signUp(name, email, password, callbackURL?)` takes it as an optional
20+
fourth argument.
21+
- `RegisterForm` gains a `verificationCallbackURL` prop, forwarded to `signUp`.
22+
23+
`@object-ui/console`:
24+
25+
- `RegisterPage` passes a safe `?redirect=` as the verification callback, and the
26+
verify-email prompt's "Resend" sends the same value. Before, Resend sent the
27+
bare router path, which the server redirects to at the ORIGIN root, outside
28+
the `/_console` mount.
29+
- Both resolve the route through the new `withConsoleBaseRootRelative`. The server
30+
never sees `<base href>`, and better-auth refuses a document-relative `./…`
31+
callback — what `withConsoleBase` answers in the embedded build — with
32+
`403 INVALID_CALLBACK_URL`, failing the whole sign-up.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
---
3+
4+
Rewrite the `JoinedReportBlock` pin in `report-chart-query-spec-parity.test.ts`
5+
(objectui#10916) so it compiles against both the installed `@objectstack/spec`
6+
17.4.0, which still erases the block type to `unknown`, and spec `main`, which
7+
objectstack#20369 typed. A test-time tripwire now fails at the first spec bump
8+
past 17.4.0, which is when the burn-down it records becomes possible. Test and
9+
ledger text only; no package is released by this change.

‎.changeset/7924-named-list-view-retire.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ sixteen members on its TypeScript authoring face (objectui#7924). Each is now a
77
`?: never` tombstone: a TypeScript author who writes one gets a compile error at that
88
key, and the member's docblock names the key to write instead.
99

10+
⚠️ **Dated note, 2026-09-28 — `NamedListView` no longer types a named view —
11+
objectui#7928.** Later in this same release `ObjectViewSchema.listViews` became the
12+
protocol's own record by reference: on both faces its value is `@objectstack/spec`'s
13+
strict `ObjectListViewSchema`, and a `NamedListView` is not assignable to it. So "one
14+
entry of `ObjectViewSchema.listViews`" above no longer holds. `NamedListView` stays
15+
exported with the tombstones this entry describes; a retired spelling written in a
16+
named view is refused there by the protocol's record as an unrecognized key, not by a
17+
tombstone here and its pointer. `.changeset/7928-listviews-by-reference-fold.md` (PR
18+
objectui#10821) states what ships; the text above is kept as the reading of this change.
19+
1020
**The eight legacy `show*` spellings** (bucket ② of the director-seat ruling on
1121
objectui#7924, letter **A**). None is a protocol key on a view; the protocol's
1222
`userActions` and `appearance` blocks are the canonical home, and `NamedListView`
@@ -43,6 +53,14 @@ row-colour configuration `rowColor: { field }`, and `addRecordViaForm` at the
4353
`densityMode` is folded onto `rowHeight` by `normalizeListViewSchema`. They stay
4454
declared as they were.
4555

56+
⚠️ **Dated note, 2026-09-28 — `densityMode` has since been retired too — objectui#7924.**
57+
Later in this same release ruling A′ made `NamedListView.densityMode` a `?: never`
58+
tombstone as well, its docblock pointing at top-level `rowHeight`. So "Two bucket-③
59+
members are NOT retired" and "They stay declared as they were" now hold for
60+
`allowExport` only. `normalizeListViewSchema` still folds a stored `densityMode` onto
61+
`rowHeight`. `.changeset/7924-density-mode-through-fold.md` (PR objectui#10793) states
62+
what ships; the text above is kept as the reading of this change.
63+
4664
**Only the authoring face changes.** Stored view documents that still carry a legacy
4765
spelling keep loading: `normalizeListViewSchema` (`@object-ui/core`) still folds the eight
4866
`show*` flags onto `userActions` / `appearance` at runtime, and hosts that read a stored

‎.changeset/8355-retire-calendar-date-aliases.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ to `SchemaRenderer` never parses the mirror at all — `SchemaRenderer` runs the
8484
structural core validator, which is dev-only and names no key — so the compiler
8585
is that population's channel, not this one.
8686

87+
⚠️ **Dated note, 2026-09-28 — a named view's `options.calendar` nesting is no longer
88+
judged inside — objectui#7928.** Later in this same release `ObjectViewSchema.listViews`
89+
became the protocol's strict `ObjectListViewSchema` record, by reference, and that
90+
record refuses a named view's `options` bag whole (`unrecognized_keys` at
91+
`listViews.KEY`, naming `options`). So an alias written under
92+
`listViews.KEY.options.calendar` no longer draws an issue naming the key or the remedy.
93+
The named view's `calendar` block still does: the protocol refuses the alias there as an
94+
unrecognized key, and this entry's check adds the pointer at the key beside it. A stored
95+
body that `@object-ui/app-shell`'s `ViewPreview` relays has its `options.calendar` folded
96+
onto the `calendar` block first (`foldStoredListOptions`). The list view's two nestings
97+
and both `object-calendar` surfaces are unchanged; `calendar-date-alias-refusal-8355.test.ts`
98+
in `@object-ui/types` re-derives each surface. `.changeset/7928-listviews-by-reference-fold.md`
99+
(PR objectui#10821) states what ships; the text above is kept as the reading of this change.
100+
87101
⚠️ **Why this is `minor` and not `major`.** This repository forbids `major` in a
88102
changeset: the fixed release group's major tracks `@objectstack`'s, so any
89103
`major` here would push all of it off that cadence
@@ -136,6 +150,19 @@ undeclared key nor the legacy `options` bag. It judges exactly the two spellings
136150
this entry retires, at the two nestings the producer merges — with pins on each
137151
of those non-effects.
138152

153+
⚠️ **Dated note, 2026-09-28 — `listViews` has since been mirrored — objectui#7928.** Later
154+
in this same release the maintainer's ruling A chose the value type this paragraph waits
155+
on: `ObjectViewSchema.listViews` is now `@objectstack/spec`'s own
156+
`ViewSchema.shape.listViews`, a record of the strict `ObjectListViewSchema`, by reference
157+
on both faces. It is in the object's `shape`, a named view needs `columns`, and the
158+
record refuses an undeclared key and the legacy `options` bag whole. The named-view check
159+
described here and in the `@object-ui/types` bullet above now reads the protocol's own
160+
refusal at `listViews.KEY.calendar` and adds the pointer at the key; it no longer walks
161+
the `options.calendar` nesting, so "a named view's two nestings" and "at the two nestings
162+
the producer merges" now hold for the `calendar` block only.
163+
`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships;
164+
the text above is kept as the reading of this change.
165+
139166
⛔ **Not a producer-side fold.** Normalising `dateField` to `startDateField` in
140167
`ListView` (option A) was put to the director seat and refused as the end state:
141168
it keeps a second spelling alive at the producer, which is the lenient alias
@@ -184,3 +211,12 @@ structural guard that `listViews` stays out of the object's `shape`),
184211
reading the node their producer really emits through a spy registration, which is
185212
the only census that can see a key arriving through a spread — and the inverted
186213
ledger rows in `calendarUnionReads-8651.test.tsx` (`@object-ui/plugin-calendar`).
214+
215+
⚠️ **Dated note, 2026-09-28 — a named view now refuses `timeline.dateField`, and the
216+
shape guard is inverted — objectui#7928.** Later in this same release the protocol's
217+
strict named-view record refuses `timeline.dateField` on a named view as an unrecognized
218+
key; the `list-view` route still accepts it, and that route is the one the timeline pin
219+
reads. The structural guard in `calendar-date-alias-refusal-8355.test.ts` now asserts
220+
the opposite of "`listViews` stays out of the object's shape": `listViews` is a member
221+
of `ObjectViewSchema.shape`. `.changeset/7928-listviews-by-reference-fold.md` (PR
222+
objectui#10821) states what ships; the text above is kept as the reading of this change.

‎.changeset/8365-stray-kanban-groupby-refused.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ fallback and was **not** taken):
4040
this arm; objectui#10321 gives that route its own door, which refuses the key
4141
in either nesting with the same message.
4242

43+
⚠️ **Dated note, 2026-09-28 — a named view's `options.kanban` bag is refused whole —
44+
objectui#7928.** Later in this same release a named view became the protocol's strict
45+
`ObjectListViewSchema` record, by reference, which refuses its `options` bag by name
46+
(`unrecognized_keys` at `listViews.KEY`, naming `options`). So the objectui#10321 door no
47+
longer refuses the key "in either nesting with the same message": it still adds that
48+
message at `listViews.KEY.kanban.groupBy`, beside the protocol's own refusal of the key,
49+
and nothing reports `listViews.KEY.options.kanban.groupBy`. A stored body that
50+
`@object-ui/app-shell`'s `ViewPreview` relays has its `options.kanban` folded onto the
51+
`kanban` block first (`foldStoredListOptions`). The `list-view` route described above is
52+
unchanged, its `options.kanban` check included.
53+
`.changeset/7928-listviews-by-reference-fold.md` (PR objectui#10821) states what ships;
54+
the text above is kept as the reading of this change.
55+
4356
**Breaking, in the sense worth stating explicitly** (shipped `minor`: this repo
4457
never declares `major`, and `.changeset/config.json` puts every package in one
4558
`fixed` group, so levels cannot be split). Two behaviours change for **stored
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
'@object-ui/app-shell': minor
3+
---
4+
5+
The metadata-admin `SchemaForm` no longer crashes on a form section that references a field group, and the form-section authoring type accepts that shape (objectui#8725).
6+
7+
**Clause-②: yes** — two exported types change shape. `FormSectionSpec.fields` becomes optional, which widens what an author may write to match `@objectstack/spec`. `RichMetadataTypeEntry.form` narrows from `Record<string, unknown>` to `FormViewSpec`.
8+
9+
**BREAKING (types).** A consumer that reads `section.fields` unguarded, or indexes `FormSectionSpec['fields'][number]`, no longer compiles (`TS18048` / `TS2537`), because a `{ group }` section carries no `fields`. Read the element type through `NonNullable`. Do not default the list with `?? []`: a `{ group }` section then renders as a silently empty one. A consumer that treated `RichMetadataTypeEntry.form` as an open record now gets the `FormViewSpec` keys only. Outside `SchemaForm`, whose three reads are what this change fixes, no published source in this repository had to change. The other readers that changed were tests: two type-level pins, one in this package and one in `apps/console` (`FormPage.fieldSpec.test.ts`), and four `mergeServerFields` assertions.
10+
11+
**What was wrong.** `@objectstack/spec` lets a form section declare its members one of two ways: enumerate `fields`, or point `group` at a declared field group. The `/meta/types` registry hands its form document to `SchemaForm` without validation, and a `{ group }` section reached the renderer's first `fields` read. That read threw `TypeError: s.fields is not iterable` out of the component body and blanked the whole form, well-formed sections included, on both the simple and the tabbed layout. The required `fields` on `FormSectionSpec` only stopped a TypeScript author from writing the shape; the server channel carried it anyway, through an `as any` cast.
12+
13+
**What changed, in observable terms.**
14+
15+
- Every read of a section's `fields` in `SchemaForm` now sees a resolved section. A `{ group }` section goes through `@object-ui/plugin-form`'s `resolveSectionGroupReferences`, the resolver `ObjectForm` and the console `FormPage` already use, so `SchemaForm` gives their answer.
16+
- No `SchemaForm` host carries an object definition, and `/meta/types` declares no field groups for a metadata type. So a `{ group }` section in a metadata-type editor names no declared field group. For that case the resolver renders the section empty and reports the dangling key once on `console.error`, naming the group and the form's `schemaId`. The other sections render normally.
17+
- A section that declares neither `fields` nor `group` is still refused out loud. The render throws a `TypeError` that names the section; it does not draw an empty section.
18+
- `RichMetadataTypeEntry.form` is typed `FormViewSpec`, and the `as any` casts where `ResourceEditPage` and `EmbeddedItemEditor` hand it to `SchemaForm` are gone.
19+
20+
No change for any form none of whose sections carries a `group` key: the resolver returns such a list by identity. A section carrying both `fields` and `group`, a shape `@objectstack/spec` refuses at parse, now takes the resolver's answer for its `group` (in a metadata-type editor, an empty section and the same `console.error`) instead of rendering its enumerated `fields`.

‎.changeset/9242-stray-kanban-groupby-lane-second-route.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ storage nor one that never passes through a validator, so what this change
4040
repairs is a pure **behaviour** gap, on any document that reaches this branch
4141
carrying the key.
4242

43+
⚠️ **Dated note, 2026-09-28 — the named-view route's two faces have since changed —
44+
objectui#7928.** Later in this same release a named view became the protocol's strict
45+
`ObjectListViewSchema` record, by reference, on both faces. On the zod face the
46+
objectui#10321 door adds its message at `listViews.KEY.kanban.groupBy` only: the record
47+
refuses the `options` bag whole (`options` by name), so "refuses the key in either
48+
nesting with the same message" no longer holds. On the TypeScript face a named view's
49+
`kanban` is typed as the protocol's kanban block, not the `list-view`'s: `tsc` still
50+
refuses `kanban.groupBy` there, as an excess property on an object literal rather than a
51+
`never` member, and it now refuses the `options` bag itself. The `list-view` route is
52+
unchanged on both faces. `.changeset/7928-listviews-by-reference-fold.md` (PR
53+
objectui#10821) states what ships; the text above is kept as the reading of this change.
54+
4355
Maintainer ruling of 2026-09-12 (decision batch #117 item 5, verbatim
4456
「8365 同意」) — option B. Option A (strip the key and silently re-group) was not
4557
taken. This card applies that ruling to the second route; it re-opens nothing.

0 commit comments

Comments
 (0)