Skip to content

Commit 021048c

Browse files
committed
merge main (cutover #25825 + 4a #25745) into the 2b branch
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
2 parents a2fec85 + 2a61f08 commit 021048c

9,312 files changed

Lines changed: 2586924 additions & 12207 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@objectstack/console': patch
3+
'@objectstack/cli': patch
4+
---
5+
6+
build(console): `@objectstack/console` is built in this workspace from `ui/apps/console`, and the Console no longer arrives through a pinned objectui commit
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
- **The package.** `@objectstack/console` ships the same `dist/` it shipped at 18.1.0: the built Console (`index.html`, `assets/`, the manifests it served). Two files leave the tarball: `dist/.objectui-sha`, which named the objectui commit the Console was built from, and `dist/.objectstack-injection.json`, which recorded the spec and client dists injected into that build. Both described a pin that no longer exists: the Console is built from the `ui/` tree of the same commit as the framework, so its version is the framework's version.
12+
- **The CLI.** When a framework checkout has no built Console, `objectstack serve` / `objectstack dev` and the 503 at `/_console/` now name `pnpm console:build`, which builds `ui/apps/console` and copies its dist into `packages/console`. The remedy used to be `pnpm objectui:build`, which cloned objectui at the pinned commit.
13+
- **One version.** The `@object-ui/*` packages and the private VS Code extension join the `@objectstack/*` fixed group, so every public package of both scopes publishes at one version and the extension ships at it.
14+
15+
What to do: nothing as a consumer; install `@objectstack/console` as before. In a framework checkout, run `pnpm console:build` where you ran `pnpm objectui:build`.

‎.changeset/config.json‎

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,52 @@
8080
"@objectstack/account",
8181
"create-objectstack",
8282
"@objectstack/connector-openapi",
83-
"@objectstack/verify"
83+
"@objectstack/verify",
84+
"@object-ui/app-shell",
85+
"@object-ui/auth",
86+
"@object-ui/cli",
87+
"@object-ui/collaboration",
88+
"@object-ui/components",
89+
"@object-ui/console",
90+
"@object-ui/core",
91+
"@object-ui/create-plugin",
92+
"@object-ui/data-objectstack",
93+
"@object-ui/fields",
94+
"@object-ui/i18n",
95+
"@object-ui/layout",
96+
"@object-ui/mobile",
97+
"@object-ui/permissions",
98+
"@object-ui/plugin-ai",
99+
"@object-ui/plugin-calendar",
100+
"@object-ui/plugin-charts",
101+
"@object-ui/plugin-chatbot",
102+
"@object-ui/plugin-dashboard",
103+
"@object-ui/plugin-designer",
104+
"@object-ui/plugin-detail",
105+
"@object-ui/plugin-editor",
106+
"@object-ui/plugin-form",
107+
"@object-ui/plugin-gantt",
108+
"@object-ui/plugin-grid",
109+
"@object-ui/plugin-kanban",
110+
"@object-ui/plugin-list",
111+
"@object-ui/plugin-map",
112+
"@object-ui/plugin-markdown",
113+
"@object-ui/plugin-report",
114+
"@object-ui/plugin-timeline",
115+
"@object-ui/plugin-tree",
116+
"@object-ui/plugin-view",
117+
"@object-ui/providers",
118+
"@object-ui/react",
119+
"@object-ui/react-runtime",
120+
"@object-ui/sdui-parser",
121+
"@object-ui/types",
122+
"object-ui"
84123
]
85124
],
86125
"linked": [],
87126
"access": "public",
88127
"baseBranch": "main",
89128
"updateInternalDependencies": "patch",
90-
"ignore": [],
129+
"ignore": ["@object-ui/example-*", "@object-ui/site", "@object-ui/runner", "@object-ui/test-support"],
91130
"privatePackages": { "version": true, "tag": false }
92131
}

‎.github/workflows/cut-rc.yml‎

Lines changed: 33 additions & 167 deletions
Large diffs are not rendered by default.

‎.github/workflows/lint.yml‎

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,31 +3064,6 @@ jobs:
30643064
continue-on-error: true
30653065
run: pnpm check:startup-registry-verdict
30663066

3067-
# objectui pin-changeset guard (#4731). A frontend-only refresh reaches the
3068-
# platform release record ONLY through the changeset `bump-objectui.sh`
3069-
# writes, and that list used to be guessed off objectui's commit subjects
3070-
# (`feat|fix` + a silent `head -40`). On one real range the guess dropped
3071-
# all 13 releasing non-feat/fix commits — every breaking `refactor(...)!`
3072-
# among them — and pulled in 5 that release nothing. The list and the bump
3073-
# level now come from what objectui DECLARED (`.changeset/*.md` added over
3074-
# the range; empty frontmatter = release-nothing). This self-test builds
3075-
# throwaway git repos carrying those exact shapes, runs the real scripts
3076-
# over them, and asserts the emitted changeset — including that a cap which
3077-
# fires announces itself and that an unwalkable range degrades loudly.
3078-
# #4843 folded `scripts/objectui-range.mjs` — the release page's Console
3079-
# section — onto that same `classifyRange()` criterion, so both self-tests
3080-
# run here: one criterion, two consumers, no room to drift apart.
3081-
- name: objectui pin-changeset digest guard
3082-
id: objectui-pin-changeset-digest-guard
3083-
continue-on-error: true
3084-
run: pnpm check:objectui-changeset
3085-
3086-
# Rationale: `scripts/bump-objectui.selftest.sh` header (#10797).
3087-
- name: objectui pin write-ordering guard
3088-
id: objectui-pin-write-ordering-guard
3089-
continue-on-error: true
3090-
run: pnpm check:objectui-bump
3091-
30923067
# Changeset-family gate self-tests (#6509). The SELF-TEST halves only —
30933068
# the real scans stay in pr-automation.yml's `changeset-check`, and the
30943069
# split is the whole point of this step.

‎.github/workflows/release.yml‎

Lines changed: 18 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,109 +1835,26 @@ jobs:
18351835
run: node scripts/check-changeset-fixed.mjs
18361836

18371837
# ──────────────────────────────────────────────────────────────────────
1838-
# ⛔ TOMBSTONE — the #3340 pin-currency gate that used to sit here is gone
1839-
# (2026-08-20 ruling, #10134). Do not re-add one.
1838+
# ⛔ TOMBSTONE — no objectui pin is read, built or checked here, and none
1839+
# is re-added (objectstack#25711, D1 ruling 「同一个版本号组」).
18401840
#
1841-
# It compared `.objectui-sha` against objectui `main` at publish time and
1842-
# refused a release whose pin lagged. The ruling removed the question, not
1843-
# just the job: WHICH objectui revision this repo pins is a decision taken
1844-
# in an objectstack issue, never derived from another repo's HEAD, so
1845-
# "the pin is behind main" is not a defect a release lane may diagnose.
1846-
#
1847-
# R4's lesson (#6170 — "a gate required on a PR the publishing lane can
1848-
# skip is not a gate") is untouched and does not resurrect this one:
1849-
# #3340's actual invariant is "everything published is covered by the
1850-
# changeset record", and that is carried by `scripts/bump-objectui.sh` +
1851-
# `scripts/objectui-changeset-digest.mjs` at BUMP time — on the manual pin
1852-
# PR, which is now the only way the pin ever moves. Publishing an old
1853-
# console is therefore a published decision, not an unnoticed gap.
1841+
# The Console is a workspace package now: `ui/apps/console`
1842+
# (@object-ui/console) builds against this tree's @objectstack/* through
1843+
# `workspace:^`, and `@objectstack/console#build:dist` (root turbo.json)
1844+
# copies that dist with the tracked sdui.manifest.json; `pnpm run release`
1845+
# runs it (`pnpm run console:build`) after the build below. The
1846+
# pin-currency gate, the vendored-dist cache keyed on `.objectui-sha`,
1847+
# its SHA stamp check and
1848+
# its spec-injection check are gone with the pin: each answered "was the
1849+
# Console built from the objectui commit, and against the spec, this
1850+
# release names", and both are true by construction when the Console
1851+
# source and the spec are one tree at one commit. The single-zod canary
1852+
# survives inside packages/console/build-dist.sh, on the bytes it ships.
18541853
# ──────────────────────────────────────────────────────────────────────
18551854

18561855
- name: Build
18571856
run: pnpm run build
18581857

1859-
- name: Read the spec's declared zod range (Console dist key input)
1860-
id: spec-zod
1861-
# Fails rather than keying on an empty or `undefined` range: a key that
1862-
# silently stopped carrying the range would restore across a zod move.
1863-
run: |
1864-
node -e '
1865-
const range = require("./packages/spec/package.json").dependencies?.zod;
1866-
if (typeof range !== "string" || range.trim() === "") {
1867-
console.error("packages/spec/package.json declares no dependencies.zod, so the Console dist key cannot carry it.");
1868-
process.exit(1);
1869-
}
1870-
console.log("range=" + range.trim());
1871-
' >> "$GITHUB_OUTPUT"
1872-
1873-
# This key hashes the pin and the build script, and carries the spec's
1874-
# DECLARED zod range (the step above). ci.yml's Console Pin Gate (#4290)
1875-
# hashes a SUPERSET of the files: those two, the probe scripts and the
1876-
# spec's entry layout (#20765). So the two workflows no longer share dist
1877-
# entries, and each one builds its own on a miss. Keeping this key narrower
1878-
# is deliberate.
1879-
# Following ci.yml would rebuild the console on every Version Packages
1880-
# merge, and publishing a cached console whose spec content lags is the
1881-
# existing cache design.
1882-
#
1883-
# The zod range is the one spec input the cached dist is NOT allowed to
1884-
# lag (#21108). The console bundles a single zod instance, the console's
1885-
# own copy, and its build refuses a console zod outside the injected spec's
1886-
# declared `zod` range (objectui#11353). A dist restored after that range
1887-
# moved would publish a console the build never judged against it. The
1888-
# range is read out of packages/spec/package.json, not hashed with it: the
1889-
# file's `version` moves on every Version Packages merge, and hashing the
1890-
# whole file would turn every publish into a cold console rebuild.
1891-
#
1892-
# Split restore/save, matching ci.yml, and not the combined actions/cache
1893-
# action: the combined form's post-step saves even when the job FAILED,
1894-
# and build-console.sh writes the SHA stamp BEFORE it asserts the bundle
1895-
# canary — so a canary failure here would seed this shared, repo-scoped
1896-
# key with a stamped-but-broken dist that later runs restore and sail
1897-
# through. See ci.yml's split-restore note for the full rationale.
1898-
- name: Restore vendored Console dist (keyed on the objectui pin)
1899-
id: console-dist-cache
1900-
uses: actions/cache/restore@v6
1901-
with:
1902-
path: packages/console/dist
1903-
key: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1904-
1905-
- name: Build vendored @objectstack/console SPA
1906-
# Clones objectstack-ai/objectui at the SHA pinned in .objectui-sha,
1907-
# builds @object-ui/console, and copies dist/ into
1908-
# packages/console/dist/. Must run before publish so the prepublishOnly
1909-
# guard in @objectstack/console passes.
1910-
if: steps.console-dist-cache.outputs.cache-hit != 'true'
1911-
run: bash scripts/build-console.sh
1912-
1913-
- name: Verify Console dist stamp matches pin
1914-
run: pnpm check:console-sha
1915-
1916-
# The spec-injection half of the same question, spelled exactly as
1917-
# ci.yml's Console Pin Gate spells it — both consumers of one cache key
1918-
# apply one check. check:console-sha answers only "which objectui SHA",
1919-
# and scripts/assert-console-spec-injection.mjs runs INSIDE
1920-
# build-console.sh, which the `if: cache-hit != 'true'` above skips — so
1921-
# on a cache hit nothing had asked whether the dist this job is about to
1922-
# PUBLISH bundles this tree's @objectstack/spec rather than the published
1923-
# tarball. --require-stamp because the vacuity check:console-sha tolerates
1924-
# (no dist, or a dist no build ever stamped) is wrong on a publish lane.
1925-
- name: Verify the restored Console dist bundles this tree's spec
1926-
env:
1927-
CONSOLE_DIST_CACHE_KEY: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1928-
run: pnpm check:console-injection --require-stamp
1929-
1930-
# Reached only with every console assertion above green: Actions steps
1931-
# default to `success()`, and nothing between the restore and here carries
1932-
# `if: always()` or `continue-on-error`. Saving only on a miss keeps an
1933-
# immutable entry from being rewritten on every release run.
1934-
- name: Save vendored Console dist
1935-
if: steps.console-dist-cache.outputs.cache-hit != 'true'
1936-
uses: actions/cache/save@v6
1937-
with:
1938-
path: packages/console/dist
1939-
key: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1940-
19411858
- name: Downstream backward-compat smoke (live hotcrm)
19421859
# Pre-publish gate (#2035): the about-to-publish @objectstack/spec must
19431860
# not break a real third-party consumer pinned to a published release.
@@ -2031,9 +1948,10 @@ jobs:
20311948
run: bash scripts/release-spec-changes.sh --verify
20321949

20331950
# ──────────────────────────────────────────────────────────────────────
2034-
# The publish itself. `pnpm run release` = build + build-console +
2035-
# scripts/release-publish.sh, which is `changeset publish` followed by ONE
2036-
# atomic `git push origin --tags` (#2191: the action's concurrent per-tag
1951+
# The publish itself. `pnpm run release` = build (both scopes; the turbo
1952+
# cache makes it the build above) + console:build (the Console dist into
1953+
# packages/console) + scripts/release-publish.sh, which is `changeset
1954+
# publish` followed by ONE atomic `git push origin --tags` (#2191: the action's concurrent per-tag
20371955
# pushes raced GitHub's ref backend and lost ~half the tags).
20381956
#
20391957
# changesets/action is NOT used here, and that is deliberate: handed a

‎.github/workflows/showcase-smoke.yml‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,13 @@ jobs:
5555
# built `dist/`. Build the whole dependency closure (excluding the
5656
# showcase's own app build, which serve --dev doesn't need).
5757
- run: pnpm turbo run build --filter=@objectstack/example-showcase^...
58-
# The console SPA served at /_console is vendored by build-console.sh
59-
# (shallow-clones objectui@.objectui-sha, builds @object-ui/console, copies
60-
# dist → packages/console/dist). Without it serve --dev warns "Console dist
61-
# not found" and the app shell never renders.
62-
- name: Vendor the pinned Console SPA
63-
run: bash scripts/build-console.sh
64-
# Self-test the drift guard: a fresh build-console.sh must stamp the dist
65-
# with the pinned SHA so `pnpm check:console-sha` reports in-sync. Catches
66-
# a regression where the stamp step is dropped or the pin/stamp diverge.
67-
- name: Verify Console SHA stamp matches pin
68-
run: pnpm check:console-sha
58+
# The console SPA served at /_console is @objectstack/console's dist: a
59+
# copy of the workspace's own ui/apps/console build, which `build` does not
60+
# produce (packages/console/build-dist.sh, run by the `build:dist` task).
61+
# Without it serve --dev warns "Console dist not found" and the app shell
62+
# never renders.
63+
- name: Build the Console SPA from ui/apps/console
64+
run: pnpm console:build
6965
- name: Install Playwright Chromium
7066
working-directory: examples/app-showcase
7167
run: pnpm exec playwright install --with-deps chromium

‎.objectui-sha‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎content/docs/protocol/backward-compatibility.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Read the **Breaking?** column, not the version number: in the 17.x minors every
116116
1. **RFC (Request for Comments)** — Breaking changes are proposed as GitHub issues with the `protocol:breaking` label.
117117
2. **Deprecation** — The old behavior is deprecated in a MINOR release (see timeline above).
118118
3. **Migration Guide** — A detailed migration guide is published before the removal lands, in the release notes for the version that carries it.
119-
4. **Release** — In the 17.x minors the breaking change shipped in the next **MINOR** version, carrying a changeset entry marked `**BREAKING**`, and `scripts/check-changeset-no-major.mjs` failed a pull request that declared a `major` bump, because under lockstep one `major` would promote all 73 published packages. During the v18 prerelease it shipped in the next `18.0.0-next.N`, because the guard stood aside in pre mode and a pull request could declare a major bump. Changesets has exited pre mode, so the guard fails a `major` bump again. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
119+
4. **Release** — In the 17.x minors the breaking change shipped in the next **MINOR** version, carrying a changeset entry marked `**BREAKING**`, and `scripts/check-changeset-no-major.mjs` failed a pull request that declared a `major` bump, because under lockstep one `major` would promote all 111 published packages. During the v18 prerelease it shipped in the next `18.0.0-next.N`, because the guard stood aside in pre mode and a pull request could declare a major bump. Changesets has exited pre mode, so the guard fails a `major` bump again. See [how a breaking stage lands on the v18 line](/docs/releases/v18#how-a-breaking-stage-lands-on-this-line).
120120

121121
---
122122

@@ -196,7 +196,7 @@ The `@objectstack/spec` package provides additional stability guarantees:
196196

197197
### Which surfaces this covers
198198

199-
**All of them.** It was not scoped to an experimental corner or a pre-release channel: all **73** packages published from this repository belong to a single Changesets `fixed` group, so they share one version number and one policy. No published surface was exempt.
199+
**All of them.** It was not scoped to an experimental corner or a pre-release channel: all **111** packages published from this repository belong to a single Changesets `fixed` group, so they share one version number and one policy. No published surface was exempt.
200200

201201
The convention was enforced rather than informal — `scripts/check-changeset-no-major.mjs` failed a pull request that introduced a `major` bump, because under lockstep a single `major` on one package would promote the entire stack. During the v18 prerelease Changesets was in pre mode with the tag `next` and the guard stood aside, so a pull request on the v18 line could declare a major bump. Changesets has exited pre mode, and the guard fails a `major` bump again.
202202

0 commit comments

Comments
 (0)