Skip to content

fix(core,app-shell): close ActionDef — delete the index signature, converge visible/disabled on the spec (#4046) - #4285

Merged
yinlianghui merged 2 commits into
mainfrom
claude/issue-4046-actiondef-index-signature
Aug 11, 2026
Merged

fix(core,app-shell): close ActionDef — delete the index signature, converge visible/disabled on the spec (#4046)#4285
yinlianghui merged 2 commits into
mainfrom
claude/issue-4046-actiondef-index-signature

Conversation

@yinlianghui

@yinlianghuiyinlianghui commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Fixes#4046

Step 3 of the staged narrowing, executing the maintainer's 2026-08-06 ruling now that its upstream half shipped. Steps 1 (#3032) and 2 (#3190) are landed history; the card's status header, not its body's staged plan, is the current state.

The ruling, quoted as delivered:

维护者裁决(2026-08-06,经 PM 会话 session_01MN3ao9kJEtD7PNAKwFVp96 转达):统一形状,spec 采纳 —— visible / disabled 两键在 spec 侧统一收敛为 boolean | string(CEL) | {dialect, source}(boolean = 条件的退化形字面量,string = CEL 简写,信封 = 完整形)。

Premise check

All three legs verified on the post-#4080 tip (4cb0562b5) before implementing. The card's line anchor had moved — it cited ActionRunner.ts:185, the index signature is at :332 — but the substance held.

legverdict
ActionDef still ends with [key: string]: anytrue, ActionRunner.ts:332
the installed spec parses all three arms on both keystrue, 17.0.0-rc.6
DeclaredActionsBar still carries (action as any).disabledtrue, :162 and :280, untouched by #4080

The spec probe was run as six real ActionSchema.safeParse calls rather than read off the typings, because the boolean arm is exactly what changed:

visible true PARSE-OK -> true
visible "record.status == \"open\"" PARSE-OK -> {"dialect":"cel","source":"record.status == \"open\""}
visible {dialect:'cel',source:…} PARSE-OK -> {"dialect":"cel","source":…}
disabled true PARSE-OK -> true
disabled "record.locked" PARSE-OK -> {"dialect":"cel","source":"record.locked"}
disabled {dialect:'cel',source:…} PARSE-OK -> {"dialect":"cel","source":…}

One thing worth recording, because it nearly produced a wrong premise: the same probe against rc.5 rejects visible: true. main moved to rc.6 recently enough that a stale checkout still reports rc.5, so anchor this check on origin/main's lockfile, not on a working tree.

The convergence

Both keys now derive from one spec field each — no local restatement:

visible?: SpecActionInput['visible'];// was SpecActionInput['visible'] | boolean
disabled?: SpecActionInput['disabled'];// was string | boolean

visible loses the hand-written | boolean because the spec adopted that arm, so restating it locally would now be a second contract rather than a declared tolerance. disabled gains the envelope arm it never had — its absence is precisely why DeclaredActionsBar had to reach around the type. condition is untouched: it is objectui dialect with no spec counterpart, outside this ruling.

Consumer triage

Deleting the index signature produced a five-error wall, not a wall of hundreds — and the two halves landed in different places. Every one resolved; none stopped.

dispositioncountkeyswhere
(i) promoted — legitimate, missed by steps 1+25to, external, newTab, replace, descriptionActionRunner.ts
(ii) fixed at the call site1executeActionRunner.ts:1076
(iii) stopped as ambiguous0

The four navigation-alias keys were ruled legitimate back in step 1 and have sat in NAVIGATION_ALIAS_KEYS ever since — declared as data, never as fields, because step 2's scope was the 18 spec-owned keys. executeNavigation reads them off the action itself, so they reached their own reader through the index signature. Promoted, and deliberately not@deprecated: step 2's acceptance ruled on exactly this point ("navigation 别名四键不标弃用(第 1 步盘点已判定其合法,派发指令有误)"). Hand-written rather than derived because there is no spec field to derive from — that is what makes them dialect.

description was the only key to error outsidecore: two TS2353s, at action-group.tsx:246 and action-menu.tsx:228. It is authorable (@object-ui/types' UIActionSchema, ui-action.ts:521), forwarded by all four action renderers because check:action-forward-parity requires it, and read by the param dialog for its subtitle (#4192) — authorable, forwarded, read, and undeclared. Derived from UIActionSchema['description'], the same source the parity gate calls authorable for a declared surface. No consumer call site was edited: declaring the key correctly at the producer is what fixed both errors, which is the contract-first shape.

execute is category (ii) with a twist worth stating: the fix is not to declare it. It is a live spec tombstone — @objectstack/spec keeps it only so the parser can reject it by name — so declaring it to make the read compile would re-legitimize a retired key. It now reads off an explicitly untyped view of the action:

constretiredExecute=(actionasRecord<string,unknown>).execute;

What did NOT retire, against step 1's expectation

Step 1 wrote that the dev-mode warning and executeScript's rename prescription "can retire" once the index signature came down. Measured, and kept — they cover a disjoint population, not the same one twice:

  • tsc sees actions authored as TypeScript, and now rejects an unknown key there outright.
  • The warning and the prescription see actions that arrive as data. objectstack#3903 established that stored sys_metadata rows are rehydrated UNPARSED, so pre-17 metadata reaches runner.execute() as a plain object no compiler ever looked at. That is the population execute: 'markDone' actually lives in.

Retiring them would have closed the compile-time half while re-opening the runtime half. ActionContext keeps its index signature for the card's own reason (runtime data bag, genuinely open), and that asymmetry is now pinned in both directions rather than assumed.

Pins

Type level, two files, deliberately not redundant. A new actionDef-closed-surface.test.ts states the contract as ordinary TypeScript compiled by tsconfig.typetests.json (@ts-expect-error on execute:, on the typo targt:, on a tombstone, and on a wrong-typed value for each promoted key; bare assignments for all six accepted arms). actionKeys.types.test.ts keeps driving the compiler API with its control interface — which is what proves the rejections come from the deletion and not from an unrelated diagnostic — and its targt row flipped from rejected: false to true, which was always its stated completion condition.

The inverted pin inverted.actionKeys.pin.test.ts asserted the index signature was still there, naming its own retirement condition ("the day this fails, step 3 has landed"). It now asserts the opposite — and via the AST, not toContain('[key: string]: any') as before, for two reasons: both files now discuss the index signature in prose, so a text-negative pin would go red on a comment; and the AST form can carry the half that matters, ActionContext KEEPING its own. A pin that only checked ActionDef would stay green through a change that "tidied up" ActionContext too.

The six arms, both faces. All six already had runtime coverage and it stays where it is — ActionRunner.disabledGate.test.ts drives a 12-row table through the execution gate, ActionEngine.visibility.test.ts does the same for visible. What neither can assert is the join, because both reach runtime through a cast (as unknown as ActionDef, as ActionDef) — correct there, since their tables carry junk shapes the closed type now rejects, but it means they would keep passing if the type stopped admitting the arm being exercised. So the new file asserts the same literal type-checking and evaluating, on both polarities per arm.

That negative half is not decoration: it caught a real flaw in the first draft of the helper. A type: 'script' action with no registered script fails on its own terms, so a helper asking result.success === false scored those failures as "blocked" and reported all six arms blocking — including the three that must release. The helper now reads the gate's own error string.

#2990's runtime prescription branch is green and stays, per the card.

Reverse verification — the direction is inverted, and that is the mechanism

The fix was taken out with a targeted edit restoring only the index signature, then restored with git checkout HEAD -- (never git stash — shared stack). Direction predicted before running, and it matched exactly.

The naive expectation is "the bad line goes red". It cannot: restoring the index signature makes { execute: … } and { targt: … }compile, which is the opposite of an error. The red arrives at the suppressions — an @ts-expect-error with nothing left to suppress is itself a build failure:

### tsc --noEmit (build project)
exit=0 ← sees nothing; it excludes src/** test files
### tsc -p tsconfig.typetests.json
actionDef-closed-surface.test.ts(57,1): error TS2578: Unused '@ts-expect-error' directive.
actionDef-closed-surface.test.ts(63,1): error TS2578: Unused '@ts-expect-error' directive.

Exactly two, at execute and targt — the two undeclared keys. Every other suppression stayed used, because each sits on a declared property whose own type still rejects the value; that split is what shows the pins are measuring the deletion rather than the promotions.

× ActionDef has NO index signature, and ActionContext still does
× an unrecognized key is REJECTED — the index signature is gone
× the retired `execute` tombstone is rejected by name
× proves the promotion is what rejects them, not some unrelated diagnostic
Tests 4 failed | 47 passed (51)

The exit=0 on the first line is worth keeping: the type-level guarantee lives entirely in tsconfig.typetests.json. Without the explicit include added here, this whole change would have been unguarded by CI's type gate.

One CI-only red, and what it taught (second commit)

The first push was green on Type Check and Lint and red on Test shard 3/4, on a single case — description rejects a number — that had been green locally. The cause is worth recording because it is a trap for the next person adding a pin to that harness, not a defect in this change:

actionKeys.types.test.ts builds its own program with a default compiler host and no paths, so it reads whatever is on disk. Every other derivation it checks resolves through @objectstack/spec, an ordinary installed package. description derives from UIActionSchema['description'] in @object-ui/types — a workspace package that resolves through its built dist/index.d.ts, and the unit-test job does not build workspace packages first. With dist stale or absent the indexed access degrades to any, { description: 42 } is accepted, and the row goes red for a reason that has nothing to do with ActionDef.

tsconfig.typetests.json has no such problem — it is a real project in the dependency graph, so CI's Type Check job builds @object-ui/types before compiling it. That is exactly why Type Check was green on the same commit while the harness was red, and it means the @ts-expect-error on { description: 42 } there is enforced for real. So the two description rows moved to that file rather than being weakened: an assertion whose colour depends on whether someone ran a build is not a pin.

Reproduced locally by moving packages/types/dist aside before re-running — 37 passed, where the pre-fix harness would have produced the two CI failures.

Gates

turbo run type-check --concurrency=2 → Tasks: 78 successful, 78 total
turbo run build --filter=!@object-ui/site → Tasks: 43 successful, 43 total
vitest run core + app-shell + components → 538 files, 6003 passed | 1 skipped
eslint (6 changed files) → 0 errors (37 pre-existing warnings)
node scripts/check-control-bytes.mjs → OK (3990 files)
node scripts/check-changeset-presence.mjs → OK (2 changesets for 2 released packages)
node scripts/check-changeset-no-major.mjs → OK
node scripts/check-spec-symbol-derivation.mjs → OK

The consumer sweep is the downstream/prefix direction — ...@object-ui/core is 36 packages — but the runs above are the whole workspace, a superset of it, and core's dist was rebuilt before any downstream judgement so nothing read a stale .d.ts.

check:action-forward-parity — green, with a delta worth explaining

before: 5 surfaces checked against 41 runtime-read keys … 19 justified omissions, 7 known gaps
after : 5 surfaces checked against 40 runtime-read keys … 19 justified omissions, 7 known gaps

The set diff is exactly one key removed and none added:

removed: [ 'execute' ]
added : []

That is the intended consequence of reading the tombstone off an untyped view: the gate derives runtime-read from property accesses bound to the ActionDef parameter, and execute is no longer one. Every surface's owed count is unchanged (24/24/24/24/12), because owed = authorable ∩ runtime-read − retired already subtracted it. The set is simply honest now — a retired key is not something any renderer should be forwarding.

The #4097 rider

Ruling B's documentation block lands at interpolateTarget's non-array params branch, per that card's re-scoping ("it rides the NEXT card touching ActionRunner.ts"). Comment only — zero behaviour change. It names the branch an INTERNAL runtime value-bag channel rather than an authoring surface, cites objectstack#6828 and the ruling, and records the hazard the ruling flagged: the branch's safety rests entirely on the producer refusing an authored object-form params, so a future spec loosening would silently re-admit an authored scope — with the upstream refusal pin and the two local pins as the guards.

Out of scope, filed

Changesets

@object-ui/coreminor and @object-ui/app-shellpatch. Minor follows #3190's measured precedent: step 2 shipped minor for a strictly larger breaking edge (shortcut / bulkEnabled went from compiling to compile errors), and check-changeset-no-major is green. No skip-changeset (#3724).


Generated by Claude Code

…nverge visible/disabled on the spec (#4046)
Step 3 of objectstack#4075, executing the maintainer's 2026-08-06 ruling now
that its upstream half shipped in @objectstack/spec 17.0.0-rc.6
(objectstack#5970, PR objectstack#6450).
- `visible` / `disabled` derive from the spec's unified three-arm shape
(`boolean | string(CEL) | { dialect, source }`); `visible` loses its local
`| boolean` restatement, `disabled` gains the envelope arm it never had.
- `[key: string]: any` deleted from `ActionDef`. `ActionContext` keeps its own —
a runtime data bag is legitimately open, a declared contract is not — and the
asymmetry is now pinned in both directions.
- Five keys the deletion surfaced promoted to real fields: the `navigation`
alias spelling (`to` / `external` / `newTab` / `replace`) and `description`.
- `DeclaredActionsBar` drops its `(action as any)` predicate casts.
- The #4097 ruling-B documentation block lands at `interpolateTarget`'s
non-array `params` branch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
@vercel

vercelBot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectuiIgnoredIgnoredAug 11, 2026 11:18am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)28.9 KB350 KB
Entry fileindex-BUeMlrxi.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)8.88KB3.25KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)7.57KB2.97KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)22.10KB4.37KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.13KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.64KB2.21KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)35.76KB9.11KB
auth (createAuthenticatedFetch.js)4.37KB1.69KB
auth (index.js)2.35KB1.07KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)4.91KB0.87KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)26.07KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.65KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)488.62KB108.26KB
core (index.js)3.04KB1.15KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)150.04KB39.79KB
fields (index.js)228.45KB56.62KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.32KB1.77KB
i18n (index.js)2.65KB1.06KB
i18n (pickLocalized.js)1.70KB0.83KB
i18n (provider.js)16.38KB5.47KB
i18n (useObjectLabel.js)27.59KB6.63KB
i18n (useSafeTranslation.js)4.52KB1.96KB
layout (index.js)38.98KB10.85KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)8.75KB3.06KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)3.67KB1.12KB
permissions (evaluator.js)4.41KB1.44KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.55KB0.71KB
plugin-ai (index.js)15.71KB3.79KB
plugin-calendar (index.js)45.23KB12.45KB
plugin-charts (index.js)61.73KB17.54KB
plugin-chatbot (index.js)180.33KB42.79KB
plugin-dashboard (index.js)118.79KB30.79KB
plugin-designer (index.js)210.91KB42.67KB
plugin-detail (index.js)238.88KB59.71KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)114.58KB27.68KB
plugin-gantt (index.js)164.14KB39.98KB
plugin-grid (index.js)187.97KB49.90KB
plugin-kanban (index.js)48.60KB13.41KB
plugin-list (index.js)109.18KB26.48KB
plugin-map (index.js)17.00KB5.32KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)40.60KB10.58KB
plugin-timeline (index.js)26.21KB7.52KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.03KB20.55KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.71KB3.53KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.67KB2.37KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)23.71KB7.96KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.23KB0.66KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)4.09KB1.74KB
sdui-parser (index.js)4.47KB2.03KB
sdui-parser (parse.js)10.04KB2.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)4.69KB1.48KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)3.05KB1.52KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…rness
CI shard 3/4 went red on `description rejects a number` while the same case was
green locally, and the difference is the harness's own resolution model rather
than anything about `ActionDef`.
`erroringLines` builds its program with a default compiler host and no `paths`,
so it reads whatever is on disk. Every other derivation it checks resolves
through `@objectstack/spec`, an installed package; `description` derives from
`UIActionSchema['description']` in `@object-ui/types`, a WORKSPACE package that
resolves through its built `dist/index.d.ts`. The unit-test job does not build
workspace packages first, so the indexed access degraded to `any`, the case was
accepted, and the row went red for an unrelated reason.
`tsconfig.typetests.json` is a real project in the dependency graph, so CI's Type
Check job builds `@object-ui/types` before compiling it and the
`@ts-expect-error` on `{ description: 42 }` there is enforced for real — which is
why Type Check was green on the same commit. The pin therefore moves rather than
weakens; an assertion whose colour depends on whether someone ran a build is not
a pin.
Reproduced locally by moving `packages/types/dist` aside: 37 passed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)28.9 KB350 KB
Entry fileindex-BUeMlrxi.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)8.88KB3.25KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)7.57KB2.97KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)22.10KB4.37KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.13KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.64KB2.21KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)35.76KB9.11KB
auth (createAuthenticatedFetch.js)4.37KB1.69KB
auth (index.js)2.35KB1.07KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)4.91KB0.87KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)26.07KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.65KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)488.62KB108.26KB
core (index.js)3.04KB1.15KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)150.04KB39.79KB
fields (index.js)228.45KB56.62KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.32KB1.77KB
i18n (index.js)2.65KB1.06KB
i18n (pickLocalized.js)1.70KB0.83KB
i18n (provider.js)16.38KB5.47KB
i18n (useObjectLabel.js)27.59KB6.63KB
i18n (useSafeTranslation.js)4.52KB1.96KB
layout (index.js)38.98KB10.85KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)8.75KB3.06KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)3.67KB1.12KB
permissions (evaluator.js)4.41KB1.44KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.55KB0.71KB
plugin-ai (index.js)15.71KB3.79KB
plugin-calendar (index.js)45.23KB12.45KB
plugin-charts (index.js)61.73KB17.54KB
plugin-chatbot (index.js)180.33KB42.79KB
plugin-dashboard (index.js)118.79KB30.79KB
plugin-designer (index.js)210.91KB42.67KB
plugin-detail (index.js)238.88KB59.71KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)114.58KB27.68KB
plugin-gantt (index.js)164.14KB39.98KB
plugin-grid (index.js)187.97KB49.90KB
plugin-kanban (index.js)48.60KB13.41KB
plugin-list (index.js)109.18KB26.48KB
plugin-map (index.js)17.00KB5.32KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)40.60KB10.58KB
plugin-timeline (index.js)26.21KB7.52KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)84.03KB20.55KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.71KB3.53KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.67KB2.37KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)23.71KB7.96KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.23KB0.66KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)4.09KB1.74KB
sdui-parser (index.js)4.47KB2.03KB
sdui-parser (parse.js)10.04KB2.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)4.69KB1.48KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)3.05KB1.52KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

Sign up for freeto 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.

[P3] objectui ActionDef's [key: string]: any absorbs every retired and misspelled action key — removing a spec key produces no compile error

2 participants

@yinlianghui@claude