Skip to content

fix(cli): objectui check judges only files that are recognisable as ObjectUI schemas, and reports what it skipped - #5334

Merged
os-support-ai merged 4 commits into
mainfrom
claude/issue-5127-schema-marker-plus-skip-count
Aug 20, 2026
Merged

fix(cli): objectui check judges only files that are recognisable as ObjectUI schemas, and reports what it skipped#5334
os-support-ai merged 4 commits into
mainfrom
claude/issue-5127-schema-marker-plus-skip-count

Conversation

@os-support-ai

@os-support-aios-support-ai commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Fixes#5127

Implements the maintainer's 2026-08-20 ruling (verbatim 「C」): objectui check judges only files that are recognisable as ObjectUI schemas, and reports what it skipped — with no public $schema URL minted.

That ruling supersedes the $schema half of the 2026-08-19 「全部接受」 ruling. The structural arm and the option-D skip count are unaffected and stand.

No permanent public identifier is proposed any more. The URL this PR previously proposed for confirmation is not adopted and appears nowhere in the code, the skip hint, the tests, the changeset or the docs — verified by grep over packages/cli/src and .changeset. The hold this PR carried (clause-②, "proposes a permanent public identifier") is therefore discharged: there is nothing left for the maintainer to confirm.
This PR does not close the coverage gap. It is the interim the ruling permits, and the debt is stated below, unchanged.

What changed since the last revision

pointsAtObjectUi() and the OBJECTUI_SCHEMA_URL constant are gone, along with the branch that called them. What remains is one arm.

The skip hint was rewritten. It used to print the URL and tell the reader to declare $schema — advice for a capability the build would no longer have, which is the "comment claims, code does not enforce" shape this repo treats as a defect in its own right. It now names the structural keys, and it does so by rendering the gate's own array rather than a sentence maintained beside it, so it cannot drift from what the gate honours:

Object UI Schema Check
Analyzing 612 files...
Skipped 304 files with a root "type" and no ObjectUI schema marker.
A file is checked when its root carries an ObjectUI structural key: body, children, className, style, placeholder, visible, visibleWhen, visibleOn, hidden, hiddenOn, disabled, disabledOn, testId, ariaLabel.
✓ All checks passed

A test reads that sentence back and feeds every key it advertises to the command on its own file; if the hint ever names a key the gate does not honour, the file is skipped and the test goes red.

The gate as it now stands

A file enters type judgement only when its root carries a key declared on BaseSchema (packages/types/src/base.ts) that is distinctive to a UI node: children, body, className, style, placeholder, visible, visibleWhen, visibleOn, hidden, hiddenOn, disabled, disabledOn, testId, ariaLabel.

Everything else with a root type is simply not judged. No exclusion list of filenames — the rejected direction B from the original ballot, of the shape #5115 had just finished deleting.

Only the .json arm is affected. The glob also matches .yaml/.yml, and those files are read by neither the parse arm nor the judgement arm, before this change or after it.

Why the structural set is drawn from BaseSchema, and why it stops short of it

The set is read out of the node contract rather than invented, and it is closed: it grows only when BaseSchema grows. BaseSchema's remaining keys are held out because their names head foreign root vocabularies. Measured over this repository: name appears at the root of 45 of the 46 foreign judged files and description at 44 — both package.json keys — so admitting BaseSchema wholesale takes foreign retention from 0 files to all 46, re-creating the exact defect. id, label and data are held out on the same reasoning; items is held out because it is a JSON Schema key.

The arm is drawn for precision over recall on purpose. A foreign file wrongly judged is this card's defect reappearing in a user's project; a real schema wrongly skipped is a coverage debt that the corpus migration repays and that the printed count keeps visible meanwhile.

Why there is no $schema arm

Recorded in the code beside the gate, so the next reader does not re-propose it. In short: a $schema URL is a permanent identifier living in users' files, which no sweep can reach, and minting the address before the document exists is backwards. The only consumer that needs a URL rather than any agreed marker is an editor resolving it over HTTP; an agent authoring schemas instead needs a contract it can read before writing and a good error after writing, and the latter is this command. Because the matching was host-based rather than literal, the arm can be added later without invalidating a single file — most soundly once @object-ui/types ships a generated JSON Schema, which the ruling files separately for the decision inbox.

Re-measured after the change

Measured first-hand at 9f118b934, both columns produced in this worktree — the before column by building main's check.ts in the same tree, not inherited from the earlier report.

beforeafter
files analysed612612
unknown-type warnings460
— of those, package.json"module"450
— of those, real10
files reported skippedn/a304
exit code00

The skipped figure did not move — 304 before this revision and 304 after — and that is a measured result, not a stale number. Removing the $schema arm released nothing, because the arm matched nothing: of the 470 files a root type string makes eligible in this repository, exactly 1 declares any $schema at all (a draft-07 JSON Schema document) and 0 point at an objectui.org host. The ruling states this; it is confirmed here rather than taken on trust.

Of the 470 eligible files, 46 are foreign (45 package manifests + one draft-07 JSON Schema) and 424 are real in-repo ObjectUI schema files (423 under examples/schema-catalog/src/schemas, plus examples/hello-world/schema.json). Under the marker as shipped, 166 of those 424 are retained and 258 leave the judgement surface (60.8%). 258 real + 46 foreign = the 304 skipped above.

The catalog's own deliberate examples/schema-catalog/src/schemas/core-schema-renderer/unknown-component-type.json fixture goes quiet. It was the single genuine warning the command emitted, and its root is {type, someData} — no marker. This is the cost the ruling names, and it is why option A alone was rejected and why D ships alongside.

The debt is repaid by the corpus migration, which is its own card and is not touched here — examples/schema-catalog/** is untouched in this diff.

Option D — the shrink is never silent

The count covers files that a root type string made eligible and no marker admitted — files that were never eligible do not inflate it, since they are not lost coverage. It is a report, not a failure: exit codes are untouched, and a JSON parse failure remains the only thing that fails the run.

Verification

All at 9f118b934, the final commit on this branch.

  • pnpm exec vitest run packages/cli/src/__tests__/ from the repo root (the canonical invocation — assertCanonicalVitestInvocation refuses a package-cwd run): 10 files, 202 tests, all passing. 203 previously; the two tests that pinned the $schema arm are gone and one hint test is new.
  • pnpm --filter @object-ui/cli type-check → clean (tsc --noEmit, and the run echoed the script name, so it is not a zero-match silent pass).
  • pnpm --filter @object-ui/cli lint → 0 errors, 11 warnings, none in any file this PR touches (grepped by filename).
  • node scripts/check-control-bytes.mjs → OK, 4723 tracked text files; the touched files also self-scanned clean for raw control bytes.
  • node scripts/check-changeset-no-major.mjs, node scripts/check-changeset-fixed.mjs → OK (changeset is minor).
  • node scripts/check-package-self-import.mjs, node scripts/check-phantom-dependencies.mjs → OK.
  • End-to-end through the built CLI: pnpm --filter @object-ui/types build && pnpm --filter @object-ui/cli build, then node packages/cli/dist/cli.js check at the repo root — the table above.

Build artifacts, per leg

  • Unit tests — no artifact between the edit and the thing under test. Proven rather than inherited: packages/cli/dist/ was deleted outright, and the three check-* files then ran 34 passed with no dist/ present at all. The imports are relative (../commands/check.js), and no root vitest alias covers them, so Vitest resolves to src/commands/check.ts.
  • End-to-end — crosses dist/, so it was rebuilt. Confirmed in both directions before each measurement: the new hint sentence is present in dist/cli.js for the after run and absent from the pre-change build used for the before run, and the removed URL greps to 0 in the shipped bundle.
  • ⚠️ Worth knowing for the next reader: cli-bin.test.ts self-builds the CLI only when dist/ is absent. A staledist/ is not refreshed by running the tests, so an end-to-end reading taken without an explicit rebuild can silently describe old code.

Reverse verification

Three ablations, each with the count predicted before running. The fix was committed first, so every restore was a git checkout back to the commit, confirmed byte-identical by an empty git status --porcelain.

1. Revert check.ts to main (the gate itself removed) — predicted 8 red, observed 8, the same set name for name: the package-manifest case, the JSON Schema case, the deployment-descriptor case, the foreign-file-whose-type-names-a-real-component case, the new $schema-is-not-a-marker case, and all three option-D assertions. The tests asserting a schema is still judged stay green under this ablation by design — the old code judged everything — which is why they are paired with the ones above rather than standing alone.

2. The fixture trap, which this revision exists to defuse. The pre-existing fixtures in check-known-types.test.ts and check-jsonc-parse.test.ts declared the $schema URL in order to stay judged. Deleting those lines and taking the green run would have put every one of them back into the state the previous revision of this body warned about: the warning assertions fail, and — worse — the silence assertions keep passing while measuring nothing. Each fixture is therefore given a structural key (className, the least semantically loaded key in the set) instead, and each silence assertion is paired with a counter-probe — a file with the same marker and an unregistered type — so the silence is a verdict rather than a judgement that never ran.

Measured, not asserted. Dropping the marker injection from check-known-types.test.ts: predicted 5 red, observed 5. Then the counterfactual, same ablation but with the counter-probe and the added warning assertion removed — i.e. the tests in their original shape: predicted 3 red, observed 3, with 2 passing while measuring nothing. Those two are exactly is silent for registered types... and reports an unknown type as a warning, never as a failure, over fixtures the gate never admitted.

3. Dropping the markers from check-jsonc-parse.test.ts — predicted 4, observed 3 on the first run. The miss was in the ablation, not the suite: the pattern used to strip the markers required a trailing space, and the commented.json fixture spells the marker with a newline after the comma, so that one fixture was never actually ablated and its test stayed green for a correct reason. Completing the ablation gave 4 red, as predicted. Recorded because the previous rounds on this card turned up two genuine phantom fixtures the same way, and the difference between "my probe missed" and "my fixture is phantom" is only visible if you go and look.

The changeset

Updated in the same push: it described the $schema URL as one of two ways a file opts in. It now describes the structural key as the only marker and records that no public $schema URL is introduced. Still minor.


Generated by Claude Code

…ObjectUI schemas (#5127)
A root `type` is not evidence that a file is a UI schema — `type` heads at
least seven unrelated JSON vocabularies, the commonest being `package.json`'s
`"type": "module"`. Measured at this repo's root: 46 warnings, 45 of them
package manifests, and the first line a user saw in their own project.
A file now enters type judgement only on a positive marker: `$schema` pointing
at an objectui.org host, or a structural key declared on `BaseSchema`. An
exclusion list of filenames was rejected — that is a second hand-maintained
list of the shape #5115 had just finished deleting.
Option D lands with it: the command reports how many eligible files carried no
marker, so the narrowed judgement surface is never silent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
…posed (#5127)
Reverse-verification predicted 8 red and observed 7. The miss was the
`.eslintrc.json` case: `globSync` does not match dot-prefixed names without
`dot: true`, so that file was never scanned and its assertion of silence held
whatever the marker did — green in both directions, measuring nothing.
It is replaced by a deployment-resource descriptor, which is scanned and whose
root `type` is unregistered, plus an explicit test that pins the dotfile scope
itself with a scanned sibling as counter-probe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)25.3 KB350 KB
Entry fileindex-DV-Upfp-.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)9.83KB3.70KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)8.92KB3.41KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)29.33KB7.05KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.13KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.64KB2.21KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.79KB
auth (createAuthenticatedFetch.js)6.34KB2.43KB
auth (index.js)2.71KB1.22KB
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.02KB0.88KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)26.07KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.65KB0.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)506.75KB113.40KB
core (index.js)4.11KB1.62KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)159.80KB44.34KB
fields (index.js)237.07KB59.46KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.42KB1.39KB
i18n (pickLocalized.js)3.69KB1.73KB
i18n (provider.js)23.13KB7.63KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)29.43KB7.15KB
i18n (useSafeTranslation.js)7.77KB3.13KB
layout (index.js)39.16KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.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.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)9.35KB3.31KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)4.42KB1.42KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.81KB0.83KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.62KB12.83KB
plugin-charts (index.js)64.75KB18.37KB
plugin-chatbot (index.js)181.21KB43.14KB
plugin-dashboard (index.js)127.92KB32.80KB
plugin-designer (index.js)212.39KB42.83KB
plugin-detail (index.js)241.46KB60.56KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)124.19KB30.20KB
plugin-gantt (index.js)164.10KB39.87KB
plugin-grid (index.js)198.22KB53.28KB
plugin-kanban (index.js)52.93KB14.60KB
plugin-list (index.js)111.66KB27.13KB
plugin-map (index.js)20.08KB6.62KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.49KB11.93KB
plugin-timeline (index.js)26.68KB7.66KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.55KB20.67KB
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.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)36.10KB12.26KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.33KB0.69KB
react (schema-input.js)1.45KB0.83KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (index.js)4.77KB2.16KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)10.76KB3.17KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)6.92KB2.40KB
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)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.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-retry.js)4.32KB2.02KB
types (index.js)3.08KB1.53KB
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 (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
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

@os-support-aiClaude

Copy link
Copy Markdown
CollaboratorAuthor

PM review: technically ACCEPTED, and deliberately NOT merged. Round 17.

This PR is not queued and I will not queue it. The 2026-08-19 ruling reserves one thing to the maintainer: "The URL proposal goes in the implementing PR for the maintainer to confirm at merge (it is a permanent public URL)." Clause-② is yes for that reason. Marked ready for review so it is reviewable; the merge is the maintainer's action. #5127 is back on needs-user-decision with the three URL options and the reasoning.

Everything else checks out:

  • Path surface (git diff --name-only origin/main... @ 015e2ee): 5 files — packages/cli/src/commands/check.ts, three test files under packages/cli, one changeset. Zero governed-surface hits, and examples/schema-catalog/** is untouched — the Migrate the in-repo schema corpus (~424 files) to carry the canonical $schema marker — the producer-side half of #5127's Option B #5329 migration boundary held.
  • Gates: every gate job completed: success — Lint, Type Check, Test shards 1–4, Build & E2E, Build Docs, Doc Snippet / Doc Component Type Check, Changeset Declaration / Bump Policy / Fixed Group, Bundle Analysis, Control Byte Scan, Internal Docs Link Check, Skill Guide Path Check. No cancelled, no in_progress.
  • Bump: minor on @object-ui/cli. ⛔ not major.
  • No filename exclusion list anywhere in the diff — the rejected ballot option stayed rejected.

What makes the marker defensible

The structural set is read out of BaseSchema rather than invented, and stops short of it on a measurement rather than a preference: admitting BaseSchema wholesale takes foreign retention from 0 files to all 46, because name heads 45 of the 46 foreign judged files and description heads 44. That is the difference between a marker and a coin flip, and it is written down.

The $schema arm matches on host, not the literal string. That is the right call for a decision that has not been made yet: whichever path is confirmed, changing it later costs one constant and invalidates no already-declared file, while a lookalike origin is still rejected.

The card's own baseline was stale and was re-measured rather than inherited — today's main gives 612 analysed / 46 warnings / exit 0, not the 47 warnings and 64 errors this card recorded, because #5236 and #5237's JSONC arm have both landed since. Likewise the exit surface: 166 retained / 258 exit (60.8%), better than the recorded ~274, at identical precision (zero foreign retained under either drawing), with the difference explained — the earlier set counted props/bind/events, which have zero occurrences in this corpus, and omitted placeholder/style/testId/ariaLabel/visibleWhen/hiddenOn/disabledOn.

Option D ships with it and goes one better than the ruling asked: check prints the count of files a root type made eligible that no marker admitted, plus the $schema line that opts one back in. The shrink is not merely visible — it tells you how to reverse it.

The verification I want on the record

The ablation caught two phantom fixtures in this PR's own new suite — green in both directions, therefore measuring nothing:

  1. .eslintrc.json is dot-prefixed, and globSync does not match dot-prefixed names without dot: true. It was never scanned.
  2. The JSON-Schema fixture used "type": "object" — and objectis a registered component key, so it was silent before the change too.

Both surfaced because the first ablation round predicted 8 red and observed 7, and the one-test gap was chased instead of rounded off. Replaced with a scanned deployment-resource descriptor and a "type": "array" document, plus an explicit dotfile-scope test with a scanned sibling as counter-probe. Second round: predicted 8, observed 8, name for name. The pre-existing fixtures were triaged for the same failure mode — without $schema their silence assertions would keep passing while measuring nothing — and the consumption radius was checked rather than assumed (check() has exactly one non-test caller repo-wide).

Filed out of it: #5335objectui check never scans dot-prefixed files or dot-directories, so .changeset/, .github/ and .vscode/ JSON is neither parse-checked nor type-checked. It matters most for the blocking arm: after #5237 a parse failure is the only thing that fails the run, and that arm is blind exactly where hand-edited machine-read JSON lives.

Stated plainly, and it is in the PR body too

This PR does not close the coverage gap. Until #5329's corpus migration lands, this is the A+D interim the ruling permits, and 258 real schema files leave the judgement surface. Recorded as a debt, not as a fix.


Generated by Claude Code

…inted (#5127)
Maintainer ruling 2026-08-20 (verbatim 「C」) supersedes the `$schema` half of
the 2026-08-19 「全部接受」 ruling. The structural arm and the option-D skip
count are unaffected and stand.
`pointsAtObjectUi()` and `OBJECTUI_SCHEMA_URL` are removed, and the skip hint
now names the structural keys by rendering the gate's own array — so it cannot
advertise a way in that the build does not honour.
The fixtures in `check-known-types.test.ts` and `check-jsonc-parse.test.ts`
declared that URL to stay judged; they now carry a structural key instead.
Each silence assertion among them gains a counter-probe, because a fixture that
is no longer admitted leaves those assertions green while measuring nothing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
The note advertised a `$schema` URL as one of two ways a file opts into type
judgement. The maintainer's 2026-08-20 ruling removed that arm, so the
structural key is the only marker, and a release note describing a way in that
does not exist is a defect in its own right.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
@os-support-aios-support-ai changed the title fix(cli): objectui check judges only files that declare themselves ObjectUI schemas, and reports what it skippedfix(cli): objectui check judges only files that are recognisable as ObjectUI schemas, and reports what it skippedAug 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)25.3 KB350 KB
Entry fileindex-BInyohVQ.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)10.04KB3.72KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)29.34KB7.05KB
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)6.35KB2.43KB
auth (index.js)2.77KB1.22KB
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.02KB0.89KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
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)506.94KB113.61KB
core (index.js)4.11KB1.62KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)159.80KB44.34KB
fields (index.js)237.07KB59.46KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.42KB1.39KB
i18n (pickLocalized.js)3.69KB1.73KB
i18n (provider.js)23.13KB7.63KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)30.51KB7.57KB
i18n (useSafeTranslation.js)7.77KB3.13KB
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)9.35KB3.31KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)4.42KB1.42KB
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)1.81KB0.83KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.62KB12.83KB
plugin-charts (index.js)64.75KB18.37KB
plugin-chatbot (index.js)181.21KB43.14KB
plugin-dashboard (index.js)128.07KB32.77KB
plugin-designer (index.js)212.39KB42.83KB
plugin-detail (index.js)241.46KB60.56KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)124.19KB30.20KB
plugin-gantt (index.js)164.10KB39.87KB
plugin-grid (index.js)197.30KB53.06KB
plugin-kanban (index.js)52.93KB14.60KB
plugin-list (index.js)111.66KB27.13KB
plugin-map (index.js)20.08KB6.62KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.49KB11.93KB
plugin-timeline (index.js)26.68KB7.66KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.52KB20.67KB
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)3.77KB1.33KB
react (SchemaRenderer.js)36.10KB12.26KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.33KB0.69KB
react (schema-input.js)1.45KB0.83KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (index.js)4.77KB2.16KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)10.76KB3.17KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)6.92KB2.40KB
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)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.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-retry.js)4.32KB2.02KB
types (index.js)3.08KB1.53KB
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 (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
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

Labels

Projects

None yet

2 participants

@os-support-ai@claude