Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(types): model `code-editor` and `bar-chart`, repair three catalog fixtures by os-sam · Pull Request #6944 · objectstack-ai/objectui · GitHub
Skip to content

fix(types): model code-editor and bar-chart, repair three catalog fixtures - #6944

Merged
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures
Aug 31, 2026
Merged

fix(types): model code-editor and bar-chart, repair three catalog fixtures#6944
os-sam merged 2 commits into
mainfrom
claude/issue-6318-corpus-safevalidate-failures

Conversation

@os-sam

@os-samos-sam commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Refs #6318. Parts 1 and 2 of that card land here; part 3 was not needed. The remaining 28 entries are filed as #6939, #6940 and #6942 — they are schema questions, not fixture bugs, and this PR deliberately leaves them alone.

Review follow-up (head 0e123f16c): the objectui#6273 one-authority gate went red on the first push and is fixed below under Name authority; the changeset is regraded patch to minor per contract review. Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Premise re-derived — the counts moved, the finding did not

⚠️#6318's counts were measured at 090927f4f. Re-measured on a clean checkout at 40c479af2:

card (090927f4f)measured (40c479af2)delta
globbed617624+7
reported by objectui check5435−19
real ObjectUI content (minus the pinned false positive)5334−19
skipped46460

The 19 that left were repaired by cards that landed in between — button (14), toast/sonner (2), timeline (3), menubar (1), dropdown-menu (1) — and 2 chart entries joined, which the card had not enumerated. The card's thesis is intact: two distinct causes, both real, bucket B still exactly 4 files / 2 types. Only the arithmetic decayed, so this is premise_still_valid: true with the delta stated.

#6320 verified, not assumed

The card warns that in a built workspace every count roughly doubles, because the ignore list only excluded a top-leveldist/. #6320 was supposed to fix that. Measured here, both ways:

  • synthetic probe — one JSON file dropped into a nestedpackages/types/dist/: anchored 624 (unchanged), unanchored 625.
  • fully built workspace — 39 dist/ directories holding 433 JSON/YAML files: anchored 624, unanchored 1057. The doubling reproduces exactly, and the anchored form is immune to it.

objectui check reported Analyzing 624 files / 28 files carry a registered ObjectUI component type / Skipped 46 filesidentically on the clean tree and on the fully built one. The numbers in this PR are build-state-independent.

Part 1 — bucket B (4 files / 2 types), no fork

code-editor and bar-chart both RENDER — @object-ui/plugin-editor and @object-ui/plugin-charts register them — and AnyComponentSchema modelled neither, so safeValidateSchema refused every document naming them whatever it said. Searching packages/types/src/zod/ for a z.literal naming either type returned zero, as the card reported.

Neither forced a product-shape decision, so neither is reported as a fork. Every key is a read site:

code-editorpackages/plugin-editor/src/index.tsx:43-49 forwards schema.value, schema.language, schema.theme, schema.height, schema.onChange, schema.readOnly, schema.className into the lazy Monaco implementation; the registration's inputs/defaultProps (same file, 64-77) name the same set; plugin-editor/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

bar-chartpackages/plugin-charts/src/ChartRenderer.tsx:28-38 forwards schema.data, schema.dataKey, schema.xAxisKey, schema.height, schema.className, schema.color; ChartBarRendererProps.schema (same file, 12-21) declares exactly that set; plugin-charts/src/index.tsx:45-64 registers the same five as inputs and defaultProps; plugin-charts/src/types.ts declared the same interface, and now re-exports the one in @object-ui/types (see Name authority below).

Two judgement calls, both anchored rather than invented:

  • language is z.string(), not the registration's six-name enum. The renderer hands it to Monaco verbatim, and the plugin's own declaration already widens its list with or string. A picker shortlist and an accepted set are different claims.
  • Every key is optional, including data — which the registration marks required: true for authoring. The renderer reads schema.data with no guard and the implementation defaults an absent array, so requiring it would refuse documents the renderer draws.

Placement follows markdown and kanban: a TS declaration in @object-ui/types plus a Zod mirror, registered in zod-mirror-parity.test.ts's MIRRORS. @object-ui/types has zero dependencies and cannot import either plugin, so this is the direction the layering allows. ⚠️ The plugins no longer carry their own copy — that is the objectui#6273 fix below, and it means there is exactly one declaration per name rather than a twin.

Part 2 — bucket A: a verdict per group, and only three fixtures were wrong

Hand-triage turned out to be entirely practical, so part 3 (the type-keyed discriminated union) was not needed and is not in this diff. The card is right that invalid_union — Invalid input tells a reader nothing; that was solved offline, by resolving the union member from the root type and parsing against it directly, without touching the shipped union.

Each verdict below was then checked the way #6318's triage asks — by rendering it through the real SchemaRenderer — because a "correction" that renders identically proves the edit was wrong.

Fixture wrong — 3 files, all fixed here

filewhat was wrongrender beforerender after
components-form-select/basic-select.jsonthird option spelled its label type; select.tsx:61 renders {opt.label} and nothing elseopen list: Option 1 Option 2 (24 elements)Option 1 Option 2 Option 3 (25)
components-basic-button-group/icon-toolbar.jsonbuttons carried only icon/value; button-group.tsx:43 reads label and neither of the other two. The sibling with-icons.json — which already validated — carries all threetext "", three blank buttonstext Copy per button
components-layout-tabs/basic-tabs.jsonitems had no value (read at tabs.tsx:52,53,63,64) and no defaultValue (the registration marks it required: true)Tab 1 Tab 2 — no panel selectableTab 1 Tab 2 Content 1

⚠️basic-tabs is the one that shows why the render check is not decoration: adding valuealone renders identically, so value plus defaultValue is the single repair, not two.

Schema under-declares — 10 groups, 28 files, reported not swept

Verdicts and evidence in full on the filed issues. Summary, with the render each "correction" would have produced:

groupfilesverdictevidence
tooltip1schema wrongcorrecting to children gives a blank tile; the fixture was already moved childrentrigger once on render evidence (objectui#4626)
context-menu1schema wrongcorrecting loses the authored trigger, falling back to the renderer's hardcoded string
tree-view4schema wrongnodes and data render identically; the fixtures are the renderer's own defaultProps
kanban2forkcards renders To Do 1 + the card; items renders To Do 0 + No cards. Two declarations of one component disagree
filter-builder4schema wrongthree mis-declarations; correcting drops the field from the condition row
chart2schema wrongthe mirror models one of two dialects the renderer documents itself as accepting
object-map3schema wrongadding objectName renders identicallystaticData still wins the three-arm resolver
object-gantt3schema wrongsame, same resolver
data-table2mirror drift → #6940zod says array, the TS twin / renderer / registered input / docblock all say boolean; true and [] render identically
text5inert key → #6942small, body, h1 and no-variant all render byte-identically — the ui:text renderer reads no variant at all

⛔ The 54th file (packages/vscode-extension/schemas/objectui-schema.json) is untouched: it is the known pinned false positive. ⛔ The 36-file adjacent measurement is untouched.

Name authority — the objectui#6273 fix

Adding BarChartSchema and CodeEditorSchema to @object-ui/types collided with the pre-existing
declarations in their owning plugins, and Test (shard 4/4) went red on
scripts/__tests__/one-authority-per-exported-name-6273.test.ts — the 2026-08-25 family ruling
(objectui#6172, decision 甲/A1): every exported schema name has exactly one authority.

Rename or re-point was decided structurally, not by reading. A tsc probe asserted mutual
assignability in both directions for each pair, plus a per-member probe for language — the one
member the two spelled differently, where 'javascript' | … | string collapses to exactly string:

pairheritagemembersLocal extends OwnerOwner extends Localverdict
BarChartSchemaboth BaseSchema6 = 6, same types + optionalitysame type ⇒ re-point
CodeEditorSchemaboth BaseSchema7 = 7, same types + optionalitysame type ⇒ re-point

⚠️ The green is a measurement, not a vacuous assertion: a deliberate counter-probe
(asserting BarChartSchema and ChartSchema are the same type) failed as required with Type 'true' is not assignable to type 'false'.
A second counter-probe on the consumer path rejected height: '300px' with
Type 'string' is not assignable to type 'number'.

Direction is forced.@object-ui/types is the lower layer and cannot import from a plugin without
a cycle, so of the two possible authorities only one is legal: the plugins re-point at types'.
export type { X } from '@object-ui/types' is a re-export, which the gate does not count.

KNOWN_COLLISIONS is untouched — it is shrink-only and fails in both directions. ⛔ The gate's own
test file is untouched; #6936 and #6937 both carry unlanded edits to it.

Nothing published moved.check:readme-exports still resolves both README self-imports through the
re-export (386 self-imports judged (386 real, 0 wrong-path, 0 fabricated)), the built .d.ts still
exports both names from the plugin entry points, and objectui check returns a byte-identical file
list
— so the schema still models exactly what the renderer reads, which was bucket B's whole point.

Routing and the declared-equals-enforced control

Recorded from contract review rather than claimed here:

  • Clause-② routing is correct. The accept set of the published validator moved, which is the event
    the rule keys on. "These components already render, the union just never modelled them" is a true
    description of the change but does not defeat the routing, and this PR does not lean on it as if
    it did.
  • Zero declared-but-unread keys. The read sites were re-derived key-for-key: NEWLY_PASS=4,
    NEWLY_FAIL=0, against a reversed hot control of REVERSED_CONTROL_NEWLY_FAIL=4. The control is the
    load-bearing half — without it the NEWLY_FAIL=0 reading would be indistinguishable from a probe that
    cannot fail. So this fix does not introduce the defect class the card exists to find.

Verification

Exit codes captured before any pipe; each gate quoted by its own verdict line.

  • pnpm --filter @object-ui/types type-check (hyphenated) — echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, exit 0.
  • Root-form vitest, pnpm exec vitest run packages/types/ examples/schema-catalog/, run at 08571fe50:
    • before (both trees restored to 40c479af2, byte-identity proven by blob hash): Test Files 93 passed (93) / Tests 2767 passed (2767)
    • after: Test Files 94 passed (94) / Tests 2775 passed (2775)
    • delta +1 file / +8 tests = exactly the new pin file. Sanity check against the target's own count: find packages/types examples/schema-catalog -name '*.test.ts*' = 94, matching; vitest root reported as the repo root, so this is not the apps/console substitution (that would read 85/22).
  • pnpm exec eslint . in each touched package, plain form: packages/typesexit 0 (260 pre-existing no-explicit-any warnings, none on a changed line); examples/schema-catalogexit 0 (1 pre-existing warning).
  • node scripts/check-changeset-presence.mjsexit 0: ✅ 10 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s). The changeset is graded minor for @object-ui/types per contract review — the package's own precedent (the visible widen, and ViewNavigationConfig) grades a change of this size minor because it is more than patch describes. Purely additive, so no migration note is owed beyond the regrade. pnpm changeset:checkexit 0.
  • objectui check, its own verdict lines:
    • before: ⚠️ 35 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • after: ⚠️ 28 files carry a registered ObjectUI component type but did not validate as an ObjectUI schema: / Skipped 46 files / ✓ All checks passed
    • diffing the two file lists: exactly the 7 addressed here left, and nothing entered — the two new union members admit no foreign document.
  • Derived gate family (packages/types/src/**, examples/**, .changeset/*), all exit 0: check:spec-symbols, check:self-import, check:phantom-deps, check:side-effects-array, check:esm-specifiers, check:element-data-source-declaration, check:doc-types, check:control-bytes, check:node-esm-load, check:entry-guard, changeset:check, and check:readme-exports.
    • ⚠️check:readme-exports was RED on first read with 312 findings, every one of them its type entry ./dist/index.d.ts is not on disk — run pnpm build first, and none in packages/types. That is the unbuilt-closure false RED: .github/workflows/readme-exports.yml:92 builds ./packages/* before running it. Rebuilt and re-read: exit 0, 0 unbuilt.
    • ⚠️check:published-dist is RED, on a file this diff does not touch — @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts. Present at 40c479af2, so pre-existing on main. Filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943.

The new pin (examples/schema-catalog/test/safe-validate-corpus-6318.test.ts, 8 tests) asserts the seven repaired entries validate, and pairs that with counter-probes on declared keys — code-editor with theme: 'solarized', bar-chart with a string height — so .success is not satisfied by a mirror that accepts everything. It deliberately does not pin the size of the remaining bucket, which would turn red on whichever card repairs one of the 28.

Re-verified at 0e123f16c

  • pnpm exec vitest run scripts/__tests__/one-authority-per-exported-name-6273.test.ts — was
    Test Files 1 failed (1) / Tests 1 failed | 10 passed (11), now Test Files 1 passed (1) /
    Tests 11 passed (11)
    , exit 0.
  • pnpm exec vitest run scripts/ packages/plugin-charts/ packages/plugin-editor/ packages/types/ examples/schema-catalog/
    Test Files 219 passed (219) / Tests 5523 passed (5523), exit 0.
  • pnpm --filter @object-ui/types type-check — exit 0; both re-pointed plugins type-check and
    build — exit 0, and the re-export reaches the shipped .d.ts.
  • examples/schema-catalog/test/safe-validate-corpus-6318.test.tsTest Files 1 passed (1) /
    Tests 8 passed (8), exit 0.
  • pnpm exec eslint . in packages/plugin-charts and packages/plugin-editorexit 0 each
    (267 and 5 pre-existing warnings, 0 errors).
  • Gate family re-run, all exit 0: check:spec-symbols, check:self-import, check:phantom-deps,
    check:esm-specifiers, check:side-effects-array, check:control-bytes, check:node-esm-load,
    check:readme-exports, check:changeset-presence, changeset:check.
  • ⚠️check:published-dist remains RED on the same unrelated pre-existing file
    (@object-ui/fields, filed as check:published-dist is RED on main: @object-ui/fields ships dist/__tests__/numberInputBrowserReadings.d.ts in its tarball #6943) — unchanged by this commit.
  • ⚠️ One local-only red worth recording: scripts/__tests__/check-sdui-registration-pins.test.ts
    fails only on a fully built tree, because the derivation picks
    packages/app-shell/dist/console/connect/ConnectAgentWidget.js over the src/…tsx it asserts.
    Removing packages/app-shell/dist turns it green; it does not touch this diff, and CI's test job
    never builds. Already filed as finding(test-infra): check-sdui-registration-pins.test.ts fails on any tree where packages/app-shell/dist exists #6893 — searched before filing, so no duplicate was raised.

Filed rather than swept

⛔ Draft, not enqueued, no auto-merge — the PM lands it.

… fixtures
Part of #6318.
Bucket B — two REGISTERED component types that `AnyComponentSchema` did not
model, so `safeValidateSchema` refused every document naming them regardless of
content. Both render today: `@object-ui/plugin-editor` registers `code-editor`
and `@object-ui/plugin-charts` registers `bar-chart`. Every key on the new
`CodeEditorSchema` / `BarChartSchema` (and their Zod mirrors) is taken from a
read site — `plugin-editor/src/index.tsx:43-49` and
`plugin-charts/src/ChartRenderer.tsx:28-38` — not from a view of what either
component's authorable surface ought to be.
Bucket A — three fixtures that were wrong about their own renderer, each
confirmed by rendering it: `basic-select`'s third option spelled its label
`type` (the open list showed two options, now three); `icon-toolbar`'s buttons
carried only `icon`/`value`, neither of which `button-group` reads (three blank
buttons, now labelled — the sibling `with-icons.json` already carried all
three keys); `basic-tabs` gave its items no `value` and no `defaultValue`, so
no panel could be selected (the tab content now paints).
The remaining 28 entries in the bucket are NOT fixture bugs and are left
untouched: each is a Zod declaration that contradicts what its renderer reads,
reported on the card rather than swept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…inor
Two fixes to the review of #6318's PR.
1. objectui#6273 (the 2026-08-25 family ruling objectui#6172 / 甲-A1) went red:
the two schemas this branch added to `@object-ui/types` collided by name with
the pre-existing declarations in their owning plugins.
The two shapes were compared STRUCTURALLY before choosing, not by reading:
a tsc probe asserting mutual assignability in both directions, per pair, plus
a per-member probe for `language` — the one member the two spelled
differently (`'javascript' | … | string`, which TypeScript collapses to
exactly `string`). Every relation held, and a deliberate counter-probe
against an unrelated shape failed as required, so the green was a
measurement rather than a vacuous assertion. Same heritage, same member set,
same per-member types and optionality ⇒ these are re-points, not renames.
Direction is forced: `@object-ui/types` is the lower layer and cannot import
from a plugin without a cycle, so the plugins re-point at types'.
`export type { X } from '@object-ui/types'` is a re-export, which the gate
does not count as a second declaration.
⛔ `KNOWN_COLLISIONS` is untouched (shrink-only), and so is the gate's own
test file — #6936 and #6937 both have unlanded edits to it.
The published import paths are unchanged: `check:readme-exports` still
resolves both README self-imports through the re-export (386 judged, 0
wrong-path, 0 fabricated), and `objectui check` reports a byte-identical
file list, so the accept set of the validator did not move.
2. Regrade the changeset `patch` → `minor` for `@object-ui/types`, per contract
review: the package's own precedent (the `visible` widen, and
`ViewNavigationConfig`) grades a change of this size `minor` on the stated
grounds that it is more than patch describes. Purely additive, so no
migration note is owed beyond the regrade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.6 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-RnBefW7y.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.09KB116.42KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)247.26KB63.17KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.11KB32.61KB
plugin-gantt (index.js)165.21KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)8.98KB3.08KB
plugin-view (index.js)85.79KB21.10KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-sam@claude