Skip to content

feat(types,plugin-form)!: the grid's sort_field is declared, and a detail's sort field is derived only (objectui#11070 round 9) - #11376

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-11070-grid-sort-field-round9
Oct 1, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-11070-grid-sort-field-round9

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Refs #11070
Clause-②: yes (narrowing). MasterDetailDetailConfig.sortField retires, and GridFieldMetadata gains sort_field. It is priced in the changeset.

Round 9 of objectui#11070: the seat's answer B on sort_field (5928627070), plus grid.mdx's Features prose. Claim 5929173058; dev session session_01TdiauJaVCHuj45EzZGUxHh. DRAFT: no ready, no enqueue.

What changes

  • (i) sort_field is declared (@object-ui/types). GridFieldMetadata.sort_field?: string. Its JSDoc says what it does (the CHILD field the grid stamps with each row's index on every change, so a drag-reorder persists; not one of the columns) and who produces it (deriveDetail in @object-ui/plugin-form, through MasterDetailForm). GridField drops UndeclaredGridKeys and reads its config as Partial of GridFieldMetadata alone, so every key it reads is declared there (@object-ui/fields, comments and one type annotation; no runtime change).
  • (ii) The authored override retires (@object-ui/plugin-form). MasterDetailDetailConfig has no sortField member. The derived value travels on the form's internal per-detail record (DetailEntry.sortField, beside the existing internal amountFieldDef), set only from derived.sortField, and the grid config reads sort_field: entry.sortField. The d.sortField ?? derived.sortField bridge is gone from both derive branches. The amount override (amountField) is untouched.
    • Why DetailEntry and not a second config type: the authored object is spread into the resolved config ({ ...d, … }), and a fully configured detail keeps it as is. A resolved-config type that carried sortField would therefore still carry a stray authored sortField at runtime on that path, which is the dual read this round removes. On DetailEntry the field has one writer, the derivation.
  • (iii) grid.mdx. The typed fence writes sort_field: 'position', and the field-level key list documents it the way round 8 documented total_field and add_label. The Features list was audited bullet by bullet against GridField (below).
  • Pins. The 11144 row "an authored sort field wins over the derived one" retires with the member; its three derived-position / amount rows stay green. The 8071 members pin is re-counted and re-pointed: header prose (eleven members, four renamed on the way, sort_field derived), row 2 with sortField moved to the off-list set (not read), a new row 2c (derived pick vs a written sortField, with a lit control), and a compile-time block (an exact keyof MasterDetailDetailConfig list, a @ts-expect-error refusal of sortField, and a lit control). GridField.fieldKeys-11070 gains a sort_field drag-reorder row and its no-key control, and its declared fixture writes sort_field.
  • Changeset. .changeset/11070-grid-sort-field-round9.md: @object-ui/types minor (one new optional member, a feature), @object-ui/plugin-form minor (a published member retires: breaking, priced minor under the fixed group's policy, stated), @object-ui/fields patch (no runtime change). Dated, append-only notes on the two pending changesets this round makes false: 11070-grid-field-keys-round8 ("sort_field … stays read and undeclared") and 11144-inline-columns-sort-amount ("or a detail's own amountField / sortField still wins").

The sortField census (measured first)

objectui base 1a88ce22 (exact-word git grep -w), objectstack origin/main e952cff5 (same query; control amountField hits 12 files there).

Site Role Before After
deriveDetail (plugin-form/src/deriveMasterDetail.ts) writer (derived) the child's first position / sort_order / sequence / line_no / line_number / sort field unchanged: the one producer
Authored documents, example apps, catalog fixtures, docs (objectui) writer 0 0
objectstack: spec, examples, docs, os migrate meta conversions writer 0 (sortField and sort_field both) 0
attachInlineSubforms (app-shell) writer of subforms[] writes childObject / relationshipField / inlineMode / title / columns / amountField; no sortField unchanged
Drawer / Modal subforms types declared shape no sortField member unchanged
object-master-detail-form registration inputs (plugin-form/src/index.tsx) declared shape details: array, no members unchanged
11144 pin, row "an authored sort field wins" test writer sortField: 'line_no' row retired
8071 pin, row 2 test writer sortField: 'position' as a member an off-list key, asserted not read
MasterDetailDetailConfig.sortField declared member declared retired (compile error)
MasterDetailForm resolve effect, both derive branches reader d.sortField ?? derived.sortField derived.sortField, on DetailEntry
MasterDetailForm grid config reader sort_field: d.sortField sort_field: entry.sortField
MasterDetailForm, fully configured detail (no derive) reader the authored sortField only none (nothing is derived there, before or after)
GridField cfg.sort_field reader through UndeclaredGridKeys declared GridFieldMetadata.sort_field

objectui#11144's thread names no user of the authored override: the issue body says attachInlineSubforms carries only inlineColumns and inlineAmountField, and the claim's "an authored amountField (inlineAmountField) or sortField still wins" states a symmetry, not a writer.

grid.mdx Features audit

Bullet Against GridField Disposition
Table Display: clean tabular layout true kept, with "every row shown"
Pagination Preview: first 5 rows, "Showing X of Y" false: every row renders (rows.map in both the read-only and editable bodies), and no "Showing" text exists in the widget removed
Type-Specific Rendering: each column renders according to its type true for editable cells; in read-only mode only date / datetime / time, file and lookup cells are formatted (probe below) corrected to say exactly that
Read-Only Mode: full table view without editing true kept
Responsive: scrollable for many columns true (overflow-x-auto, per-type minimum widths) kept

M3 (scripts/measure-strict-authoring-face.mjs --json, types dist built)

base 1a88ce22 5376e31a (this diff)
nodes / strict-refused / strict-only / red today 2229 / 77 / 46 / 31 2229 / 77 / 46 / 31
documents / strict-refused whole tree / red-today documents 601 / 72 / 24 601 / 72 / 24
per-component rows identical identical

Only rendererMentionsOfUndeclaredKeys (a raw word count over renderer sources: change and key each one lower, field and schema each one higher, from this diff's comments) and unloadableModules (environmental: app-shell unbuilt at base) differ. H3 holds.

Ablations (predictions written before each run; every mutation through objectstack scripts/ablation-replace.mjs, anchor hit as declared, blob changed, restored to the HEAD blob with git diff HEAD empty)

  • A1, an undeclared sort_field read (the member deleted from GridFieldMetadata, types rebuilt; dist marker 1 to 0). Predicted and observed: fields tsc --noEmit TS2339 on cfg.sort_field; fields tsc -p tsconfig.test.json TS2353 on the declared fixture and on grid({ sort_field }); check:doc-snippets 1 failed block, grid.mdx TS2353 sort_field. Restore leg: types rebuilt, dist marker back to 1, git status --porcelain empty.
  • A2, an authored sortField type-checking again (sortField?: string; planted back on MasterDetailDetailConfig). Predicted and observed: plugin-form tsc --noEmit green; tsc -p tsconfig.test.json exactly 2 errors in the 8071 file, TS2322 on the member list and TS2578 on the now-unused @ts-expect-error.
  • A3, the ?? bridge restored (both sortField: derived.sortField, sites to (d as any).sortField ?? derived.sortField). Predicted and observed over the three touched test files: 1 failed, 24 passed; the failure is row 2c, expected 'line_no' to be 'position'.
  • A4, the false Features bullet restored in grid.mdx (the "Showing X of Y" pagination claim). Predicted and observed: check:doc-snippets, check:doc-fences, docs:check-links, check:doc-types and check:doc-example-ids all green. No gate can see a prose bullet; this round's correction is held by review only.

Local verification (final head 2c59d3b5, the merge of origin/main c82ff391 on top of 5376e31a)

  • Builds through the verify lock: the check-doc-snippet-types --build-filter closure, turbo --concurrency=2, 35 of 35 tasks.
  • type-check green for @object-ui/types, @object-ui/fields and @object-ui/plugin-form (each tsc --noEmit plus its test project; --listFiles shows the touched test files are in those programs). The type-checker set is these three: MasterDetailDetailConfig is referenced only inside plugin-form (a comment in an apps/console test names it), and GridFieldMetadata gains one optional member, which no consumer can break.
  • vitest (--maxWorkers=2, through the lock): packages/plugin-form/ 159 files, 1836 passed and 1 skipped; packages/types/ plus every GridField* / LineItems* test, 325 files and 8103 tests passed.
  • Green: check:doc-snippets (768 of 768 blocks), check:doc-fences, docs:check-links, check:control-bytes, check:changeset-claims, check:pending-changeset-literals, check-changeset-presence, changeset:check, check-changeset-overwrite (it reports the two dated notes, its case 2), check:new-line-citations (0 new), check:test-path-roots, check:doc-types, check:doc-example-ids, check:vi-mock-specifiers, check:readme-exports, check-type-check-coverage. check-governed-queue-guard --test: NOT GOVERNED.
  • The claims gate names two pending changesets on touched files (6357-basechema-bind-declaration on grid.mdx, 6625-retire-fieldmeta-decimals on GridField.tsx). Both paragraphs were read and still hold.
  • Narrowed lint (eslint --no-inline-config --format json) over the 6 changed ts/tsx files: 0 errors, 68 warnings, the same per-file warning counts as the base blobs. Population: the config's **/*.{ts,tsx} blocks (the .mdx and .md files match none). File count 6, read from the json. Invariance: no parserOptions.project or projectService, and no rule in eslint-rules/ reads the filesystem, so this diff cannot move a verdict on an untouched file.

Hypotheses

  • H1 holds: 0 authored writers in either repository; the writers are deriveDetail and two test fixtures.
  • H2 holds: a type split was enough, with no renderer change, for every child that has a sort-named field and is derived. A fully configured detail derives nothing, before and after; that is objectui#11144's own carrier note, not a change here.
  • H3 holds: M3 does not move.

Stop condition reached: the object-master-detail-form.details parity row (excluded file, PR #11335)

apps/console/src/__tests__/registry-inputs-spec-parity.test.ts is not touched. Its MEMBER_PINS['object-master-detail-form.details'] row stays mechanically green (the locator needs only the pin file to exist and to name the block and the key). Its pins prose, though, is now false in two places: "five members reach the grid through ONE hand-written object and four are RENAMED on the way (sortField to sort_field, …)" and "names five of the twelve members the renderer reads". The brief says to stop and report before that row changes, so the row is reported, not edited, and the dev report puts it to the seat with options.

Acceptance notes (not this round's scope)

  • Read-only GridField formats only date / datetime / time, file and lookup cells. A scratch probe (uncommitted, removed) rendered one row { amount: 1234.5, status: 'paid', qty: 1234.5 } with currency, select (option label Paid) and number columns: read-only cells read 1234.5, paid, 1234.5; the same row in list mode reads 1,234.5, Paid, 1,234.5. No reach was measured (the docs page's read-only example writes values that read the same either way), so it is noted here and not filed.
  • grid.mdx's "Integration with Advanced Grid" list (outside the Features list) offers add/remove rows, drag-and-drop reordering and formula columns as plugin features, which the basic grid also has. Left as is.
  • docs/adr/0001-master-detail-subform.md (governed) names sort_field and row[sortField] = index. An ADR records the decision taken; left as is.

Patch (answer A) — added by the seat

  • Seat answer A (5929940616 on objectui#11070) to this PR's open question. After PR feat(plugin-tree,plugin-map,types): object-tree and object-map are judged and publish the keys their renderers honour (objectui#11168 slice 3) #11335 landed, origin/main 20d23bef was merged in as 36313b7f; the merge touches none of this PR's files.
  • 09d3ebf0 edits exactly the two clauses of the object-master-detail-form.details row's pins prose in apps/console/src/__tests__/registry-inputs-spec-parity.test.ts: "four members … each RENAMED … beside columns and the DERIVED sort_field", and "five of the eleven members".
  • The same commit moves the 8071 pin's fully configured sortField check from row 2 into row 2c, so row 2 keeps exactly the two off-list members that the parity row describes.
  • The follow-up dev report is 5930257276. The dev's contract forbids a dev PATCH of this body, so the seat wrote this section.

Generated by Claude Code

claude added 2 commits October 1, 2026 10:15
…tail's sort field is derived only (objectui#11070 round 9)

GridFieldMetadata declares sort_field, the child field GridField stamps
with each row's index on every change, so GridField reads its config as
GridFieldMetadata alone and UndeclaredGridKeys is gone.

MasterDetailDetailConfig loses its authored sortField override (0
writers in either repository, no spec carrier). MasterDetailForm hands
the grid the sort field deriveDetail picks, carried on the internal
per-detail entry; the `?? derived.sortField` bridge is removed.

The 11144 "authored sort field wins" row retires with the member; the
8071 members pin is re-counted with a compile-time member list, a
refusal line and a runtime absence row. grid.mdx documents sort_field
and drops the false "Pagination Preview" Features bullet. Dated notes
on the two pending changesets the retirement makes false.

Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh
Co-authored-by: Claude <noreply@anthropic.com>
Takes c82ff39 (objectui#11347, PR #11360), which touches none of this
branch's files.

Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 3 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/6357-basechema-bind-declaration.md

  • names content/docs/fields/grid.mdx → content/docs/fields/grid.mdx — edited by this change

    bind was read by ten production sites and declared by no schema shape. It resolved as any through BaseSchema's index signature and rode .passthrough() on the validator, while three separate documents taught it as an authorable key of every node: this repo's own AGENTS.md §4 ("Every node in the UI tree follows this shape (@object-ui/types)"), the published agent-facing skills/objectui/rules/protocol.md ("Every UI component node MUST follow this shape"), and content/docs/fields/grid.mdx. So the agent-facing protocol told authors to write a key the published types did not know existed.

.changeset/6625-retire-fieldmeta-decimals.md

  • names GridField.tsx → packages/fields/src/widgets/GridField.tsx — edited by this change

    buildFieldMeta computed decimals: overrides.decimals ?? meta?.decimals ?? meta?.scale on every call and the value reached nothing. Re-measured on this branch's base (efdc6c62): zero .decimals member reads across @object-ui/fields, @object-ui/i18n, @object-ui/components, @object-ui/core and plugin-dashboard itself — the only non-comment occurrence was the write being removed here. The positive control in the same query shape fires: .scale member reads hit NumberField.tsx, GridField.tsx and fields/src/index.tsx. So the zero is a finding, not a broken query. The overrides.decimals ?? head of that chain had already lost its only feeder when objectui#6425's ruling removed the authored read from ObjectDataTable.enrich(); RecordDetailDrawer, the only other buildFieldMeta caller, passes no overrides at all. Both halves retire together, so the key leaves in one move.

.changeset/8067-component-input-member-kind.md

  • names apps/console/src/__tests__/registry-inputs-spec-parity.test.ts → apps/console/src/__tests__/registry-inputs-spec-parity.test.ts — edited by this change

    A registration's type: 'array' said a value was a list and stopped there, so a member that drifted from @objectstack/spec was invisible to every layer that reads a declaration. page:header.actions is the measured cost: the contract declares z.array(z.string()) ("Action IDs"), the renderer read the members as ActionDef objects, and the repo-wide parity gate in apps/console/src/__tests__/registry-inputs-spec-parity.test.ts stayed green for the whole life of the drift because both sides carried the key and neither could say what was inside it. What settled it was a maintainer ruling, not a test — and even after the fix, "these are ids" survived only as English in the registration's description.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Compared the checked-out tree with 20d23befe (merge-base with origin/main): 8 file(s) changed outside .changeset/, read against 1929 pending declaration(s) that publish a body (2548 pending in total). · run

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3552.4 KB 3574.6 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-CJO7KE9q.js —
Status PASS —

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 570.62KB 136.73KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 260.89KB 66.19KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.93KB 11.29KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 53.15KB 15.45KB
plugin-charts (index.js) 84.07KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.07KB 37.18KB
plugin-designer (index.js) 216.54KB 44.64KB
plugin-detail (index.js) 245.45KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.14KB 44.58KB
plugin-gantt (index.js) 173.11KB 43.10KB
plugin-grid (index.js) 231.53KB 63.59KB
plugin-kanban (index.js) 49.49KB 15.54KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.54KB 7.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.91KB 10.00KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

claude added 2 commits October 1, 2026 11:08
Takes 20d23be, which carries PR #11335 (objectui#11168 slice 3), so the
object-master-detail-form.details parity row can be patched on this
branch (seat answer A). The merge touches none of this branch's files.

Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh
Co-authored-by: Claude <noreply@anthropic.com>
…what round 9 left (objectui#11070 round 9, seat answer A)

The object-master-detail-form.details MEMBER_PINS row's pins prose
named `sortField` as a renamed member and counted twelve members. It now
says four members reach the grid renamed, beside `columns` and the
derived `sort_field`, and counts eleven. Nothing else in the parity file
changes.

The 8071 pin's fully configured `sortField` check moves from row 2 into
row 2c, so row 2 again carries exactly the two off-list members the
parity row describes, and the check keeps its coverage.

Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the apps label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3552.3 KB 3574.6 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-mB-eVQxr.js —
Status PASS —

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 570.62KB 136.73KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 260.89KB 66.19KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.93KB 11.29KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 53.15KB 15.45KB
plugin-charts (index.js) 84.07KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.70KB 37.42KB
plugin-designer (index.js) 216.54KB 44.64KB
plugin-detail (index.js) 245.45KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.14KB 44.58KB
plugin-gantt (index.js) 173.23KB 43.13KB
plugin-grid (index.js) 231.72KB 63.65KB
plugin-kanban (index.js) 49.49KB 15.54KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 25.60KB 8.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 34.29KB 10.13KB
plugin-tree (index.js) 14.58KB 5.17KB
plugin-view (index.js) 90.32KB 22.76KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 1, 2026 11:45
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit 0a3e540 Oct 1, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-11070-grid-sort-field-round9 branch October 1, 2026 12:00
Sign up for free to 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