Repository navigation
feat(i18n)!: the Console's language packs follow the platform locale table, keyed by its tags, and Traditional Chinese (zh-Hant) ships - #30902
objectstack-fleet[bot] wants to merge 19 commits into
Conversation
…pack, key packs by table tag The Console's language packs are now the platform locale table (PLATFORM_LOCALES in @objectstack/spec/system): one pack per tag, keyed by the tag (zh-Hans, zh-Hant, pt-BR). zh-Hant is generated from zh-Hans by scripts/gen-zh-hant.mjs (OpenCC s2twp, pinned at 1.3.1, with the www.objectos.ai overrides plus five straddle repairs found reading the pack). Stored and browser codes keep resolving through the table's read aliases: resolveBuiltInLanguage (new export) reads zh/zh-CN as zh-Hans, zh-TW/zh-HK as zh-Hant, pt as pt-BR, then each shorter prefix; createI18n's fallbackLng maps every alias to its tag. The app-shell splash, outbound agent text and flow permission line read the snapshot by tag. The parity, outbound, eager-catalogue and en-drift checks read the table; en-drift reads a follower pack absent at the base as new. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
…pack, key packs by table tag The Console's language packs are now the platform locale table (PLATFORM_LOCALES in @objectstack/spec/system): one pack per tag, keyed by the tag (zh-Hans, zh-Hant, pt-BR). zh-Hant is generated from zh-Hans by scripts/gen-zh-hant.mjs (OpenCC s2twp, pinned at 1.3.1, with the www.objectos.ai overrides, four straddle repairs and one phrase override found reading the pack). Stored and browser codes keep resolving through the table's read aliases: resolveBuiltInLanguage (new export) reads zh/zh-CN as zh-Hans, zh-TW/zh-HK as zh-Hant, pt as pt-BR, then each shorter prefix; createI18n's fallbackLng maps every alias to its tag. The app-shell splash, outbound agent text and flow permission line read the snapshot by tag. The parity, outbound, eager-catalogue and en-drift checks read the table; en-drift reads a follower pack absent at the base as new. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
…package The suites outside ui/packages/i18n that hard-coded ten packs, a zh / pt key, a 'zh' pack lookup or the menu's 中文 entry now read the platform locale table or the tag. Three readers keyed by the old codes are fixed with them. The provider wrote a booted alias's catalogue (zh, zh-TW, pt) a second time under the alias, an added event that re-rendered every reader and refetched every chart for a catalogue already resident; it now writes under the tag. A stored zh-TW locale took the first offered zh variant (zh-Hans); pickRenderableLocale now takes the first offered code the table reads as the same language first. The page-tab label dictionary served its Simplified rows to every non-exact zh session; a zh-Hant, zh-HK or zh-MO session reads its Traditional rows. The en-drift fixtures write a const that is not named by the tag, and a new describe pins the base-absent follower rule. The generated zh-Hant pack is recorded as not driver-managed in the merge-driver ledger, and the converter's declaration twin joins the package's test program. The changeset declares the change. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
Main's pack edits to zh.ts and pt.ts land in zh-Hans.ts and pt-BR.ts; zh-Hant.ts is regenerated from the merged zh-Hans.ts. The two conflicted tests take main's CJK-Latin spacing cases under the zh-Hans tag, and a case pins the spacing for both Chinese packs booted by their tags. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
The suite types its language by the keys of builtInLocales, which are now the platform locale table's tags, so its zh cases name the zh-Hans pack. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
…er's twin A doc link and a test comment named the old zh.ts path; they name zh-Hans.ts. The nested-layout drift case pinned that a pack missing at the base throws; under the follower rule only en does, and a follower the base lacks reads as empty and is named, so the case pins both. The lint-rule-coverage ledger declares the converter's declaration twin, packages/i18n/scripts/zh-hant.d.mts, beside the two script twins it already declares, and its tests accept an objectstack card on a row. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
34c9ccb is the first commit as pushed before its message was reworded (c857810 has the same tree). Merged with the ours strategy so the branch fast-forwards from what is already on the remote; no file changes. Claude-Session: https://claude.ai/code/session_01L6bhgThgWPADcpU1xXCBsw Co-authored-by: Claude <noreply@anthropic.com>
Merges main through the lazy marketplace namespace. Its catalogues move to platform locale table tags with the packs (zh -> zh-Hans, pt -> pt-BR), a zh-Hant catalogue is generated from zh-Hans by gen:zh-hant (now one list of targets: the pack and each pack-shaped namespace), the namespace's loaders are typed on the table, and the all-packs door merges each tag's pack with its catalogue. The en-drift reader keeps both the follower-pack excuse and the namespace partial packs. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
The marketplace shape, lazy-load and console gate suites name the zh-Hans / zh-Hant / pt-BR catalogues and packs; a stored zh-TW reader is pinned to the Traditional catalogue; the freshness suite holds every zh-Hant target the generator writes. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
pickRenderableLocale now calls resolveLocaleAmong from @objectstack/spec/system, the ladder the server's resolveLocale runs, instead of keeping a copy of it with its own table step. The table's read aliases already name the script-subtag spellings, so a zh-Hant-TW row still renders Traditional; a variant the table reads as the language itself (es-ES) is now taken ahead of the first offered variant, as the server takes it. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
The docs chrome and membership filter chip cases that main added read a pack as builtInLocales.zh; they read zh-Hans (and the docs chrome also zh-Hant) now. The chip cases keep booting the page in the stored zh code, so they also pin that the alias still renders Simplified. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
…indexing its loader Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
… declaration, so importing the gate runs nothing Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
|
domain:ui#2 · os-tesla · session_01L9qibw7DekEe3wx5f3zphf Contract reviewServed-tier: ① Derived judgmentsPublic surface,
Gates (edits to existing checks, no new
Tests that make the card's ask real: Generator: Head check-runs on ② Semver level
Clause-②: yes (narrowing) — the record agrees with the declaration; ③ Boundary flagsos-dev-report 6682318861 carries no
Nothing escalated. ④ Design judgmentThe narrowing against the published spec on Must-fix (a FAIL on this head):
Should-fix (none blocks a corrected head):
Implemented-by: VERDICT: FAIL |
…talogue beside the pack's Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyWSiXh6B2sMVHfXYC
|
domain:ui#2 · os-tesla · session_01L9qibw7DekEe3wx5f3zphf Contract reviewServed-tier: ① Derived judgmentsDelta only; every judgment in 6682790803 ① stands for the 150 untouched files and is carried forward by reference.
Head check-runs on ② Semver levelUnchanged from 6682790803 ②: Clause-②: yes (narrowing) — carried forward; ③ Boundary flagsNo new os-dev-report on the card since 6682318861; the two delta commits answer M1 and S5 of 6682790803 and raise no flag of their own. Everything else in 6682790803 ③ stands: S3 ( ④ Design judgmentThe narrowing itself is unchanged from Implemented-by: VERDICT: PASS |
|
domain:ui#2 · os-tesla · session_01L9qibw7DekEe3wx5f3zphf 席位核对 · ACCEPT · 2026-11-06T11:07Z · head
|
Requested by Tesla · project thread
domain:ui#2 · os-tesla · session_01L9qibyWSiXh6B2sMVHfXYC
Part of #30511. Every item the card asks for is in this PR; the seat closes the card when it lands, and phase 4 (the locale menu) follows.
Supersedes #30595 (the same reviewed diff, resumed from
claude/project-thread-xplvvb@9b15e9ad45on this thread's own branch, then merged withmainthrough #30640's lazymarketplacenamespace and #30601's shared locale ladder).Clause-②: yes (narrowing) — widens: a
zh-Hantpack (thezhHantexport of@object-ui/i18n/locales, the@object-ui/i18n/locales/zh-Hantmodule), theresolveBuiltInLanguageexport of@object-ui/i18n, and every stored or browser code the platform locale table reads as one of its tags (zh-TW,zh-HK,zh-MO→zh-Hant;zh,zh-CN,zh-SG→zh-Hans;pt→pt-BR). Narrows: the Simplified Chinese and Portuguese packs are keyedzh-Hansandpt-BR, no longerzhandpt, inbuiltInLocales,BUILT_IN_LANGUAGE_CODES,getLoadedBuiltInLocales()andgetAvailableLanguages(), and their modules@object-ui/i18n/locales/zhand@object-ui/i18n/locales/ptare@object-ui/i18n/locales/zh-Hansand@object-ui/i18n/locales/pt-BR.Metadata-protocol: none
Skills-docs: follow-up owed — skills/objectui/guides/i18n.md
维护者速读
zh→zh-Hans,pt→pt-BR),新增繁体中文zh-Hant,由简体包自动转换生成。刚合入的应用市场按需文案包同样按标签拆成 11 份,也有繁体。存值语言(sys_user.locale)挑选改用平台统一的匹配顺序,与服务端一致。zh-CN、zh、pt照常渲染;zh-TW、zh-HK用户从简体变为繁体。仓外代码若按builtInLocales.zh或@object-ui/i18n/locales/zh取包会断,changeset 写了改法。首屏英文包字节不变。回滚即 revert 本 PR。ui/packages/i18n/src/locales/registry.ts(按标签加载与resolveBuiltInLanguage)、ui/packages/i18n/src/namespaces/marketplace/index.ts(应用市场文案按标签加载)、ui/packages/i18n/scripts/zh-hant.mjs(繁体转换规则)。pnpm --dir ui exec vitest run packages/i18n/,预期全部通过;再把ui/packages/i18n/src/locales/index.ts里'zh-Hant': zhHant,一行删掉重跑all-locales-key-parity,预期转红并点名zh-Hant。CONTRACT_REVIEW_TIERPASS 在案(评论 6683373168,Head-shac1f166cc40e17e5a1c069137a6ffa32897da33fb;前一 head 的 FAIL 6682790803 已由 143ef31 修复)。批准后席位翻 ready、挂自动合并。c1f166cc的 diff 复核:152 个文件,语言包键随平台语言表改为标签(zh→zh-Hans、pt→pt-BR),新增由简体自动生成的zh-Hant,应用市场按需文案包同样按标签拆分;旧存值zh、zh-CN、pt经表的读别名照常解析,首屏英文包字节不变、上限未动。属收窄(BREAKING,patch,changeset 带 FROM → TO 与 ADR-0087 标记),独立复审员按CONTRACT_REVIEW_TIER先判 FAIL(lint 入口守卫),修复后 delta 复审 PASS;CI 57 项全绿。复审提出的后续已立卡:A Traditional Chinese console reads and writes the Simplified entry of an inline label map #30910(繁体会话读写内联标签取到简体键)、skills/objectui i18n guide still teaches the zh and pt pack keys that #30511 retires #30911(skills i18n 指南仍教zh/pt);服务端与 studio 命名空间缺繁体归 Platform locale table (ruling F of #29349): one list of 11 languages in spec, complete on every surface #29428。同意落地,待人批。What changes
The pack set comes from the platform locale table.
ui/packages/i18nno longer keeps its own list of ten languages. It readsPLATFORM_LOCALESfrom@objectstack/spec/system(phase 1, PR #30007).src/locales/zh.tsis nowzh-Hans.ts,pt.tsis nowpt-BR.ts, andzh-Hant.tsis new.builtInLocalesis keyed by table tag, in table order, andsatisfies Record<PlatformLocaleTag, unknown>. A tag the table gains without a pack, or a pack the table lacks, is a compile error.registry.ts.LAZY_LOCALE_LOADERSis typed by the table's tags, andBUILT_IN_LANGUAGE_CODESisPLATFORM_LOCALE_TAGS.resolveBuiltInLanguage(code)names the pack that a stored or browser code reads as. It tries the table's tag or read alias first (platformLocaleTagOf, case-insensitive), then each shorter prefix (zh-Hant-TW→zh-Hant,en-GB→en).loadBuiltInLocaleandisBuiltInLanguagego through it, so every legacy code still loads its pack.i18n.ts.fallbackLngis a map built from the table. Every tag falls back to the fallback language. Every read alias falls back to its tag, then to the fallback language. So an instance whose language is a legacyzhorzh-CNrenders thezh-Hansresource.provider.tsx. The boot effect andchangeLanguagenow write a built-in catalogue under its table tag, the bundlecreateI18nkeyed it by.zh,zh-TW,pt) got the resident catalogue written a second time under the alias. That fired anaddedevent, which re-rendered every reader and refetched every chart keyed on the resolver.ObjectChart.refreshIndicatorLocale-10580found it: its zh chart never left the skeleton.zh-Hant is generated.
scripts/zh-hant.mjsis the converter. It uses:s2twp, withopencc-jspinned at 1.3.1 as a devDependency;scripts/gen-zh-hant.mjswritessrc/locales/zh-Hant.tsfromzh-Hans.ts(pnpm --filter @object-ui/i18n gen:zh-hant). It refuses to write when a pinned conversion case fails. There are two additions over the site's rules, both pinned as conversion cases:STRADDLE_OVERRIDES: 并发布 → 並發布, 头发送 → 頭發送, 是只读 → 是只讀, 只影响 → 只影響.s2twpsegments by its Simplified phrase dictionary before it converts. A phrase that straddles a word boundary (审阅「并发」布) therefore cannot be repaired at the Traditional phrase stage. The fix puts the Simplified phrase into the segmentation dictionary and at the head of the first group.TWP_PHRASE_OVERRIDESgains 操作運行時 → 操作執行時.Other details of the generated pack:
console.ai.*outbound keys are left out of zh-Hant, as they are from every non-gate pack. Comments replace them so line numbers stay aligned with zh-Hans.src/__tests__/zh-hant-generated.test.tsreds when the committed pack is not byte-for-byte what the generator writes, and names the command that repairs it. It is a package test, not acheck:*gate (ruling F adds none).zh-Hant.tsasNOT_DRIVER_MANAGED(gengen:zh-hant). The pack is generated whole, but aREGEN_ARTIFACTSrow needs acheck:script, and this phase adds none.zh-hant.d.mtstwin joins the package'stsconfig.test.json, socheck:type-check-coveragereads it.ui/scripts/check-lint-rule-coverage.mjsdeclares the same twin inUNREACHED_GROUPS, beside the two script twins it already declares. Its tests now accept anobjectstack#card on a ledger row as well as anobjectui#one.The lazy
marketplacenamespace follows (#30640).src/namespaces/marketplace/zh.tsis nowzh-Hans.ts,pt.tsis nowpt-BR.ts, andzh-Hant.tsis new, generated by the same command.MARKETPLACE_LOADERSis typedRecord<PlatformLocaleTag, …>, eleven literal imports, so a table tag without a catalogue is a compile error.resolveMarketplaceLanguagereads a stored code throughresolveBuiltInLanguage, sozh-TWloads the Traditional catalogue andptthept-BRone. The loader stores the catalogue under the table tag.locales/index.ts) deep-merges each tag's catalogue into its pack, as main'scomplete()already did, and still throws on a leaf defined twice.generateZhHantNamespaceCatalogueand a frozenZH_HANT_TARGETSlist (the locales pack and the marketplace catalogue);gen:zh-hantwrites both, and the freshness test walks the list.apps/console/vite.config.tsnames onei18n-ns-marketplace-<tag>chunk per table tag.install.previewkeys came in through the renames and are inzh-Hans,pt-BRand the regeneratedzh-Hant.Readers keyed by the old codes.
app-shellreaders.LoadingScreen(the boot line),outboundAgentTextandflowResponseread the loaded-pack snapshot by table tag, throughresolveBuiltInLanguage.app-shellpickRenderableLocale(thesys_user.locale→ UI language pick) is nowresolveLocaleAmongfrom@objectstack/spec/system(fix(spec,core): resolve locales through the platform table's read aliases, so a zh-TW / zh-HK reader gets zh-Hant #30601), the ladder the server'sresolveLocaleuses, instead of a copy of it. A storedzh-TWmeets a list offering both scripts and renderszh-Hant; before, it took the firstzhvariant,zh-Hans. A variant the table reads as the language itself (es-ESfores) is taken ahead of the first offered variant, as the server takes it.componentspage tabs. The Traditional rows of the exact-locale label dictionary now serve azh-Hantsession, andzh-HK/zh-MOsessions too. Before, every non-exactzhfell to the Simplified rows.apps/console/vite.config.ts. One locale chunk per table tag.Gates read the table.
check-i18n-en-drift.mjstakes its locales fromPLATFORM_LOCALE_TAGSand merges each namespace's partial pack in (main'sPACK_NAMESPACE_DIRS), throwing on a key defined twice. A follower pack that the base commit does not have (this PR's renames andzh-Hant) reads as empty at the base and is named in the summary.enmissing at the base, or any pack missing at HEAD, still throws.check-i18n-dead-keys.mjsstrips map-chain tags by the table.check-eager-locale-catalogues.mjskeeps its deliberate explicit list, now the eleven tags. Its test pins that list to the table and to the registry's loader table.Paths. One doc link (
ui/packages/plugin-gantt/docs/verification/README.md, whichcheck-doc-linksreads) and one test comment namedzh.ts. Both now namezh-Hans.ts.Tests
Suites that read the table. The parity, region-fallback, entry-shape and en-drift suites read the table.
all-locales-key-paritywalksPLATFORM_LOCALE_TAGS, so a table language with no pack reds it by name.region-locale-fallback-11326covers both scripts:zh-CNandzh-SGread Simplified;zh-TW,zh-HKandzh-MOread Traditional.zh-hant-generated.test.ts(new) covers:provider-load-rerender-10382.test.tsx. An instance booted inzh,zh-CN,zh-TWorptreads its tag's resident catalogue, renders once, and keeps no bundle under the alias. A catalogue that lands after mount reaches azh-TWreader.i18n.test.ts. Main's CJK-Latin title spacing (Console and CLI polish from the real-user walkthrough #30126) is pinned for bothzh-Hansandzh-Hantbooted by tag.check-i18n-en-drift.test.ts. Fixtures write a const namedpack, because a tag is not an identifier. A new describe pins the base-absent follower rule, its CLI line, and the two cases that still throw.git-paths-nested-layout.test.ts. It pinned that any pack missing at the base throws. Under the follower rule onlyendoes, so the case now pins both halves:enmissing at the base throws, and a follower the base lacks reads as empty and is named.userLocale-10059.test.tsx. A new describe pins the table step:zh-TW,zh-HK,zh-MOandzh-Hant-TW→zh-Hant;zh,zh-CNandzh-SG→zh-Hans;pt→pt-BR;The pin "first offered variant" moved from
zhtoes(esoveren,es-MX,es-AR→es-MX), because the table reads a barezhas Simplified. A new case pins the shared ladder's table step:esoveren,es-MX,es-ES→es-ES.Marketplace namespace suites (
marketplace-namespace,marketplace-namespace-lazy,MarketplacePage.namespaceGate-30588) are keyed by tag, and pinzh-TW/zh-HK→zh-Hantandpt→pt-BRresolution plus azh-TWreader's lazy load.zh-hant-generatedruns each case overZH_HANT_TARGETS, with a counter-probe on the list itself.page-tabs-builtin-label-i18n-4645.test.tsx.zh-Hant,zh-HKandzh-MOsessions read 詳情 / 備註 / 概覽, and two of those are dict-only tokens. Thezh-Hans/zh-SGcontrol reads Simplified.LocaleSwitcher suites (
appLocales,persistence,unsavedEditsAsk-13254). They pick and expect the menu's names for the table's tags throughlocaleLabel, and the fallback-menu cases expect one entry per tag. The component itself is not edited.About 100 other suites hard-coded ten packs, a
zh/ptkey or a'zh'lookup. They now read the table or the tag. For example,toHaveLength(10)becamePLATFORM_LOCALE_TAGS.length, and where a table names every pack, a convertedzh-Hanttwin sits beside each retaggedzh-Hansrow.Readings (head
f7e9df2d, base98f640d5)Ablations, suites, type-check and gates
The heavy runs were taken on
e94c13c8.f7e9df2dadds one merge of main (11 commits) and the regeneratedzh-Hant; the i18n package, the en-drift test, the 32 test files those 11 commits added or changed, the i18n checks and the ADR-0087 and no-major checks were rerun on it.zh-Hans,zh-Hantandpt-BRand the Console had no pack keyed by any of them, yetall-locales-key-parityandregion-locale-fallback-11326were green (2 files, 58 tests; taken for feat(i18n)!: the Console's language packs follow the platform locale table, keyed by its tags, and Traditional Chinese (zh-Hant) ships #30595).git diff HEADempty.zh-Hantentry removed frombuiltInLocales→all-locales-key-parity3 failed / 42 passed, and the diff nameszh-Hant(taken for feat(i18n)!: the Console's language packs follow the platform locale table, keyed by its tags, and Traditional Chinese (zh-Hant) ships #30595).zh-Hansvalue edited without regenerating →zh-hant-generatedred, naming the command that repairs it (taken for feat(i18n)!: the Console's language packs follow the platform locale table, keyed by its tags, and Traditional Chinese (zh-Hant) ships #30595; the test now walks both targets).zh-Hantloader removed from the marketplace namespace →tscTS2741 ("zh-Hant"missing from theRecord<PlatformLocaleTag, …>), andmarketplace-namespace+marketplace-namespace-lazy6 failed / 64 passed, including "a Traditional Chinese reader (a stored zh-TW) gets the zh-Hant catalogue". Restored: green.pnpm --dir ui run test) ond0632482: 6631 files passed, 7 skipped; 21 files red. 19 of them read builtdist/.d.tsoutput that the skip-dts build had not written; the other 2 named the oldbuiltInLocales.zhkey and were fixed ind0632482. After the full workspace build, the 21 files rerun: 21 / 21, 513 tests.packages/i18n/,scripts/,packages/app-shell/src/hooks/and the 36 test files main had added since the first merge, one94c13c8: 401 files passed, 2 skipped; 7830 tests.f7e9df2d:packages/i18n/, the en-drift test and the 32 test files of the last merge: 131 files, 2014 tests, green.e94c13c8, after the full workspace build:pnpm --filter @objectstack/dogfood test: 424 files passed, 3 skipped; 3538 tests.turbo run build --filter='!@objectstack/docs'): 118 / 118. It caught one gap that the skip-dts runs had not:loadMarketplaceCatalogueindexed the tag-typed loader table with astring.e94c13c8makeshasMarketplaceCataloguea type guard.turbo run type-check --filter='...[origin/main]': 101 / 101. uitype-check:coverage,:e2e,:scripts,:vitest-setupand:vitest-config: exit 0.e94c13c8.dispatch-gates --ranreads 76 derived, 76 run, 0 NOT-MEASURED, 0 UNRUN.check:eager-closure,check:eager-locale-catalogues,check:i18n-keys,check:i18n-drift,check:i18n-dead-keys,check:spec-symbols,check:phantom-deps,check:unreferenced-sources,check:sdui-registration-pinsandnode scripts/check-sdui-manifest.mjs: exit 0.i18n-locale-enchunk holds the single moduleen.ts, whose source is identical to main's; 57,625 gz bytes. No size ceiling is raised.zh-Hantis 62,336 gz bytes, and the marketplacezh-Hantcatalogue 4,560, both loaded on demand.check-adr-0087-registration --base origin/mainandcheck-changeset-no-major --base origin/main: exit 0 onf7e9df2d, the latter also with this body as--event(level axisyes (narrowing)+none, every entry atpatch).Acceptance notes
Native read of zh-Hant. The conversion follows the site's rules, but a Traditional reader should still skim the pack. Renderings worth a look:
A rule change goes in
scripts/zh-hant.mjsand in the site's converter, never in a hand edit of the pack.Studio. The Studio namespace still ships
enandzh. Azh-Hantorzh-TWreader sees Studio's Simplified catalogue (ruling app-shell: a published library that is 66% Console product surface — retire the 67 zero-reference exports now, decide the split, and fold the second i18n table into @object-ui/i18n #25922's namespace, untouched here).The language menu (phase 4).
LocaleSwitcheris not edited. Its hand-kept names are keyedzhandpt, soIntl.DisplayNamesnames the three tags they no longer match: 简体中文, 繁體中文 and Português (Brasil). The menu gains 繁體中文 as an eleventh entry.Inline locale maps.
pickLocalizedis unchanged. Take a metadata label written{ 'zh-CN': …, 'zh-TW': … }: azh-Hantreader takes the firstzh-key. Azh-TW-browser reader did the same before this PR, because that browser's language then resolved tozh. TeachingpickLocalizedthe table is a follow-up candidate, not done here.One ladder. The Console's
sys_user.localepick and the server'sresolveLocalenow shareresolveLocaleAmong, so the stored-locale ladder has one copy. The server's catalogues are its own and are not touched here.ADR-0087. The changeset holds
not-required (no-migration-prescription), and its marker names why../localessubpath, which is the classruntime-export-retiredserves.Studio keys. fix(app-shell): word the flow closure refusal on the Problems list in the Console's language #30721's studio keys came in with the merge unchanged; Studio stays
en+zh, so nothing in it is retagged.Unchanged on purpose. The root
ci.ymlstep is still named "followed by the nine translations", because the workflow is not edited. The eager-locale gate keeps its explicit list, now pinned to the table by its test.Verification
Two minutes, from
ui/:pnpm exec vitest run packages/i18n/: everything passes.'zh-Hant': zhHant,line frompackages/i18n/src/locales/index.tsand runpnpm exec vitest run packages/i18n/src/__tests__/all-locales-key-parity.test.ts: red, namingzh-Hant.pnpm --filter @object-ui/i18n gen:zh-hant: writes the same twozh-Hant.tsfiles (the pack and the marketplace catalogue) that are committed, sogit diffstays empty.A sample of the generated pack, with Taiwan vocabulary from
s2twp:zh-Hans.tszh-Hant.tsstop: '结束模拟登录'stop: '結束模擬登入'manage_users: '管理用户'manage_users: '管理使用者'manage_metadata: '管理元数据'manage_metadata: '管理中繼資料'manage_platform_settings: '管理平台设置'manage_platform_settings: '管理平台設定'manage_connector_connections: '管理连接器连接'manage_connector_connections: '管理聯結器連線'save: '保存'save: '儲存'