Skip to content

chore(deps): take the 17.4.0 @objectstack/* line - #8783

Merged
os-bill merged 14 commits into
mainfrom
claude/issue-8772-objectstack-17-4-0-line
Sep 9, 2026
Merged

chore(deps): take the 17.4.0 @objectstack/* line#8783
os-bill merged 14 commits into
mainfrom
claude/issue-8772-objectstack-17-4-0-line

Conversation

@os-bill

@os-bill os-bill commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #8772
Fixes #7783
Fixes #7663
Fixes #8172
Fixes #7845
Fixes #8785

Moves the @objectstack/* family from 17.3.0 to 17.4.0 as one line, and answers every
contract that move flipped. ⛔ No red is patched green by relaxing an assertion: in each
one the spec is the producer and it moved deliberately, so the pin is re-pointed at the
truth or the local duplication is deleted.

Why one PR and not six. Each repair alone still leaves this branch red on the other
fifteen, so none could merge on its own. The bump and every pin it flips by design are
one queue position.

What moved in the dependency line

pnpm-lock.yaml — all seven, together: client, core, formula, lint,
sdui-parser, spec, types.

package.json is untouched, as the card predicted. Every declared range is a caret
inside major 17 (^17.0.0, ^17.1.0, ^17.2.0, ^17.3.0) and all of them already
admit 17.4.0. All seven were verified present on npm before the line moved.

Two other files move because they are pinned to the lockfile by this repo's own rules,
and each names this exact event:

  • e2e/live/ci/backend.envOBJECTSTACK_VERSION 17.3.0 to 17.4.0. Its header,
    content/docs/guide/ci-cd-pipeline.md, and scripts/__tests__/ci-cd-pipeline-doc.test.ts
    all require it to equal the spec version the lockfile resolves; a mismatched pair makes
    the live-e2e lane carry no information either way (objectui#7689).
  • scripts/__tests__/check-lockfile-integrity.test.ts — its two samples are
    transformations OF the real lockfile, anchored on the current pin. The assertion that
    broke says so itself: "the spec snapshot key moved — rebuild this sample before trusting
    it". Only the anchor moved; the simulated downgrade target (17.2.0) and every assertion
    are unchanged, so both samples still reproduce objectui#8326 and objectui#8333.

The lockfile diff is confined to the seven, deliberately

A plain pnpm update -r "@objectstack/*" is not what landed here. It does two things
this card must not do:

  1. It rewrites 29 package.json files (ranges to ^17.4.0, plus unrelated indentation),
    which the card forbids.
  2. It floats zod ^4.4.3 to 4.5.4. That forks ai@7.0.65's peer context and yields
    two physical copies each of spec, formula and lint — precisely the
    objectui#8326 / objectui#8333 defect class scripts/check-lockfile-integrity.mjs
    exists to catch. It also drifted seroval and @mongodb-js/saslprep.

That float is not caused by this bump: @objectstack/spec and @objectstack/core declare
the identical zod: ^4.4.3 at both 17.3.0 and 17.4.0. It is pnpm update re-resolving
an already-satisfied range. The re-resolve was therefore run with those four pinned through
a temporary root pnpm.overrides block, the manifests restored, and the lockfile settled
with a plain pnpm install.

Result: every changed line in pnpm-lock.yaml is an @objectstack/* identity or its
integrity hash. zod, seroval, seroval-plugins and @mongodb-js/saslprep are
byte-identical to base. Resolution count 1822 to 1822.

The sixteen reds, answered

red card repair
types type-check: zod-mirror-parity.test.tsDashboardComponentSchema drift gained refreshInterval #7783 re-point pin
plugin-dashboard/__tests__/dashboardAuthoredInputs.test.tsx — spec refuses refreshInterval by tombstone #7783 re-point pin
app-shell metadata-form-i18n.test.ts — the 自动刷新 label, key gone #7783 re-point pin
components/__tests__/record-picker-inputs-spec-parity.test.ts (2 tests) #7663 re-point pin
console registry-inputs-spec-parity.test.tselement:record_picker arm #7663 re-point pin
console registry-inputs-spec-parity.test.tsobject-kanban now declares limit #8172 re-point pin
block-config-schema-parity-8216.test.ts (2 tests) — ledger row object-kanban::limit@spec stale #8172 delete duplication
plugin-gantt ObjectGantt.blockPrecedence.test.tsx — 40 keys, 30 unique #7845 delete duplication
plugin-chatbot toolLabels-locale-parity-7481.test.tsAHEAD_OF_PIN caught up (#7481, CLOSED) delete duplication
app-shell MetadataService.specKeyReference.test.ts — the pin reached the trim (objectstack#16920) re-point pin
console preview-samples-spec-valid.test.ts — job sample, jobs.0.timeout #8785 fix sample
console preview-samples-spec-valid.test.ts — flow sample, nodes.13.config.outcome #8785 fix sample
app-shell metadata-form-i18n.test.ts — the gap "Tailwind" control #8785 re-point pin
ci-cd-pipeline-doc.test.ts, check-lockfile-integrity.test.ts (lockfile-coupled) fixed with the bump

⛔ Two of these have no open objectui card and are repaired here without opening one:
objectui#7481 is CLOSED (completed via PR #7710) and is not reopened, and
objectstack#16920 lives in the other repo and is not touched.

What each card's repair actually was

#7845 — gantt: the deletion the card prescribes

GANTT_CONFIG_EXTENSION_KEYS (plugin-gantt) and GanttConfigExtensionFields
(@object-ui/types) were objectui's copy of the ten keys it read through
GanttConfigSchema's .passthrough() window. objectstack#15469 closed the window and
declared all ten, so the copies became duplicates — which is exactly what the
no-duplicates pin measured (40 keys, 30 unique). Both are retired; the flat face takes all
ten from SpecGanttConfigSchema.shape by reference like its other members, and the nested
gantt block is the spec schema itself.

⭐ Compared member for member before deleting, as the card required: the spec's declarations
cover the same ten keys, the same interactions (move/resize/progress/link) and
timeSegments (dayStart/bands/showMidnight) sub-shapes and the same band members, with
strictly fuller describes. The local copy carried no describe, alias or member the spec's
lacks, so there is no difference to file.

The card's item 3 (prose that still calls the spec loose) is done, and one of its three
sites was premise-false: normalize-list-view.test.ts's "the configs are
.passthrough() for" needs no change. Measured — that test asserts kanban.swimlaneField
and timeline.endField survive normalization, and both are still absent from the spec's
KanbanConfigSchema / TimelineConfigSchema; the passthrough carrying them is objectui's
own local schema, not the spec's. What was false is the note in zod/objectql.zod.ts
justifying that local .passthrough() "for the same reason the spec puts it on
GanttConfigSchema/TreeConfigSchema" — that precedent is gone, and only the local reason
survives.

#7783 — dashboard refreshIntervalrefreshIntervalSeconds

objectui's zod DashboardComponentSchema takes its spec-owned half from
SpecDashboardFields by reference, so that face moved on its own the moment the
lockfile did. What did not move was the TypeScript twin, and the pair's drift ledger is
what caught it. Moved here: the TS declaration, the four reader sites (the * 1000
arithmetic is identical — the value is still seconds, and the multiply is exactly the tell
the rename exists to remove), the published registration input, the metadata-admin zh
overlay key, the config panel's field key and the DashboardConfig model behind it, and
the fixtures and pins that spell the key.

⚠️ Premise falsified — two of the four TS sites the card names are not this key. The
card lists types/src/data.ts and types/src/ai.ts among "the TS types" for the rename.
They are DataBinding.refreshInterval and AIInsightsSchema.refreshInterval: neither has
a zod mirror, and @objectstack/spec/ui exports nothing matching either name, so there is
no producer behind a rename. DataBinding's is documented in milliseconds, which makes
refreshIntervalSeconds the wrong name for it outright. Both left alone — this is the
same trap the card itself flagged for the report component.

content/docs/api/schema-reference.md documented this key as milliseconds with a 30000
sample. It was never milliseconds; corrected with the rename.

#7663element:record_picker.filter takes the array arm

Measured at the installed spec before flipping: the record form is refused by KIND at
filter (invalid_type, expected array), a bare tuple is refused at filter.0 (expected
object), and [{ field, operator, value }] is accepted — with operator: 'eq' normalised
to 'equals' on parse, which is why the fixture spells the canonical form. type: 'object'
becomes 'array', the description is rewritten around the rule array (the PRECEDENCE
paragraph is unchanged in substance — dataSource.filter ?? filter did not move), and the
two parity pins swap sides with the refusals asserted as an envelope rather than a bare
success === false. No renderer change. The console arm goes green by derivation.

⚠️ The coarse-type test now states where the agreement ends: 'array' has no member
arm, so a tuple list passes the manifest check and is refused only by the spec. Named
rather than papered over.

#8172object-kanban publishes limit

All three of the card's disagreeing faces were re-measured at this pin, not assumed
the card's explicit instruction:

face reading now
renderer still sends $top: schema.limit ?? DEFAULT_KANBAN_LIMIT, schema.limit in the effect deps. Unchanged.
@object-ui/types BOTH faces declare limitobjectql.ts and the zod mirror. ⚠️ This falsifies the reading recorded on the card by the spec seat, which measured only the plugin's own KanbanSchema at pin a472b07.
docs plugin-kanban.mdx teaches it correctly. One loose sentence tightened, because the key is now published with a precedence-bearing description and the two must agree.
spec (the one that moved) ComponentPropsMap['object-kanban'] declares limit as of objectstack#16503.

So the only face still out of step was this repo's registration. ⛔ The declaration carries
no default: a materialised limit would defeat ElementDataSourceGate's
readLimit(base) === undefined branch and a bound view's pagination.pageSize would then
never fill it — the spec seat's explicit warning. Precedence verified against that branch
directly, not restated from the spec's describe.

The stale object-kanban::limit@spec ledger row is deleted, which is the ratchet working.
Its self-deleting probe went with it, leaving the spec-face ledger empty — and an empty
probe list is indistinguishable from a broken oracle lookup, so a live control replaces it.

#8785 — the three unannounced changes

Each measured against both spec versions.

  1. job.timeouttimeoutMs. The sample carried a comment arguing for the old spelling
    ("the unit is already milliseconds"); the spec's tombstone makes the opposite argument,
    the same ruling family as dashboard refreshIntervalrefreshIntervalSeconds: two declarations and six reader sites to move when the spec rename ships #7783. The sample moves; the value is unchanged.
  2. The flow end node's outcome enum narrowed to completed | refused. 'success' becomes
    'completed' — ⛔ not 'refused', which the spec additionally requires a message
    beside (measured: it fails at config.message) and which describes the wrong ending.
  3. The dashboard gap help text. That assertion is a non-vacuity control, not the
    subject, and this repo does not own the sentence — re-pointing it at the new wording buys
    one release. It now asserts the property the overlay exists for: the producer's copy
    reaches for developer vocabulary (a framework name, or digits welded to a CSS unit) and
    the zh overlay carries none of it. ⚠️ \brem\b does not work for this — the boundary
    before rem never matches in 0.25rem, because 5 is a word character. Both legs were
    measured against both versions' copy.

The two uncarded tripwires

Both are tests that predicted this exact event in their own prose and said what to do.

  • MetadataService.specKeyReference.test.ts — the VERSION SKEW row. objectstack#16920 now
    trims before the emptiness test, so ' ', '' and an absent target are all refused
    under the same custom issue at the same reference path the writer names, while
    'account' and ' account ' still parse. The verdict flips and is asserted as an
    envelope. MetadataService.ts is untouched, exactly as the note predicted.
  • toolLabels-locale-parity-7481.test.tsAHEAD_OF_PIN emptied, ⛔ not deleted: the next
    tool registered ahead of a snapshot needs the same hatch. ⚠️ Emptying it turns three
    guards into tautologies ([].filter(…) is []), including the one whose comment says it
    exists to stop the suite going vacuously green. They are re-anchored on a GRADUATED
    constant asserted to be in the registry.

Verification

All readings are on the merged head 5f90b36, taken after origin/main (42ddd7f) was
merged and pnpm install re-run. Exit codes were captured to a file before any pipe.

gate verdict
pnpm build PASS — 43 of 43 successful, exit 0
pnpm type-check PASS — 81 of 81 successful, exit 0. This is where #7783's red was.
pnpm vitest run over the nine touched packages + scripts PASS — 1562 files, 19054 tests, 0 failing, exit 0
pnpm test (the WHOLE suite, run to completion on an earlier head) 2816 files, 36682 passing, 2 failing — both doc ratchets this branch's own edits had moved, both repaired and re-verified
pnpm exec eslint --no-inline-config over this PR's 28 changed TS/JS files PASS — exit 0, 0 errors, 231 warnings (all pre-existing no-explicit-any, counted file-wide)
25 check:* gate scripts PASS — every exit code 0
check-governed-queue-guard --test over the 36 changed paths NOT GOVERNED — the ordinary review and merge-queue route applies

The 25 gates: lockfile-integrity · control-bytes · spec-symbols · sdui-registration-pins ·
element-data-source-declaration · designer-field-key-parity · handler-key-reads ·
i18n-keys · i18n-drift · i18n-dead-keys · i18n-designer-parity · self-import ·
unreferenced-sources · readme-exports · side-effects-array · phantom-deps ·
icon-record-names · action-forward-parity · doc-fences · shell-escape-residue ·
vi-mock-specifiers · vi-mock-inherit · the three changeset gates.

check:i18n-designer-parity is new on main since this branch opened (objectui#8834)
and it reads the metadata-admin designer string tables this PR edits, so it was picked up
from the merged tree rather than from the gate list this branch started with. It passes.

⚠️ Two declared narrowings, so a reader can tell a measurement from a silence.

  1. The full pnpm test was run to completion once and then narrowed, on each re-merge, to
    the nine packages this PR touches plus scripts. The two merges brought 45 commits of
    other people's already-CI-green work and produced exactly one conflict — a
    line-number-keyed ledger row both sides had shifted, resolved by measuring the merged
    tree rather than by arithmetic. CI runs the full farm on the merged head.
  2. pnpm lint repo-wide is CI-owned; eslint here is narrowed to this PR's own changed
    files. That narrowing is sound rather than convenient: eslint.config.js declares no
    parserOptions.project, no projectService and no *TypeChecked preset (measured: zero
    occurrences of parserOptions), so linting is per-file and type-unaware and this diff
    cannot move the verdict on a file it does not touch.

⚠️ One gate reports red and is NOT this PR's, stated rather than omitted:
check-published-dist-tooling exits 1 on 10 dist/tsconfig.tsbuildinfo build records —
the known objectui#7003 class. Eight of the ten packages are untouched by this PR, the
records are produced by running a local build at all, and published-dist-gate.yml runs
nightly and on changes to its own wiring, never on an ordinary pull request. Not caused
here and not repaired here.

The lockfile, re-verified after each merge

Neither merge touched pnpm-lock.yaml, and the two manifests main did move
(packages/plugin-ai/package.json, the root package.json) each added a scripts entry,
not a dependency. Nothing was hand-resolved and nothing was regenerated. Measured against
the merge base by the gate itself:

node scripts/check-lockfile-integrity.mjs
base: 42ddd7f:pnpm-lock.yaml (1822 resolutions)  head: pnpm-lock.yaml (1822 resolutions)
VERDICT clean - no @objectstack/* identity moved backward and no package gained a copy.

All seven @objectstack/* resolve at 17.4.0; zod, seroval, seroval-plugins and
@mongodb-js/saslprep are byte-identical to base. Every one of the 132 changed lockfile
lines is an @objectstack/* identity, its integrity hash, or a version: 17.3.0 → 17.4.0
line for one of the seven — the residue after excluding those three classes is empty.
pnpm install after the merge changed nothing.

Changeset

.changeset/8772-objectstack-17-4-0-line.md, measured not assumed:
node scripts/check-changeset-presence.mjs read "34 file(s) changed, 26 of them published
source of a package the release covers" and refused until one was added. Scored minor
across the eight packages whose src/ moved — ⛔ never major, because this repo's fixed
group tracks the @objectstack major (AGENTS.md §版本号策略,
scripts/check-changeset-no-major.mjs). The pending
.changeset/dashboard-declare-honoured-inputs.md names refreshInterval in prose
describing a key this PR renames before either ships, so its one token is corrected too.

Acceptance note, out of scope

e2e/live/ci/backend.env says to retire BETTER_AUTH_VERSION and
e2e/live/ci/better-auth-pin.mjs "in the PR that bumps OBJECTSTACK_VERSION past the
upstream fix" (objectstack#16186). That condition now appears met: @objectstack/plugin-auth
pins the whole better-auth family exactly at 17.4.0 (1.7.2, caret dropped) where
17.3.0 declared ^1.7.2. Not acted on here — retiring the pin changes the live-e2e lane's
behaviour and adds a verification surface this PR cannot exercise.

#7267 does not fire on this bump, contrary to the card starred on #8772:
LocationField.optionalKeys.test.tsx runs and all 12 tests pass. The repair already landed
under the 17.3.0 pin. Already routed to pm:retriage; ⛔ not folded in here. #7716 and
#7707 were checked and are also not this family.

🤖 Generated with Claude Code

https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms


Generated by Claude Code


Generated by Claude Code

Float all seven `@objectstack/*` entries from 17.3.0 to 17.4.0 as one line:
client, core, formula, lint, sdui-parser, spec, types.

`package.json` is untouched — every declared range is a caret inside major
17 (`^17.0.0`, `^17.1.0`, `^17.2.0`, `^17.3.0`), all of which already admit
17.4.0. This is a lockfile refresh only.

The re-resolve is pinned so the diff carries nothing but the seven
identities. A plain `pnpm update -r "@objectstack/*"` also floats
`zod ^4.4.3 -> 4.5.4`, which forks `ai@7.0.65`'s peer context and yields two
physical copies each of spec, formula and lint — the objectui#8326 / #8333
defect class that `scripts/check-lockfile-integrity.mjs` exists to catch.
That float is not caused by this bump: `@objectstack/spec` and
`@objectstack/core` declare the identical `zod: ^4.4.3` at 17.3.0 and
17.4.0. It is `pnpm update` re-resolving an already-satisfied range.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
Both are mechanically coupled to the family move in the previous commit, and
each carries its own prescription for exactly this event.

`e2e/live/ci/backend.env` — `OBJECTSTACK_VERSION` 17.3.0 -> 17.4.0. The file's
own header states the rule ("bump this in the same PR that bumps the console's
@objectstack pins"), `content/docs/guide/ci-cd-pipeline.md` repeats it, and
`scripts/__tests__/ci-cd-pipeline-doc.test.ts` enforces equality with the
version `pnpm-lock.yaml` resolves. A mismatched pair makes the live-e2e lane
carry no information either way (objectui#7689).

`scripts/__tests__/check-lockfile-integrity.test.ts` — its two samples are
transformations OF the real lockfile, anchored on the current pin, and the
assertion that broke says so itself: "the spec snapshot key moved — rebuild
this sample before trusting it". Only the anchor moves; the simulated
downgrade target (17.2.0) and every assertion are unchanged, so both samples
still reproduce objectui#8326 and objectui#8333 as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
…e sample

The previous commit rewrote the sample anchor from 17.3.0 to 17.4.0 and lost
one backslash level in the process. The pattern is built through
`new RegExp(...)` from a template literal, so `17\.4\.0` reaches the
constructor as `17.4.0` and both dots become "any character" — matching, but
by accident. `no-useless-escape` caught it. Restored to `17\\.4\\.0`, which is
byte-identical to the base line apart from the version digit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3485.1 KB 3512.7 KB
Main entry chunk (gzip) 144.0 KB 350 KB
Entry file index-B4g_jB7k.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 499.42KB 114.32KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 26.68KB 8.94KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 245.88KB 62.05KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.53KB 46.34KB
plugin-dashboard (index.js) 131.43KB 34.44KB
plugin-designer (index.js) 215.51KB 44.29KB
plugin-detail (index.js) 252.39KB 65.32KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 134.25KB 33.52KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 210.67KB 57.19KB
plugin-kanban (index.js) 55.50KB 15.75KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.55KB 3.32KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

….shape (objectui#7845)

objectstack#15469 closed `GanttConfigSchema` and declared the ten keys
plugin-gantt used to read through its `.passthrough()` window. objectui carried
its own copy of those ten in two places; with the spec declaring them, the copies
became duplicates and `ObjectGantt.blockPrecedence.test.tsx`'s no-duplicates pin
measured it (40 keys, 30 unique).

Retired both copies:

- `GANTT_CONFIG_EXTENSION_KEYS` (`plugin-gantt/src/ObjectGantt.tsx`) — the flat
  key list is now `GanttConfigSchema.shape` plus the `dependencyField` alias.
- `GanttConfigExtensionFields` (`types/src/zod/objectql.zod.ts`) — the flat face
  takes all ten from `SpecGanttConfigSchema.shape` by reference like its other
  members, and the nested `gantt` block is the spec schema itself rather than
  the spec schema extended with the local map.

Compared member for member before deleting, as the card required: the spec's
declarations cover the same ten keys, the same `interactions`
(move/resize/progress/link) and `timeSegments` (dayStart/bands/showMidnight)
sub-shapes and the same band members, with strictly fuller describes. The local
copy carried no describe, alias or member the spec's lacks, so there is no
difference to file.

Also corrected the prose that still called the spec loose: `types/objectql.ts`
said `timeSegments` was "the one key the spec genuinely does not model" and that
`GanttConfigSchema` is `$loose` upstream — both false, and the first read as an
invitation to write undeclared sub-keys that the `strictObject` now refuses by
name. `zod/objectql.zod.ts` justified its own local `.passthrough()` by pointing
at the spec's gantt/tree windows, which no longer exist; the local reason (and
the measurement that `swimlaneField` / `endField` are still spec-undeclared)
replaces it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
…g the spec rename (objectui#7783)

@objectstack/spec 17.4.0 renamed the dashboard's auto-refresh key
(objectstack#15680, ruling B on objectstack#14478: a duration-shaped number
carries its unit in the key name, not only in the describe prose) and left a
`retiredKey` tombstone behind the old spelling.

objectui's zod `DashboardComponentSchema` takes its spec-owned half from
`SpecDashboardFields` by reference, so that face moved on its own the moment the
lockfile did. What did NOT move was the TypeScript twin, and the pair's drift
ledger caught it: `zod-mirror-parity.test.ts` refused to compile with
`complex.zod.ts#DashboardComponentSchema` gaining `refreshInterval`.

Moved here: the TS declaration; the four reader sites, keeping the `* 1000`
arithmetic identical (the value is still seconds — the multiply is exactly the
tell the rename exists to remove, and it now sits under a key that says so); the
published registration input; the metadata-admin zh overlay key; the config
panel's field key and the `DashboardConfig` model behind it; and the fixtures
and pins that spell the key.

⛔ Deliberately NOT renamed, measured rather than swept:

- `plugin-report` / `types` `reports.ts` / `reports.zod.ts` — the report
  component's own key, excluded by the card.
- `DataBinding.refreshInterval` (`types/src/data.ts`) and
  `AIInsightsSchema.refreshInterval` (`types/src/ai.ts`). The card lists both
  among "the TS types" for this rename; they are not. Neither has a zod mirror
  or a `@objectstack/spec` counterpart (spec/ui exports nothing matching either
  name), so there is no producer behind a rename — and `DataBinding`'s is
  documented in MILLISECONDS, which makes `refreshIntervalSeconds` the wrong
  name for it outright.

`content/docs/api/schema-reference.md` documented this key as milliseconds with
a `30000` sample. It was never milliseconds; corrected with the rename.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
…Rule array arm (objectui#7663)

objectstack#14406 converged `ComponentPropsMap['element:record_picker'].filter`
from the MongoDB-style `FilterConditionSchema` record onto
`z.array(ViewFilterRuleSchema)` — the last record-form `filter` in the map,
closing the maintainer's 2026-08-25 ruling that the platform carries one filter
orthography (objectui#6206-B). @objectstack/spec 17.4.0 ships it, so the
declaration here now teaches a shape the save gate refuses and a JSX page
writing the legal array form draws a false `type-mismatch`.

Measured at the installed spec before flipping: the record form is refused by
KIND at `filter` (`invalid_type`, expected array), a bare tuple is refused at
`filter.0` (expected object), and `[{ field, operator, value }]` is accepted —
with `operator: 'eq'` normalised to `'equals'` on parse, which is why the
fixture spells the canonical form.

- `inputs.filter` flips `type: 'object'` to `'array'` and its description is
  rewritten around `[{ field, operator, value }, …]`. The PRECEDENCE paragraph
  is kept verbatim in substance: `dataSource.filter ?? filter` did not change.
- The two parity pins swap sides — the record form is now the refused shape,
  the rule array the accepted one — and the refusals are asserted as an
  envelope (issue code plus path), so a parse that failed for an unrelated
  reason cannot stand in for the contract refusing the record form.
- The coarse-type agreement test moves with them, and now states WHERE the
  agreement ends: `'array'` has no member arm, so a tuple list passes the
  manifest check and is refused only by the spec. That gap is named rather than
  papered over — the description carries what the coarse type cannot say.

No renderer change: `filter?: unknown` passes through to `$filter` and `find()`
already lowers the array form. The console parity test's `element:record_picker`
arm goes green by derivation once the declaration moves; only its MEMBER_PINS
prose is edited, to describe the arm that is actually pinned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
… declares it (objectui#8172)

objectui#8172 was filed because four faces taught `limit` on an `object-kanban`
— the renderer sending `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT`, both
`@object-ui/types` faces, and a documented section — while the strict
`ComponentPropsMap` refused it BY NAME, so an author following this repo's own
docs wrote a node the save gate rejected. The maintainer ruled option A (the
contract catches up, 2026-09-07 「同意」), objectstack#16503 landed as
objectstack#16562, and @objectstack/spec 17.4.0 ships
`limit: z.number().int().positive().optional()`.

⭐ All three of the card's disagreeing faces were RE-MEASURED at this pin rather
than assumed, as the card asked:

- renderer — `ObjectKanban.tsx` still sends `$top: schema.limit ??
  DEFAULT_KANBAN_LIMIT`, with `schema.limit` in the effect deps. Unchanged.
- `@object-ui/types` — BOTH faces declare `limit` now (`objectql.ts` and the
  zod mirror `objectql.zod.ts`). ⚠️ This falsifies the reading recorded on the
  card by the spec seat, which measured only the plugin's own `KanbanSchema`
  declaring it at pin `a472b07`; objectui's shared faces have since caught up,
  so there was no missing declaration to add.
- docs — `plugin-kanban.mdx` teaches it correctly. Its one loose sentence is
  tightened here, because the key is now published with a precedence-bearing
  description and the two must agree: the binding's own `limit` wins outright,
  a named view's `pagination.pageSize` fills the cap only when the board leaves
  `limit` unset. Verified against `ElementDataSourceGate`'s `readLimit(base) ===
  undefined` branch, not restated from the spec's describe.

So the only face still out of step was this repo's registration, and that is
what moves. ⛔ The declaration carries NO default: a materialised `limit` would
defeat that same `readLimit(base) === undefined` branch and a bound view's
`pageSize` would then never fill it — the spec seat's explicit warning.

The `object-kanban::limit@spec` ledger row in `block-config-schema-parity-8216`
is deleted, which is the ratchet working: a row that no longer describes a
violation is as red there as a violation with no row. Its self-deleting probe
went with it, so the spec-face ledger is now empty — and an empty probe list is
indistinguishable from a broken oracle lookup, so a live control replaces it:
the former violation must now parse clean AND an undeclared sibling must still
be refused by name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
…this repo asserted against (objectui#8785)

Each was measured against BOTH spec versions before being repaired, so
"changed in 17.4.0" is a reading rather than an inference.

1. `job.timeout` retired in favour of `timeoutMs`. The preview sample carried
   `timeout: 600000` and a comment arguing for that spelling ("the unit is
   already milliseconds"). The spec now refuses the key with a tombstone making
   the opposite argument — the unit belongs in the name, since the sibling
   `retryPolicy.backoffMs` already spelled its own and one surface was teaching
   two conventions. Same ruling family as objectui#7783. The SAMPLE moves; the
   value is unchanged. Measured: `timeoutMs: 600000` parses clean through
   `ObjectStackSchema`, `timeout: 600000` is refused at `jobs.0.timeout`.

2. The flow end-node `outcome` enum narrowed to `completed | refused`. The
   sample's `outcome: 'success'` is no longer a member. It becomes `'completed'`
   — ⛔ NOT `'refused'`, which the spec additionally requires a `message` beside
   (measured: `refused` with no message fails at `config.message`), and which
   would in any case describe the wrong ending for this sample.

3. The dashboard `gap` help text. The pin asserted that the ENGLISH producer
   copy still says "Tailwind"; 17.4.0 rewrote it to "Space between widgets, in
   steps of 0.25rem (4 = 1rem)".

   That leg is a non-vacuity control, not the subject: without it, "the zh copy
   does not say Tailwind" would pass just as well on copy that never said it.
   Re-pointing it at the new sentence buys exactly one release — this repo does
   not own that text. So the control now asserts the PROPERTY the overlay exists
   for: the producer's copy reaches for developer vocabulary (a framework name,
   or digits welded to a CSS unit) and the zh overlay carries none of it. Still
   non-vacuous, no wording pinned, and if the spec ever writes this hint in
   plain author language the control reddens and someone re-reads the overlay —
   which is correct, since the overlay would then have nothing left to do here.

   ⚠️ `\brem\b` does not work for this: the boundary before `rem` never matches
   in `0.25rem`, because `5` is a word character. Measured both ways against
   both spec versions' copy before landing.

⛔ None of the three is patched green by relaxing an assertion: in all three the
spec is the producer and it moved deliberately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
Neither has an open objectui card. Both are tests that predicted this exact
event in their own prose and said what to do when it fired, so the repair is the
one each prescribes — not a new decision.

`MetadataService.specKeyReference.test.ts` — the VERSION SKEW row. Until 17.3.0
the spec's `reference` emptiness test was an equality against `''`, so `'   '`
parsed green while this writer refused it: a real divergence, declared rather
than hidden, with the spec half written as a tripwire for the day
objectstack#16920 reached the pin ("this line reddens when the pin reaches it —
at which point the reading becomes `false` and nothing else here moves").
17.4.0 carries the fix. Measured: `'   '`, `''` and an absent target are now all
refused under the same `custom` issue at the same `reference` path the writer
names, while `'account'` and `' account '` still parse — the trim is for the
TEST only, which is what the writer's own pass-it-through row depends on. The
verdict flips and is asserted as an envelope (code plus path), because "refused"
and "refused AS a blank target" are separable claims. `MetadataService.ts` is
untouched, exactly as the note predicted. Closes the divergence objectui#8621
recorded; objectstack#16920 is the other repo's card and is not touched.

`toolLabels-locale-parity-7481.test.ts` — `AHEAD_OF_PIN`, the hand-held list of
tools the cloud runtime registers ahead of the spec snapshot. All five names it
carried are in `PLATFORM_TOOLS_BY_PACKAGE` at 17.4.0, and the file's own rule is
that a caught-up name must be REMOVED so the list never becomes a second
registry. Emptied, ⛔ not deleted: the next tool registered ahead of a snapshot
needs the same hatch.

⚠️ Emptying it turns three guards into tautologies — `[].filter(…)` is `[]`,
`arrayContaining([])` passes on anything — including the one whose comment says
it exists to stop the suite going vacuously green if the spec export disappears.
So they are re-anchored: a `GRADUATED` constant records the five names and
asserts they ARE in the registry, and the coverage floor is read off the
registry rather than off the emptied list. If the registry ever stops listing
one of them, that is now what reddens, and the repair is to put the name back on
`AHEAD_OF_PIN`.

⛔ objectui#7481 is CLOSED (completed via PR #7710) and is not reopened.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
Both surfaced in the full suite, both caused by edits in this branch and neither
by a spec change:

- `check-doc-example-types.mjs`'s `UNGATED_EXAMPLES` is keyed by `path:line
  symbol`, and the gantt prose corrections in `packages/types/src/objectql.ts`
  added six lines above `ObjectFormSchema`'s `@example`. Re-anchored 1607 to
  1613; verified by reading the `@example` line at both revisions.

- `doc-version-claims` refuses a version literal on a doc surface that nothing
  in this repo can re-check. The `refreshIntervalSeconds` row added to
  `schema-reference.md` carried "@objectstack/spec 17.4.0". Taken out rather
  than added to `KNOWN_CLAIMS`, which is the remedy the gate itself prefers: the
  sentence needs the RENAME, not the release it shipped in, and the card number
  already points at the full account.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
…ectstack-17-4-0-line

# Conflicts:
#	scripts/check-doc-example-types.mjs
…ollows

`node scripts/check-changeset-presence.mjs` refused without one: 26 of the
changed files are published source of a package the release covers. Scored
`minor` across the eight packages whose `src/` moved — never `major`, because
this repo's fixed group tracks the @objectstack major (AGENTS.md §版本号策略,
enforced by scripts/check-changeset-no-major.mjs).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wtfW1ZxGnP1XKGc9uZVms
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3486.0 KB 3512.7 KB
Main entry chunk (gzip) 144.1 KB 350 KB
Entry file index-CcJdoxM_.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.23KB 114.67KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 26.68KB 8.94KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 246.35KB 62.12KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.53KB 46.34KB
plugin-dashboard (index.js) 131.50KB 34.45KB
plugin-designer (index.js) 215.51KB 44.29KB
plugin-detail (index.js) 252.45KB 65.33KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 134.25KB 33.52KB
plugin-gantt (index.js) 166.96KB 40.93KB
plugin-grid (index.js) 210.67KB 57.19KB
plugin-kanban (index.js) 57.00KB 16.28KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.55KB 3.32KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3487.0 KB 3512.7 KB
Main entry chunk (gzip) 144.1 KB 350 KB
Entry file index-XtQfqHb9.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.23KB 114.67KB
core (index.js) 7.48KB 2.96KB
create-plugin (index.js) 26.68KB 8.94KB
data-objectstack (index.js) 198.39KB 55.29KB
fields (index.js) 246.94KB 62.28KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 6.57KB 2.76KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.39KB 19.92KB
plugin-chatbot (index.js) 194.54KB 46.34KB
plugin-dashboard (index.js) 131.50KB 34.45KB
plugin-designer (index.js) 215.51KB 44.29KB
plugin-detail (index.js) 252.45KB 65.33KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.26KB 34.13KB
plugin-gantt (index.js) 166.96KB 40.93KB
plugin-grid (index.js) 210.86KB 57.28KB
plugin-kanban (index.js) 57.53KB 16.46KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.55KB 3.32KB
plugin-view (index.js) 84.54KB 20.84KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.55KB 2.45KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 13.64KB 4.59KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-bill
os-bill marked this pull request as ready for review September 9, 2026 17:29
@os-bill
os-bill added this pull request to the merge queue Sep 9, 2026
Merged via the queue into main with commit 093af32 Sep 9, 2026
36 checks passed
@os-bill
os-bill deleted the claude/issue-8772-objectstack-17-4-0-line branch September 9, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants