MusePi i18n 架构
English | 中文
活文档(2026-08-16 建立)——覆盖仓库内两套独立 i18n 系统:渲染端(desktop-web,GUI/托盘/协作 Web)与 TUI(coding-agent)。词表已于 2026-08-16 拆分为按域模块,en 侧编译级 parity,并提供插件注册 seam。实现为准。
两套系统
desktop-web(packages/desktop-web/src/i18n) |
coding-agent(packages/coding-agent/src/i18n) |
|
|---|---|---|
| 消费方 | GUI 主窗/托盘/气泡、collab Web UI | TUI、daemon(复用同模块) |
| 占位符 | 命名参数 {count}(模板字面量类型提取校验) |
位置参数 {0}(历史约定,未迁移) |
| key 类型 | TranslationKey = keyof typeof zhCN 严格(拼错/漏参数编译报错) |
宽松(key: string,英文原文即 key) |
| en 映射 | 有(en-US/ 域文件,编译级 parity) | 无(英文 passthrough) |
| 词表 | 12 域(zh-CN/ + en-US/) |
13 域(zh-CN/) |
| 插件 seam | registerTranslations(locale, map) + tLoose(key, params) |
registerTranslations(locale, map) |
共同约定:key 即英文原文,t() 未命中回退到 key 本身;t() 只在渲染/调用时执行,不在模块加载期。
词表拆分(desktop-web)
- 域模块:
zh-CN/{shell,composer,sessions,context,collab,transcript,settings,agents,tools,pet,guest}.ts(每域导出XxxKey = keyof typeof x),en-US/同构。 - barrel(
zh-CN/index.ts/en-US/index.ts)合并为扁平 map,模块加载时跨域重复 key 抛错(spread 静默覆盖的替代);TUI 的zh-CN/index.ts同款守卫。 - en 编译级 parity:每个 en 域文件
export const x = { … } as const satisfies Record<ZhKey, string>—— en 缺/多 key 是编译错误(负向验证:shell.ts 注入额外 key → TS2353)。比测试更强,新增 zh key 必须同步加 en。 - 测试:
desktop-web/src/i18n/i18n.test.ts(key 集 parity、跨域重复守卫、注册覆盖/隔离、新 locale)+desktop-web/test/i18n.test.ts(查找/替换/回退/passthrough/无位置参数残留)。测试内setLocale必须afterAll恢复初始值(bun test 同进程顺序执行)。
插件 seam
registerTranslations(locale, map):运行时注册/覆盖某 locale 文案。desktop-web 版触发emit()让 UI 即时重渲染;TUI 版无订阅者,t()每次调用读注册表,天然即时。均不持久化(重启恢复核心词表)。tLoose(key, params)(仅 desktop-web):插件自有、不在核心词表的 key 用它(核心t只收TranslationKey;TUI 的t本就不限 key)。- 支持全新 locale(如插件注册
fr-FR);该 locale 未注册的 key 回退到 key 原文。
维护指引
- 改文案:按功能找对应域文件(settings 2137 键最大,其次 tools/pet),不要加回单文件。
- 加 key:zh 域加后,en 域必须同步(否则编译错);key 保持英文原文风格;命名参数用
{name},不用{0}。 - 域间不重复 key:重复会在 barrel 加载时抛错(报出两个域名)。
- GUI 动态 key(schema 驱动 label、运行时错误串、
tag.${…}拼接):显式as TranslationKey;插件/扩展文案走registerTranslations+tLoose。 - TUI:
{0}位置参数不动;新增域模块时同步更新zh-CN/index.ts的 import/spread/守卫 parts。