Skip to content

feat(types): one named authoring-face type per chatbot registration — ChatbotEnhancedSchema and ChatbotFloatingSchema (objectui#7655) - #7705

Merged
os-sam merged 4 commits into
mainfrom
claude/issue-7655-chatbot-registration-authoring-types
Sep 5, 2026
Merged

feat(types): one named authoring-face type per chatbot registration — ChatbotEnhancedSchema and ChatbotFloatingSchema (objectui#7655)#7705
os-sam merged 4 commits into
mainfrom
claude/issue-7655-chatbot-registration-authoring-types

Conversation

@os-sam

@os-sam os-sam commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7655

What

One named, importable authoring-face type per plugin-chatbot registration. ChatbotEnhancedSchema (type: 'chatbot-enhanced') and ChatbotFloatingSchema (type: 'chatbot-floating') join ChatbotSchema in @object-ui/types, with Zod twins in @object-ui/types/zod and both discriminants routed by ComplexSchema; the two registrations in packages/plugin-chatbot/src/renderer.tsx type their schema as those faces and drop the anonymous intersections. The docs' floating example is a typed tsx fence again — the card's own evidence — plus a typed chatbot-enhanced example. ChatbotSchema itself is unchanged.

Clause-②: yes — two new published node types, two new Zod twins, one new published type alias (ChatbotSharedKey, below). Draft, needs:contract-review. Changeset: @object-ui/types: minor with the accept-set change and the new symbol spelled out; @object-ui/plugin-chatbot: patch.

Contract-review remediation — what changed between 30a53bd32 and 4579bdff9

The review (PR comment 5550439212) returned REFUSE on seven items. Each is addressed in this push, and every measurement below was re-taken here rather than copied from the review.

  1. The floating face's channel claims were false and are gone. The first cut said processVisibility and surface were "not forwarded — the panel renders the component defaults" (in ChatbotFloatingSchema's JSDoc, emitted into dist/complex.d.ts, and in the docs rows). Re-measured through the real SchemaRenderer host: the chatbot-floating registration ends its FloatingChatbot element with a raw {...props} spread, LAST, so every authored key reaches the panel's ChatbotEnhanced unfiltered — showAvatars, surface and processVisibility are LIVE on a floating node (table below). The JSDoc, the census pin's docblock, the docs rows and this body now say so: the census counts NAMED schema.KEY reads, the raw spread is a second channel, and the face neither declares nor promises it. The three readings are pinned as a TRIPWIRE in the plugin's real-host test (ablation 2 shows it bites), and the channel is carded as objectui#7708 for a fence-vs-declare ruling — not decided here.
  2. Every displayMode tense reads the ruled state. objectui#7654 was ruled at 2026-09-05T02:48:39Z (comment 5548848737, maintainer verbatim 「同意」, ruling B: retire — ?: never tombstone on ChatbotSchema, designer control and defaultProps seed removed). The eight "parked on a maintainer decision" lines (changeset, complex.ts twice, complex.zod.ts, the parity ledger, the census test) and this body now read: ruled B; execution is finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's own PR; this PR carries the key untouched on both faces so that PR finds the member exactly as ruled.
  3. Option B taken. displayMode and floatingConfig are restored on ChatbotSchema — the declaration lines and displayMode's three JSDoc lines byte-identical to the base (diffed against 6eebc54b6), the // --- Floating / FAB display mode --- heading included; ChatbotFloatingSchema declares the same two. The UnmirroredDeclared entry for ChatbotSchema is back to its three keys with its base comment verbatim. The two "moved" pins are inverted into assertionChatbotKeepsItsWholeFace and assertionFloatingKeysStayTypedOnChatbot, and a third, assertionFloatingKeysHaveOneTypeOnBothFaces, pins the two members equal across the faces. The MOVED narrative is gone from every carrier. The measured reasons, verified here: on the first cut ChatbotSchema['displayMode'] and ['floatingConfig'] read as any and { type: 'chatbot', floatingConfig: { triggerIcon: 'Sparkles' } } compiled clean — the objectui#7669 tombstone had lost its reach on chatbot nodes, and nothing was red for it because that card's pins sit on FloatingChatbotConfig directly. Both are now pinned on the node (floating-chatbot-trigger-icon-retired.test.ts refuses triggerIcon through ChatbotSchema.floatingConfig AND through ChatbotFloatingSchema.floatingConfig; the census test refuses displayMode: 'bogus' on a chatbot node), and ablation 1 shows every one of them turning red in the option-A state.
  4. Changeset completeness. ChatbotSharedKey is named as a new published symbol: exported for TS4022, emitted into dist/complex.d.ts (5 hits), reachable through the @object-ui/types/complex subpath, not re-exported from the entry. The "two keys MOVED" paragraph is replaced by "ChatbotSchema is unchanged".
  5. Parity-ledger prose rewritten from measurement. At this PR's original base three instruments (a key regex over the MIRRORS block, the Declared entry count, Object.keys(MIRRORS).length at runtime) read 154 pairs where the prose said 160 — six too high, carried into every derivative — and the first cut had added its two to the stale number (162). main found the same rot independently at finding(types): DrillDownConfig has no zod mirror — drillDown is declared on ChartSchema and ObjectDataTableSchema and validated on neither #7352's contract review (its re-derivation: 155 after DrillDownConfigSchema, UnmirroredDeclared 13 / 94, union 14) and landed while this PR was open, so the merged file carries main's re-derived text plus this PR's two pairs, every figure re-measured on the merged tree by the same three instruments: 157 pairs, KnownDrift 42 / 63, UnmirroredDeclared 14 / 96 (2 / 12 spec-derived, 12 / 84 local; the seeded pair is gone), union of the two unmirrored ledgers 15, 115 pairs with no KnownDrift entry, 142 with no entry in either unmirrored ledger.
  6. floatingConfig's JSDoc was rewritten, on both faces. The base text said "Only used when displayMode is 'floating'", which was false — the key is read by chatbot-floating alone and forwarded to FloatingChatbot. The corrected sentence is what the restored ChatbotSchema member carries too: its declaration line is verbatim, and that comment is the only difference from the base in the restored block (the diff shows exactly that).
  7. main merged — twice, no rebase, no amend, no force-push. First 8ad218d58 (merge commit 368045e28; conflicts in the two ledger tests reconciled as the union of both sides — finding(types,components,docs): ui:alert-dialog's three surfaces name three DISJOINT key sets — every declared authoring key is inert, and every key the renderer reads is a type error #7104's AlertDialogSchema.onAction plus this PR's six chatbot slots: 66 sites / 44 runtime slots / 22 retired). Then, because main moved again under the first merge (fix(types): ChartDataSeriesSchema declares the six series keys the renderer reads (objectui#7546) #7684, fix(types): close two validating-face gaps — the ObjectQL union arms and the DrillDownConfig mirror (objectui#7363, objectui#7352) #7701), 52c8cf741 (merge commit 4579bdff9, the head): twelve conflict hunks, all in the parity ledger's prose and figures, reconciled as main's finding(types): DrillDownConfig has no zod mirror — drillDown is declared on ChartSchema and ObjectDataTableSchema and validated on neither #7352 re-derivation plus this PR's two pairs and then re-measured (item 5). The head has origin/main 52c8cf741 as a parent; git merge-tree against it is clean.

The ruling followed: one interface per registration, not a widened type

The governing line is quoted in the registration file itself (renderer.tsx, the chatbot registration's head comment): "objectui#6169, the #6172 family ruling: every component node has exactly one named, importable authoring-face type". Widening ChatbotSchema['type'] to the union of the three registered keys would give three nodes ONE type and re-open what #6169 closed. Each new face declares what ITS registration reads by name; the twenty keys all three read are picked off ChatbotSchema by name (ChatbotSharedKey, a Pick keyed by that alias) so they stay one declaration with one doc comment.

The census — NAMED reads per key, per registration, with lit controls

Counts are schema.KEY reads inside each ComponentRegistry.register(...) body of renderer.tsx (a script splits the file at the three register( calls and counts word-bounded schema.KEY), re-run on origin/main 8ad218d58, as chatbot / chatbot-enhanced / chatbot-floating:

keys named reads declared on
messages, placeholder, api, conversationId, systemPrompt, model, streamingEnabled, headers, requestBody, maxToolRoundtrips, onError, userAvatarUrl, userAvatarFallback, assistantAvatarUrl, assistantAvatarFallback, autoResponse, autoResponseText, autoResponseDelay, onSend 1 / 1 / 1 all three (ChatbotSharedKey)
showTimestamp 2 / 2 / 2 all three (ChatbotSharedKey)
maxHeight 1 / 1 / 0 ChatbotSchema, ChatbotEnhancedSchema
processVisibility 0 / 1 / 0 ChatbotEnhancedSchema (still on ChatbotSchema too — not retired here, #7703) — LIVE on chatbot-floating through the raw spread, undeclared there (#7708)
surface 0 / 1 / 0 ChatbotEnhancedSchema ('card' or 'plain', objectui#6687) — LIVE on chatbot-floating through the raw spread, undeclared there (#7708)
enableMarkdown, enableFileUpload, onClear 0 / 1 / 1 both new faces — ChatbotSchema never declared them
floatingConfig 0 / 0 / 1 ChatbotSchema (unchanged) and ChatbotFloatingSchema
displayMode 0 / 0 / 0 reads; inputs 0 / 0 / 1; defaultProps 0 / 0 / 1 ChatbotSchema (unchanged) and ChatbotFloatingSchema — ruled retired on #7654, executed there
loading, showAvatars, userAvatar, assistantAvatar, markdown, height 0 / 0 / 0 neither new face (#7703) — showAvatars is nonetheless LIVE on chatbot-floating through the raw spread (#7708; told on #7703)

disabled is not redeclared on either face — it stays BaseSchema's boolean | string (objectui#7087). Lit controls: the instrument reads non-zero exactly on the rows where the registrations differ (processVisibility, floatingConfig, surface), so the zeros are readings.

The second channel, measured through the real host

chatbot and chatbot-enhanced open their rendered element with {...toDomProps(props)} (whitelist-filtered, FIRST); chatbot-floating ends its FloatingChatbot element with raw {...props} (LAST), and FloatingChatbot forwards the rest onto ChatbotEnhanced. Rendered through SchemaRendererProvider + SchemaRenderer with a lit/dark pair per key and chatbot-enhanced as the control — identical readings on origin/main 8ad218d58 and on this branch (renderer.tsx is byte-identical between the first remediation commit and the head):

authored key → marker chatbot-floating lit / dark chatbot-enhanced lit / dark
showAvatars: true → per-message avatar element 1 / 0 0 / 0 (the whitelist drops it; no named forward)
surface: 'plain'.max-w-2xl wrappers 2 / 0 2 / 0 (named read — lit control)
processVisibility: 'debug' → raw tool name for a tool result shown / hidden shown / hidden (named read — lit control)

Mechanism pinned on the whitelist itself: toDomProps({ showAvatars, surface, processVisibility, className }) keeps className and drops the other three.

One prediction missed, recorded: my first processVisibility control on chatbot-enhanced used the data-trace-id link and read 0 where I predicted 1. Cause, read off the source: useObjectChat's normalizeMessages rebuilds every seed message with a fixed key set and drops traceId, so the link cannot render on the named-read path — while on floating the raw spread overrides messages with the authored seed, which keeps traceId, so it does render there. The raw-tool-name marker rides toolInvocations, which normalisation keeps, and lights on both; that is the marker the tripwire uses. The same messages override is why a sent message never renders on a floating node — measured (userShown: false, replyShown: false on floating; both true on chatbot-enhanced) and carded on #7708, deliberately not pinned here (pinning a bug as expected is the wrong shape).

displayMode — ruled retired on objectui#7654; carried untouched here, on both faces

Re-measured on the base: word-boundary displayMode over packages/plugin-chatbot/src, tests excluded — two hits, renderer.tsx (a designer inputs control and a defaultProps seed, both the chatbot-floating registration's), zero reads. #7654 ruled B on that measurement: the node type is the one selector of presentation. The retirement — tombstone on ChatbotSchema, control and seed removed — executes in #7654's own PR. Here the member stays on ChatbotSchema byte for byte and is declared on ChatbotFloatingSchema with the same three lines, unmirrored on both twins (UnmirroredDeclared records it under both pairs), and the census test pins as a TRIPWIRE that any value still parses green — #7654's PR flips that pin with the ruling in hand. Nothing was retired, tombstoned, mirrored or made live.

Zod twins and the ledgers — counts as measured on 4579bdff9

  • Two pairs registered in zod-mirror-parity.test.ts: 157 pairs (155 on main after finding(types): DrillDownConfig has no zod mirror — drillDown is declared on ChartSchema and ObjectDataTableSchema and validated on neither #7352; 154 at this PR's original base). KnownDrift: each born with exactly its three runtime-slot refusals (onClear | onError | onSend, the objectui#6124 shape) — 42 entries / 63 keys (40 / 57 on main). UnmirroredDeclared: ChatbotSchema keeps displayMode | floatingConfig | requestBody; ChatbotFloatingSchema is born with displayMode | floatingConfig14 / 96 (13 / 94 on main). RuntimeOnlyDeclared 7 / 24 unchanged. Derivatives: 115 pairs with no KnownDrift entry, 142 with no entry in either unmirrored ledger.
  • handler-keys-json-refusal-6124.test.ts: 66 sites, 44 runtime slots, 22 retired (this PR's six plus finding(types,components,docs): ui:alert-dialog's three surfaces name three DISJOINT key sets — every declared authoring key is inert, and every key the renderer reads is a type error #7104's onAction from the first merge); the type-level KeepsFunction pins carry all of them.
  • floatingConfig: no FloatingChatbotConfig mirror minted on either twin — objectui#6152's axis. The objectui#7669 tripwire (floating-chatbot-trigger-icon-retired.test.ts) now runs on BOTH twins (describe.each), and the tombstone's reach is pinned on both node types.
  • requestBody is mirrored under its own name on both twins; ChatbotSchema's body naming collision (in KnownDrift) was not copied across and is not ruled on here. The twenty shared arms are taken off ChatbotSchema's own .shape by .pick(...), so each has one spelling; the test asserts description equality per key.

Fence extension, declared: packages/types/src/zod/index.zod.ts (two export lines)

The fence lists complex.zod.ts, so Zod twins were in scope, but the Zod barrel is an explicit named-export list — a twin not exported from @object-ui/types/zod would be declared-but-unreachable. This PR's barrel edits are the same two lines the review read; the only other barrel change on the branch is main's own DrillDownConfigSchema export (#7701), carried by the merge. packages/types/src/registry.ts was deliberately NOT touched (#7704).

chatbot-floating and disabled — one consequence, no render outcome moves

Unchanged from the first cut: the raw disabled={schema.disabled} read was already overridden on every render by the host verdict the trailing spread carried; the registration now destructures disabled: hostDisabled and forwards it, as its two siblings do. Pinned through the real host both ways. The trailing spread itself is untouched (see #7708) — only annotated at the site.

Evidence — every run below is on 4579bdff9, after the final commit (tree clean, git status 0 lines)

  • pnpm --filter @object-ui/types build && pnpm --filter @object-ui/types type-check && pnpm --filter @object-ui/plugin-chatbot type-check, chained, under the verify lock: VERDICT command-exit 0, the sha echoed after the chain; each script name echoed (tsc && check-dist-completeness; tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json; tsc --noEmit && tsc -p tsconfig.test.json), 0 error TS lines in all three logs. The types type-check is the channel the parity ratchet and every new pin live in; the plugin type-check read the REBUILT types dist (which emits displayMode?: on both faces and ChatbotSharedKey 5 hits) with the dependency closure built in this worktree (test-support, react-runtime, types, core, i18n, sdui-parser, data-objectstack, components, react — all exit 0).
  • pnpm exec vitest run --maxWorkers=2 over the four affected packages/types test files plus all of packages/plugin-chatbot/Test Files 39 passed (39), Tests 747 passed (747), git rev-parse --short HEAD = 4579bdff9 echoed at its head. One red on the way, recorded: chat-message-contract.test.ts counts the literal runtime-messages prop in renderer.tsx and my first spread-site comment contained it — reworded; a comment tripping a source-scanning pin, no behaviour involved.
  • Gates re-run on the merged tree, each quoting its own verdict line, exit codes captured by redirect before any pipe: check:doc-fences ✅ (227 documents); check:doc-types ✅ "Every documented component type is registered"; check:control-bytes ✅ (6280 files); check:published-tsconfig-exclude OK (34 packages); check:shell-escape-residue ✅; check-doc-links "Links are valid across 17 scan roots"; check-changeset-no-major ✅.
  • check:doc-snippets NOT MEASURED locally — exit 2, PRECONDITION NOT MET (it wants the whole workspace built: app-shell, auth, cli, every plugin), which its own text says is "I could not run", not a verdict. Declared narrowing with evidence: a line-level diff of the mdx between the reviewed head and this branch changes 9 → 16 prose lines and 0 lines inside any code fence (26 fenced blocks before and after), against a lit control — the same instrument on the first cut vs the merge-base reads 29 changed fence lines; the mdx is untouched by both merges; and the only type change since the reviewed 455 / 455 run is additive on ChatbotSchema. CI runs it.
  • check:readme-exports not re-run: this PR's two barrel lines are byte-identical to the reviewed head 30a53bd32, where it ran green after the closures were built; the merges add only main's own export. CI runs it.
  • Lint on the merged tree: pnpm --filter @object-ui/types lint and pnpm --filter @object-ui/plugin-chatbot lint (each package's own eslint .) → exit 0, 0 errors (269 / 90 warnings, all pre-existing). Narrowing declared with the three evidences: the population is eslint's own config (eslint.config.js, 0 projectService / parserOptions hits, so no untouched file's verdict can move); a --format json run over the diff's ten lintable files judged 10 files, 0 errors, 13 warnings; other packages are untouched by the diff.
  • Reach probes (tsc over packages/types source, predictions written first, scratch files never committed; complex.ts is byte-identical between the first remediation commit and the head): at origin/main 8ad218d58ChatbotSchema['displayMode'] / ['floatingConfig'] typed (green); displayMode: 'bogus', a wrong-shaped floatingConfig and floatingConfig.triggerIcon on a chatbot node all TS2322 (3 errors). At the first cut (368045e28) — the two typed-read pins TS2344 (any), all three wrong values compile CLEAN (2 errors, the opposite set). After the restore — identical to the base (3 errors on the same three lines), plus the floating face refusing triggerIcon and 'bogus' (5 in total, 0 outside the probes).
  • Ablation 1 — the option-A state turns the new pins red (re-run on 4579bdff9). After committing, the restored block was deleted from ChatbotSchema (heading count 1 → 0, displayMode?: 'inline' count 2 → 1, blob 06d14941 ≠ HEAD fd59df10); predicted red on tsc -p tsconfig.test.json: five TS2344 (the whole-face pin; the two typed-key pins; the two one-type-on-both-faces pins), two TS2578 unused-directive (displayMode: 'bogus' on a chatbot node; triggerIcon reached through ChatbotSchema.floatingConfig), one TS2322 naming complex.zod.ts#ChatbotSchema (the ledger records three keys, the declaration then had one). Observed: exactly those 8, at lines 154 / 170 / 171 / 188 / 189 / 289 of the census test, 107 of the trigger-icon test, 1571 of the parity test. Restored with git checkout HEAD -- ABSOLUTE_PATH under an EXIT INT TERM trap; blob back to fd59df10 = HEAD, git diff HEAD empty. Rebuild statement: none needed and none done — tsconfig.test.json resolves ../complex from source (the reach probes read the same channel), and the dist on disk was built from the final source before the leg and untouched by it.
  • Ablation 2 — the spread tripwire bites (re-run on 4579bdff9). The floating spread was fenced to {...toDomProps(props)} (count 2 → 3, blob 5acbed9b ≠ HEAD 3dbd2634); predicted: the three render tripwires red, the mechanism test and the other six green. Observed: Tests 3 failed | 7 passed (10) — exactly showAvatars, surface, processVisibility. Restored the same way; blob back to 3dbd2634 = HEAD, git diff HEAD empty. No build involved: the test imports ../renderer from source.
  • Heavy runs went through os-verify-lock.sh (slots issue-7655-*), every wait 0 s; wall-clock figures are shared-box readings.
  • NOT measured locally, CI owns: check:doc-snippets and check:readme-exports (above), the full pnpm lint farm beyond the two packages, check:published-dist, check:sdui-registration-pins.

Out of scope, filed — nothing addressed here

Related cards that stay open

objectui#7654 — ruled B (retire displayMode), open for its own PR; this PR leaves the member on both faces for it. objectui#6152 (the unmirrored ledger) and objectui#7665 (SchemaRegistry's docblock) are untouched. objectui#7669's tripwire now watches both twins.

Session session_01KbJQ1y1J12nZxYzFWhP8Q3, domain:ui dev seat.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3

… ChatbotEnhancedSchema and ChatbotFloatingSchema (objectui#7655)

`plugin-chatbot` registers three components and `@object-ui/types` published
one face for the family with `type` pinned to `'chatbot'`. Add one interface
per registration, each declaring exactly the keys its registration reads
(read-site-censused per key with lit controls), with the twenty shared keys
picked off `ChatbotSchema` by name so they stay one declaration. Zod twins in
lockstep, registered in the parity ledger (two pairs born ledgered: three
runtime-slot refusals each in KnownDrift; `displayMode` | `floatingConfig`
carried unmirrored onto the floating pair, moved off `ChatbotSchema`'s entry).

`displayMode` crosses onto `ChatbotFloatingSchema` UNCHANGED; its fate stays
with objectui#7654. `chatbot-floating` now consumes the host-evaluated
`disabled` verdict like its siblings — the raw read it replaced was already
overridden by the trailing `{...props}` spread on every render.

Docs: the floating example is a typed `tsx` fence again, plus a typed
`chatbot-enhanced` example; per-face scope notes on the properties tables.

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

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3180.0 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CNbsGyNf.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) 15.67KB 5.75KB
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) 5.13KB 2.35KB
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) 510.70KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.27KB 61.22KB
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) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
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.98KB 10.98KB
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) 11.71KB 4.29KB
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) 5.12KB 1.74KB
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) 15.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.20KB 46.34KB
plugin-dashboard (index.js) 132.86KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.57KB 11.96KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
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.74KB 1.41KB
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 (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 (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

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Contract review — claude-fable-5-1, adopted verbatim

Isolated review subagent. Tier verified from its transcript: 118/118 assistant turns stamped claude-fable-5-1, 0 fallback notices, against a lit control that reads claude-opus-5 in this session's other transcripts. Adopted verbatim — not edited, trimmed or paraphrased.


No further measurements are needed — every item is instrumented, my two scratch worktrees are removed, the primary checkout is untouched, and no GitHub writes were made. The report follows.

Contract review — PR #7705 (card #7655), head 30a53bd32, merge-base 6eebc54b6

Instruments used, all my own, all on detached scratch worktrees (removed after): a per-registration census that splits renderer.tsx at the three ComponentRegistry.register( calls and counts schema.KEY / schema['KEY'] / destructure-from-schema / bare-word hits per key; tsc probes against source at both trees (--ignoreConfig, predictions written first); the author's three ablation/reverse legs re-run with blob hashes; a render probe through the real SchemaRenderer host with lit/dark pairs; the author's vitest union; pnpm --filter @object-ui/types type-check and build. CI at head, re-read: 32 check runs, 29 success / 3 skipped (Type Check, all four Test shards, Doc Snippet Type Check, Lint all green). Card/PR states re-read before writing: #7705 open draft needs:contract-review, mergeable_state: dirty at read time; #7655 open pm:dispatched; #7654 open, pm:queue, needs-user-decision STRIPPED — maintainer ruled B (retire displayMode, tombstone on ChatbotSchema.displayMode, remove the inputs control and defaultProps seed) at 2026-09-05T02:48:39Z, comment 5548848737, 4h43m before this PR opened; #7703 open pm:queue (PM tension comment 07:37Z); #7704 open pm:queue, its Blocked-by #7662 corrected on the card at 07:37Z; #7662 merged 07:14:56Z (bc640ec56); #7669 merged 02:15:48Z; #7683 merged 03:08Z; #7684 open draft; #7645 closed completed; #7664 open pm:queue (ruled (a), names registry.ts); #6152 open pm:blocked; #7665 open pm:queue; #7678 open pm:queue.

① Derived judgments

Premise and ruling. The #6169 quote at renderer.tsx:65-68 on the base reads exactly "every component node has exactly one named, importable authoring-face type" (line 65 opens (objectui#6169, the #6172 family ruling: …). Three registrations at base :62 / :271 / :421; ChatbotSchema.type pinned to 'chatbot' at complex.ts:695. Shape shipped (two interfaces, not a type union): matches the ruling. RIGHT.

Census, re-measured on base (chatbot / enhanced / floating, schema.KEY reads): all 19 shared keys 1/1/1, showTimestamp 2/2/2, maxHeight 1/1/0, processVisibility 0/1/0, surface 0/1/0, enableMarkdown/enableFileUpload/onClear 0/1/1, floatingConfig 0/0/1, displayMode 0/0/0 (word hits 0/0/2 = inputs + defaultProps), the six legacy keys 0/0/0, destructure-from-schema sites 0/0/0. Identical to the author's table, row for row, controls lit on the same rows. But the instrument has a second channel it cannot see: SchemaRenderer.tsx:1451-1480 strips 16 metadata keys and spreads every other authored key as props; chatbot-floating spreads {...props} raw and LAST onto <FloatingChatbot> (renderer.tsx:490), which forwards ...chatbotProps onto <ChatbotEnhanced> (FloatingChatbot.tsx:82-83). Rendered through the real host on a chatbot-floating node: showAvatars: true → avatar <img> 1 (dark 0); processVisibility: 'debug'a[data-trace-id] 1 (dark 0); surface: 'plain'.max-w-2xl 2 (dark 0). Control on chatbot-enhanced, whose spread is toDomProps(props): showAvatars 0, surface: 'plain' 2 (marker lit). Three keys the floating node honours are declared on neither the face nor its census.

  • ChatbotEnhancedSchema — RIGHT. type: 'chatbot-enhanced'; shared twenty (Pick by ChatbotSharedKey), maxHeight (1), processVisibility (1), enableMarkdown/enableFileUpload/onClear/surface (1 each). Nothing declared that the registration does not read; nothing read that is not declared (the registration's spread is toDomProps-filtered, so the second channel is dark there — measured, C1 = 0).
  • ChatbotFloatingSchema — WRONG as shipped, in the under-declared direction. Declared members are all read (shared twenty; enableMarkdown/enableFileUpload/onClear 1 each; floatingConfig 1; displayMode carried per fence). Omission of maxHeight RIGHT (reaches the panel via the spread but FloatingChatbot.tsx:84 sets maxHeight="100%" after it — dead). Omissions of processVisibility, surface, showAvatars WRONG: live through the spread (readings above), and the face's own JSDoc (complex.ts "NOT declared, on purpose … processVisibility and surface (not forwarded — the panel renders the component defaults)") is false and is emitted into dist/complex.d.ts. The docs row this PR re-asserts ("chatbot-floating does not forward the key either, so its panel always renders at the 'summary' default") is false by the same reading. assertionFloatingDeclaresWhatItReads pins the named-read instrument only; its name overclaims.
  • displayMode (moved) — declaration line byte-identical ( displayMode?: 'inline' | 'floating';); the three original JSDoc lines byte-identical as a prefix; a note appended. Runtime: no reader, twin never had an arm, .passthrough() — a chatbot node's parse outcome unchanged (RIGHT). TypeScript face of ChatbotSchema: ChatbotSchema['displayMode'] is a typed union at base and any at head (probe L1); { type: 'chatbot', displayMode: 'bogus' } errors at base and compiles at head (L3). That is a published-type change the changeset does not name. And the appended note ("parked on a maintainer decision") is STALE against finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's ruling B. WRONG as shipped — see ③ A-vs-B.
  • floatingConfig (moved) — declaration byte-identical; JSDoc rewritten (the old "Only used when displayMode is 'floating'" was false; the new text is true — RIGHT as a doc fix). ChatbotSchema['floatingConfig'] is any at head (L2); a wrong-shaped floatingConfig on a chatbot node compiles at head, erred at base (L4). Consequence unrecorded anywhere: the feat(types)!: retire FloatingChatbotConfig.triggerIcon as an ADR-0049 tombstone (objectui#7654) #7669 triggerIcon tombstone no longer reaches a chatbot node — { type: 'chatbot', floatingConfig: { triggerIcon: 'Sparkles' } } errors at base (T1-base) and compiles clean at head (T1-head); it still bites on ChatbotFloatingSchema (T2). feat(types)!: retire FloatingChatbotConfig.triggerIcon as an ADR-0049 tombstone (objectui#7654) #7669's pins are on FloatingChatbotConfig directly, so nothing went red. WRONG as shipped.
  • ChatbotSharedKey export — mechanism RIGHT (TS4022 forces it), but it is emitted into dist/complex.d.ts (5 hits) and reachable through the published @object-ui/types/complex subpath; "not re-exported from the entry" is true and insufficient. Changeset silent. Rider.
  • index.ts +2 / index.zod.ts +2 — RIGHT. Both barrels are explicit lists (0 export *); a twin absent from index.zod.ts is unreachable from @object-ui/types/zod. Entailed by the fence including complex.zod.ts; uncontended (fix(types): ChartDataSeriesSchema declares the six series keys the renderer reads (objectui#7546) #7684 touches data-display.*, fix(types): SchemaRegistry's kanban entry stops describing a component it cannot name #7662 registry.ts, both barrels untouched).
  • ComplexSchema +2 arms (TS and Zod) — RIGHT; routing live (Ablation B: the routing test goes red when the arm is damaged).
  • Zod twins: shared arms via .pick (one spelling, description equality pinned) RIGHT; requestBody under its own name, body collision not copied RIGHT (the renderer reads schema.requestBody, 1/1/1); surface z.enum(['card','plain']) RIGHT (live — Ablation B); three handlerKeyRefusal slots per twin RIGHT (each registration forwards onError/onSend into useObjectChat and calls schema.onClear?.(); consumption in the hook re-counted: onSend 9, onError 7, showTimestamp 5, autoResponse* 4 each, maxToolRoundtrips 10).
  • chatbot-floating disabled — RIGHT, no outcome moves. SchemaRenderer strips disabled from componentProps and re-adds disabled: __disabled || undefined (:1584); at base the trailing {...props} carried that verdict and overrode disabled={schema.disabled} on every render (by true or by undefined); at head the same value is destructured and forwarded. Pinned through the real host both ways; my union run passed all 742.
  • Ledger edits: two pairs registered — test-entailed (Ablations A/B show the ratchet lights on both new pairs). KnownDrift 42 entries / 62 keys — parsed independently, correct, test-entailed. UnmirroredDeclared 16 / 96 (ChatbotSchemarequestBody; floating born with displayMode | floatingConfig) — correct, test-entailed. RuntimeOnlyDeclared 7 / 24 unchanged. Handler-keys +6 rows, 65 sites / 43 slots / 22 retired — asserted at runtime, green, entailed. feat(types)!: retire FloatingChatbotConfig.triggerIcon as an ADR-0049 tombstone (objectui#7654) #7669 tripwire retargeted at the floating twin — entailed by the move (the ChatbotSchema twin never had the arm either); the type-level reach loss on chatbot nodes above is the part nobody recorded. Prose pair counts WRONG: three instruments (key regex, line count of the MIRRORS block, Declared interface entries) all read 156 pairs at head, 154 at base, not 162 / 160; the PR advanced inherited rot by +2 ("162 − 42 = 120" should be 114; "145 (162 − 17)" should be 139) while its body says every count statement "was updated to match". Rider, but it is a false record in a ledger whose subject is measurement, and the file's own header warns of exactly this.
  • Ablations and reverse verification — RIGHT, all three reproduced exactly with the author's own blob hashes: Ablation A ac01c082→9a77bdec, TS2344 at the census pin (test line 120) + TS2322 naming complex.zod.ts#ChatbotFloatingSchema; Ablation B 40dce36b→25e86575, vitest 3 failed | 14 passed (the same three tests) + TS2322 naming #ChatbotEnhancedSchema; the reverse probe through source, exactly two errors at the injected line. The new pins are not dark.
  • Docs: typed tsx fences RIGHT (Doc Snippet Type Check green); the re-asserted "does not forward" row WRONG (above).
  • Pre-existing, measured here, recorded nowhere (out of fence, not a ground against this PR, must be carded): on the chatbot-floating registration path the trailing {...props} also overrides messages={runtimeMessages} with the authored seed array — through the real host, after sending a message on a floating node neither the user message nor the auto-reply renders (userShown:false, replyShown:false), while the identical send on chatbot-enhanced renders both; and authored displayMode/systemPrompt/model land as DOM attributes inside the panel (1/1/1 on floating, 0/0/0 on enhanced). The PR's only edit in that hunk is the disabled line, so this is base-identical.

② Semver grading

@object-ui/types: minor — level CORRECT under AGENTS.md §版本号策略 (lines 236-241: objectui's own breaking changes ship as minor with the semantics spelled out; major is refused by check-changeset-no-major, CI green). Nothing narrows: no document that parsed at base is refused at head (ChatbotSchema's twin is untouched; the two new discriminants had no arm before and were refused at type); no value that compiled at base fails at head. What moved and is unstated: ChatbotSchema's two removed members go typed → any (silent any-read on the published type, wrong values now compile, the triggerIcon tombstone's reach on chatbot nodes lost), and ChatbotSharedKey is a new published symbol via the ./complex subpath. The body also carries the stale "#7654 … parked on a maintainer decision" sentence. @object-ui/plugin-chatbot: patch — CORRECT: ComponentRegistry is untyped so the parameter-type change reaches no consumer, and the one runtime edit moves no outcome. Grade: levels right, types body incomplete on two measured effects (the first is moot under option B below) and false on one tense.

③ Boundary-flag disposition

VERDICT: REFUSE

What must change (1-4 blocking; 5-7 riders to land in the same push):

  1. Stop asserting the opposite of what the tree does. Remove the "not forwarded — the panel renders the component defaults" / "no read for" claims for processVisibility, surface, showAvatars from the ChatbotFloatingSchema JSDoc, from the docs row this PR re-asserts, and from the PR body; state in the census pin's docblock that the instrument counts named schema.KEY reads and that the registration's trailing raw {...props} spread is a second channel measured live for those three keys. Card that channel (with the S1 messages override and the D1 DOM-attribute leak) for a declare-vs-fence ruling — fencing with toDomProps(props) like the two siblings is the honest fix but a behaviour change that makes plugin-chatbot minor and needs its own review; declaring the three would fossilise an accidental channel as contract (AGENTS.md #0.1). Either way this PR may not ship the false statement.
  2. Rewrite every finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654 tense to the ruled state (all eight lines listed in ③, the changeset, the PR body): ruled B at 02:48:39Z; execution is finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's own PR; this PR carries the key untouched pending it.
  3. Take option B: restore displayMode and floatingConfig on ChatbotSchema (declarations verbatim), revert its UnmirroredDeclared entry to three keys (16 / 98), invert assertionChatbotKeepsItsOwnFaceMinusTheTwoMoved and assertionMovedKeysLeftChatbot to "keeps its whole face", and drop the "MOVED" narrative. If the PM overrules to A, the changeset must name the any-read, the compiled wrong values, and the lost triggerIcon reach on chatbot nodes, and the deletion route must be reconciled with finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's ruling B — which prescribes a tombstone on that very member — so A cannot be shipped as written.
  4. Changeset completeness: name ChatbotSharedKey as a new symbol reachable via @object-ui/types/complex; under B delete the "two keys MOVED" paragraph.
  5. Parity-ledger prose: write the measured pair count (Object.keys(MIRRORS).length = 156 at head) and its derivatives (114 pairs with no KnownDrift entry; 139 with no entry in either unmirrored ledger), replacing the inherited 162 / 120 / 145.
  6. Note in the PR body that floatingConfig's JSDoc was rewritten (the old text gated it on displayMode, which was false) — it is a correct change, currently described only as "kept its shape".
  7. Merge main (no rebase) and re-run the union; mergeable_state is dirty.

Generated by Claude Code

…tbot-registration-authoring-types

# Conflicts:
#	packages/types/src/__tests__/handler-keys-json-refusal-6124.test.ts
#	packages/types/src/__tests__/zod-mirror-parity.test.ts
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3180.0 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CNbsGyNf.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) 15.67KB 5.75KB
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) 5.13KB 2.35KB
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) 510.70KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.27KB 61.22KB
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) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
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.98KB 10.98KB
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) 11.71KB 4.29KB
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) 5.12KB 1.74KB
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) 15.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.20KB 46.34KB
plugin-dashboard (index.js) 132.86KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.57KB 11.96KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
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.74KB 1.41KB
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 (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 (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

…Schema, state the floating spread channel truthfully, measure the parity counts (objectui#7655 review)

Remediation of the contract review on PR #7705 (REFUSE, seven items):

- ChatbotSchema keeps `displayMode` and `floatingConfig` (declarations
  verbatim from the base); ChatbotFloatingSchema declares the same two.
  Restores the typed read of both members on the published face and the
  objectui#7669 `triggerIcon` tombstone's reach on `chatbot` nodes, now
  pinned on the node in both faces' tests. The "moved" narrative is gone.
- ChatbotFloatingSchema's docblock, the census pin, the docs rows and the
  changeset no longer claim `processVisibility` / `surface` / `showAvatars`
  are dark on `chatbot-floating`: the registration's trailing raw
  `{...props}` spread carries them to the panel today (measured through the
  real host, lit/dark pairs, `chatbot-enhanced` as control). The census
  counts NAMED reads; the spread is a second channel, pinned as a tripwire
  in the plugin's real-host test and carded as objectui#7708.
- Every `displayMode` tense reads the ruled state: objectui#7654 ruling B
  (retire; tombstone, control and seed removed) executes in that card's
  own PR; this PR carries the key untouched on both faces.
- zod-mirror-parity prose rewritten from measurement: 156 pairs at head
  (154 at base; the inherited "160/162" was six too high), KnownDrift 42/63
  after the main merge, UnmirroredDeclared 16/98, 114 / 139 derivatives.
- Changeset names the new published symbol `ChatbotSharedKey`
  (`@object-ui/types/complex` subpath) and the `floatingConfig` JSDoc fix.

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

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3180.0 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CNbsGyNf.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) 15.67KB 5.75KB
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) 5.13KB 2.35KB
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) 510.70KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.27KB 61.22KB
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) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
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.98KB 10.98KB
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) 11.71KB 4.29KB
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) 5.12KB 1.74KB
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) 15.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.20KB 46.34KB
plugin-dashboard (index.js) 132.86KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.57KB 11.96KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
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.74KB 1.41KB
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 (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 (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

…tbot-registration-authoring-types

# Conflicts:
#	packages/types/src/__tests__/zod-mirror-parity.test.ts
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3184.8 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-DrtWYTZx.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) 15.67KB 5.75KB
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) 5.13KB 2.35KB
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) 510.70KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.27KB 61.22KB
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) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
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.98KB 10.98KB
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) 11.71KB 4.29KB
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) 5.12KB 1.74KB
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) 15.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.20KB 46.34KB
plugin-dashboard (index.js) 132.86KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.57KB 11.96KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
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.74KB 1.41KB
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 (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 (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

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Contract re-review (round 2) — claude-fable-5-1, adopted verbatim

Isolated review subagent. Tier verified from its transcript: 113/113 assistant turns stamped claude-fable-5-1, 0 fallback notices, against a lit control that reads claude-opus-5 in this session's other transcripts. Adopted verbatim — not edited, trimmed or paraphrased.


No further measurements are needed: the named-read census is identical between main and head except for the one removed raw schema.disabled read, all four scratch worktrees are removed, the primary checkout is untouched (77b3cf1f5, 0 status lines, stash stack 0 and never touched), no GitHub writes were made, and the PR and cards were re-read within the last minutes before writing any tense below.

Contract review — PR #7705 (card #7655), round 2, head 4579bdff9, base 52c8cf741

Instruments, all my own, all on detached scratch worktrees under /tmp/claude-0/-home-user/a10fe65b-83d8-5954-95c5-cffe775e6ac0/scratchpad/ (four trees: 8ad218d58 base, 368045e28 first cut, 4579bdff9 head, 52c8cf741 main; pnpm install from the local store; all removed after): tsc reach probes with a lit red control and a dark green control at every state; a byte diff of the whole ChatbotSchema interface base→head; a Python parser over MIRRORS / Declared / the three ledger interfaces at four revisions; git merge-tree --write-tree replays of both merges with blob comparison of every non-conflicting file; a render probe of my own through SchemaRendererProvider + SchemaRenderer (seed carrying traceId and a tool result, lit/dark pairs, chatbot-enhanced as control) at main and head; the author's two ablations re-run with blob hashes and git checkout HEAD -- restores; the vitest union; tsc -p tsconfig.test.json; a types build to read the emitted dist. States re-read before writing: #7705 open draft, mergeable_state: clean, head 4579bdff9, labels package: types / plugin / tests / needs:contract-review; CI at head 32 check runs, 29 success / 3 skipped, 0 failed (Type Check, all four Test shards, Doc Snippet Type Check, README Export Check, Lint, Changeset Bump Policy all success); #7655 open pm:dispatched needs:contract-review; #7654 open pm:queue, ruled B at 02:48:39Z (comment 5548848737), no closing PR; #7708 open bug / priority:p2 / pm:queue / plugin: chatbot, triaged 08:46:32Z; #7703 open pm:queue p3 with the showAvatars correction at 5550594380; #7704 open pm:queue p3, Blocked-by #7662 corrected on-card (merged 07:14:56Z); #7669 merged 02:15:48Z; #7352 closed via #7701 (52c8cf741); #6169 closed via #6688. main moved three times between this PR's original base and its head (bc640ec56 #7662, 8ad218d58 #7700, 8fe8e5c16 #7684, 52c8cf741 #7701); the head has 52c8cf741 as its second parent, so merge-base = base and merge-tree is trivially clean.

① Derived judgments

  • ChatbotEnhancedSchema (new published node type, TS + Zod twin) — RIGHT. Named-read census at head is identical to main row for row (my split-at-register( counter: processVisibility 0/1/0, surface 0/1/0, maxHeight 1/1/0, enableMarkdown/enableFileUpload/onClear 0/1/1, floatingConfig 0/0/1, the twenty shared 1/1/1 with showTimestamp 2/2/2); the only census delta main→head is the floating schema.disabled read 1→0, the one runtime edit. assertionEnhancedDeclaresWhatItReads compiles at head (tsc -p tsconfig.test.json 0 errors, 7 s); the twin's surface arm and ComplexSchema routing are live in the union (747/747).
  • ChatbotFloatingSchema (new published node type, TS + Zod twin) — RIGHT, and its docblock is now true. Declares the named reads plus displayMode and floatingConfig; the JSDoc emitted into dist/complex.d.ts now states that processVisibility / surface / showAvatars reach the panel through the raw trailing spread and that the face neither declares nor promises it. My own readings agree at both main and head: showAvatars avatar element floating 1/0, enhanced 0/0; surface: 'plain' .max-w-2xl floating 2/0, enhanced 2/0; processVisibility: 'debug' raw tool name floating 1/0, enhanced 1/0. The maxHeight omission is right on the tree: FloatingChatbot.tsx:83-84 spreads chatbotProps then writes maxHeight="100%".
  • displayMode restored on ChatbotSchema — RIGHT, byte-identical. Lines 879–886 of packages/types/src/complex.ts (heading, three JSDoc lines, declaration) diff empty against 6eebc54b6, and 52c8cf741 carries the same bytes. Reach probes: ChatbotSchema['displayMode'] is the typed union at base, main and head; any at the first cut (TS2344). { type: 'chatbot', displayMode: 'bogus' } is TS2322 at base/main/head and compiles clean at the first cut. The designer control (renderer.tsx:498) and the defaultProps seed (:520) are still present, so finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's ruling B (tombstone on this member, control and seed removed) is executable as written, not hollowed.
  • floatingConfig restored on ChatbotSchema — RIGHT. Declaration line byte-identical; the whole 199-line interface differs from base in exactly two JSDoc lines (the false "Only used when displayMode is 'floating'" replaced by a sentence the census supports: read by chatbot-floating alone, 0/0/1), disclosed in PR body item 6 and the changeset. Reach: ChatbotSchema['floatingConfig'] typed at base/main/head, any at the first cut; a wrong-shaped floatingConfig and floatingConfig.triggerIcon on a chatbot node are TS2322 at base/main/head and compile clean at the first cut. Full probe tally with my red control subtracted: base 3, first cut 2 (the opposite set), head 5 (base's three plus the floating face refusing triggerIcon and 'bogus') — exactly the author's three states. Ablation 1 (block deleted, blob fd59df1006d14941) turns red exactly the 8 sites the author named: census test 154/170/171/188/189/289, trigger-icon test 107, parity test 1571; restored, blob back to fd59df10, diff empty. The feat(types)!: retire FloatingChatbotConfig.triggerIcon as an ADR-0049 tombstone (objectui#7654) #7669 tombstone's reach on chatbot nodes is restored and now pinned on the node.
  • packages/types/src/index.ts +2 and packages/types/src/zod/index.zod.ts +2 — RIGHT. Both symbols appear in the built dist/index.d.ts and dist/zod/index.zod.d.ts; README Export Check green; the merges added only main's own DrillDownConfigSchema line.
  • ChatbotSharedKey (new published type alias) — RIGHT and correctly named in the changeset. 5 hits in dist/complex.d.ts, 0 in dist/index.d.ts, reachable via the ./complex entry of packages/types/package.json exports; the changeset states the symbol, the TS4022 reason, the subpath, and that it is not re-exported from the entry.
  • ComplexSchema +2 arms (TS union and Zod discriminated union) — RIGHT; routing pinned and green.
  • Zod twins' accept sets — RIGHT. ChatbotSchema's own export const is untouched in the diff; the two new twins are born with three handlerKeyRefusal slots each; handler-keys-json-refusal-6124.test.ts asserts 66 sites / 44 runtime slots / 22 retired at runtime (main's finding(types,components,docs): ui:alert-dialog's three surfaces name three DISJOINT key sets — every declared authoring key is inert, and every key the renderer reads is a type error #7104 onAction retained plus this PR's six) — green in the union.
  • Parity-ledger prose — RIGHT, re-derived. My parser at head: 157 pairs (MIRRORS = Declared, no orphan), KnownDrift 42 / 63, UnmirroredDeclared 14 / 96 (2 / 12 spec-derived = ObjectViewSchema 10 + DashboardWidgetSchema 2; 12 / 84 local), RuntimeOnlyDeclared 7 / 24, union 15 (TreeViewSchema the runtime-only extra), 115 pairs with no KnownDrift entry, 142 with no entry in either unmirrored ledger. main: 155 / 40 / 57 / 13 / 94 / 14 / 115 / 141 — matches finding(types): DrillDownConfig has no zod mirror — drillDown is declared on ChartSchema and ObjectDataTableSchema and validated on neither #7352's re-derivation. First cut: 156 / 42 / 63 / 16 / 96 / 17 / 114 / 139 — the figures round 1 refused. No first-cut figure (156, 139, 114, "16 entries", "98 keys", 162, "160 pairs") survives in the head file.
  • chatbot-floating disabled — RIGHT, unchanged from round 1; SchemaRenderer.tsx:1584 spreads disabled: __disabled || undefined last, so the removed raw read was already dead; real-host pins both ways green.
  • Docs (content/docs/plugins/plugin-chatbot.mdx) — RIGHT. The false "does not forward the key either, so its panel always renders at the 'summary' default" row is gone; the surface / processVisibility rows and the section intro now state the unfiltered spread and point at finding(plugin-chatbot): chatbot-floating spreads the whole authored node raw and LAST onto its panel — three undeclared keys are live, the authored messages seed overrides the runtime messages (a sent message never renders), and node keys land as DOM attributes #7708; typed tsx fences compile (Doc Snippet Type Check green). content/docs/releases/ untouched.
  • Every #7654 tense — RIGHT. Zero hits for "parked", "maintainer decision", "needs-user-decision" across the PR's 12 files; every carrier (changeset :58, complex.ts :1082, complex.zod.ts :496, parity test :1107, census test :46 and :385/:390, docs row :210, PR body) reads ruled B at 2026-09-05 with execution in finding(types/plugin-chatbot): chatbot-floating declares two keys nothing reads - displayMode (designer control included) and FloatingChatbotConfig.triggerIcon #7654's own PR. The one "still OPEN" left in the parity file (:1342) is DataTableSchema.onColumnReorder, pre-existing and unrelated.
  • The two merges — RIGHT, both. Merge 1 (368045e28): files differing from its main parent are exactly the PR's 12; files differing from its PR parent are exactly what main moved 6eebc54b6..8ad218d58; merge-tree replay conflicts in handler-keys-json-refusal-6124.test.ts (2 hunks) and the parity test (1). Merge 2 (4579bdff9): same two file-set identities against 52c8cf741 and 8ad218d58..52c8cf741; merge-tree replay conflicts only in the parity test, 12 hunks; every one of the other 11 files in the actual merge is blob-identical to the auto-merge result. In the parity file, the lines the merge rewrote relative to main's own change are only the count-bearing sentences (155→157, 40/57→42/63, 13/94→14/96, 14→15, 141→142, 11/82→12/84) with the two pairs inserted; no first-cut prose was taken wholesale.
  • The three live-key tripwires — RIGHT as measurement. Reproduced with my own pairs at main and head (above); ablation 2 (spread fenced to {...toDomProps(props)}, blob 3dbd26345acbed9b) yields 3 failed | 7 passed, exactly showAvatars, surface, processVisibility; restored, blob back, diff empty. (My first run of that ablation was a zero-match anchor and is not a reading; the redo above is.)
  • The disclosed missed prediction — CONFIRMED on source and by probe. useObjectChat.ts:388-398 normalizeMessages rebuilds each seed message with {id, role, content, timestamp, metadata, streaming, toolInvocations} and drops traceId; the hook seeds localMessages from it (:651-653) off initialMessages: schema.messages (renderer.tsx:79/294/432). My probe: a[data-trace-id] floating 1/0 (the raw spread's authored messages override keeps the seed's traceId), enhanced 0/0; the raw-tool-name marker rides toolInvocations and reads 1/0 on both — the marker the tripwire uses.

② Semver grading

@object-ui/types: minor — CORRECT under AGENTS.md §版本号策略 (:236-241: objectui's own contract changes ship as minor with the semantics spelled out; major refused by check-changeset-no-major, Changeset Bump Policy green). @object-ui/plugin-chatbot: patch — CORRECT: ComponentRegistry is untyped so the parameter-type change reaches no consumer; the one runtime edit moves no outcome (real-host pins both ways; my probes identical at main and head). Nothing narrows. ChatbotSchema's TypeScript face is byte-identical in every declaration (probe A reads the same four results at base, main and head); its Zod twin is untouched; the two new discriminants had no arm before (refused at type by every twin), so a document that parsed at base still parses at head; the surface: 'frameless' / enableMarkdown: 'yes' / requestBody: 'x' refusals apply only to documents that had no green state before. What widens — two node types, two twins, two ComplexSchema arms, one alias via ./complex — is stated in the changeset. The changeset's "ChatbotSchema is unchanged" is true of declarations and accept set and is immediately qualified by the JSDoc correction; the PR body's bold headline says the same without the qualifier until item 6 — wording, not grade.

③ Boundary-flag disposition

VERDICT: PASS


Generated by Claude Code

@os-sam
os-sam marked this pull request as ready for review September 5, 2026 09:01
@os-sam
os-sam added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 4ce14f1 Sep 5, 2026
34 checks passed
@os-sam
os-sam deleted the claude/issue-7655-chatbot-registration-authoring-types branch September 5, 2026 09:15
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.

finding(types): ChatbotSchema pins type to 'chatbot', so chatbot-enhanced and chatbot-floating nodes have no authoring-face type

2 participants