Skip to content

fix(types): align TimelineSchema with the keys the timeline renderer reads - #6352

Merged
os-support-ai merged 1 commit into
mainfrom
claude/issue-6170-timeline-schema-drift
Aug 25, 2026
Merged

fix(types): align TimelineSchema with the keys the timeline renderer reads#6352
os-support-ai merged 1 commit into
mainfrom
claude/issue-6170-timeline-schema-drift

Conversation

@os-support-ai

Copy link
Copy Markdown
Collaborator

Part of #6170.

Gates measured at e3c074869, which is this branch's head and the tree every number below was read from.


⚠️ Read first — a dispatch/ruling conflict, flagged not resolved

My dispatch carried a STOP-AND-REPORT clause: if the fix would widen or narrow the accept set of a published type, stop and report the fork instead of picking a side — naming the deletion of events/orientation/position and the absorption of object-bound keys as the two examples.

The card already carries a maintainer ruling (2026-08-25, verbatim 「同意」) that decides exactly that fork: "TimelineSchema aligns to what authors write and TimelineRenderer reads", scale canonical, events/orientation/position to the ADR-0049 route, docs re-verified, Clause-②: yes — published type surface changes, contract-review tier at dispatch. The dispatch's assumption table and hypothesis never reference that ruling, which suggests it was composed from the pre-ruling needs-user-decision framing.

I did not pick a side on the part the ruling did not settle. This PR lands only the non-breaking subset:

  • every change is either an added declaration or a strict widening;
  • nothing is removed, and nothing that compiles or renders today stops;
  • the breaking half — the ADR-0049 tombstoning of events/orientation/position — is NOT here. It is written up below as a fork for the maintainer.

That is why this is Part of #6170 and not a closing reference: merging it leaves the ADR-0049 removal and the timeScale alias retirement live on the card.


The census — mine, exact, both directions

Measured on origin/main @ 79ebf30d1, over packages/plugin-timeline/src excluding test files.

Declared by TimelineSchema beyond type (packages/types/src/data-display.ts:1204): events (required), orientation, position3.

Read, split by the component that reads it:

component keys read off the schema node n
TimelineRenderer (renderer.tsx:250) — presentational destructured variant, items, dateFormat, onItemClick; dotted minDate, maxDate, rowLabel, scale, timeScale 9
ObjectTimeline (ObjectTimeline.tsx) — object-bound objectName, timeline, filter, sort, limit, mapping, titleField, dateField, startDateField, endDateField, descriptionField, groupByField, colorField, scale, bind, items, className 17
index.tsx (registration + dataSource mapping) objectName, limit 2

Distinct dotted schema.* reads across the package: 21. Adding the three destructured-only keys (variant, dateFormat, onItemClick) gives 24 distinct read keys.

The difference, both ways:

  • Declared and never read — 3: events, orientation, position. Zero read points anywhere in the repository, not just in plugin-timeline. (TimelineEvent, the element type events names, is dead with it — its date key is not even the time key the renderer reads.)
  • Read and never declared — 23 of the 24. Only className was declared, and by BaseSchema. Against TimelineRenderer alone, 9 undeclared reads.

⚠️ The card's "seven" does not survive. The card counted variant, items, dateFormat, timeScale, minDate, maxDate, rowLabel. Today the renderer also reads scale (added by objectui#2942, and preferred over timeScale) and onItemClick. The measured figure is 9, not 7. The card's "declares three it never reads" is exact and survives.


M1–M5 verdicts

# assumption verdict
M1 TimelineSchema (data-display.ts:1204) declares, beyond type, exactly events/orientation/position TRUE — line number exact; events required
M2 ~21 distinct schema.* reads, none of them those three TRUE — exactly 21 dotted reads; none is any of the three
M3 renderer.tsx:250 types schema as TimelineSchema TRUE — verbatim, line 250
M4 ObjectTimeline.tsx:52 widens it by hand TRUE — line 52, 14 added keys
M5 ListViewTimelineConfig = spec TimelineConfig & { dateField?; [key: string]: any } TRUEobjectql.ts:116; untouched here (objectui#5155 / objectui#6269)

All five hold.


The hypothesis: diagnosis confirmed, proposed remedy refuted

"There may be two different timelines… the renderer may be typed against the wrong one, and the honest fix is re-pointing the type at the shape the code already consumes — mechanical, no published accept set moves."

Two timelines: CONFIRMED.

  • presentational — how to draw a rail from items in hand. Read by TimelineRenderer.
  • object-bound — which record fields to project. @objectstack/spec's TimelineConfig via ListViewTimelineConfig, read by ObjectTimeline.

The composition seam is real and correct: ObjectTimeline resolves field names against fetched records, builds effectiveSchema, and calls <TimelineRenderer schema={effectiveSchema} /> (ObjectTimeline.tsx:443).

"The renderer is typed against the wrong one": REFUTED. renderer.tsx reads only presentational keys and not one object-bound key. TimelineSchema is meant to be the presentational type — it is the right one of the two. Its problem is that its member list is a third, unimplemented vocabulary (events/orientation/position — an MUI/Ant-style Timeline API that was never built) which is neither presentational-as-implemented nor object-bound.

Consequence: the "mechanical re-point" is not available. Re-pointing requires an existing type that declares variant/items/dateFormat/rowLabel/minDate/maxDate. No such type exists — I searched every TimelineSchema reference repo-wide and every spec ui export. So the fix necessarily changes TimelineSchema's member list, which is why the STOP clause was reached and why the maintainer ruling is load-bearing.

Supporting evidence gathered:

  • Does anything author the presentational events shape? One artifact: packages/types/examples/data-display-examples.json authors { type: 'timeline', events, orientation, position }. It is imported by nothing, type-checked by nothing (tsconfig.examples.json includes only examples/**/*.ts), and would render an empty rail. Left untouched on purpose — see findings.
  • Which registration mounts what?'timeline' is registered twice: renderer.tsx:498TimelineRenderer (namespace plugin-timeline), and index.tsx:366ObjectTimelineRenderer (namespace view). index.tsx:300 (export * from './renderer') evaluates first, so the later call wins the bare-name fallback and type: 'timeline' resolves to ObjectTimelineRenderer, which delegates inward to TimelineRenderer. Filed as a finding — the collision guard in Registry.register warns on exactly this.
  • Do the docs describe one timeline or two? One. content/docs/plugins/plugin-timeline.mdx documents only the presentational vocabulary, and agrees with the renderer and the registry inputs on all 8 rows.

Producer-boundary check (binding per the ruling): spec does NOT need to move

@objectstack/spec@17.2.0 ui/TimelineConfig.json declares startDateField, endDateField, titleField, groupByField, colorField, scale, with additionalProperties: false and required: [startDateField, titleField, scale].

Every key is a field name — object-bound. The presentational vocabulary is entirely absent from it and, under additionalProperties: false, could never live there. The two shapes are disjoint by construction.

The only overlap is scale, and it already agrees: the spec's six values are byte-identical to the renderer's TIMELINE_SCALES, pinned by plugin-timeline/src/__tests__/timeline-scale-spec-parity.test.ts. Declaring scale on TimelineSchema with those same six adopts the spec's spelling rather than competing with it.

No spec change needed; no fork to the domain:spec lane. packages/spec was not touched.


T1 — the mistyped-before / correct-after demonstration

A types-only change proves nothing by compiling, so both directions were measured with the same probe file against the same tsc invocation.

Probe A — the docs page's own TypeScript example (plugin-timeline.mdx, "TypeScript Support", verbatim):

BEFORE: error TS2741: Property 'events' is missing in type
        '{ type: "timeline"; variant: string; items: {...}[]; }'
        but required in type 'TimelineSchema'.
AFTER:  compiles.

The published page taught an authoring form its own published type refused.

Probe B — values the renderer never implemented (variant: 'diagonal', dateFormat: 'medieval', scale: 'fortnight'):

BEFORE: no error at all — all three absorbed by BaseSchema's index signature.
AFTER:  error TS2322: Type '"diagonal"' is not assignable to type '"horizontal" | "vertical" | "gantt" | undefined'.
        error TS2322: Type '"medieval"' is not assignable to type '"short" | "long" | "iso" | undefined'.
        error TS2322: Type '"fortnight"' is not assignable to type 'TimelineScale | undefined'.

Both probes are now permanent in packages/types/src/__tests__/timeline-declared-keys.test.ts, which tsconfig.test.json compiles — verified by tsc --listFiles | grep -c timeline-declared-keys.test.ts1, so the @ts-expect-error pins are real enforcement and not decoration.

Ablation — the pin has teeth. Predicted direction: removing one declaration reddens tsc with TS2578 naming that key (the member falls back to any and the wrong-typed assignment starts succeeding). Renaming variant?:variantABLATED?: in data-display.ts, confirmed on disk in both directions (deleted-text count 1 → 0, injected-text count 1, blob hash ≠ HEAD blob):

ABLATION_TSC_EXIT=2
src/__tests__/timeline-declared-keys.test.ts(230,5): error TS2578: Unused '@ts-expect-error' directive.
src/__tests__/zod-mirror-parity.test.ts(1203,14): error TS2322: Type '"data-display.zod.ts#TimelineSchema"' is not assignable to type 'never'.

Predicted instrument fired; a second independent instrument (the mirror-parity ratchet) fired too. No build leg was needed — tsconfig.test.json resolves ../data-display.js to source, not dist/. Restore leg proven, not assumed: git checkout HEAD -- <abs path>, then blob hash byte-identical to the HEAD blob (44a3416d…), residual marker count 0, git diff HEAD empty.


What changed

packages/types/src/data-display.tsTimelineSchema declares the eight authorable keys TimelineRenderer reads: variant, items, dateFormat, scale, timeScale, rowLabel, minDate, maxDate. New exported TimelineScale (the six spec buckets). events goes required → optional. events/orientation/position keep their declarations, gain @deprecated + a zero-read-points warning + the ADR-0049 route note.

onItemClick — the ninth read key — is deliberately left undeclared: it is a runtime slot ObjectTimeline installs, and this package keeps callback-shaped keys off the authored surface (RuntimeOnlyDeclared, zod-mirror-parity.test.ts). Declaring it would have required a new entry in that shared ledger for no authoring gain.

items is declared any[] rather than a narrowed union: the renderer accepts two element shapes discriminated by variant and reads both dynamically. Pinning a precise element union is a separate question (filed below), and narrowing it here would have been the one genuinely risky move in the diff.

packages/types/src/zod/data-display.zod.ts — the mirror follows key-for-key. Non-negotiable: zod-mirror-parity.test.ts registers this pair with no KnownDrift/UnmirroredDeclared entry, so a declared-but-unmirrored key reddens the ratchet. TimelineScaleSchema is module-local, not exported — every exported const in that directory must be registered in MIRRORS or EXCLUSIONS, and a shared inline enum is not a mirror of any declaration.

packages/plugin-timeline/src/renderer.tsx — the designer now offers scale with all six buckets, sourced from the existing TIMELINE_SCALES const. timeScale stays for round-tripping stored JSON, marked advanced with a DEPRECATED description (ComponentInput has no deprecated slot and no index signature, so description is this package's stated ceiling). Before this the designer offered only timeScale with three of the six — hour/quarter/year have rendered correctly since objectui#2942 but were offered by neither the designer nor the type, so they were authorable and undiscoverable from both surfaces.

Declared bounded in-place fix: the registry inputs edit is not named in the ruling's four bullets. It is included because bullet 2 (scale canonical, "not a silent second spelling") is about the vocabulary, and the designer is one of the three vocabularies this card is about — leaving it offering timeScale: day|week|month against a type declaring scale: hour…year would re-create the exact divergence being closed. It is additive, mechanical, and in the same gate family.

content/docs/plugins/plugin-timeline.mdx — property table gains scale, marks timeScale deprecated; the Schema API block and the "Time Scales" feature line corrected from three buckets to six; a callout that events/orientation/position are read by nothing and render an empty rail.

packages/types/src/__tests__/timeline-declared-keys.test.ts — new, modelled on gantt-declared-keys.test.ts (objectui#5903), the house form for this defect class. 16 assertions across runtime + compile-time halves, including the objectui#5155 ceiling stated explicitly ("declaring these did NOT buy rejection of a misspelling") and counter-probes so a never-narrowed declaration cannot satisfy the @ts-expect-error block.


⛔ The fork I did NOT take — for the maintainer

The ruling routes events/orientation/position to ADR-0049 enforce-or-remove. Both directions, with costs:

Direction A — remove (tombstone). The house form is already in this same file: StaticTableColumn (objectui#5474, maintainer ruling 2026-08-22, Option C) uses ?: never members with @deprecated, twinned by z.never().optional() in the mirror, giving a tsc error and a loud parse rejection.

  • Cost: breaking narrowing of a published type. Every value carrying events: [...] — legal and type-checking today — becomes a tsc error and a Zod rejection. events is currently required, so this is the maximal-breakage direction.
  • Breaks: nothing in-repo reads these keys (measured: zero read points). In-repo authors: one artifact, packages/types/examples/data-display-examples.json. Out-of-repo consumers are unmeasurable from here — the same unmeasurable half objectui#5674's ruling answered with a deprecation window (deprecate one release, then delete). This PR ships that window's first half.
  • Also needs: replacing the example fixture (it pins the removed branch), and a check against check-lucide-icon-record-names.mjs, whose census counts 3 timeline icon names in that file.

Direction B — enforce (implement). Build an events-driven presentational timeline alongside the items-driven one.

  • Cost: two presentational timelines to maintain, for a vocabulary with zero measured pull — no author, no fixture, no example app uses it. objectui#5474 declined the analogous Option A for exactly this reason.
  • Startup scope discipline says no; a published-but-unconsumed capability gets no exemption from sunk cost.

My recommendation: A, on the deprecation-window shape — this PR is stage 1 (declared, deprecated, documented, still accepted), a follow-up card is stage 2 (tombstone). It keeps the ruling's direction, gives external consumers a warned break rather than a silent one, and matches the two precedents this repo has already set. But the timing of stage 2 is a maintainer call, not mine, and no code here presumes it.

The timeScale alias retirement is routed the same way and is likewise not done here.


Gates — each gate's own verdict line, at e3c074869

gate exit its own verdict line
turbo run build --filter='!@object-ui/site' 0 Tasks: 43 successful, 43 total
vitest run packages/types/ packages/plugin-timeline/ 0 Test Files 69 passed (69) / Tests 729 passed (729)
@object-ui/types type-check 0 script echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json
@object-ui/plugin-timeline type-check 0 script echoed tsc --noEmit && tsc -p tsconfig.test.json
downstream sweep --filter '...@object-ui/types' 0 42 consumer packages type-check: Done
check-changeset-presence 0 ✅ 4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)
check-changeset-no-major 0 ✅ No changeset declares a 'major' bump.
check-lint-coverage 0 ✅ lint coverage: 46/46 packages linted, 0 with outstanding errors (0 total).
eslint packages/types packages/plugin-timeline 0 138 files, errorCount: 0 (311 pre-existing warnings; lint.yml sets no --max-warnings)
check:doc-types 0 ✅ Every documented component type is registered.
check:doc-snippets 0 Semantic phase: 267 of 267 block(s) judged, 0 failed.
check:doc-fences 0 ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript
check:control-bytes 0 ✅ OK (scanned 5226 tracked text file(s); skipped 85 binary).
check:readme-exports 0 ✅ OK (… 378 self-imports judged (378 real, 0 wrong-path, 0 fabricated); 3246 export symbol(s) read from 37 of 40 package(s) (0 unbuilt…)
check:icon-record-names 0 OK lucide icon names: 167 authored/declared names … are live 'icons' keys
check:designer-field-key-parity 0 designer-field-key-parity: OK
check:spec-symbols 0 ✅ 1306 files scanned against 4959 spec export names
check:self-import 0 ✅ No package names itself inside its own src/.
check:phantom-deps 0 ✅ Every in-scope import is declared by the package that publishes it.
check:vi-mock-specifiers 0 ✅ OK (3749 tracked source file(s)…)
check:shell-escape-residue 0 ✅ OK (4/4 root(s) resolved…)
pnpm check (the CLI check lint.yml runs) 0 ✓ All checks passed
the three published catalog fixtures, objectui validate 0,0,0 vertical / horizontal / gantt all still validate under the narrowed type

Two runs were NOT MEASURED rather than red, and are recorded as such: check:readme-exports and check:doc-snippets first returned a precondition failure (the population COLLAPSED — this run proves nothing; PRECONDITION NOT MET (exit 2) — the snippet program was NOT run) because packages were unbuilt. Both are green above, re-run after the build. check-half-states.mjs exits 3 (no reading at all) — it is a scheduled GitHub-board patrol, not a PR gate.

Lint scope, declared. Repo-scale turbo run lint was narrowed to the two affected packages. The narrowing is a measurement, not a skip, on three pieces of evidence: ① the population came from eslint's own config resolution, not my guess; ② the count is from --format json — 138 files, 0 errors; ③ type-aware linting is not enabledeslint.config.js's languageOptions carries only ecmaVersion and globals, with no parserOptions.project/projectService — so no rule's verdict on an untouched file can depend on this diff. check-lint-coverage.mjs independently reports 46/46 packages clean.


Out-of-scope findings (to be filed unassigned, not fixed here)

  1. 'timeline' is registered twice, and the bare-name fallback silently goes to the later registration (index.tsx:366, ObjectTimelineRenderer) over renderer.tsx:498 (TimelineRenderer). Registry.register's own collision guard exists to warn about this. Working-as-intended is plausible; undocumented and order-dependent is not.
  2. packages/types/examples/data-display-examples.json teaches the dead vocabulary — its timeline node authors events/orientation/position and would render an empty rail. It is imported by nothing and type-checked by nothing. Best replaced in the same change as the ADR-0049 removal, since it must move then anyway and check-lucide-icon-record-names.mjs counts 3 icon names in it.
  3. TimelineEvent is dead with events — nothing reads it, and its date key is not even the time key the renderer reads. Belongs to the same ADR-0049 sweep.
  4. items has no declared element type. Two shapes discriminated by variant; declaring them precisely is real authoring value but a genuine narrowing, so it wants its own card and its own measurement.
  5. schema.bind is read undeclared (ObjectTimeline.tsx:142, useDataScope(schema.bind)) — not on BaseSchema, not on any timeline shape; it rides the index signature. Likely a repo-wide pattern rather than a timeline defect.

Generated by Claude Code

…reads

TimelineSchema declared events (required), orientation and position and nothing else, while TimelineRenderer -- annotated schema: TimelineSchema -- reads variant, items, dateFormat, onItemClick, minDate, maxDate, rowLabel, scale and timeScale off that node and none of the three declared keys. BaseSchema's index signature typed every undeclared key as any, so the annotation constrained nothing and tsc could not see the divergence.

Declares the eight authorable keys on the interface and its zod mirror together; scale becomes the canonical axis key (the spec spelling the renderer already reads first) and the designer now offers all six buckets instead of three; timeScale stays as a deprecated alias. events goes required -> optional, which is what the docs page's own TypeScript example needed in order to compile.

events, orientation and position stay declared and stay read by nothing: removing them is a breaking narrowing routed through ADR-0049, not done here.

Part of #6170
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 52 chunks) 3223.6 KB 3266.6 KB
Main entry chunk (gzip) 154.2 KB 350 KB
Entry file index-BzSNuUeF.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) 10.96KB 4.16KB
app-shell (runtime-config.js) 18.10KB 6.51KB
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) 506.08KB 114.67KB
core (index.js) 5.30KB 2.13KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 171.74KB 47.48KB
fields (index.js) 238.89KB 60.02KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
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.44KB 1.39KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 33.40KB 8.71KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.95KB 10.97KB
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.55KB 0.62KB
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 (useResponsiveConfig.js) 1.37KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.53KB 3.38KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.64KB 1.50KB
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) 1.93KB 0.88KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.66KB 18.32KB
plugin-chatbot (index.js) 188.21KB 44.67KB
plugin-dashboard (index.js) 133.35KB 34.45KB
plugin-designer (index.js) 211.95KB 42.75KB
plugin-detail (index.js) 245.10KB 62.31KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 126.93KB 30.90KB
plugin-gantt (index.js) 164.14KB 39.87KB
plugin-grid (index.js) 201.21KB 54.43KB
plugin-kanban (index.js) 52.83KB 14.55KB
plugin-list (index.js) 111.94KB 27.24KB
plugin-map (index.js) 20.09KB 6.62KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.49KB 11.93KB
plugin-timeline (index.js) 26.70KB 7.69KB
plugin-tree (index.js) 9.26KB 3.13KB
plugin-view (index.js) 84.55KB 20.74KB
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) 54.84KB 18.43KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.35KB 0.70KB
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) 12.13KB 3.65KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 7.54KB 2.63KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
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) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 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.49KB 2.14KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
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 (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) 3.40KB 1.71KB
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-support-ai
os-support-ai marked this pull request as ready for review August 25, 2026 15:16
@os-support-ai
os-support-ai added this pull request to the merge queue Aug 25, 2026
Merged via the queue into main with commit e4559d1 Aug 25, 2026
28 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-6170-timeline-schema-drift branch August 25, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants