Skip to content

fix(plugin-chatbot): build discriminated tool parts at the producer and delete the last cast on useChat (objectui#8426) - #10017

Merged
os-tesla merged 2 commits into
mainfrom
claude/issue-8426-chat-parts-discriminated
Sep 19, 2026
Merged

os-tesla merged 2 commits into
mainfrom
claude/issue-8426-chat-parts-discriminated

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #8426

The API-mode parts builder in useObjectChat declared its part array as Array(Record(string, unknown)) and pushed plain objects into it. That is not the chat runtime's part union, and the mismatch was absorbed by an as any on the messages option rather than reported. This makes the builder construct the discriminated parts, so the option is checked and the cast is gone.

Ruling carried in, not re-decided: director seat, decision batch #86, 2026-09-08, option A — contract-first. Its first clause landed as objectui#9229; this is the remaining one. The three shortcuts the dispatch forbids by name (widen the declared type to any; keep the cast with a comment; re-litigate A) are all absent.

The 2x2, re-run on this branch before repairing

Each leg mutated on disk through an anchor that must hit, with blob-hash proof, and restored by state (git diff HEAD empty after every leg). Two type-check programs per leg: tsc --noEmit and tsc -p tsconfig.test.json.

outer } as any) nested (aiInitialMessages as any) main test
present present exit 0 exit 0
absent (today's main, PR #8401) present exit 0 exit 0
present removed exit 0 exit 0
absent removed exit 2, 1x TS2322 exit 2, 1x TS2322

All four legs reproduce the card's table. The red leg's diagnostic, verbatim:

error TS2322: Type '{ id: string; role: "user" | "assistant" | "system"; parts: Record(string, unknown)[]; }[] | undefined'
  is not assignable to type 'UIMessage(unknown, UIDataTypes, UITools)[] | undefined'
  ...  Type 'Record(string, unknown)' is not assignable to type 'UIMessagePart(UIDataTypes, UITools)'

(angle brackets transliterated to round ones above so the body survives sanitizing.)

⚠️ One thing did not survive, and it is a method note rather than a finding about the card. The first attempt at the two nested-cast legs was a NO-OP: the mutation tool refused the write because the replacement text was a substring of the anchor, so its rise-count check could not distinguish the two. The file was restored and both legs then ran against a pristine tree — reading exit 0, i.e. a false green pointing the wrong way. They were re-run with a distinguishable replacement, and the table above is the re-run. Recorded because a silently-reverted ablation reads exactly like a passing one.

After: both casts gone, both programs green

pnpm --filter @object-ui/plugin-chatbot type-check    -> exit 0   (tsc --noEmit && tsc -p tsconfig.test.json)
pnpm exec vitest run packages/plugin-chatbot/         -> exit 0   47 files, 522 tests passed

Program membership proved with a lit control rather than assumed — main program 1626 files: src/useObjectChat.ts 1, src/mapMessages.ts (positive control) 1, useObjectChat.honestMessages.test.tsx (negative control) 0, and the same negative pattern returns 1 against the test program's file list.

Dependents, on a freshly built union closure (Scope: 36 of 47 built, then Scope: 7 of 47 type-checked): all seven pass, zero error TSplugin-chatbot, app-shell, console, site, example-schema-catalog, example-console-starter, example-byo-backend-console. That is the measurement behind the claim that the published-input narrowing breaks nothing in this repository.

Reverse verification — the green is not vacuous

Both legs run from the committed fix, mutated through an anchor that must hit, restored to a byte-identical blob, and the restore leg re-run.

  1. Type. Put the dead toolName back on a constructed tool arm. Predicted red; measured red: exit 2, TS2353: Object literal may only specify known properties, and 'toolName' does not exist in type .... Restored: exit 0.
  2. Test. Delete the HITL carve-out in the un-backed-approval report. Predicted red, and only the HITL test; measured exactly that: Tests 1 failed | 11 passed (12), the failure being says NOTHING when the invocation is an ObjectStack HITL approval. Restored: 12 passed.

What changed

  • The three approval states are now reachable. approval-requested, approval-responded and output-denied require the runtime's approval envelope beside them; ChatToolInvocation gained it in objectui#9229 and the builder now constructs those arms from it. The per-arm shapes differ (approved is forbidden on the outstanding request, required on the response, pinned to false on the denial) so each is built rather than spread.
  • tool-${toolName} is expressible. The dynamic member the card feared was the blocker is not one: the runtime's tool set is open, so the mapped type collapses to an index signature and the discriminant is a template. Pinned by a test.
  • Legacy authoring states are folded, not passed through. partial-call / call / result are not runtime states; passing them through left the round-trip reader refusing them, so the invocation came back stateless. Each test pairs the folded subject with a control asserting the authored spelling is still rejected by the runtime's own validateUIMessages.
  • The dead toolName excess property is dropped. Only the dynamic-tool arm declares one, and the reader derives the name off type, so this is behaviour-preserving.
  • UseObjectChatOptions.initialMessages' optional parts narrows to the store's own part array. Breaking for an external host that passes pre-built parts; minor per this repo's version policy, with the breaking note carried in the changeset.
  • mapMessages' tool-invocation extraction lifts approval. Assigned to this card when objectui#9229 shipped the additive half, and deliberately held until its first reader existed — lifting it earlier would have minted a declared-but-unread key. It closes the recorded asymmetry where the hydrated path carried the envelope and the live path dropped it.

An invocation claiming an approval state with no envelope to back it is not constructible, and no envelope is invented for it (inventing approval.id is the fabrication AGENTS.md #0.1 forbids): the state is derived from the data the invocation does carry, and the producer is warned once, by name. An ObjectStack HITL approval is deliberately not warned about — it is carried by pendingActionId and a pending_approval result, and the mapper re-promotes the state from that result on the way back out, so the approval card survives the round trip.

Acceptance notes

⚠️ The ruling's residual clause is NOT in this PR, and it is not silently dropped. The ruling says the authoring state union should shed the three runtime-only approval states so that "a schema-authored invocation cannot claim approval-requested without an envelope". That union lives on ChatToolInvocation in @object-ui/types, which objectui#9229 left alone and whose own doc records the narrowing as this card's. The dispatch fences packages/types out with "if you find it incomplete, report; do not extend it here". So the conflict is reported rather than resolved by me: the narrowing is what would delete the un-backed-approval branch added here by construction, and it wants its own card or an explicit widening of this one's fence.

Out of scope, noted, not filed:

  • (aiMessages[idx] as any)?.metadata in the same file is untouched and unrelated to this card's call. Successor: the next card on this file's message-output path.
  • objectui#9233 (mergeToolResultsInto rewriting state to output-available for every merged result) is recorded on this card as possibly changing what "done" means here. It is unchanged by this PR: building the arms does not by itself put an approval card in front of an operator on that sub-path. Successor: objectui#9233 itself, which is open.
  • objectui#9232 (the localStorage cache write side rebuilding tool parts without approval) is likewise untouched and open. Successor: objectui#9232.

Gates run locally

check:control-bytes 0 · check:new-line-citations 0 (0 new citation(s)) · check:changeset-claims 0 · check:pending-changeset-literals 0 · check-changeset-presence 0 (1 changeset(s)) · check-changeset-no-major 0 · check-governed-queue-guard --test — NOT GOVERNED · eslint --no-inline-config on the four changed source files exit 0, 9 pre-existing warnings, none from this diff.


🤖 Generated with Claude Code

https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq


Generated by Claude Code

…nd delete the last cast on useChat

`useObjectChat`'s API-mode builder declared its part array as
`Array<Record<string, unknown>>` and pushed plain objects into it. That is not
the chat runtime's part union, and the mismatch was absorbed by an `as any` on
the `messages` option instead of being reported. Re-measured 2x2 on this branch,
each leg mutated on disk with hash proof and restored by state: only the
both-casts-removed leg is red, with one TS2322 in each of the two type-check
programs.

The builder now CONSTRUCTS each part, so the option is checked and the cast is
gone. Per the ruling on this chain (director seat, decision batch #86,
2026-09-08, option A, contract-first) the fix lands at the producer, never as a
wider cast at the consumer.

- The three approval states are reachable: they require the runtime's
  `approval` envelope alongside them, `ChatToolInvocation` gained it in the
  first clause of this chain, and the builder now constructs those arms from it.
- The legacy authoring states `partial-call` / `call` / `result` are folded onto
  the lifecycle arms they mean instead of passing through as states the
  round-trip reader refuses.
- The dead `toolName` member is no longer written onto a `tool-*` part: only the
  dynamic-tool arm declares one, and the reader derives the name off `type`.
- `UseObjectChatOptions.initialMessages`' optional `parts` narrows to the store's
  own part array. Breaking for an external host that passes pre-built parts;
  nothing in this repo sets it.

An invocation claiming an approval state with no envelope to back it is not
constructible, and no envelope is invented for it: the state is derived from the
data it does carry and the producer is told once. An ObjectStack HITL approval
is deliberately not reported, since it is carried by `pendingActionId` and the
mapper re-promotes the state from the tool result.

Also lifts the `approval` envelope in the mapper's tool-invocation extraction,
closing the disagreement where the hydrated path carried the envelope and the
live path dropped it. The lift lands in the same round as its first reader.

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

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 2 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/6169-chatbot-authoring-face-type.md

  • names useObjectChat.tspackages/plugin-chatbot/src/useObjectChat.ts — edited by this change

    Each was read-site-censused before being declared (renderer.tsx and/or useObjectChat.ts reads every one); none were dead, so none took the ADR-0049 retirement route. disabled — also present in the original intersection — is NOT redeclared: it is already BaseSchema.disabled (boolean | string), read generically for every node type, and redeclaring it here would have narrowed away the inherited expression-string case.

.changeset/8214-chatbot-anypart-state-widen.md

  • names mapMessages.tspackages/plugin-chatbot/src/mapMessages.ts — edited by this change

    mapMessages.ts's local AnyPart is written to absorb whatever a producer hands the mapper — every other member is string / unknown — but state was typed against the OUTPUT contract (ChatToolInvocation['state'], the tool-invocation lifecycle). The AI SDK's own text and reasoning parts carry state: 'streaming' | 'done', which is not in that union, so the deliberately-permissive input interface was on that one property STRICTER than the union it exists to absorb and the whole UIMessage[] assignment was refused (TS2345). An app that followed the README and drove useChat() itself had to add an as never / as any of its own, permanently disabling checking on that seam.

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 b234a8497 (merge-base with origin/main): 4 file(s) changed outside .changeset/, read against 1210 pending declaration(s) that publish a body (1769 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3056.4 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-CMPS7neL.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 545.92KB 130.72KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 216.90KB 60.15KB
fields (index.js) 249.62KB 63.02KB
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) 5.52KB 2.10KB
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.73KB 20.08KB
plugin-chatbot (index.js) 198.00KB 47.11KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 255.18KB 66.49KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 139.56KB 35.40KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.71KB 15.17KB
plugin-list (index.js) 113.55KB 27.99KB
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.68KB 8.95KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.18KB 21.05KB
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) 109.04KB 36.08KB
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 (body-dialect.js) 4.38KB 1.98KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.74KB 2.54KB
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) 15.71KB 5.30KB
types (ai.js) 4.11KB 2.06KB
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

…ormly permissive

`AnyPart.approval` arrived typed as the envelope's declared shape. That made the
deliberately-permissive input interface structured on one member — the same
mistake, one member over, that the earlier widening of `state` was filed to
undo, and it falsified that pending declaration's own sentence that "every other
member is `string` / `unknown`".

So the member is `unknown` like its neighbours, and `liftApproval` does the
narrowing — which is where the output check belongs and which the interface's
doc already says. Each member is checked on its own, so a producer that gets one
of them wrong loses that member rather than the whole envelope: the `id` is what
makes an approval answerable, and it is established first.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3056.4 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-6DG_juF9.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 545.92KB 130.72KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 216.90KB 60.15KB
fields (index.js) 249.62KB 63.02KB
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) 5.52KB 2.10KB
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.73KB 20.08KB
plugin-chatbot (index.js) 198.20KB 47.14KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 255.18KB 66.49KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 139.56KB 35.40KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.71KB 15.17KB
plugin-list (index.js) 113.55KB 27.99KB
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.68KB 8.95KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.18KB 21.05KB
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) 109.04KB 36.08KB
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 (body-dialect.js) 4.38KB 1.98KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.74KB 2.54KB
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) 15.71KB 5.30KB
types (ai.js) 4.11KB 2.06KB
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 19, 2026 12:04
@os-tesla
os-tesla added this pull request to the merge queue Sep 19, 2026
Merged via the queue into main with commit 4dbab84 Sep 19, 2026
38 checks passed
@os-tesla
os-tesla deleted the claude/issue-8426-chat-parts-discriminated branch September 19, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants