Repository navigation
Commit f708cf2
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8PeP4DzppH3b1kDPCjihHVx)_
Part of #25922
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:app-shell 设计器私有表里除 `engine.translationPreview.*`
之外的全部剩余行(流程设计器各族、页面区块画布、文档与书预览、`engine.studio.inspector` 及其余 Studio
界面文案,共 44 族,en 538 键、zh 583 键),搬进 `@object-ui/i18n` 的 `studio`
命名空间,文案一字未改,调用点不动;`engine.flowNode.*`、`engine.enum.*` 两族照旧仅 zh。
- 为什么改:执行 #25922 裁决 6431032267(Q2 = A,6431234244 维持),这是 (M) 的第 6
片(S6),派单 6457069488;之后表里只剩 22 行 translationPreview,S7 再删表。
- 风险与回滚:与前几片相同,zh 用户首次打开这些页面时标签先显示英文、zh 分片到达后同一挂载重渲染为中文;回滚即 revert 本 PR。
- 先看:`ui/packages/i18n/src/namespaces/studio/zh.ts` 末尾的 S6 段(含仅 zh
两族的说明),再看钉测试新增的 44 个家族下限与三个仅 zh 断言。
- 两分钟验证:`cd ui && pnpm run check:i18n-designer-parity && pnpm exec
vitest run
packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts`,应全绿。
- 需要你做的:无,席位落地。
## What changes
- **Slice S6 of the (M) item.** Every row left in `ENGINE_STRINGS_EN` /
`ENGINE_STRINGS_ZH` in
`ui/packages/app-shell/src/views/metadata-admin/i18n.ts`, except
`engine.translationPreview.*`, is appended to `STUDIO_EN` / `STUDIO_ZH`
in `ui/packages/i18n/src/namespaces/studio/{en,zh}.ts`, text
byte-for-byte unchanged. These are the 44 families, by keys per
language:
| group | families (`en` = `zh` unless noted) | `en` | `zh` |
|---|---|---|---|
| the flow designer | `flowSim` 64, `flowCanvas` 21, `flowRuns` 19,
`flowPreview` 17, `flowScope` 17, `flowValidate` 16, `flowProblems` 9,
`flowPalette` 8, `flowExpr` 6, `flowRef` 5, `flowRegion` 4, `flowNode`
(zh-only, 41), `enum` (zh-only, 4) | 186 | 231 |
| canvases and previews | `pageBlockCanvas` 59, `docPreview` 26,
`bookPreview` 22, `layers` 16, `widgetPicker` 16 | 139 | 139 |
| the Studio inspector | `studio.inspector` 35 | 35 | 35 |
| the rest of the Studio chrome | `list` 36, `catalog` 25, `sharingRule`
16, `diagnostics` 16, `directory` 14, `draftConflict` 10, `validation`
10, `position` 9, `appNav` 8, `embedded` 7, `quickfind` 5, `badge` 3,
`fieldsListEditor` 3, `typeAction` 2, `celTest` 2, `sourcePageEditor` 2,
`condition` 2, and one key each: `celLint`, `package`, `breadcrumb`,
`repeater`, `viewColumnPanes`, `home`, `engine.cancel`, `engine.close` |
178 | 178 |
| **total** | | **538** | **583** |
Every family is moved; none is left for S7.
`engine.translationPreview.*` stays (22 rows in each language) because
#26831 is still open. After this PR, those 22 rows are all the table
holds. #26920 is still open too, so its two `engine.studio.notFound.*`
rows are not in this PR. Whichever of #26920 and this PR lands second
resolves the conflict.
- **zh-only rows stay zh-only.** `engine.flowNode.*` (41) and
`engine.enum.*` (4) have no `en` entry, before and after:
- The flow node labels and hints fall back to the engine descriptor's
own name for English.
- `translateEnumOption` returns the raw value for any non-zh locale.
`check:i18n-designer-parity` already lists both in `ZH_ONLY_FAMILIES`,
and the zh heading comment says why.
- **One anchor kept in place (forced edit).** `ZH_ONLY_FAMILIES` cites
the anchor `resolved by translateNodeLabel/Hint` in `i18n.ts`. That text
lived in the `engine.flowNode.*` rows' comment, which moved with the
rows, so the gate's own test
(`check-i18n-designer-table-parity.test.ts`, "every citation resolves")
went red. The gate stays untouched, as the order requires. Instead,
`translateNodeLabel`'s doc comment now says that the rows are resolved
by translateNodeLabel/Hint through `lookupString` from the namespace.
That makes the cited text occur once again in `i18n.ts`.
- The S2–S5 AST pass, with a heading comment marking the S6 section in
each catalogue. Two comment groups were mixed: their first row moved, so
the comment moved, and the `engine.translationPreview.*` rows after it
stayed.
- **No runtime change.** `lookupString` already asks the table first and
the namespace second, so `t` / `tFormat` / `tOptional`,
`translateNodeLabel` / `translateNodeHint` / `translateEnumOption` and
every call site are untouched. The table object, `t()` / `tOptional()`,
`TYPE_LABELS` / `DOMAIN_LABELS`, `FLOW_FIELD_ZH` and
`check:i18n-designer-parity` are left as they are for S7.
- **Readers.** Every non-test reader of a moved family is under
app-shell's `views/metadata-admin/` or `views/studio-design/`. None
calls `t()` at module scope. The dynamic keys
(`engine.flowNode.${type}.label|hint`, `engine.enum.${field}.${value}`)
go through `lookupString`. Nothing to stop and report.
- **Main merged twice** (`5fbed2b9`, `b94ef650`). The first merge picked
up #26967, which added nine `engine.widgetPicker.type.*` rows to the
namespace. That PR's comment said the family's other rows "still sit in
the app-shell designer table (objectstack#25922 moves them)". This PR
moves them, so the comment now points at the S6 section. Text and key
set are otherwise unchanged.
- Before the move, I read the patches of every open PR that touched
either home (#26831, #26920, #26967, #26977, #26982, #26987). None
touches a moved key. #26967, #26977 and #26987 have since merged and
arrived through the main merges.
- **Changeset:** `.changeset/25922-studio-i18n-flow-and-chrome.md`,
`@object-ui/i18n` patch.
- ⛔ Untouched: `ui/packages/i18n/src/locales/*.ts`, `ui/.github/**`,
root `ci.yml`, `engine.translationPreview.*`,
`ui/scripts/check-i18n-designer-table-parity.mjs`.
## Why
Ruling 6431032267 Q2 = A (upheld by 6431234244): the designer table
becomes one lazy `@object-ui/i18n` namespace, moved in slices.
## Tests
- **Pin widened:**
`inspectors/inspectorStrings.studioNamespace-25922.test.ts` gains a
floor for each of the 44 S6 families (86 families in all). Every key in
each family must resolve through `t()` to the namespace value in
`en-US`, `zh-CN` and `de-DE`. The zh-only case now covers three families
(`engine.packages.form.help.`, `engine.flowNode.`, `engine.enum.`). For
each, the rows are absent from `en`, `tOptional` in `zh-CN` returns the
`zh` value, and `tOptional` in `en-US` stays `undefined`.
- **zh preloads (forced edits).** Each suite below reads a moved S6 zh
row synchronously, so it now loads the `zh` catalogue first with a
top-level `await loadStudioCatalogue('zh')`. No assertion changed.
- 9 dom suites:
- in `metadata-admin/`: `CelPredicateField.i18n-10862-s2`
- in `metadata-admin/inspectors/`:
`FlowNodeInspector.nodeTypeOptions-11778`
- in `metadata-admin/previews/`: `AppNavCanvas.labelMaps-11128`,
`AppNavCanvas.untitledCard-11862`, `DocPreview`,
`FlowPreview.headerPills-11779`, `NodePalette`, `flowNodeLabels-13200`
- in `studio-design/`: `ObjectListViewInspector.displayTitle-13151`
- 3 unit suites: `metadata-admin/flowNodePaletteI18n.test.ts`,
`previews/FlowRunsPanel.test.ts` and
`previews/flow-problems.repeatedEdge-11772.test.ts`. All three are in
the `unit` project (`isolate: false`). Each passed in the full run only
because an earlier file had already loaded `zh`, and failed when run
alone.
### The sweep
I delayed the `zh` loader in `namespaces/studio/index.ts` by 4000 ms
(`scripts/ablation-replace.mjs --hold`, restored byte-identical). Under
that delay I ran every app-shell test that names zh or a moved key, plus
the i18n namespace and script tests (458 files). Then I ran each of the
50 unit-project files alone.
- **Before the fixes:** 11 files failed in the full run and 3 failed
when run alone.
- `i18n/src/__tests__/studio-namespace-lazy.test.tsx` fails by
construction under the delay, because its `findByText` waits 1 s against
a 4 s delay.
- `scripts/__tests__/check-i18n-designer-table-parity.test.ts` failed
because of the moved citation anchor described above, not because of the
delay.
- The other 12 are the suites listed above.
- **All 12 come from S6 itself.** I checked out main's three homes and
main's versions of the 12 test files and ran them under the same delay.
All 12 pass on main, so this sweep found no leftover from S1–S5.
- **After the fixes:** the 12 suites, the pin, the parity test and the
equivalence check pass at normal speed (`Tests 305 passed (305)`). The
dom suites and those three pass under the delay too (`Tests 271 passed
(271)`). The three unit suites pass alone, both delayed and at normal
speed.
- **After the merge:** after each of the two main merges, I ran under
the delay every test file those merges added or changed in ui (6 after
the first merge, 21 after the second), together with the pin, the parity
test, both `block-config-i18n` tests and the equivalence check. Last
run: `Tests 501 passed (501)`. The equivalence check still reports 4,235
lookups, 0 differing.
## Acceptance notes
- **With the table nearly empty, every lookup resolves as before.** This
was a one-off measurement and is not committed. I read all 560 `en` and
605 `zh` rows of the base table at `49b50591` by AST, which includes the
22 + 22 `engine.translationPreview.*` rows that stay. I compared each
with `t()` and `tOptional()` on this branch, with `zh` resident:
- the base `en` value in `en-US`, `en`, `de-DE` and `fr`;
- the base `zh` value in `zh-CN`, `zh` and `zh-TW`;
- for the 45 zh-only rows, in `en-US` and `de-DE`, `t()` must echo the
key and `tOptional()` must return `undefined`;
- `translateNodeLabel` / `translateNodeHint` for every
`engine.flowNode.*` row (the `zh` value in `zh-CN`, the caller's
fallback in `en-US`), and `translateEnumOption` for every
`engine.enum.*` row (the `zh` value in `zh-CN`, the raw value in
`en-US`).
Result: 4,235 lookups, 0 differing.
- **Ablations** (mutation landed by anchor count and blob, restored
byte-identical to `HEAD`):
- Removing the `?? studioString(key, locale)` arm from `lookupString`
turns 90 tests red: the pin's `t()` case for all 86 families, its three
zh-only cases, and the equivalence check. The equivalence check reports
3,946 of 4,235 lookups differing. The 289 that hold are the 154
`engine.translationPreview.*` lookups the table still serves, plus the
135 `en`-side zh-only lookups, whose expected answer is "not found" or
the fallback either way.
- Altering one moved zh row (`engine.flowNode.start.label`) makes the
equivalence check report exactly 4 differing lookups (`zh-CN`, `zh`,
`zh-TW` and `translateNodeLabel` in `zh-CN`). The pin stays green, as
designed.
- **Eager bundle:** not re-measured locally, as in S2–S5. CI's `Build &
E2E UI` measures it.
## Verification
At `b94ef650` (the second main merge).
<details><summary>Tests and gates</summary>
- `pnpm --filter @object-ui/i18n --filter @object-ui/app-shell run
type-check`: VERDICT command-exit 0.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: 34 commands, each exit 0, including `pnpm
--dir ui exec vitest run scripts/` (`Test Files 176 passed | 2 skipped
(178)`). `--ran`: 34 derived, 34 run, 0 NOT-MEASURED. I also ran the
same 34 after the first merge, all exit 0, and re-derived after the
second merge: the same 34 commands.
- ui `check:i18n-designer-parity`, `check:i18n-dead-keys`,
`check:i18n-drift` (0 `en` values changed) and `check:i18n-keys` all
exit 0, before and after each merge. `check:new-line-citations`: exit 0
(0 new citations). `node scripts/check-nul-bytes.mjs`: exit 0.
- Changed lines: 2,816 (+1,473 / −1,343) over 17 files, under the 3,000
threshold.
</details>
## Human Minimum
- [x] 1. No `packages/spec` change.
- [x] 2. No new names; the only new file is the changeset.
- [x] 3. No formatter ran; `pnpm lint` is CI's.
- [x] 4. One card slice, one branch off `main`, one pull request.
- [x] 5. Patch changeset with both declaration lines.
- [x] 6. n/a.
- [x] 7. No hand edits to generated or release-owned files.
- [x] 8. English.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbX9LnJhjTQPJEmoBYi)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3230bdb commit f708cf2
17 files changed
Lines changed: 1473 additions & 1343 deletions
File tree
- .changeset
- ui/packages
- app-shell/src/views
- metadata-admin
- inspectors
- previews
- studio-design
- i18n/src/namespaces/studio
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
39 | 44 | | |
40 | 45 | | |
41 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
22 | 29 | | |
23 | 30 | | |
24 | 31 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
27 | 32 | | |
28 | 33 | | |
29 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
78 | 79 | | |
79 | 80 | | |
80 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
81 | 127 | | |
82 | 128 | | |
83 | 129 | | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
88 | 136 | | |
89 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
90 | 142 | | |
91 | 143 | | |
92 | 144 | | |
| |||
110 | 162 | | |
111 | 163 | | |
112 | 164 | | |
113 | | - | |
114 | | - | |
115 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
116 | 168 | | |
117 | 169 | | |
118 | 170 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
35 | 40 | | |
36 | 41 | | |
37 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
33 | 38 | | |
34 | 39 | | |
35 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
42 | 47 | | |
43 | 48 | | |
44 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
35 | 40 | | |
36 | 41 | | |
37 | 42 | | |
| |||
0 commit comments