Skip to content

feat(app-shell)!: a record page shows a discussion panel only when it composes one (objectui#7298 half two) - #9439

Merged
os-tesla merged 2 commits into
mainfrom
claude/issue-7298-discussion-explicit-composition
Sep 13, 2026
Merged

feat(app-shell)!: a record page shows a discussion panel only when it composes one (objectui#7298 half two)#9439
os-tesla merged 2 commits into
mainfrom
claude/issue-7298-discussion-explicit-composition

Conversation

@os-tesla

@os-tesla os-tesla commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7298

Half two of objectui#7298, implementing the maintainer ruling of 2026-09-12
(director seat, decision batch #120 item 5, ruled C′). Half one landed as
objectui#9123 and is untouched here.

What the ruling asked for, and where each item landed

ruled landed
1. RecordDetailView stops auto-appending a discussion panel; a record page shows one when and only when it declares record:discussion; the panel's own config is honoured as authored packages/app-shell/src/views/RecordDetailView.tsx — the showAutoDiscussion branch and its JSX are gone
2. the disableDiscussion read is deleted with the append same file — the as any read and the hasExplicitDiscussion call that fed it are both gone
3. object-level enable.feeds stays the object's switch, declared or not; precedence stated in one docs sentence stripDiscussionNodes in packages/app-shell/src/utils/pageSchemaIntrospect.ts, applied to the composed tree; sentence in content/docs/guide/slotted-pages.md
4. no transition window; changeset banner + record-page docs .changeset/7298-discussion-explicit-composition.md, content/docs/guide/slotted-pages.md
5. Clause-②: no no new key, no spec edit; the observable behaviour change is declared in the changeset
6. the page-key read gate is domain:devx and gets its own card filed as objectui#9438 — ⛔ not a rider on this PR

The two PM mechanical assumptions, measured

Assumption 1 — locations. ⚠️ Drifted, as warned. The card cited
RecordDetailView.tsx:2046 / :2418; triage (2026-09-05) re-derived :2173 /
:2546; on this branch's base 7098eed36 they were at :2179 (the read),
:2188 (showAutoDiscussion) and :2552-:2589 (the comment + JSX). Re-located
before editing; the file is still in packages/app-shell/src/views/.

Assumption 2 — record:discussion still exists and is spelled as quoted.
HOLDS, measured by parsing the resolved @objectstack/spec 17.4.0
(the ruling quoted a component.zod.ts line from a 2026-09-12 reading of an
older pin), with both controls lit:

PageComponentType members: 32
  SUBJECT record:discussion -> true
  record:chatter           -> true
  CONTROL record:details   -> true      (a member that must be there)
  CONTROL zzz:not_a_type   -> false     (a member that must not)

And the key the ruling deletes is still unauthorable, refused the same way a
nonsense key is — so the read really was unreachable, not merely undocumented:

BASE (control: must be GREEN):      success=true
SUBJECT disableDiscussion:true:     success=false  unrecognized_keys:['disableDiscussion']
CONTROL nonsense key (must be RED): success=false  unrecognized_keys:['zzzNotAKey']

Assumption 3 — how enable.feeds gates the panel. ⚠️ FALSIFIED, and this
is the one finding that changed the work.
The PM had not verified it and asked
for a measured sentence rather than an assumed one. Measured on the base commit,
before any edit: feedsEnabled was read in exactly three places, and the only
one that touched rendering was the auto-append predicate. So:

page enable.feeds panel on origin/main
authored, no discussion node on shown (the auto-append — the ruling's target)
authored, declares the node off shown — the object's switch did nothing
synthesized default (composes the node) off shown — same

⇒ ruling item 3 is not a docs-only item on this tree. Written as prose alone
it would have been a false sentence of exactly the kind AGENTS.md #9 is about.
It is implemented: the composed page tree is pruned of discussion nodes when the
object opted out, which is what makes "the object outranks the page" true rather
than merely written down. The prune is identity-preserving — a tree with
nothing to remove comes back by reference, so every object that never opted out
hands the very same page object to the renderer.

What is NOT in this diff, deliberately

  • packages/spec — untouched (route A is refused by the ruling).
  • ⛔ No transition window, deprecation shim or dual behaviour.
  • ⛔ The renderer-vs-PageSchema page-key read gate — objectui#9438, per ruling item 6.
  • The synthesized default page keeps its panel, because it composes
    record:discussion itself. The ruling removes the host's append, not the
    default page's panel; out-of-the-box record pages are unchanged, and that is
    pinned.

Tests

New pin RecordDetailView.discussionExplicitComposition-7298.test.tsx (8 cases).
The load-bearing one is the negative — an authored page that does not declare
the node renders no panel, no composer, no rows — and every negative is paired
with a lit control that differs from it in exactly one way, so it cannot pass by
the panel being broken:

negative its lit control
no node ⇒ no panel the same page WITH the node ⇒ panel, rows, composer
feeds off ⇒ no panel though declared feeds on, declared, empty feed ⇒ panel chrome + composer

⚠️ The feeds-off pair is read on the panel's chrome, not on feed rows:
enable.feeds: false also skips the sys_comment read, so both sides would
have zero rows for two different reasons and rows could not discriminate.

Baseline on the base commit, before the source change: 5 passed, 3 failed
and the three failures are exactly the three rows of the table above that the
ruling changes. After: 8/8.

Three existing files were re-aimed rather than deleted, because each drove its
subject through the retired append:

Ablation — from the committed state, mutation proved on disk, restore proved by state

Direction predicted before running: this is a real behaviour change, not a
dead-code removal, so the new pin must go RED when the ruled code comes back.

The mutation is git checkout 7098eed36 -- RecordDetailView.tsx pageSchemaIntrospect.ts
— the pre-ruling source itself, so the ablation is against the exact behaviour
the ruling retires rather than a hand-written approximation.

HEAD blobs: view=0c63ff1f utils=295b6512
marker showAutoDiscussion   in view: 2   (expect >0)   ← mutation reached disk
marker disableDiscussion    in view: 3   (expect >0)
marker stripDiscussionNodes in view: 0   (expect 0)    ← and in the other direction
marker stripDiscussionNodes in utils: 0  (expect 0)
mutated blobs: view=f4fb0b7a utils=d2f251f2         ← both differ from HEAD's
Tests  3 failed | 5 passed (8)   ABLATION-EXIT=1

The three that red are exactly the three the ruling changes; the five controls
stay green, so the harness is not simply broken by the mutation.

Restored with git checkout HEAD -- ABSOLUTE_PATH (never a bare checkout, which
restores from the index the mutation polluted), under a trap on EXIT INT TERM
with an absolute REPO_ROOT, and proved by state, never by an exit code:
git diff HEAD empty, git status --porcelain empty, and both blob hashes back
to 0c63ff1f / 295b6512.

Gates

Exit codes captured before any pipe; each gate's own verdict line quoted. All at
final HEAD 26115bb unless noted.

  • pnpm exec vitest run packages/app-shell/Test Files 698 passed (698), Tests 6815 passed | 1 skipped (6816), lock VERDICT command-exit 0
  • pnpm --filter '@object-ui/app-shell' type-checktsc --noEmit && tsc -p tsconfig.test.json, VERDICT command-exit 0
  • pnpm lint (turbo run lint, the command CI runs) → Tasks: 47 successful, 47 total, 0 errors repo-wide, VERDICT command-exit 0
  • pnpm --filter '@object-ui/app-shell^...' buildVERDICT command-exit 0 (run FIRST — a stale dist lies in both directions, and the first type-check attempt without it is the classic phantom TS2307 wall)
  • pnpm exec turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2Tasks: 35 successful, 35 total
  • pnpm check:doc-snippets → exit 0, 650 of 650 block(s) judged, 0 failed
  • pnpm check:doc-examples → exit 0, Every covered @example compiles, or fails exactly as its ledger row declares
  • pnpm check:doc-types · check:doc-fences · check:doc-example-ids · check:docs-route-closure · node scripts/check-doc-links.mjs → all exit 0
  • node scripts/check-changeset-presence.mjs → exit 0 · node scripts/check-changeset-no-major.mjs → exit 0 · pnpm check:changeset-claims → exit 0
  • pnpm check:control-bytes → exit 0, plus a direct grep -naP control-byte scan over the ten touched paths: no hits
  • pnpm check:test-path-roots · check:vi-mock-specifiers · check:vi-mock-inherit · check:vi-mock-override-shape · check:readme-exports · check:unreferenced-sources · check:comment-mask-corpus · check:new-line-citations · node scripts/check-lint-coverage.mjs (46/46 packages, 0 outstanding errors) → all exit 0
  • node scripts/check-governed-queue-guard.mjs --test over the five paths → exit 0, NOT GOVERNED

⚠️ Two readings that are NOT MEASURED, and are reported as such rather than as
green.
pnpm check:doc-snippets and pnpm check:doc-examples first answered
PRECONDITION NOT MET (exit 2) — the gate says in its own words that this is
"I could not run", not "I ran and found errors". They were re-run after the
scoped build named above, and the exit-0 lines quoted here are from that second
run.

The nine required CI contexts were still in_progress when this was written;
waiting on CI is not this seat's step. The run report on objectui#7298 records
their state at that moment.

Acceptance notes

  • packages/plugin-detail/src/renderers/record-chatter.tsx carries a comment
    that this PR makes stale
    — it explains its three affordance defaults as
    "the WHOLE of what the host's auto-appended discussion is" and points at the
    showAutoDiscussion branch, a symbol that no longer exists. ⛔ Left untouched:
    packages/plugin-detail is outside this dispatch's file surface. Noted here so
    it is not discovered as a surprise; it is prose, not behaviour.
  • BuildPageOptions.hideDiscussion in buildDefaultPageSchema is unchanged and
    still accurate — it suppresses the node the synthesizer composes, which is
    a different thing from the host append this PR removed.
  • packages/app-shell/src/utils/pageSchemaIntrospect.ts is inside the dispatch's
    stated scope (packages/app-shell/**) but outside the narrower file list on
    the claim comment. Called out rather than folded in.

🤖 Generated with Claude Code

https://claude.ai/code/session_011QreXiyMEqKLN4U5daMPVa


Generated by Claude Code

… composes one

objectui#7298 half two, maintainer ruling 2026-09-12 (decision batch #120
item 5). `RecordDetailView` stops auto-appending a discussion panel below any
record page whose tree places no `record:discussion` / `record:chatter` node,
and the `(effectivePage as any).disableDiscussion` read goes with it — nothing
reads an undeclared page key here any more. `PageSchema` is a `strictObject`,
so that key was a hard parse error rather than a dropped one and the escape
hatch the renderer's own comment documented could never be authored, while the
panel it was meant to decline was hard-coded open for writes.

`enable.feeds` stays the OBJECT's switch and now outranks the page: the composed
tree is pruned by `stripDiscussionNodes` when the object opted out, so a
declared (or synthesized) node no longer renders a panel over a feed the view
deliberately never fetched. The prune is identity-preserving, so a feeds-on page
is handed through by reference.

`hasExplicitDiscussion` is replaced rather than left dead: its only question was
whether to append, and the two walkers now share one container-key table so
"is the panel there" and "remove the panel" cannot disagree.

No transition window and no opt-in flag, per the ruling. Synthesized and slotted
pages are unchanged — `buildDefaultPageSchema` composes the node itself.

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

Copy link
Copy Markdown
Contributor

⚠️ Console Performance Budget — gauge not trustworthy

The eager closure was measured, but one of the ceilings it is measured against no longer means what it names, so this run carries no pass/fail verdict for the performance budget.

This is not a budget violation. Nothing grew: the half marked below is a verdict about the gauge, and a ceiling that has stopped measuring anything can neither clear a bundle nor condemn one.

Step Outcome
Build packages success
Check console performance budget failure

Which half objected:

Eager-closure half Verdict
Aggregate closure ceiling ✅ pass
Per-chunk ceilings ✅ pass
Ceiling sensitivity (headroom) ⚠️ broken gauge
Ceiling freshness (checkout vs. base branch) ✅ pass

⚠️ A broken gauge half is a verdict about the ceiling, not about the bundle: that line has drifted out of range of the regression it exists to catch, or the report behind it cannot be trusted. It does not say anything grew. The Check console performance budget step log carries the ceiling and the number it was compared against.

Reason: The entry chunk measured 144.5 KB, but the eager-closure half of this gate returned no trustworthy VERDICT: the report could not be read, a ceiling has drifted out of range of the regression it must catch, or (objectui#6245) a ceiling was replaced on the base branch after this checkout was made. The step log says which. This is not a passing budget — and it is not a size regression either.

See the workflow run for details.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 502.94KB 115.47KB
core (index.js) 8.52KB 3.41KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 213.54KB 59.33KB
fields (index.js) 247.89KB 62.50KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.33KB 19.90KB
plugin-chatbot (index.js) 195.34KB 46.51KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 252.17KB 65.50KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.71KB 34.16KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.55KB 57.83KB
plugin-kanban (index.js) 46.63KB 14.53KB
plugin-list (index.js) 112.53KB 27.63KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 84.36KB 20.78KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 96.00KB 31.71KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.04KB 5.36KB
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

…ge doc to plain markdown

`no-useless-assignment` flagged `let result: any = node` in `stripDiscussionNodes`
— both branches assign it, so the initialiser only hid a branch that forgot to.

`content/docs/guide/slotted-pages.md` is a `.md` file and every `Callout` in
this docs tree lives in `.mdx`; the upgrade note is a blockquote instead, which
is the form the same file already uses.

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

Copy link
Copy Markdown
Contributor

⚠️ Console Performance Budget — gauge not trustworthy

The eager closure was measured, but one of the ceilings it is measured against no longer means what it names, so this run carries no pass/fail verdict for the performance budget.

This is not a budget violation. Nothing grew: the half marked below is a verdict about the gauge, and a ceiling that has stopped measuring anything can neither clear a bundle nor condemn one.

Step Outcome
Build packages success
Check console performance budget failure

Which half objected:

Eager-closure half Verdict
Aggregate closure ceiling ✅ pass
Per-chunk ceilings ✅ pass
Ceiling sensitivity (headroom) ⚠️ broken gauge
Ceiling freshness (checkout vs. base branch) ✅ pass

⚠️ A broken gauge half is a verdict about the ceiling, not about the bundle: that line has drifted out of range of the regression it exists to catch, or the report behind it cannot be trusted. It does not say anything grew. The Check console performance budget step log carries the ceiling and the number it was compared against.

Reason: The entry chunk measured 144.5 KB, but the eager-closure half of this gate returned no trustworthy VERDICT: the report could not be read, a ceiling has drifted out of range of the regression it must catch, or (objectui#6245) a ceiling was replaced on the base branch after this checkout was made. The step log says which. This is not a passing budget — and it is not a size regression either.

See the workflow run for details.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 502.94KB 115.47KB
core (index.js) 8.52KB 3.41KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 213.54KB 59.33KB
fields (index.js) 247.89KB 62.50KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.33KB 19.90KB
plugin-chatbot (index.js) 195.34KB 46.51KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 252.17KB 65.50KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.71KB 34.16KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.55KB 57.83KB
plugin-kanban (index.js) 46.63KB 14.53KB
plugin-list (index.js) 112.53KB 27.63KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 84.36KB 20.78KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 96.00KB 31.71KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

@os-tesla
os-tesla marked this pull request as ready for review September 13, 2026 22:40
@os-tesla
os-tesla added this pull request to the merge queue Sep 13, 2026
Merged via the queue into main with commit 7aaa891 Sep 13, 2026
37 of 38 checks passed
@os-tesla
os-tesla deleted the claude/issue-7298-discussion-explicit-composition branch September 13, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants