Skip to content

fix(i18n): console.ai.pendingDrafts lands in the eight remaining locale packs (#5705) - #5708

Merged
os-sales merged 1 commit into
mainfrom
claude/issue-5705-pending-drafts-locale-parity
Aug 22, 2026
Merged

fix(i18n): console.ai.pendingDrafts lands in the eight remaining locale packs (#5705)#5708
os-sales merged 1 commit into
mainfrom
claude/issue-5705-pending-drafts-locale-parity

Conversation

@os-sales

Copy link
Copy Markdown
Collaborator

Fixes #5705

main is red on packages/i18n/src/__tests__/all-locales-key-parity.test.ts: the
standing unpublished-changes bar's console.ai.pendingDrafts block existed only in
en and zh. The other eight packs — ar, ru, pt, es, fr, de, ko, ja
— had no such block at all. Eight packs x five keys.

#5696 landed the feature en-only; #5697, titled for the locale packs, reached zh
only. Source-free diffs skip the shard that runs this test, which is why it survived
several merges.

What changed

The five keys — count, publish, published, failed, publishedWithFindings
added to the eight packs, translated, at en's position: first key inside
console.ai, immediately before usage. Insertion was anchored on the parsed
ai: { line, never on a grep for pendingDrafts — there are two unrelated
blocks by that name and an occurrence count answers wrongly in both directions.

Nothing else: 60 insertions, 0 deletions, 8 locale files plus the changeset. No
reordering, no other parity gaps touched.

Each pack keeps its own conventions rather than en's:

  • All eight quote with " (en uses ').
  • ru puts the number last (...: {{count}}), the convention that pack already
    documents for the sibling home.pendingDrafts counts.
  • ja uses the full-width before {{detail}}, because that pack's documented
    rule is full-width when the interpolation carries a message and half-width when it
    carries a single token — {{detail}} is a joined list of runtime probe messages.
  • Both deviations carry a short in-pack note, in the pack's own language, matching
    how these files already annotate translation choices.

Terminology is lifted from each pack's existing publish-bar vocabulary
(home.pendingDrafts, console.ai.seedWarn, console.ai.publishFailed) so the two
banners read alike.

Verification

All results below are at the final commit, 739dd78b6.

Red leg, captured before the fix (origin/main @ 83ec61881):

Test Files  1 failed (1)
     Tests  8 failed | 24 passed (32)
AssertionError: ja is missing 5 key(s)
+ [ "console.ai.pendingDrafts.count", "console.ai.pendingDrafts.failed",
+   "console.ai.pendingDrafts.publish", "console.ai.pendingDrafts.published",
+   "console.ai.pendingDrafts.publishedWithFindings" ]

...identically for ko, de, fr, es, pt, ru, ar. Exactly the five keys,
nothing else.

Green leg — same file, --reporter=verbose, so the assertions are named rather
than aggregated:

Test Files  1 passed (1)
     Tests  32 passed (32)

That includes all nine %s defines every en key cases, all nine of the sibling
%s defines no key that en lacks (the other direction — a mis-nested key would fail
here), placeholders match en in every pack, and both non-vacuity guards.

Placeholders, checked mechanically against the evaluated packs rather than the
file text — for all ten packs, console.ai.pendingDrafts has exactly en's five
keys, {{count}} is present in count, {{detail}} in publishedWithFindings, the
per-key placeholder shape equals en's, and the unrelated home.pendingDrafts block
still has its message / cta and gained nothing:

locales: en zh ja ko de fr es pt ru ar (10)
  ok ar keys=5 count[{{count}}]=yes findings[{{detail}}]=yes home.pendingDrafts=intact
  ... (all ten)
VERIFY OK — 0 failures

Scoped suite — the edited package plus the one provable consumer of these keys
(packages/app-shell/src/console/ai/PendingDraftsBar.tsx, found by grepping every
call site of console.ai.pendingDrafts; it is the only one):

pnpm exec vitest run --maxWorkers=2 packages/i18n/ \
  packages/app-shell/src/console/ai/__tests__/PendingDraftsBar.test.tsx
Test Files  52 passed (52)
     Tests  883 passed (883)

This is a provable superset for an i18n-data change, not app-shell's full 493-file
suite.

Gates:

Gate Result
check-i18n-en-drift.mjs exit 0 — no en value changed
check-i18n-call-site-keys.mjs exit 0
check-i18n-dead-keys.mjs exit 0 (a report, not a gate)
check-control-bytes.mjs OK (scanned 4756 tracked text file(s); skipped 85 binary)
pnpm --filter @object-ui/i18n type-check exit 0 (tsc --noEmit && tsc -p tsconfig.test.json)
pnpm --filter @object-ui/i18n lint 34 problems (0 errors, 34 warnings) — all pre-existing, none in a locale file

Lint narrowing, stated as a measurement: eslint --no-inline-config --format json on
the diff reports 8 files, 0 errors, 0 warnings. The full repo population eslint
itself resolves is 3544 files; that run also reports 0 findings in any
packages/i18n/src/locales/ file
. The config sets no projectService /
project:, so linting is not type-aware and this diff cannot move the verdict of any
untouched file.

Not in scope

main is separately red on Build Docs (#5668) and Test (coverage) (#5402). Those
are not addressed here and remain open.

The card also raises whether the parity test should run in a cheap, unskippable job
rather than only inside a shard that a source-free diff skips — that is a real gap
(it is why this survived several merges) but it is a CI-topology decision, left for
the maintainer rather than ridden along on a blocker fix.


Generated by Claude Code

…cale packs (#5705)

The standing unpublished-changes bar's five strings existed only in `en` and
`zh`, so `all-locales-key-parity` was red on `main` and on every PR whose diff
touched source. `ar`, `ru`, `pt`, `es`, `fr`, `de`, `ko` and `ja` had no
`console.ai.pendingDrafts` block at all — eight packs x five keys.

objectui#5696 landed the feature `en`-only; objectui#5697, titled for the locale
packs, reached `zh` only. Source-free diffs skip the shard that runs the parity
test, which is why the breakage survived several merges.

Each pack keeps its own conventions rather than `en`'s: all eight quote with `"`,
`ru` puts the number last (`...: {{count}}`) as it already does for the sibling
`home.pendingDrafts` counts, and `ja` takes the full-width `:` before
`{{detail}}` because that value is a runtime message rather than a single token.
Both deviations carry an in-pack note. Terminology comes from each pack's
existing publish-bar vocabulary so the two banners read alike.

Both interpolations survive verbatim everywhere - `{{count}}` in `count`,
`{{detail}}` in `publishedWithFindings` - checked against the evaluated packs
rather than by eye. The unrelated `home.pendingDrafts` block (`message` / `cta`)
is a different node and is untouched.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 52 chunks) 3914.3 KB 3990.2 KB
Main entry chunk (gzip) 152.3 KB 350 KB
Entry file index-DvF64ISu.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 (index.js) 10.04KB 3.72KB
app-shell (runtime-config.js) 12.80KB 4.47KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 29.34KB 7.05KB
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) 6.35KB 2.43KB
auth (index.js) 2.77KB 1.22KB
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.02KB 0.89KB
auth (useIsWorkspaceAdmin.js) 3.04KB 1.45KB
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.90KB 113.84KB
core (index.js) 4.92KB 1.97KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 160.15KB 44.52KB
fields (index.js) 238.40KB 59.89KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.44KB 1.39KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 23.13KB 7.63KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 33.40KB 8.71KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
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.65KB 18.32KB
plugin-chatbot (index.js) 181.41KB 43.22KB
plugin-dashboard (index.js) 128.41KB 32.95KB
plugin-designer (index.js) 212.30KB 42.80KB
plugin-detail (index.js) 242.34KB 60.98KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 125.63KB 30.64KB
plugin-gantt (index.js) 164.10KB 39.87KB
plugin-grid (index.js) 200.79KB 54.26KB
plugin-kanban (index.js) 52.93KB 14.60KB
plugin-list (index.js) 111.80KB 27.20KB
plugin-map (index.js) 20.06KB 6.62KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.49KB 11.93KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.61KB 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) 3.77KB 1.33KB
react (SchemaRenderer.js) 43.66KB 14.77KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.33KB 0.69KB
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 (index.js) 4.77KB 2.16KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 10.76KB 3.17KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 6.92KB 2.40KB
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) 0.20KB 0.18KB
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 (index.js) 3.59KB 1.79KB
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 (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
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-sales
os-sales marked this pull request as ready for review August 22, 2026 12:42
@os-sales
os-sales added this pull request to the merge queue Aug 22, 2026
Merged via the queue into main with commit 1e66879 Aug 22, 2026
23 checks passed
@os-sales
os-sales deleted the claude/issue-5705-pending-drafts-locale-parity branch August 22, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants