Repository navigation
按平台正式写法补 zh-CN 翻译包(os i18n extract 生成),消除中文界面下的英文对象名与列头 #24
Description
Activity
认领(调度员占坑,2026-09-03)
- 会话:
local_0e65d2bc-719b-4314-aae2-351176a17e5f(派发 | 软件公司岗位KPI数据集+全流程实测 | 0903,同批第 2 项) - 分支:
issue-24-i18n-zh-bundle,基线 main @4a02994d837bcc4641555520a4da0a95f1cc8bed - 环境分配:worktree
../kpi-issue-24-i18n-zh-bundle,dev 端口3112,数据库file:./.objectstack/issue-24.db - 执行方式:按 os-project-pm-dispatch 派发独立开发子 agent(Opus);调度员只做收单核实与评审闸门,不写代码。
- 会话:
需求理解与实现方式(#24 开工确认)
会话:开发子 agent(Claude Code),分支
issue-24-i18n-zh-bundle,worktree 独立实例(端口 3112 / 库.objectstack/issue-24.db),基线 main @ 4a02994。需求理解
界面英文的根因不是「翻译写错」,而是缺 zh-CN 翻译包:元数据 label 本身是中文,但仓库只注册了
en包;平台运行时按「zh-CN 包 → en 包 → 元数据原文」查标签,zh-CN 包不存在 → 凡 en 包覆盖到的键一律落到英文。本单按平台文档的正式写法整改:每个支持语言各带一个翻译包,默认语言(zh-CN)的包由os i18n extract从元数据标签生成,不手写词条、不改 label 文案、不改 en 包。实现方式(方案分级:低风险)
项 内容 改动面 新增 src/translations/zh-CN.*.generated.ts(工具产出)+ 改src/translations/index.ts注册 +package.json加脚本/门禁 +CLAUDE.md改指定一句路径 唯一——平台文档 objectstack-i18n 的标准做法,无自研机制 是否改已有逻辑 否;不动对象/视图/hook/lib,不改任何 label 文案,不动 en 包 回滚 删生成文件 + 还原 index.ts 即回到现状 分级结论:低风险(纯新增 + 注册,路径唯一),可直接开工。
一处需要说明的偏差(已按验收标准取值,提请复核)
正文「范围 §1」给出的命令是
os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations;该命令的--objects-only是平台默认开启的,只产出objects/globalActions子树,不含apps/dashboards/pages/flows。而「验收标准 §1」明确要求/api/v1/meta/app/kpi_app返回「KPI 考核管理」——app 标签正是被en包(apps.kpi_app.label = 'KPI Assessment')覆盖的键,不含apps的 zh-CN 包救不回来。因此实际执行命令加
--no-objects-only(平台文档 objectstack-i18n「Extract Skeletons from Metadata」对此有明确警示:默认 objects-only 会让 app/navigation/dashboard/page/flow 键漏掉、而os i18n check仍要求它们)。仍然是纯工具产出、零手改词条,只是覆盖面按验收标准取全。若 PM 认为应严格照正文命令执行(接受 app 名保持英文),请在本单回复,我改回并把验收 §1 的 app 断言标为未实现。测试计划(按正文草稿执行)
T1 diff 面核对 · T2 zh-CN API 标签断言 · T3 en API 对照断言 · T4 UI 四页面前后截图对比(≥4 张) · T5
pnpm verify+os i18n check+extract --check新鲜度门禁。需求符合度清单(#24,提 PR 前门禁)
分支
issue-24-i18n-zh-bundle@312cb7a。逐条对照工作项正文,三态标注,无「基本实现 / 大致完成」类含糊词。范围
# 需求条目(正文原文) 态 说明 范围1 用 os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations生成 zh-CN 包,落在src/translations/,文件名保留工具默认⚠️ 有偏差见下「偏差 1」。实际命令为 objectstack i18n extract --locales=zh-CN --no-metadata-forms --no-objects-only --filter=kpi_ --out=src/translations;文件名保留工具默认zh-CN.objects.generated.ts,529 词条,全部由元数据中文 label 自动填充,零人工翻译、零手改范围2 在 src/translations/index.ts注册'zh-CN'包;en包原样保留✅ 完整实现 KpiTranslationBundle首项加'zh-CN': zhCNTranslations;en 包对象内容一字未改(diff 仅新增 import + 注册行 + 注释块)范围3 CLAUDE.md翻译包那一句改为正式写法,只改这一句✅ 完整实现 只动了「用户可见文案默认中文…」这一条,改为「label 直接写中文; zh-CN包由os i18n extract生成、随元数据改动重新生成、禁止手改词条;en包手工维护英文回退」。std-copy 四条红线原文保留范围4 package.json增加i18n:extract;verify中加入extract --check;若--check不可用则如实记录✅ 完整实现 --check在本仓库可用。新增i18n:extract(生成)与i18n:extract:check(新鲜度门禁),verify改为validate && typecheck && test && i18n:extract:check不做(负向核对)
条目 态 证据 不改任何对象/字段 label 文案 ✅ diff 未触及 src/objects/不改 en 包内容 ✅ index.ts内 en 对象字面量逐字节未变不动 src/data/、scripts/、README、docs/✅ 全量改动仅 4 个文件: CLAUDE.md、package.json、src/translations/index.ts、src/translations/zh-CN.objects.generated.ts(新增)不修改平台包 ✅ 未触碰 node_modules验收标准
# 验收标准 态 证据 验收1 Accept-Language: zh-CN下kpi_entry_sheet的label=填报单、fields.name=填报单名称、fields.status=状态、fields.total_score=最终得分;kpi_app=KPI 考核管理✅ 完整实现 五项逐字命中,测试报告 T2 验收2 Accept-Language: en仍返回 Entry Sheet / Sheet / Status / Final Score✅ 完整实现 四项逐字命中,测试报告 T3;UI 对照图 13 验收3 中文浏览器下方案版本列表、填报单列表与详情、指标库详情的对象名/列头/相关列表标题全部中文;填报明细相关列表不再「指标 / Indicator」并存(应为「指标 / 指标名称」);截图前后对比 ≥ 4 张 ✅ 完整实现 6 组前后对比 + 1 张英文对照,共 13 张,测试报告 T4 验收4 pnpm verify绿;os i18n check默认语言零错误;新增的新鲜度门禁通过✅ 完整实现 测试报告 T5;zh-CN 覆盖率 100.0%(1290/1290,missing 0) 验收5 生成文件只由工具产出,PR 中不得手改词条;评审能用 extract --check或重跑生成对账✅ 完整实现 pnpm i18n:extract:check报 in sync;负向测试:人为改脏一个词条后门禁报out of date并以退出码 1 失败⚠️ 偏差 1(唯一一处):生成命令多了--no-objects-only --filter=kpi_差异是什么:正文范围 §1 的命令未带这两个开关,实际执行带了。
为什么:
--objects-only是平台默认开启的,只产出objects/globalActions子树,不含apps。而验收标准 §1 明确要求/api/v1/meta/app/kpi_app返回「KPI 考核管理」——应用名正是被 en 包(apps.kpi_app.label = 'KPI Assessment')覆盖的键,不含apps的 zh-CN 包救不回来。范围 §1 的字面命令与验收 §1 互相矛盾,本单按验收标准取值。 平台文档(objectstack-i18n)对此有明确警示:默认 objects-only 会漏掉 app/navigation/dashboard/page/flow 键。- 加上
--no-objects-only后发现:即便同时传--no-metadata-forms,工具仍把平台 Studio 的metadataForms基线(761 个词条,内容是英文)内联进同一个文件。把这份英文基线挂在本应用的 zh-CN 包里分发,会让 Studio 元数据表单在中文下变英文,且这份基线按平台文档「属于一个包,不属于每个插件」。--filter=kpi_把范围收在本应用自有的 objects/apps/dashboards/pages 上。 --filter=kpi_不造成任何内容损失:带与不带 filter 的两份产物做过逐行 diff,差异有且仅有metadataForms整块(1660 行),objects / apps / dashboards / pages 四段逐字节相同。
仍然守住的红线:词条 100% 工具产出、零手改;命令原样写进
package.json的i18n:extract,评审重跑即可对账;新鲜度门禁用的是同一条命令加--check。若 PM 认为应严格照正文字面命令执行(接受应用名保持英文、且接受把平台英文基线打进包里),请回复,我改回并把验收 §1 的 app 断言改标 ❌。
三出口条款
无 ❌ 条目;唯一
⚠️ 条目为实现口径与正文字面命令的取舍,已在上方完整披露差异与理由,并给出改回选项,不属于静默降级。未使用「退回细化 / 挂起 / 失败升级」三出口。测试报告 — #24 zh-CN 翻译包(开发自测)
项 值 工作项 #24 分支 / 提交 issue-24-i18n-zh-bundle@312cb7a基线 main @ 4a02994测试环境 worktree kpi-issue-24-i18n-zh-bundle,OS_PORT=3112,OS_DATABASE_URL=file:./.objectstack/issue-24.db,改动后rm -rf dist重启账号 admin@objectos.ai / admin123 数据 演示种子 + node scripts/e2e-flow.mjs建链(73 PASS / 0 FAIL),提供填报单与填报明细执行档位 同会话自测(项目启用清单 H2:暂不具备双实例条件)。为对抗确认偏误,「前」态在改代码之前、同一实例上先行采集并落盘,「后」态复用同一库同一记录 ID,前后可逐图对位 证据 孤儿分支 acceptance-evidence@8c584f20de742d6d6c35c5cb8b6be53aa38168d9,目录issue-24/说明:
acceptance-evidence分支此前在远端不存在(派发说明称已存在),本次按项目约定 E2 新建为孤儿分支。
T1 改动面 diff 核对 — ✅ 通过
git show --stat 312cb7a全量改动 4 个文件,与工作项范围完全一致,零越界:CLAUDE.md | 4 +- package.json | 4 +- src/translations/index.ts | 9 +- src/translations/zh-CN.objects.generated.ts | 1364 +++++++++++++++++ (新增)未触及禁触碰面:
src/data/、scripts/、README.md、docs/、src/objects/、src/views/、src/hooks/、src/lib/、node_modules。CLAUDE.md只改了指定的那一句。
T2 API zh-CN 标签断言(验收 1)— ✅ 通过
Accept-Language: zh-CN,管理员会话:断言对象 期望 实测 结论 kpi_entry_sheet.label填报单 填报单 ✅ kpi_entry_sheet.fields.name填报单名称 填报单名称 ✅ kpi_entry_sheet.fields.status状态 状态 ✅ kpi_entry_sheet.fields.total_score最终得分 最终得分 ✅ kpi_app.labelKPI 考核管理 KPI 考核管理 ✅ 顺带核到(验收 3 的 API 侧佐证):
kpi_entry_line.label= 填报明细、fields.indicator= 指标、fields.indicator_name= 指标名称(改前为Indicator);kpi_plan= 考核方案 / 方案名称 / 考核周期类型 / 状态;kpi_indicator= 考核指标 / 指标编码 / 指标名称 / 指标类别 / 计分方式。改前同一断言的实测(反证根因):zh-CN 请求返回
Entry Sheet/Sheet/Status/Final Score/KPI Assessment,即 zh-CN 包缺失时全部落到 en 包。
T3 API en 对照断言(验收 2)— ✅ 通过
Accept-Language: en,同一实例、同一时刻:断言 期望 实测 结论 kpi_entry_sheet.labelEntry Sheet Entry Sheet ✅ kpi_entry_sheet.fields.nameSheet Sheet ✅ kpi_entry_sheet.fields.statusStatus Status ✅ kpi_entry_sheet.fields.total_scoreFinal Score Final Score ✅ kpi_app.labelKPI Assessment KPI Assessment ✅ en 包不受影响,与改前逐字相同。
T4 UI 前后对比截图(验收 3)— ✅ 通过
中文浏览器(
Accept-Language: zh-CN,locale: zh-CN),1500×950 @2x,登录后逐页采集。前后同一记录 ID、同一路由。# 页面 前(英文) 后(中文) 1 方案版本列表 01 面包屑 KPI Assessment / Assessment Plan,标题 Assessment Plan02 KPI 考核管理 / 考核方案,列头 方案名称 / 考核周期类型 / 考核年度 / 状态 全中文2 填报单列表 03 标题 Entry Sheet04 标题「填报单」,列头全中文 3 填报单详情 05 对象名 Entry Sheet,字段标题SUBJECT/STATUS/FINAL SCORE06 对象名「填报单」,字段标题「考核方案 / 主体类型 / 状态 / 最终得分」 4 填报明细相关列表 07 相关列表标题 Entry Line;两列并存「指标」与「Indicator」;下方Assessment Result08 标题「填报明细」;两列为「指标」与「指标名称」——验收 3 的点名项命中;下方「考核结果」 5 指标库详情 09 面包屑 Indicator,字段标题DEPARTMENT SEGMENT/SCORING METHOD/STATUS,指标编码/类别无标题10 面包屑「考核指标」,「部门板块 / 计分方式 / 状态 / 指标编码 / 指标类别」全中文 6 控制台首页 11 我的应用 KPI Assessment12 「KPI 考核管理」 7 英文对照 — 13 Accept-Language: en下仍为Entry Sheet/Sheet/Plan/Subject/Status/KPI Assessment,en 包未受影响前后对比 6 组(要求 ≥ 4 张,实交 12 张)+ 对照 1 张 = 13 张。
T5 门禁(验收 4、5)— ✅ 通过
pnpm verify全绿(四段):段 结果 objectstack validate通过(元数据无错) tsc --noEmit通过 vitest run6 个测试文件 / 90 个用例全通过 i18n:extract:check(新增)✓ 1 bundle(s) are in sync with the schemaos i18n check:zh-CN ████████████████████████ 100.0% (1290/1290, missing 0) ⚠ Non-default locales have gaps but the default locale is fully covered.默认语言 zh-CN 零错误、零缺失。en 的 1252 条 warning 为改动前即存在的历史状态(en 包本就只手工覆盖 6 个对象的部分字段),本单「不改 en 包内容」,未新增也未消除。
新鲜度门禁负向测试(证明门禁不是摆设):人为把生成文件里一个词条改脏 →
pnpm i18n:extract:check报✗ out of date: src/translations/zh-CN.objects.generated.ts ✗ Translation bundles have drifted from the schema. Regenerate and commit ELIFECYCLE Command failed with exit code 1还原后重跑即恢复
in sync。门禁能挡住手改词条与元数据漂移两种情况。
自测结论
通过。 5 条验收标准全部命中,4 条范围项 3 ✅ 1
⚠️ (⚠️ 为生成命令口径的公开取舍,已在需求符合度清单完整披露并给出改回选项,非静默降级)。未发现回归:en 包输出逐字未变,pnpm verify与 e2e 链路(73 PASS / 0 FAIL)均绿。遗留问题(不在本单范围,记录备查)
- en 包覆盖不全:
os i18n check报 en 缺 1252 键(除 6 个对象外的全部 kpi 对象/字段/选项、导航、看板、页面)。英文界面下这些位置回退成中文(见对照图 13 的「主体类型 / 当前节点序号 / 指标数」)。改前即如此,本单「不改 en 包」。影响面:仅英文界面用户的观感,不影响中文界面与任何功能。 - 平台 CLI:
--no-metadata-forms抑制不了 metadataForms 内联到单文件。传--no-objects-only --no-metadata-forms时,工具仍把 761 条 Studio 英文基线写进<locale>.objects.generated.ts。本单用--filter=kpi_规避(经逐行 diff 确认只少 metadataForms 一块、应用自有内容零损失)。与已上报的 i18n: metadata label lookup falls through to theenbundle on a zh-CN workspace —localeChaindefaultsfallbackChainto ['en'] and ignoresi18n.fallbackLocale, so an authored Chinese label loses to a courtesy English bundle objectstack#14882 同属 i18n 工具与运行时口径问题;是否合并上报请示。 - 平台 CLI:
extract --check失败时打印的重跑命令有误,输出os i18n extract --locales= --fill=empty --out=src/translations(locales 为空、丢了本仓库实际用的开关),照抄会跑错。仓库侧已用pnpm i18n:extract封装规避。属提示文案缺陷,不影响门禁判定正确性。
遗留 2、3 均为平台侧现象,按项目约定「只上报、不修复」;本会话未在平台仓开单(避免与 #14882 重复上报),是否另行开单请 PM 定。
- en 包覆盖不全:
提 PR + 交接验收侧
- PR:i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25(
issue-24-i18n-zh-bundle→main,不含自动关闭关键字,关闭动作归验收线) - 状态:
status:自测报告中→status:PR审查中 - 处理人:交接给验收侧 @baozhoutao(工作项创建人)
- 前置产出:测试报告(自测通过)、需求符合度清单(4 项范围 3 ✅ 1
⚠️ 、5 条验收标准全 ✅) - 截图归档:孤儿分支
acceptance-evidence@8c584f20de742d6d6c35c5cb8b6be53aa38168d9,目录issue-24/,13 张。该分支此前在远端不存在,本次按项目约定 E2 新建为孤儿分支。
请验收侧留意的一处取舍:生成命令比正文范围 §1 多了
--no-objects-only --filter=kpi_,是为满足验收标准 §1 的应用名断言、并避免把平台 Studio 的英文基线打进应用包;理由与「改回」选项都写在需求符合度清单的「偏差 1」里。开发侧到此为止,不自行合并 PR。
- PR:i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25(
- added a commit that references this issue
on Sep 3, 2026 合并记录(调度员,2026-09-03)
- 收单核实:PR i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25 存在且关联本单、无自动关闭关键字;单提交、改动 4 文件与范围一致、无夹带;CI verify 绿;状态标签与处理人已交接;测试报告、需求符合度清单(三态齐全,唯一
⚠️ 已披露理由与改回选项)、13 张证据图在acceptance-evidence@8c584f2均核对存在。全项通过。 - 评审闸门:独立评审子 agent(轻量档)结论「可合并」,🔴 阻塞 0、🟡 应修 0、⚪ 记录 4(见 PR i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25 评审报告);记录级不阻塞。
- 调度员裁定:范围 §1 字面命令与验收 §1 的矛盾系立单笔误,以验收标准为准,生成命令带
--no-objects-only --filter=kpi_不视为越界。 - 已合并 PR i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25 到 main。状态切
status:PM验收中,处理人不变(验收侧)。功能是否达标归验收线判定。 - 记录级条目 2(
--filter=kpi_对不含前缀的 app/page 失明)值得跟踪,待验收后视情况立单。
- 收单核实:PR i18n: 按平台正式写法补 zh-CN 翻译包,消除中文界面下的英文对象名与列头 #25 存在且关联本单、无自动关闭关键字;单提交、改动 4 文件与范围一致、无夹带;CI verify 绿;状态标签与处理人已交接;测试报告、需求符合度清单(三态齐全,唯一
背景
界面上对象名与部分字段名显示英文(Assessment Plan、Plan Name、Period Type、Status、Entry Sheet、Final Score 等),用户已选中文仍然如此。成因(2026-09-03 复核):应用元数据标签直接用中文书写,只随附一个
en翻译包、没有zh-CN翻译包;平台运行时查标签走「zh-CN 包 → en 包 → 元数据原文」,zh-CN 包没有 kpi 对象词条,于是凡 en 包覆盖的标签一律英文。平台的os i18n check又把中文原文算作默认语言已覆盖,工具与运行时口径不一致,已上报 objectstack-ai/objectstack#14882 待裁定。平台文档(objectstack-i18n skill)的正式写法是每个支持的语言各带一个翻译包,默认语言的包由
os i18n extract从元数据标签生成。本单按正式写法整改,不等平台。范围
os i18n extract --locales=zh-CN --no-metadata-forms --out=src/translations生成 zh-CN 包(dry-run 结果:1290 个词条,全部由元数据中文标签自动填充,不需要人工翻译),按平台生成文件的约定落在src/translations/(生成文件名保留工具默认,如zh-CN.objects.generated.ts)。src/translations/index.ts注册'zh-CN'包;en包原样保留。CLAUDE.md「项目约定」中「用户可见文案默认中文(对象/字段 label 直接中文;zh-CN翻译包只补 en 回退)」一句改为正式写法:label 直接中文,zh-CN 包由os i18n extract生成并随元数据改动重新生成,en 包补英文回退。只改这一句。package.json增加脚本i18n:extract(生成命令)与在verify中加入objectstack i18n extract --check(平台文档的新鲜度门禁,保证标签改了包也跟着改);若--check在本仓库不可用,如实记录并只加生成脚本。不做
不改任何对象/字段的 label 文案;不改 en 包内容;不动
src/data/、scripts/、README、docs/;不修改平台包。验收标准
curl -H "Accept-Language: zh-CN" /api/v1/meta/object/kpi_entry_sheet返回label= 填报单、fields.name= 填报单名称、fields.status= 状态、fields.total_score= 最终得分;/api/v1/meta/app/kpi_app返回「KPI 考核管理」。Accept-Language: en请求仍返回 Entry Sheet / Sheet / Status / Final Score(en 包不受影响)。pnpm verify绿;os i18n check默认语言零错误;新增的新鲜度门禁通过。os i18n extract --check或重跑生成对账。测试计划草稿
T1 生成前后 diff 只含生成文件、index.ts、CLAUDE.md、package.json | T2 API zh-CN 标签断言(验收 1) | T3 API en 标签断言(验收 2) | T4 UI 四个页面截图对比 | T5 pnpm verify + i18n check + extract --check
依赖与风险
src/data/、scripts/、README);CLAUDE.md 两单各改不同位置,合并时若冲突由后合者在自己分支解决。