Skip to content

fix(app-shell): the inbox opens on the first tab with items (objectui#11698) - #11743

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-11698-inbox-opens-on-items
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-11698-inbox-opens-on-items

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11698

Clause-②: no

What changed

@object-ui/app-shell InboxPopover: the bell's popover no longer always opens on Notifications. The tab was a useState('notifications') that nothing moved, while the badge above it counts unreadTopics + pendingApprovalsCount. With 0 unread notifications and 3 pending approvals the bell read "3" and the click showed "You're all caught up".

On every open the popover now picks its tab, in this order:

  1. the tab the user last picked in this browser-tab session, if that tab has something in it;
  2. otherwise the first tab that has something in it: Notifications, then Approvals, then Activity;
  3. otherwise the user's last pick;
  4. otherwise Notifications.

"Has something in it" means what each tab shows by default: an unread notification topic for Notifications (the Unread filter is the default, and unread topics are the badge's first addend), a pending approval for Approvals (the badge's second addend), and an activity row for Activity.

The pick happens in the popover's open handler (handleOpenChange), never while it is open, so a count that changes under an open popover does not move the tab. Only a tab the user selects (handleTabChange) is remembered. The tab the popover picks for them on open is not remembered.

No new export, no new locale key, no new prop. InboxPopover is not exported from the package. The other caller, the global:notifications page block, gets the same behaviour.

"Keeps the user's choice within a session": the definition pinned here

Once the user selects a tab, every later open of an inbox bell in the same browser tab reopens on it, across navigation and reload. A new browser tab starts from the opening pick again. The pick is held in sessionStorage (key inbox-popover-tab). Nothing goes to localStorage or to the server.

Why not component state: the header bell is a different React instance on Home, Organizations, an organization's pages, the AI page and inside an app. AppHeader is mounted separately by HomeLayout, OrganizationsLayout, OrganizationLayout, AiChatPage and ConsoleLayout, so component state would forget the pick the first time the user moved between Home and an app. sessionStorage is the scope the ChatDock's expanded flag already uses for the same kind of per-tab UI posture (chatDockState.ts). Every storage touch is guarded, so private mode degrades to "nothing picked".

This survives a reload, which goes further than the dispatch's example ("until reload"). The reason is above. If the seat prefers page lifetime, the change is to hold the pick in a module variable instead.

Two acceptance texts, one edge where they disagree

The triage grade says the popover "keeps the user's choice within a session". The card's Expected says "'You're all caught up' is never the first thing shown under a non-zero badge". They disagree in one case: the user picked Notifications, later reads the notification elsewhere, and 3 approvals are still pending. Keeping the pick would show "You're all caught up" under a "3".

Step 1 above settles it: a pick is kept only while its tab has something in it. Otherwise the first tab with items wins. If every tab is empty, the pick is kept, since the badge is then 0. This keeps both texts true everywhere they can both be true. It is pinned by the case named "a picked tab that is now empty yields to the first tab with items".

The dispatch's mechanism hypotheses, measured

  • H1 (constant initial tab; badge = unread topics + approvals; Tabs value is tab). Confirmed on origin/main 6be0f7a.
  • H2 (the counts may load after the popover opens). Falsified. The popover fetches nothing. Its counts are props from useInboxBell. That hook reads the shared polled feeds (useSharedInboxFeed, useSharedPendingApprovalsCount), which start when the header mounts and do not depend on the popover being open. The badge renders from those same props, so the pick at open time reads the numbers the bell showed when it was clicked. If the user opens before the first poll lands, the badge is 0 too, and the popover opens on Notifications or Activity. When counts arrive while the popover is open, the tab does not move. That is pinned.
  • H3 ("within a session" is ambiguous). Defined above and pinned.

Tests

New suite packages/app-shell/src/layout/__tests__/InboxPopover.openingTab-11698.test.tsx, 11 cases. It mocks nothing: the real Radix popover and tabs, the real router and the real English i18n pack. The selected tab is read from Radix's aria-selected. The cases:

  • the card's pin: 0 notifications and 3 approvals, so the badge reads 3 and the popover opens on Approvals, with no "You're all caught up" anywhere in the popover;
  • 2 notifications and 3 approvals open on Notifications;
  • activity only opens on Activity;
  • notifications that are all read are not items;
  • all empty, with nothing picked, opens on Notifications;
  • the popover's own pick is not remembered;
  • the tab does not move while the popover is open;
  • a pick is kept on reopen;
  • a pick survives a remounted bell;
  • an empty pick yields to the first tab with items;
  • with every tab empty, the pick is kept.

InboxPopover.displayLocale-10668.test.tsx changed in its test helper only. It read "the Notifications panel" as whatever the bell opened on. Its first case selects Activity, and that pick now persists in sessionStorage into the en-US control, so the control read the Activity panel twice: 1 of 2 timestamps, red. The helper now selects Notifications explicitly before reading it. Its assertions are unchanged.

Reverse verification, on committed 770c375. A trap-guarded script wrote the base version of InboxPopover.tsx over the fix. Landing was proven on disk: onOpenChange={setOpen} was found once, and openingTab( and handleOpenChange zero times. The new suite then went red with 7 failed and 4 passed, the same split as the pre-fix run, and the card's pin failed with expected 'Notifications' to match /approvals/i. The file was restored with git checkout HEAD, and the restore was proven by its blob hash equalling the HEAD blob and an empty git diff HEAD. The 4 cases that pass on the base version are the ones the old constant default already satisfied: 2 and 3 open on Notifications, all empty with nothing picked opens on Notifications, a reopen within one mount keeps a pick, and an all-empty pick is kept.

Gates (all on 770c375, run from the worktree root)

Command Exit The gate's own verdict line
pnpm exec vitest run --maxWorkers=2 over the narrowed set below (via os-verify-lock) 0 Test Files 56 passed (56) · Tests 414 passed (414)
pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 (the dependency closure the type-check reads) 0 Tasks: 28 successful, 28 total
pnpm --filter @object-ui/app-shell type-check (the script name type-check is echoed; it chains tsc --noEmit and tsc -p tsconfig.test.json, and the test project's file list includes both touched suites) 0 zero error TS lines
pnpm --filter @object-ui/console exec vite build 0 the bundle is written to apps/console/dist/index.html
pnpm exec eslint --format json over the 3 touched .ts/.tsx files 0 3 files, 0 errors, 0 warnings
pnpm check:control-bytes 0 check-control-bytes: OK (scanned 7691 tracked text file(s); skipped 85 binary).
pnpm check:test-path-roots 0 check-test-path-roots: OK
pnpm check:changeset-claims 0 No pending changeset names a file this change touches.
pnpm check:pending-changeset-literals 0 No test source names a pending changeset.
pnpm check:vi-mock-specifiers 0 check-vi-mock-specifiers: OK
pnpm check:new-line-citations 0 VERDICT new-cross-file-line-citations: 0 new citation(s)
node scripts/check-changeset-presence.mjs 0 3 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)

Narrowed, and declared as narrowed. The whole app-shell package would hold the shared verify lock for about 30 minutes, so the vitest run covers every test directory and file that mounts the popover. That is every file under packages/app-shell/src/layout/, which holds all the InboxPopover*, AppHeader* and ConsoleLayout* suites, plus global-page-blocks.render (the global:notifications block), sharedInboxFeed.twoSurfaces, HomePage.approvalsTarget, KeyboardShortcutsDialog.wiredOnly-11674 (it mounts ConsoleLayout) and the console's approvalsInboxComponentRef. The set was chosen with git grep for InboxPopover, AppHeader and global:notifications over test files. Like any grep, it cannot see a test that mounts the header through a path that names none of them. The full farm belongs to CI.

ESLint was narrowed and proven. The population comes from eslint.config.js itself: the touched .ts/.tsx files fall under its **/*.{ts,tsx} blocks. The file count is 3, read from --format json, with 0 errors and 0 warnings. The invariance holds because --print-config shows empty parserOptions (no project or projectService). Type-aware linting is off, so this diff cannot move a verdict on any untouched file.

The console compiles InboxPopover.tsx through its @object-ui/app-shell alias to src/. That compile was measured with the same command CI's E2E job uses, pnpm --filter @object-ui/console exec vite build. It exited 0 and wrote apps/console/dist/index.html. The diff adds no import, so the bundle graph the console's build checks read is unchanged.

Acceptance notes

  • @object-ui/app-shell patch changeset .changeset/11698-inbox-opens-on-items.md. node scripts/check-changeset-presence.mjs: 3 published source files of 1 released package, 1 changeset. Not governed: check-governed-queue-guard --test over the 4 paths printed NOT GOVERNED.
  • No out-of-scope findings filed.

Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8


Generated by Claude Code

claude added 2 commits October 6, 2026 17:28
…#11698)

The popover's tab was a fixed 'notifications', so a bell reading "3" for
three pending approvals opened on "You're all caught up". On each open it
now picks the user's last-picked tab if that tab has items, else the first
tab with items (Notifications, Approvals, Activity), else the pick, else
Notifications. A picked tab is remembered in sessionStorage so the header
bells of Home, an app and the other layouts share it for the tab session.

Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8
Co-authored-by: Claude <noreply@anthropic.com>
…reads (objectui#11698)

The suite read the Notifications panel as whatever the bell opened on. The
bell now opens on the user's last pick in the browser-tab session, and the
first case's pick of Activity stays in sessionStorage, so the en-US control
read the Activity panel twice. Select Notifications explicitly too.

Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 331 chunks) 3326.8 KB 3330.4 KB
Main entry chunk (gzip) 154.7 KB 350 KB
Entry file index-BF6dlB7T.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) 17.82KB 6.58KB
app-shell (runtime-config.js) 22.59KB 7.89KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.11KB 7.97KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.50KB 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) 578.98KB 139.21KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 233.72KB 64.83KB
fields (index.js) 263.36KB 66.69KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 37.51KB 10.04KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.18KB 11.71KB
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) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
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) 16.04KB 3.92KB
plugin-calendar (index.js) 53.39KB 15.52KB
plugin-charts (index.js) 84.26KB 23.05KB
plugin-chatbot (index.js) 199.63KB 47.46KB
plugin-dashboard (index.js) 144.26KB 38.97KB
plugin-designer (index.js) 231.46KB 48.87KB
plugin-detail (index.js) 247.28KB 65.06KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 177.09KB 45.89KB
plugin-gantt (index.js) 179.16KB 45.06KB
plugin-grid (index.js) 238.51KB 65.53KB
plugin-kanban (index.js) 52.17KB 16.37KB
plugin-list (index.js) 116.85KB 29.12KB
plugin-map (index.js) 25.60KB 8.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.12KB 12.29KB
plugin-timeline (index.js) 38.90KB 11.74KB
plugin-tree (index.js) 15.07KB 5.33KB
plugin-view (index.js) 90.23KB 22.73KB
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.81KB 3.58KB
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) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
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) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
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) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.25KB
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

…(objectui#11698)

With every tab empty the popover reopens on the tab the user last
selected, and on Notifications only when nothing was selected. The
changeset said Notifications unconditionally.

Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 331 chunks) 3326.8 KB 3330.4 KB
Main entry chunk (gzip) 154.7 KB 350 KB
Entry file index-BF6dlB7T.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) 17.82KB 6.58KB
app-shell (runtime-config.js) 22.59KB 7.89KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.11KB 7.97KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.50KB 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) 578.98KB 139.21KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 233.72KB 64.83KB
fields (index.js) 263.36KB 66.69KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 37.51KB 10.04KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.18KB 11.71KB
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) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
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) 16.04KB 3.92KB
plugin-calendar (index.js) 53.39KB 15.52KB
plugin-charts (index.js) 84.26KB 23.05KB
plugin-chatbot (index.js) 199.63KB 47.46KB
plugin-dashboard (index.js) 144.26KB 38.97KB
plugin-designer (index.js) 231.46KB 48.87KB
plugin-detail (index.js) 247.28KB 65.06KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 177.09KB 45.89KB
plugin-gantt (index.js) 179.16KB 45.06KB
plugin-grid (index.js) 238.51KB 65.53KB
plugin-kanban (index.js) 52.17KB 16.37KB
plugin-list (index.js) 116.85KB 29.12KB
plugin-map (index.js) 25.60KB 8.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.12KB 12.29KB
plugin-timeline (index.js) 38.90KB 11.74KB
plugin-tree (index.js) 15.07KB 5.33KB
plugin-view (index.js) 90.23KB 22.73KB
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.81KB 3.58KB
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) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
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) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
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) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.25KB
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

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 6, 2026 19:09
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 6, 2026 19:09
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit 2c876f0 Oct 6, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-11698-inbox-opens-on-items branch October 6, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants