Repository navigation
chore(i18n): delete 92 message keys nothing reads from all ten locale packs - #26158
Conversation
…ranslated notices (WIP) Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HUu4jGnAzZqaB5qTG2fsX4
… backlog Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HUu4jGnAzZqaB5qTG2fsX4
…tead of toasting the field list The invalid-submit toast repeated what each field already says under its input, truncated its own list after three names, and was drawn over the record dialog's title row. Drop it; keep reveal + focus on the first invalid field (activating its tab first). A server rejection naming a field with no drawn input (a predicate-hidden tab or section) now falls through to the form-level banner, which the toast used to cover. Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
…change Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HUu4jGnAzZqaB5qTG2fsX4
…anner and toast Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
… and name the inviter on the accept page A visitor who opens an invitation link signed out lands on /login with ?redirect=/accept-invitation/ID. Both login pages now title the card for the invitation instead of "Welcome back", and where sign-up is offered show a full-width "Create an account and join" link above the sign-in form in place of the small "Sign up" link. Both register pages ask for the invited address. The accept page shows "Invited by" with the inviterEmail that get-invitation already returns. No organization, inviter or invited address is shown signed out: the only invitation read is session-gated (401 signed out), so that part needs a server read and is left out. Claude-Session: https://claude.ai/code/session_016msqupguN18F4BUKKWYbWY Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
…-tvk6g5 # Conflicts: # scripts/sdui-manifest.record.json
…n-arrival change Claude-Session: https://claude.ai/code/session_016msqupguN18F4BUKKWYbWY Co-authored-by: Claude <noreply@anthropic.com>
…-eprqgc # Conflicts: # scripts/sdui-manifest.record.json
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HUu4jGnAzZqaB5qTG2fsX4
Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
…ompt export The prompt is a new root export of the published @object-ui/app-shell, so the change widens a public surface. Claude-Session: https://claude.ai/code/session_016msqupguN18F4BUKKWYbWY Co-authored-by: Claude <noreply@anthropic.com>
…and bring two comments in line Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CzUs1oNtFWhWUXT7rmoGy2 Co-authored-by: Claude <noreply@anthropic.com>
Re-measured with ui/scripts/check-i18n-dead-keys.mjs on 6d15aca: 122 CONFIRMED. 92 are deleted here from ar/de/en/es/fr/ja/ko/pt/ru/zh. The other 30 stay: 28 are the `_one`/`_other` plural forms of keys that call sites pass with `count` (i18next resolves them), and 2 are `console.ai.agentLabels.*` entries the pack marks as kept on purpose. Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com>
…bjectView keys Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com>
… product-specific allowlist Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com> # Conflicts: # scripts/sdui-manifest.record.json
Claude-Session: https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP Co-authored-by: Claude <noreply@anthropic.com> # Conflicts: # packages/objectql/src/engine.ts # packages/services/service-automation/src/builtin/notify-node.ts # scripts/partition-test-shards.mjs # scripts/sdui-manifest.record.json # scripts/test-shard-timings.json
Contract reviewServed-tier: ① Derived judgments
② Semver levelThere are four changesets, all ③ Boundary flags
Implemented-by: VERDICT: PASS |
席位核对 · ACCEPT · seat
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40356711668 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40360053085 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
The locale packs auto-merged with both sides' keys kept (main deleted unread keys in #26158; the dependencyMissing block is untouched). scripts/sdui-manifest.sources/i18n.json conflicted on the i18n digest; resolved by regenerating with `node scripts/gen-sdui-manifest-node.mjs` over the merged tree (sdui.manifest.json unchanged). Claude-Session: https://claude.ai/code/session_01NndsH9Qm7k6AS2i2fWbjNA Co-authored-by: Claude <noreply@anthropic.com>
Requested by Steve · project thread
Part of #25921 (the dead i18n keys slice; the card's other items stay open there).
Clause-②: yes (
TranslationKeysnarrows: the 92 dead keys of #25921 andvalidation.formInvalidfrom #26040; additiveInvitationSignUpPromptexport from #26044; patch per the objectui#4730 key-retirement precedent)Metadata-protocol: none
i18n batch (seat
domain:ui#1)This PR also carries three already-reviewed PRs on the same locale packs, merged in rather than landed one by one, so
scripts/sdui-manifest.sources/i18n.jsonis re-recorded once and the merge queue runs once. The queue squash-merges, so stacked PRs would still conflict. The source PRs are closed as superseded when this merges.Each source PR keeps its own changeset. The non-locale files are byte-identical to each source PR's head (checked by the seat), and the diff against
mainis exactly the union of the four PRs' files plusscripts/sdui-manifest.sources/{components,i18n,plugin-map}.json. Cards 25874, 25886 and 25889 are referenced without a closing keyword on purpose: each seat closes out its own card after this lands.What
Deletes 92 message keys that nothing reads from all ten locale packs under
ui/packages/i18n/src/locales/(ar,de,en,es,fr,ja,ko,pt,ru,zh). Pure deletions: no key is renamed or added, and no value changes. Each pack loses the same 92 leaves (enshows 93 deleted lines becausepublicForm.unavailableDescriptionspans two).Two test ratchets that name keys follow the deletion in the same PR:
ui/packages/i18n/src/__tests__/objectView-config-keys-retired-4730.test.ts:console.objectView.ufTabsandviewTypeUnavailableShortmove from the surviving half (105 to 103) to the retired list (124 to 126). The total stays 229, and the retired list now pins both keys absent from every pack.ui/packages/app-shell/src/__tests__/product-specific.allowlist.json:workspace.inviteandworkspace.membersare deleted from the live list, as its own test asks ("a migrated one is deleted from the live list"). The list takes deletions only, and this is one.How each key was proved unused
Measured on
origin/main6d15acab(objectstack-ai/objectstack), with three searches per key:node ui/scripts/check-i18n-dead-keys.mjs --json: every key below is in its CONFIRMED tier (not()/tt()call site, no dynamic template head that reaches it, no indirect one-hop template, and no key-boundary textual occurrence of the dotted key or its property chain anywhere inui/). The run reported 3,879 pack keys, 398 candidates, 122 CONFIRMED, 276 NEEDS-REVIEW,wrongVerdicts: []andclassFourUncovered: [].ui/scope:git grep -n -F -f KEYS -- . ':!ui/packages/i18n/src/locales', then a filter that keeps a hit only where the key is bounded on both sides by a character that cannot continue a dotted key. Result: 0 hits for all 92 keys. The one raw line it printed isobject-grid.rowHeightin apackages/speccomment, a component name and notgrid.rowHeight. Positive control: the same search forpreview.changes.typeCount.objectfindsDraftChangesPanel.tsx.LoadingScreen.tsxspreadsconsole.errorbut reads onlyconnectionFailedandcheckServer;outboundAgentText.tsindexesconsole.aionly by its fourOutboundAgentTextKeynames;flowResponse.tsreads onlyform.noPermissionToSave. None of them reads a deleted key. A probe for template heads (a template literal or a string concatenation that starts with the key's parent namespace) over all non-test source inui/packages,ui/apps,ui/examplesandui/e2efound one, atable.template inside an error message inui/packages/types/src/zod/objectql.zod.ts, which is refusal text and not a translation lookup.After the change the tool reports 3,787 pack keys, 30 CONFIRMED (the 30 kept on purpose, listed below) and the same 276 NEEDS-REVIEW, so the deletion moved no key into either tier.
The 92 deleted keys
appDesigner:addComponent,aggregate,appearance,colorVariant,componentProperties,createApp,editApp,fields,livePreview,modeCode,modePreview,navBuilder,rowHeight,selectObjects,showFilters,showSearch,showSort,toolbar,valueField,viewTypeconsole.ai:conversationReady,preparingConversation,workspaceSubtitle,workspaceTitleconsole.commandPalette:createAppconsole.error:serverUnreachable,timeoutconsole.objectView:ufTabs,viewTypeUnavailableShortconsole:titledashboard:addWidget,editLayout,resetLayout,saveLayouterrors:networkError,notFound,serverError,timeoutform:deleteSuccess,invalidFormat,removeItem,saveSuccessgrid:rowHeighthome:allApps,createFirstApp,title,welcomeDescriptionhome.gettingStarted:cta,titlekanban:deleteCard,deleteColumnlayout.appSwitcher:addApp,editApp,editNavigation,home,manageAllApps,noAppsConfigured,systemConsolepublicForm:consentLabelDefault,consentLink,retry,secureNotice,submitAnother,tryDemo,unavailableDescription,unavailableTitlereport:allLabel,columnTotal,columnsLabel,emptyLabel,failedToLoad,grandTotal,needsAcross,rowTotal,rowsLabelsidebar:scope,settingstable:collapseRow,expandRow,exportExcel,filterColumn,freezeColumn,showing,unfreezeColumnuser:settingsvalidation:typeview:activeFilters,activeSort,saveAsView,unsavedChangesworkspace:invite,membersKept although the tool lists them CONFIRMED (30)
preview.changes.typeCount.{object,view,page,dashboard,app,action,report,flow,permission,agent,email_template}_one/_other,notifications.arrivalMany_one/_other,notifications.arrivalRepeats_one/_other,fields.relativeDate.overdue_one/_other. Their base keys are called withcount(DraftChangesPanel.tsx,useInboxArrivalNotifier.ts,core/src/utils/date-display.ts), so i18next reads exactly these suffixed forms. The tool expands plural suffixes only for call sites it classifies as pack calls; these call sites reach the base key through a passed-in translator, so the base key lands in NEEDS-REVIEW and its suffixed forms fall to CONFIRMED. Deleting them would turn every count string on those screens back to the bare fallback.console.ai.agentLabels.dataChatandmetadataAssistant. No code reads them (AiChatPage.tsxmaps onlyaskandbuild), but the pack marks them "Legacy keys kept for back-compat with any external overrides". Dropping them is a separate call.Acceptance notes
ui/scripts/check-i18n-dead-keys.mjsfalse-positive class, not fixed here: the plural forms of a base key that is called withcountthrough a translator the AST pass does not classify as a pack call are reported CONFIRMED. 28 of today's 122 CONFIRMED entries (23%) are this class. Carrier: none.ui/scripts/check-i18n-dead-keys.mjs's text footprint does not see a key that a JSON list spells as namespace plus leaf (product-specific.allowlist.json):workspace.inviteandworkspace.memberswere CONFIRMED while that list named them. Carrier: none.typeof en,TranslationKeys) lose the deleted members. Nothing in this repository reads one of them by property (search 2 above covers the property chains too, and the tool's property-chain leg found none); an external host that does would see a type error. Recorded here because the claim line says no exported type changes.scripts/sdui-manifest.sources/i18n.jsonis re-recorded (node scripts/gen-sdui-manifest-node.mjsafter mergingmainata335f1de), because@object-ui/i18nis in the console registry closure;node scripts/check-sdui-manifest.mjsis green on the pushed head. The i18n packs are serialised: fix(i18n): zh sign-out menu item reads 退出登录, not 注销 #26045, fix(components): a refused submit focuses the first invalid field instead of toasting the field list over the dialog title #26040, fix(app-shell,console): greet a signed-out invitee for the invitation and name the inviter on the accept page #26044, fix(plugin-map): a failed map style degrades to the record list with translated notices #26048 and feat(plugin-detail): the record activity timeline folds consecutive updates by one actor into one row with a count #26055 land first, and fix(components): a refused submit focuses the first invalid field instead of toasting the field list over the dialog title #26040 also edits these packs. When its turn comes this branch mergesmainagain, re-records the digest and rebuilds the Console; the seat enqueues it. It is not armed or queued from here.Local test runs and gate readings are in the
os-dev-reportcomment on #25921.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01FpUtgwNrSiRgWJ8GAepPeP