Skip to content

Commit 076bb90

Browse files
committed
release(ui-merge): one fixed group, an in-workspace Console build, no objectui pin (objectstack#25711, WIP)
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
1 parent 43edf90 commit 076bb90

17 files changed

Lines changed: 201 additions & 10129 deletions

‎.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/runner",
121+
"@object-ui/sdui-parser",
122+
"@object-ui/types"
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/test-support"],
91130
"privatePackages": { "version": true, "tag": false }
92131
}

‎.objectui-sha‎

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

‎package.json‎

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"description": "ObjectStack Protocol & Specification - Monorepo for TypeScript Interfaces, JSON Schemas, and Convention Configurations",
66
"scripts": {
77
"build": "turbo run build --filter=!@objectstack/docs",
8-
"dev": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-showcase dev",
9-
"dev:showcase": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-showcase dev",
10-
"dev:crm": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-crm dev",
11-
"dev:todo": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-todo dev",
8+
"dev": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-showcase dev",
9+
"dev:showcase": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-showcase dev",
10+
"dev:crm": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-crm dev",
11+
"dev:todo": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-todo dev",
1212
"spec:rebuild": "turbo run build --filter=...@objectstack/spec",
1313
"test": "VITEST_MAX_WORKERS=$(node scripts/vitest-worker-cap.mjs) turbo run test test:repo --concurrency=50%",
1414
"test:smoke": "turbo run test:smoke",
@@ -18,16 +18,13 @@
1818
"prepare": "node scripts/setup-git-hooks.mjs",
1919
"check:merge-driver": "node scripts/git-env.mjs --self-test && node scripts/git-merge-regen.mjs --self-test && node scripts/check-regen-pending.mjs --self-test",
2020
"version": "node scripts/release-pending-publish.mjs annotate-shipped; changeset version && node scripts/sync-protocol-version.mjs && node scripts/sync-template-versions.mjs && node scripts/sync-docs-image-tags.mjs && node scripts/sync-release-index-currency.mjs && node scripts/check-skill-compatibility-version.mjs --fix",
21-
"release": "pnpm run build && bash scripts/build-console.sh && bash scripts/release-publish.sh",
21+
"release": "pnpm run build && bash scripts/release-publish.sh",
2222
"docs:dev": "pnpm --filter @objectstack/docs dev",
2323
"docs:build": "pnpm --filter @objectstack/docs build",
2424
"docs:start": "pnpm --filter @objectstack/docs start",
2525
"os": "node packages/cli/bin/run.js",
26-
"objectui:build": "bash scripts/build-console.sh",
26+
"console:build": "turbo run build --filter=@objectstack/console",
2727
"gen:sdui-lockstep": "node scripts/check-sdui-lockstep.mjs --update",
28-
"objectui:bump": "bash scripts/bump-objectui.sh",
29-
"objectui:refresh": "bash scripts/bump-objectui.sh && bash scripts/build-console.sh",
30-
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*",
3128
"lint": "node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config",
3229
"i18n:extract": "tsx packages/cli/bin/run-dev.js i18n extract packages/platform-objects/scripts/i18n-extract.config.ts --locales=zh-CN,ja-JP,es-ES --fill=default --source-hashes --out=packages/platform-objects/src/apps/translations",
3330
"check:i18n": "node scripts/check-i18n-bundles.mjs --self-test && node scripts/check-i18n-bundles.mjs",
@@ -147,12 +144,7 @@
147144
"check:optional-error-sink": "node scripts/check-optional-error-sink-contract.mjs --self-test && node scripts/check-optional-error-sink-contract.mjs",
148145
"check:logger-receiver-detach": "node scripts/check-logger-receiver-detach.mjs --self-test && node scripts/check-logger-receiver-detach.mjs",
149146
"check:startup-registry-verdict": "node scripts/check-startup-registry-verdict.mjs --self-test && node scripts/check-startup-registry-verdict.mjs",
150-
"check:console-sha": "node scripts/check-console-sha.mjs",
151-
"check:console-injection": "node scripts/check-console-injection.mjs --self-test && node scripts/check-console-injection.mjs",
152147
"check:dev-prereqs": "node scripts/check-dev-prereqs.mjs --self-test && node scripts/check-dev-prereqs.mjs",
153-
"check:objectui-changeset": "node scripts/objectui-changeset-digest.mjs --self-test && node scripts/objectui-range.mjs --self-test",
154-
"check:objectui-bump": "bash scripts/bump-objectui.selftest.sh",
155-
"check:prerelease-pins": "node scripts/check-prerelease-pin-watch.mjs --self-test && node scripts/check-prerelease-pin-watch.mjs",
156148
"check:empty-changeset": "node scripts/check-empty-changeset.mjs --self-test && node scripts/check-empty-changeset.mjs",
157149
"check:adr-0087-registration": "node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-adr-0087-registration.mjs",
158150
"check:changeset-gate-self-tests": "node scripts/check-empty-changeset.mjs --self-test && node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-changeset-no-major.mjs --self-test",

‎packages/console/build-dist.sh‎

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env bash
2+
# The build of @objectstack/console: a copy of this workspace's own
3+
# @object-ui/console build. Nothing is cloned and nothing is pinned — the
4+
# Console source lives in ui/apps/console, its @objectstack/* dependencies are
5+
# `workspace:^`, and the root turbo.json makes `@objectstack/console#build`
6+
# depend on `@object-ui/console#build`, so the dist copied here was built
7+
# against this tree's spec and client by construction. Run it through turbo
8+
# (`pnpm console:build`, or the root `pnpm build`), never directly: a direct
9+
# run copies whatever ui/apps/console/dist holds, however old.
10+
#
11+
# What it ships: ui/apps/console/dist as-is, with the TRACKED repo-root
12+
# sdui.manifest.json copied over `dist/sdui.manifest.json` (ADR-0080; the CLI's
13+
# JSX gate reads it there, see packages/cli/src/utils/sdui-manifest.ts). The
14+
# manifest copy is the one file in this package's dist that comes from outside
15+
# the Console build, and `scripts/check-changeset-no-major.mjs` reads it out of
16+
# this script (PACKED_COPY_BUILD_SCRIPTS) to grade what a manifest change ships.
17+
#
18+
# Usage:
19+
# bash packages/console/build-dist.sh
20+
# bash packages/console/build-dist.sh --check-single-zod <assets-dir>
21+
# run ONLY the single-zod canary (below) over an
22+
# existing dist's assets/ and exit with its verdict;
23+
# copies nothing, writes nothing
24+
25+
set -euo pipefail
26+
27+
# ── Single-zod canary (objectstack#21108) ────────────────────────────
28+
# The console bundle must carry exactly ONE zod instance. Two copies split
29+
# zod's internals: a spec schema built by one instance and walked by the other
30+
# (`z.toJSONSchema`) throws, so every spec-derived Studio form lost its fields —
31+
# the New Package dialog could not create a package and the dashboard/report
32+
# inspectors read "Spec schema unavailable".
33+
#
34+
# The console's own Vite build pins every `zod` import to one copy and fails on
35+
# more than one zod package directory in the emitted chunks (objectui#11353).
36+
# This is the belt to that brace, measured on what this package SHIPS rather
37+
# than on how the console build is configured, so it still holds for a build
38+
# that drops or weakens that guard — one workspace lockfile can still resolve
39+
# two zod versions.
40+
#
41+
# What it counts: zod 4 stamps every instance with a version object literal
42+
# (`version` in `zod/v4/core/versions`, read back as `_zod.version`), which the
43+
# minifier emits as `{major:4,minor:6,patch:5}`. One instance = one literal, so
44+
# the canary requires EXACTLY ONE occurrence across assets/*.js:
45+
# - two DIFFERENT literals: two zod versions, the shipped defect;
46+
# - one literal found twice: two instances of the same version — still two
47+
# instances, which is what the crash keys on;
48+
# - none at all: the matcher has gone blind (the console always bundles zod),
49+
# and a negative check that cannot see its subject would pass forever.
50+
ZOD_VERSION_LITERAL='\{[[:space:]]*major:[[:space:]]*[0-9]+,[[:space:]]*minor:[[:space:]]*[0-9]+,[[:space:]]*patch:[[:space:]]*[0-9]+[[:space:]]*,?[[:space:]]*\}'
51+
52+
assert_single_zod() {
53+
local assets="$1"
54+
if [[ ! -d "$assets" ]]; then
55+
echo "✗ Single-zod canary: ${assets} is not a directory."
56+
return 1
57+
fi
58+
local files=()
59+
local f
60+
for f in "$assets"/*.js; do
61+
[[ -f "$f" ]] && files+=("$f")
62+
done
63+
if (( ${#files[@]} == 0 )); then
64+
echo "✗ Single-zod canary: no .js files under ${assets} — nothing was measured."
65+
return 1
66+
fi
67+
local hits="" rc=0
68+
hits="$(grep -oHE "$ZOD_VERSION_LITERAL" "${files[@]}")" || rc=$?
69+
if (( rc > 1 )); then
70+
echo "✗ Single-zod canary: grep failed (exit ${rc}) reading ${assets}/*.js."
71+
return 1
72+
fi
73+
# One line per occurrence: <file>:<literal>, the literal's whitespace and any
74+
# trailing comma dropped so a re-formatted bundle reads the same version.
75+
local occurrences
76+
occurrences="$(printf '%s\n' "$hits" | sed -e '/^$/d' -e 's/[[:space:]]//g' -e 's/,}$/}/')"
77+
local count=0 distinct=0
78+
if [[ -n "$occurrences" ]]; then
79+
count="$(printf '%s\n' "$occurrences" | wc -l | tr -d ' ')"
80+
distinct="$(printf '%s\n' "$occurrences" | sed 's/^.*:{/{/' | sort -u | wc -l | tr -d ' ')"
81+
fi
82+
if (( count == 0 )); then
83+
echo "✗ Single-zod canary: none of the ${#files[@]} assets/*.js files carries a zod version"
84+
echo " literal ({major:N,minor:N,patch:N}). The console always bundles zod, so zero means"
85+
echo " this matcher can no longer see it — and a check that cannot see its subject cannot"
86+
echo " fail. Fix the matcher (ZOD_VERSION_LITERAL in packages/console/build-dist.sh) before"
87+
echo " trusting this bundle."
88+
return 1
89+
fi
90+
if (( count > 1 )); then
91+
if (( distinct > 1 )); then
92+
echo "✗ Single-zod canary: the console bundle carries ${distinct} different zod versions"
93+
echo " (${count} version literals) and must carry exactly one:"
94+
else
95+
echo "✗ Single-zod canary: the console bundle carries ${count} copies of ONE zod version"
96+
echo " literal — two instances of the same version are still two instances:"
97+
fi
98+
printf '%s\n' "$occurrences" | sed "s|^${assets%/}/| |"
99+
echo " A schema built by one zod instance and walked by another breaks every spec-derived"
100+
echo " Studio form. The workspace lockfile resolves zod twice for the console's closure:"
101+
echo " dedupe it (one zod line across packages/spec and ui/apps/console), then rebuild."
102+
return 1
103+
fi
104+
echo "✓ Single-zod canary: exactly one zod version literal $(printf '%s' "$occurrences" | sed 's/^.*:{/{/') in ${occurrences%%:*}."
105+
echo " (${#files[@]} assets/*.js files read)"
106+
return 0
107+
}
108+
109+
if [[ "${1:-}" == "--check-single-zod" ]]; then
110+
if [[ -z "${2:-}" ]]; then
111+
echo "usage: packages/console/build-dist.sh --check-single-zod <assets-dir>"
112+
exit 2
113+
fi
114+
if assert_single_zod "$2"; then exit 0; fi
115+
exit 1
116+
fi
117+
118+
FRAMEWORK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
119+
CONSOLE_DIST="${FRAMEWORK_ROOT}/ui/apps/console/dist"
120+
TARGET="${FRAMEWORK_ROOT}/packages/console/dist"
121+
MANIFEST_SRC="${FRAMEWORK_ROOT}/sdui.manifest.json"
122+
123+
if [[ ! -f "${CONSOLE_DIST}/index.html" ]]; then
124+
echo "✗ ${CONSOLE_DIST}/index.html is missing — @object-ui/console has not been built."
125+
echo " Build through turbo, which builds it first: pnpm console:build"
126+
exit 1
127+
fi
128+
if [[ ! -f "$MANIFEST_SRC" ]]; then
129+
echo "✗ ${MANIFEST_SRC} is missing — the console dist ships the tracked SDUI manifest."
130+
echo " Regenerate it: node scripts/gen-sdui-manifest-node.mjs"
131+
exit 1
132+
fi
133+
134+
echo "→ Copying ${CONSOLE_DIST} → ${TARGET}"
135+
rm -rf "$TARGET"
136+
cp -R "$CONSOLE_DIST" "$TARGET"
137+
cp "$MANIFEST_SRC" "${TARGET}/sdui.manifest.json"
138+
139+
# Placed after the copy so it judges the bytes this package publishes.
140+
if ! assert_single_zod "${TARGET}/assets"; then
141+
rm -rf "$TARGET"
142+
exit 1
143+
fi
144+
145+
BYTES="$(du -sk "$TARGET" 2>/dev/null | awk '{print $1}')"
146+
echo "✓ @objectstack/console dist ready (${BYTES} KB) from ui/apps/console, with the tracked sdui.manifest.json"

‎packages/console/package.json‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@objectstack/console",
33
"version": "18.1.0",
4-
"description": "Prebuilt Console SPA pinned to this framework release, installed as a dependency of @objectstack/cli. Source of truth: @object-ui/console (https://github.com/objectstack-ai/objectui).",
4+
"description": "Prebuilt Console SPA built from this workspace's ui/apps/console (@object-ui/console) at the same version, installed as a dependency of @objectstack/cli.",
55
"license": "Apache-2.0",
66
"homepage": "https://github.com/objectstack-ai/objectstack/tree/main/packages/console",
77
"repository": {
@@ -24,6 +24,7 @@
2424
"./package.json": "./package.json"
2525
},
2626
"scripts": {
27-
"prepublishOnly": "node -e \"const fs=require('fs');const p='dist/index.html';if(!fs.existsSync(p)){console.error('\\n✗ @objectstack/console: '+p+' is missing — run scripts/build-console.sh before publishing.\\n');process.exit(1)}\""
27+
"build": "bash build-dist.sh",
28+
"prepublishOnly": "node -e \"const fs=require('fs');const p='dist/index.html';if(!fs.existsSync(p)){console.error('\\n✗ @objectstack/console: '+p+' is missing — run pnpm console:build at the repo root before publishing.\\n');process.exit(1)}\""
2829
}
2930
}

0 commit comments

Comments
 (0)