i18n — 国际化指南
OmniRoute 支持 42 种语言,提供完整的控制台 UI 翻译、文档翻译,以及阿拉伯语和希伯来语的 RTL 支持。
翻译管道(推荐 — v3.8.0)
Section titled “翻译管道(推荐 — v3.8.0)”OmniRoute 使用基于哈希的增量文档翻译器,后端为 OpenAI 兼容的 LLM 端点(通常通过 OmniRoute Cloud 使用 cx/gpt-5.4-mini):
# 运行翻译(增量模式 — 仅处理变更的源文件)npm run i18n:run
# 限定到单个语言/地区npm run i18n:run -- --locale=pt-BR
# 指定文件(逗号分隔,仓库相对路径)npm run i18n:run -- --files=CLAUDE.md,docs/architecture/ARCHITECTURE.md
# 强制全部重新翻译(开销大)npm run i18n:run -- --force
# 预览将执行的操作(无 API 调用,无文件写入)npm run i18n:run:dry
# CI 门禁 — 状态漂移时返回非零退出码npm run i18n:check唯一数据源。 config/i18n.json 列出每个语言/地区(UI + 文档),以及 RTL 集合和 docsExcluded 代码。运行时配置 src/i18n/config.ts 是该 JSON 的薄适配层。
后端。 通过 env 配置(在 .env 中设置,永不提交):
| 变量 | 用途 |
|---|---|
OMNIROUTE_TRANSLATION_API_URL |
OpenAI 兼容的 base URL,例如 …/v1 |
OMNIROUTE_TRANSLATION_API_KEY |
bearer Token(日志中脱敏) |
OMNIROUTE_TRANSLATION_MODEL |
模型 ID,例如 cx/gpt-5.4-mini |
OMNIROUTE_TRANSLATION_TIMEOUT_MS |
可选,默认 60000 |
OMNIROUTE_TRANSLATION_CONCURRENCY |
可选,默认 4 |
状态追踪。 .i18n-state.json(已提交)按源文件 + 按语言/地区维护 SHA-256 哈希。漂移检测自动且确定性 — i18n:check 无需 API 调用。
输出格式。 每个翻译文件包含顶层 # <标题> (<本地名称>) 行、🌐 Languages: … 条、--- 分隔符和翻译后的正文。此布局与 scripts/check/check-docs-sync.mjs 已为 llm.txt 和 CHANGELOG.md 镜像强制执行的格式一致。
旧版脚本(已弃用)
Section titled “旧版脚本(已弃用)”较旧的 Python 脚本(scripts/i18n/i18n_autotranslate.py)和基于 Google Translate 的生成器(scripts/i18n/generate-multilang.mjs)仍然存在但带有弃用标头,将在 v3.10 中移除。generate-multilang.mjs 的 messages 和 readme 模式(UI 字符串 + 根 README 变体)尚未被新管道处理,仍在使用。
| 任务 | 命令 |
|---|---|
| 翻译文档(LLM) | npm run i18n:run(推荐 — 增量,基于哈希) |
| 翻译 UI 字符串 | node scripts/i18n/generate-multilang.mjs messages |
| 检查翻译漂移 | npm run i18n:check |
| 校验一个语言/地区 | python3 scripts/i18n/validate_translation.py quick -l cs |
| 检查代码中的 Key | python3 scripts/i18n/check_translations.py |
| 生成 QA 报告 | node scripts/i18n/generate-qa-checklist.mjs |
| 视觉 QA(Playwright) | node scripts/i18n/run-visual-qa.mjs |
- UI 字符串:
src/i18n/messages/en.json(英文源,约 2800 个 Key) - 语言/地区文件:
src/i18n/messages/{locale}.json(30 种翻译) - 框架:
next-intl,基于 Cookie 的语言/地区解析 - 配置:
src/i18n/config.ts— 定义全部 30 个语言/地区、语言名称、旗帜
- 用户选择语言 → 设置
NEXT_LOCALECookie src/i18n/request.ts解析语言/地区:Cookie →Accept-Language头 → 回退en- 动态 import 加载
messages/{locale}.json - 组件使用
useTranslations("namespace")和t("key")
支持的语言/地区
Section titled “支持的语言/地区”| 代码 | 语言 | RTL | Google Translate 代码 |
|---|---|---|---|
ar |
العربية | 是 | ar |
bg |
Български | 否 | bg |
cs |
Čeština | 否 | cs |
da |
Dansk | 否 | da |
de |
Deutsch | 否 | de |
es |
Español | 否 | es |
fi |
Suomi | 否 | fi |
fr |
Français | 否 | fr |
he |
עברית | 是 | iw |
hi |
हिन्दी | 否 | hi |
hu |
Magyar | 否 | hu |
id |
Bahasa Indonesia | 否 | id |
it |
Italiano | 否 | it |
ja |
日本語 | 否 | ja |
ko |
한국어 | 否 | ko |
ms |
Bahasa Melayu | 否 | ms |
nl |
Nederlands | 否 | nl |
no |
Norsk | 否 | no |
phi |
Filipino | 否 | tl |
pl |
Polski | 否 | pl |
pt |
Português (Portugal) | 否 | pt |
pt-BR |
Português (Brasil) | 否 | pt |
ro |
Română | 否 | ro |
ru |
Русский | 否 | ru |
sk |
Slovenčina | 否 | sk |
sv |
Svenska | 否 | sv |
th |
ไทย | 否 | th |
tr |
Türkçe | 否 | tr |
uk-UA |
Українська | 否 | uk |
vi |
Tiếng Việt | 否 | vi |
zh-CN |
中文 (简体) | 否 | zh-CN |
1. 注册语言/地区
Section titled “1. 注册语言/地区”编辑 src/i18n/config.ts:
// 添加到 LOCALES 数组"xx",// 添加到 LANGUAGES 数组{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },2. 添加到生成器
Section titled “2. 添加到生成器”编辑 scripts/i18n/generate-multilang.mjs — 在 LOCALE_SPECS 中添加条目:
{ code: "xx", googleTl: "xx", label: "XX", flag: "🏳️", languageName: "Language Name", readmeName: "Language Name", docsName: "Language Name",},3. 生成初始翻译
Section titled “3. 生成初始翻译”node scripts/i18n/generate-multilang.mjs messages此命令通过 Google Translate 从 en.json 自动翻译生成 src/i18n/messages/xx.json。
4. 审查并修正自动翻译
Section titled “4. 审查并修正自动翻译”自动翻译是起点。手动审查以下方面:
- 技术准确性
- 语境适宜的术语
- 占位符的正确处理(
{count}、{value}等)
python3 scripts/i18n/validate_translation.py quick -l xxpython3 scripts/i18n/validate_translation.py diff common -l xx6. 生成翻译后的文档
Section titled “6. 生成翻译后的文档”node scripts/i18n/generate-multilang.mjs docs自动翻译管道
Section titled “自动翻译管道”generate-multilang.mjs(Google Translate)
Section titled “generate-multilang.mjs(Google Translate)”主要自动翻译引擎 — 使用 Google Translate 免费 API 为 UI 字符串、README 和文档生成翻译。
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]| 模式 | 功能 |
|---|---|
messages |
从 en.json 翻译 src/i18n/messages/{locale}.json 中缺失的 Key |
readme |
将 README.md 翻译为所有语言/地区,生成根目录下的 README.{code}.md |
docs |
将 DOC_SOURCE_FILES 翻译到 docs/i18n/{locale}/{docName} |
all |
运行以上全部三种模式 |
功能特性:
- 文本保���:翻译前脱敏代码块(
```)、内联代码(`)、Markdown 链接/图片([text](url))、HTML 标签、表格和 ICU 占位符({count}、{value}、{total}等),翻译后还原 - 分块批处理:使用
__OMNIROUTE_I18N_SEPARATOR__分隔符合并多个字符串,最小化 API 调用(每次请求最多 1800 字符) - 内存缓存:避免同一会话中重复字符串的冗余 API 调用
- 重试逻辑:对 429/5xx 错误使用指数退避(最多 5 次尝试,延迟 300ms × 尝试次数)
- 超时:每次请求 20 秒
- 跳过已有:若目标文件已存在,不覆盖
重要行为:
docs/i18n/README.md每次运行会重新生成 — 它是自动生成的全部文档索引- 根目录
README.{code}.md文件仅在不存在时创建(跳过EXISTING_README_CODES中的语言/地区)
i18n_autotranslate.py(基于 LLM)
Section titled “i18n_autotranslate.py(基于 LLM)”辅助翻译器 — 使用任意 OpenAI 兼容的 LLM API(包括 OmniRoute 自身)翻译已有的 docs/i18n/ Markdown 文件。适用于优化或重新翻译文档,质量优于 Google Translate。
python3 scripts/i18n/i18n_autotranslate.py \ --api-url http://localhost:20128/v1 \ --api-key sk-your-key \ --model gpt-4o功能特性:
- 扫描
docs/i18n/中的 Markdown 文件,定位英文段落 - 跳过代码块、表格和已翻译内容
- 向 LLM 发送段落及技术翻译系统提示
- 支持全部 42 种语言
CLI i18n
Section titled “CLI i18n”omniroute CLI 拥有独立的 i18n 层,与 Next.js 控制台分离。
- CLI 命令中的每个用户可见字符串都通过
bin/cli/i18n.mjs中的t("module.key", vars)处理。 - 翻译目录是
bin/cli/locales/中的 JSON 文件 — 预置 42 个语言/地区。 - 缺失 Key 时回退到
en,因此部分翻译也是有效的。 - 可用语言/地区的唯一数据源是
config/i18n.json(与控制台共享)。
语言/地区选择
Section titled “语言/地区选择”检测顺序(优先匹配):
| 优先级 | 来源 | 示例 |
|---|---|---|
| 1 | --lang 标志 |
omniroute --lang de status |
| 2 | OMNIROUTE_LANG 环境变量 |
OMNIROUTE_LANG=ja omniroute providers |
| 3 | LC_ALL 系统环境变量 |
从终端语言/地区自动检测 |
| 4 | LC_MESSAGES 系统环境变量 |
从终端语言/地区自动检测 |
| 5 | LANG 系统环境变量 |
从终端语言/地区自动检测 |
| 6 | 回退 | en |
含下划线的语言/地区代码(pt_BR)规范化为连字符形式(pt-BR)。
语言/地区代码通过 /^[a-zA-Z0-9-]+$/ 校验 — 路径穿越将被拒绝。
保存语言偏好
Section titled “保存语言偏好”# 设置语言并保存到 ~/.omniroute/.env(跨会话持久化)omniroute config lang set pt-BR
# 查看当前语言omniroute config lang get
# 列出全部 42 种可用语言omniroute config lang list
# JSON 输出omniroute config lang list --output json保存的偏好以原子方式写入 ~/.omniroute/.env,并在 CLI 引导阶段加载,先于任何命令执行。
# 仅覆盖单条命令(不持久化)omniroute --lang de providers list注意:--lang 标志不写入 env 文件 — 它仅影响当前调用。使用 config lang set 持久化。
可用语言/地区
Section titled “可用语言/地区”bin/cli/locales/ 中预置 42 个语言/地区文件。完整翻译:en、pt-BR。
仅骨架(所有 Key 回退到 en):bn、gu、he、in、mr、ms、phi、sw、ta、te、ur。
其余 29 个语言/地区已翻译 common + program Key。
添加新的 CLI 语言/地区
Section titled “添加新的 CLI 语言/地区”- 在
config/i18n.json中添加语言/地区条目。 - 运行
node bin/cli/scripts/generate-locales.mjs— 创建语言/地区文件。 - 翻译 Key(或留空
{}以使用 en 回退骨架)。 - PR 必须向
en.json和pt-BR.json添加字符串;其他文件尽力而为。
校验与 QA
Section titled “校验与 QA”validate_translation.py
Section titled “validate_translation.py”翻译校验器 — 将任意语言/地区的 JSON 与 en.json 对比并报告问题。
# 快速检查(仅统计数量)python3 scripts/i18n/validate_translation.py quick -l cs# 输出:# Missing: 0# Untranslated: 0# Ignored (UNTRANSLATABLE_KEYS): 236
# 按类别的详细差异python3 scripts/i18n/validate_translation.py diff common -l cspython3 scripts/i18n/validate_translation.py diff settings -l cs
# 导出为 CSVpython3 scripts/i18n/validate_translation.py csv -l cs > report.csv
# 导出为 Markdownpython3 scripts/i18n/validate_translation.py md -l cs > report.md
# 完整报告(默认)python3 scripts/i18n/validate_translation.py -l cs检测内容:
- 缺失的 Key — Key 存在于
en.json但不在语言/地区文件中 - 多余的 Key — Key 存在于语言/地区文件但不在
en.json中 - 未翻译的 Key — 语言/地区值与英文源相同(排除允许清单)
- 占位符不匹配 — ICU 占位符在源与翻译间不匹配
退出码:
| 代码 | 含义 |
|---|---|
| 0 | 正常 |
| 1 | 一般错误 |
| 2 | 缺失字符串(硬错误) |
| 3 | 未翻译警告(软错误) |
环境变量: 设置 TRANSLATION_LANG=cs 或使用 -l cs 标志。
check_translations.py
Section titled “check_translations.py”代码到 JSON Key 检查器 — 扫描 src/**/*.tsx 和 src/**/*.ts 中的 useTranslations() 调用,验证所有引用的 Key 是否存在于 en.json。
# 基本检查python3 scripts/i18n/check_translations.py
# 详细输出python3 scripts/i18n/check_translations.py --verbose
# 自动修复(将缺失的 Key 添加到 en.json)python3 scripts/i18n/check_translations.py --fixgenerate-qa-checklist.mjs
Section titled “generate-qa-checklist.mjs”静态分析 QA — 扫描 Next.js 页面文件以获取 i18n 风险指标,生成 Markdown 报告。
node scripts/i18n/generate-qa-checklist.mjs检查内容:
- 固定宽度类使用(溢出风险)
- 方向性的 left/right 类(RTL 风险)
- 易截断的模式
- 语言/地区一致性(vs
en.json的缺失/多余 Key) - 优先语言/地区的 README 语言选择器条(
es、fr、de、ja、ar)
输出: docs/reports/i18n-qa-checklist-{date}.md
run-visual-qa.mjs
Section titled “run-visual-qa.mjs”通过 Playwright 进行视觉 QA — 对多种语言/地区和视口尺寸下的所有控制台路由截图,然后评估页面健康。
# 默认:es、fr、de、ja、ar,访问 localhost:20128node scripts/i18n/run-visual-qa.mjs
# 自定义基础 URL 和语言/地区QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
# 自定义路由QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs检测内容:
- 文本溢出
- 元素截断
- RTL 布局不匹配
输出: docs/reports/i18n-visual-qa-{date}.md + JSON 报告
管理不可翻译的 Key
Section titled “管理不可翻译的 Key”untranslatable-keys.json
Section titled “untranslatable-keys.json”文件: scripts/i18n/untranslatable-keys.json
允许保留英文的 Key 清单,供 validate_translation.py 使用,避免误报“未翻译”警告。
{ "description": "Keys that should remain untranslated...", "keys": [ "common.model", "common.oauth", "health.cpu", ... ]}适用内容:
- 品牌/产品名:
landing.brandName、common.social-github - 技术术语/缩写:
health.cpu、mcpDashboard.pid、settings.ai - ICU/格式字符串:
apiManager.modelsCount、health.millisecondsShort - 占位符值:
providers.openaiBaseUrlPlaceholder、cliTools.baseUrlPlaceholder - 协议名:
common.http、common.oauth、providers.oauth2Label - 导航分组:
sidebar.primarySection、sidebar.cliSection
添加 Key: 编辑 scripts/i18n/untranslatable-keys.json 中的 keys 数组,然后重新运行校验。
GitHub Actions(.github/workflows/ci.yml)
Section titled “GitHub Actions(.github/workflows/ci.yml)”CI 管道在每次 push 和 PR 时校验所有语言/地区:
i18n-matrix任务 — 动态发现所有语言/地区文件(排除en.json)i18n任务 — 对每个语言/地区并行运行validate_translation.py quick -l '<lang>'ci-summary任务 — 聚合结果到控制台摘要
# i18n-matrix:发现语言LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
# i18n:校验每种语言python3 scripts/i18n/validate_translation.py quick -l '${{ matrix.lang }}'控制台输出:
## 🌍 Translations| Metric | Value ||--------|------|| Languages checked | 30 || Total untranslated | 0 |
✅ All translations completesrc/i18n/├── config.ts # 语言/地区定义(30 个语言/地区,RTL 配置)├── request.ts # 运行时语言/地区解析└── messages/ ├── en.json # 唯一数据源(约 2800 个 Key) ├── cs.json # 捷克语翻译 ├── de.json # 德语翻译 └── ... # 共计 30 个语言/地区文件
scripts/├── i18n/│ ├── generate-multilang.mjs # 自动翻译引擎(Google Translate,888 行)│ ├── generate-qa-checklist.mjs # 静态分析 QA│ ├── run-visual-qa.mjs # Playwright 视觉 QA│ └── untranslatable-keys.json # 校验允许清单(236 个 Key)├── validate_translation.py # 翻译校验器├── check_translations.py # 代码到 JSON Key 检查器└── i18n_autotranslate.py # 基于 LLM 的文档翻译器
.github/workflows/└── ci.yml # CI 矩阵中的 i18n 校验
docs/├── I18N.md # 本文件 — i18n 工具链文档├── i18n/│ ├── README.md # 自动生成的语言索引│ ├── cs/ # 捷克语文档│ │ └── docs/│ │ ├── I18N.md # 本文件的捷克语翻译│ │ └── ...│ ├── de/ # 德语文档│ └── ... # 30 个语言/地区目录└── reports/ ├── i18n-qa-checklist-*.md # 静态分析报告 └── i18n-visual-qa-*.md # 视觉 QA 报告- 始终先编辑
en.json— 它是唯一数据源 - 运行
generate-multilang.mjs messages将新的 Key 传播到所有语言/地区 - 审查自动翻译 — Google Translate 是起点,不是最终结果
- 提交前校验 —
python3 scripts/i18n/validate_translation.py quick -l <lang> - 更新
untranslatable-keys.json如果某个 Key 应保留为英文
- ICU 占位符(
{count}、{value}、{total}、{seconds})必须精确保留 - 复数格式(
{count, plural, one {# model} other {# models}})必须维持结构 - 校验器会自动检测占位符不匹配
在代码中添加新的翻译 Key
Section titled “在代码中添加新的翻译 Key”// 使用命名空间 Keyconst t = useTranslations("settings");t("cacheSettings"); // 映射到 JSON 中的 settings.cacheSettings
// 运行 check_translations.py 验证 Key 存在python3 scripts/i18n/check_translations.py --verboseRTL 注意事项
Section titled “RTL 注意事项”- 阿拉伯语(
ar)和希伯来语(he)是 RTL 语言/地区 - 避免硬编码
left/rightCSS — 使用start/end逻辑属性 - 视觉 QA 通过
run-visual-qa.mjs捕获 RTL 布局不匹配
已知问题与历史
Section titled “已知问题与历史”in.json → hi.json 修复
Section titled “in.json → hi.json 修复”生成器最初对印地语使用 code: "in"(已弃用的 Google Translate 代码),而非正确的 ISO 639-1 hi。这导致创建了 hi.json 的孤立副本 in.json。通过将 generate-multilang.mjs 中的 code: "in" 改为 code: "hi" 并删除孤立文件完成修复。
⚠️ 审计(2026-05-13):
docs/i18n/in/目录在磁盘上仍然存在(hi/的完整副本)。翻译生成器不再向其写入,但历史目录树未被清理。确认无外部链接引用旧路径后,可使用rm -rf docs/i18n/in/安全删除。
docs/i18n/README.md 是自动生成的
Section titled “docs/i18n/README.md 是自动生成的”docs/i18n/README.md 文件由 generate-multilang.mjs docs 完全重新生成。任何手动编辑都会丢失。如需持久化的手写文档,请使用 docs/guides/I18N.md(本文件)。
外部不可翻译 Key 列表
Section titled “外部不可翻译 Key 列表”untranslatable-keys.json 允许清单从 validate_translation.py 中的内联 Python set 迁移到外部 JSON 文件,以便维护。校验器在运行时加载该清单。
generate-multilang.mjs 印地语代码修复
Section titled “generate-multilang.mjs 印地语代码修复”生成器最初对印地语使用 code: "in"(已弃用的 Google Translate 代码),而非正确的 ISO 639-1 hi。该问题由上版本 952b0b22c(作者 diegosouzapw)引入。通过将 LOCALE_SPECS 数组中的 code: "in" 修改为 code: "hi" 并删除孤立的 in.json 文件完成修复。
validate_translation.py 被忽略 Key 的计数输出
Section titled “validate_translation.py 被忽略 Key 的计数输出”quick 检查现在显示来自 untranslatable-keys.json 的被忽略 Key 数:
Missing: 0Untranslated: 0Ignored (UNTRANSLATABLE_KEYS): <各版本数量不同>HagiCode
HagiCode 是一套智能体编码工作台:结构化工作流、多 Agent 并行执行与 Hero Dungeon 视图,把想法变成真正交付的软件。
让想法更快变成好用的软件,让智能编码更聪明、更高效,也更有趣。

- Smart结构化工作流将意图转化为从想法到交付的可执行路径。
- Efficient多 Agent 工作流让调研、实现与审阅并行推进。
- FunHero Dungeon 让长时间编码协作更直观、更有参与感。