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
83 changes: 19 additions & 64 deletions content/docs/guide/release-notes.md
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,26 @@
---
title: "Release Notes"
description: "Release notes for ObjectUI — highlights, breaking changes and migration notes for each version."
description: "Where to find what shipped in each ObjectUI release — the per-package changelogs and GitHub Releases."
---

# Release Notes

This page summarises every released version of ObjectUI. For granular, per-release
detail, read the `CHANGELOG.md` published inside each `@object-ui/*` package —
Changesets writes those on every release commit, so they are the source of truth
for current history. The monorepo
ObjectUI does not keep a hand-written release history on this page. Two sources carry
it, both written as part of the release itself:

- **Each package's own `CHANGELOG.md`** — the source of truth for granular history.
Changesets writes an entry into every affected `@object-ui/*` package on each release
commit, so the changelog beside the package you depend on states exactly what changed
in it, including breaking changes and migration notes. Read it in the installed
package (`node_modules/@object-ui/<name>/CHANGELOG.md`), on that package's npm page,
or in this repository under
[`packages/<name>/CHANGELOG.md`](https://github.com/objectstack-ai/objectui/tree/main/packages).
- **[GitHub Releases](https://github.com/objectstack-ai/objectui/releases)** — every
published version, newest first, with its tag and publication date. Start here to see
which version is current.

The monorepo
[CHANGELOG.md](https://github.com/objectstack-ai/objectui/blob/main/CHANGELOG.md)
is a periodically hand-curated summary, not an auto-maintained record, and can lag
the latest releases.

## v3.3.0 — 2026-04-17 · First Official Release 🚀

v3.3.0 is the **first official release** of ObjectUI published for third-party
consumption. All 39 packages under `packages/*` are now published to npm with
complete release metadata and aligned with `@objectstack/spec` ^4.0.4 and
`@objectstack/client` v3.3.0.

### Highlights

- **39 published packages** (`@object-ui/*`) with
standardized `package.json` metadata, per-package `LICENSE` and
`CHANGELOG.md`.
- **Standard README template** applied across every package (Installation →
Quick Start → API → Compatibility → Links → License).
- **Refreshed docs site** with up-to-date architecture overview, plugin
coverage and schema reference.
- **Thin integration packages** — `@object-ui/app-shell` (~50 KB) and
`@object-ui/providers` (~10 KB) enable third-party integrations without
inheriting the full console.
- **Spec v4 alignment** — plain-string `label` types across Navigation
schemas; Protocol bridges (`DndProtocol`, `KeyboardProtocol`,
`NotificationProtocol`) updated.
- **Unified Copilot Skills** — single `skills/objectui/` tree aligned with
shadcn/ui best practices.

### Upgrade Notes

If you were pinning to the earlier `0.x` prerelease tags:

1. Bump every `@object-ui/*` dependency to `^3.3.0`.
2. Ensure peer dependencies match the new baselines
(`react ^18 || ^19`, `react-dom ^18 || ^19`, TypeScript `>=5.0`).
3. Replace any `i18n` label objects (`{ key, defaultValue }`) on Navigation
schemas with plain strings — runtime `resolveI18nLabel()` still handles
both formats for backward compatibility.
4. Remove imports of the deprecated `ViewDesigner` — its capabilities are now
delivered by `ViewConfigPanel`.

### Compatibility Matrix

| Package | Version |
| --- | --- |
| `@object-ui/*` | `3.3.0` |
| `@objectstack/spec` | `^4.0.4` |
| `@objectstack/client` | `3.3.0` |
| React | `18.x` or `19.x` |
| Node.js | `≥ 18` |
| TypeScript | `≥ 5.0` (strict) |
| Tailwind CSS | `≥ 3.4` |

## Previous Versions

See the [monorepo CHANGELOG](https://github.com/objectstack-ai/objectui/blob/main/CHANGELOG.md)
for the hand-curated summary of earlier versions, including the `0.x` development
series. It is maintained by hand rather than generated, so treat each package's own
`CHANGELOG.md` as authoritative where the two disagree.
is a periodically hand-curated summary, not an auto-maintained record, and can lag the
latest releases. Treat each package's own `CHANGELOG.md` as authoritative where the two
disagree.
77 changes: 63 additions & 14 deletions scripts/__tests__/doc-version-claims.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

Expand DownExpand Up@@ -1307,22 +1308,70 @@ describe('doc version claims - the scan itself', () => {
});

it('exercises the version-heading exemption, so the exemption is not decorative', () => {
// objectui#3697 names two lines as the control group that must stay green:
// objectui#3697 named two lines as the control group that must stay green:
// release-notes.md's `Bump every @object-ui/* dependency to ^3.3.0` upgrade step
// and the `| Node.js | >= 18 |` row of the v3.3.0 compatibility matrix. Green by
// NOT MATCHING would prove nothing, so the floor asserts the exemption path is
// actually taken, and the file assertion names where.
expect(
exemptClaims.length,
'no claim was structurally exempted - either release-notes.md lost its version ' +
'sections or VERSION_HEADING stopped matching them, and the exemption this gate ' +
'depends on is now untested',
).toBeGreaterThanOrEqual(8);
// and the `| Node.js | >= 18 |` row of its v3.3.0 compatibility matrix. Both are
// gone: objectui#5786 retired that page's hand-written version table — it had
// drifted ~14 majors behind the packages it described and the maintainer ruled it
// away in favour of the per-package `CHANGELOG.md` files — and it was the corpus's
// ONLY version-heading section. Measured across that change: `exemptClaims` went
// from 8 to 0, and this assertion was the one gate that noticed.
//
// So the control group cannot be a corpus file any more, and a floor over
// `exemptClaims.length` would now be a pin demanding that SOME published page keep
// carrying release sections — a shape this repository deliberately no longer has.
// The exemption is still live code that every corpus claim passes through, so it is
// exercised here against a fixture, via `claimsIn`, the same function the corpus
// goes through. The fixture keeps the retired compatibility row verbatim and states
// the spec range the way that page did (name, then version, within `SEP`'s six
// characters — `Bump every @object-ui/* dependency to ^3.3.0` is a sentence, and a
// sentence is not a claim: its name and version sit fourteen characters apart). The
// assertion is strictly stronger than the one it replaces: BOTH directions are
// pinned on one document, which the corpus arrangement never did — there, "green by
// NOT MATCHING" was ruled out only for the exempt side.
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'doc-version-claims-'));
try {
const fixture = path.join(dir, 'release-notes-shaped.md');
fs.writeFileSync(
fixture,
[
'# Release Notes',
'',
'At the time of writing it aligned with `@objectstack/spec` ^4.0.4.',
'',
'## v3.3.0 — 2026-04-17 · First Official Release',
'',
'### Compatibility Matrix',
'',
'| Node.js | >= 18 |',
'',
].join('\n'),
'utf8',
);

const exemptFiles = new Set(exemptClaims.map((c) => c.file));
expect(exemptFiles, 'the v3.3.0 release section must still be reached by the exemption').toContain(
'content/docs/guide/release-notes.md',
);
const claims = claimsIn(fixture);
const exempt = claims.filter((c) => c.underVersionHeading !== null);
const flagged = claims.filter((c) => c.underVersionHeading === null);

expect(
flagged.map((c) => c.claim),
'the claim ABOVE the release heading must stay SCANNED - an exemption that ' +
'swallowed the whole file would report green over a live claim',
).toEqual([expect.stringContaining('^4.0.4')]);

expect(
exempt.map((c) => c.claim),
'the claim under the release heading must be exempt, or the frozen history this ' +
'gate refuses to ratchet would start failing it',
).toEqual([expect.stringContaining('>= 18')]);

// Via an ANCESTOR heading: the matrix row sits under `### Compatibility Matrix`,
// not directly under the release heading. That walk is the part of `collect` a
// narrower "nearest heading" rule would silently break.
expect(exempt[0].underVersionHeading).toBe('v3.3.0 — 2026-04-17 · First Official Release');
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
});

it('does not treat a numbered section heading as a release section', () => {
Expand Down
Loading