跳转到内容
OmniRoute source

i18n — 国际化指南

OmniRoute 支持 42 种语言,提供完整的控制台 UI 翻译、文档翻译,以及阿拉伯语和希伯来语的 RTL 支持。

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 镜像强制执行的格式一致。

较旧的 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

基于哈希的增量 i18n 管道

源文件:diagrams/i18n-flow.mmd

  • UI 字符串:src/i18n/messages/en.json(英文源,约 2800 个 Key)
  • 语言/地区文件:src/i18n/messages/{locale}.json(30 种翻译)
  • 框架:next-intl,基于 Cookie 的语言/地区解析
  • 配置:src/i18n/config.ts — 定义全部 30 个语言/地区、语言名称、旗帜
  1. 用户选择语言 → 设置 NEXT_LOCALE Cookie
  2. src/i18n/request.ts 解析语言/地区:Cookie → Accept-Language 头 → 回退 en
  3. 动态 import 加载 messages/{locale}.json
  4. 组件使用 useTranslations("namespace") 和 t("key")
代码 语言 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

编辑 src/i18n/config.ts:

// 添加到 LOCALES 数组
"xx",
// 添加到 LANGUAGES 数组
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },

编辑 scripts/i18n/generate-multilang.mjs — 在 LOCALE_SPECS 中添加条目:

{
code: "xx",
googleTl: "xx",
label: "XX",
flag: "🏳️",
languageName: "Language Name",
readmeName: "Language Name",
docsName: "Language Name",
},
终端窗口
node scripts/i18n/generate-multilang.mjs messages

此命令通过 Google Translate 从 en.json 自动翻译生成 src/i18n/messages/xx.json。

自动翻译是起点。手动审查以下方面:

  • 技术准确性
  • 语境适宜的术语
  • 占位符的正确处理({count}、{value} 等)
终端窗口
python3 scripts/i18n/validate_translation.py quick -l xx
python3 scripts/i18n/validate_translation.py diff common -l xx
终端窗口
node scripts/i18n/generate-multilang.mjs docs

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 中的语言/地区)

辅助翻译器 — 使用任意 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 种语言

omniroute CLI 拥有独立的 i18n 层,与 Next.js 控制台分离。

  • CLI 命令中的每个用户可见字符串都通过 bin/cli/i18n.mjs 中的 t("module.key", vars) 处理。
  • 翻译目录是 bin/cli/locales/ 中的 JSON 文件 — 预置 42 个语言/地区。
  • 缺失 Key 时回退到 en,因此部分翻译也是有效的。
  • 可用语言/地区的唯一数据源是 config/i18n.json(与控制台共享)。

检测顺序(优先匹配):

优先级 来源 示例
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-]+$/ 校验 — 路径穿越将被拒绝。

终端窗口
# 设置语言并保存到 ~/.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 持久化。

bin/cli/locales/ 中预置 42 个语言/地区文件。完整翻译:en、pt-BR。 仅骨架(所有 Key 回退到 en):bn、gu、he、in、mr、ms、phi、sw、ta、te、ur。 其余 29 个语言/地区已翻译 common + program Key。

  1. 在 config/i18n.json 中添加语言/地区条目。
  2. 运行 node bin/cli/scripts/generate-locales.mjs — 创建语言/地区文件。
  3. 翻译 Key(或留空 {} 以使用 en 回退骨架)。
  4. PR 必须向 en.json 和 pt-BR.json 添加字符串;其他文件尽力而为。

翻译校验器 — 将任意语言/地区的 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 cs
python3 scripts/i18n/validate_translation.py diff settings -l cs
# 导出为 CSV
python3 scripts/i18n/validate_translation.py csv -l cs > report.csv
# 导出为 Markdown
python3 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 标志。

代码到 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 --fix

静态分析 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

通过 Playwright 进行视觉 QA — 对多种语言/地区和视口尺寸下的所有控制台路由截图,然后评估页面健康。

终端窗口
# 默认:es、fr、de、ja、ar,访问 localhost:20128
node 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 报告

文件: 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 时校验所有语言/地区:

  1. i18n-matrix 任务 — 动态发现所有语言/地区文件(排除 en.json)
  2. i18n 任务 — 对每个语言/地区并行运行 validate_translation.py quick -l '&lt;lang&gt;'
  3. 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 complete
src/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 报告
  1. 始终先编辑 en.json — 它是唯一数据源
  2. 运行 generate-multilang.mjs messages 将新的 Key 传播到所有语言/地区
  3. 审查自动翻译 — Google Translate 是起点,不是最终结果
  4. 提交前校验 — python3 scripts/i18n/validate_translation.py quick -l &lt;lang&gt;
  5. 更新 untranslatable-keys.json 如果某个 Key 应保留为英文
  • ICU 占位符({count}、{value}、{total}、{seconds})必须精确保留
  • 复数格式({count, plural, one {# model} other {# models}})必须维持结构
  • 校验器会自动检测占位符不匹配
// 使用命名空间 Key
const t = useTranslations("settings");
t("cacheSettings"); // 映射到 JSON 中的 settings.cacheSettings
// 运行 check_translations.py 验证 Key 存在
python3 scripts/i18n/check_translations.py --verbose
  • 阿拉伯语(ar)和希伯来语(he)是 RTL 语言/地区
  • 避免硬编码 left/right CSS — 使用 start/end 逻辑属性
  • 视觉 QA 通过 run-visual-qa.mjs 捕获 RTL 布局不匹配

生成器最初对印地语使用 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 文件由 generate-multilang.mjs docs 完全重新生成。任何手动编辑都会丢失。如需持久化的手写文档,请使用 docs/guides/I18N.md(本文件)。

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: 0
Untranslated: 0
Ignored (UNTRANSLATABLE_KEYS): <各版本数量不同>

OmniRoute 源码 (a58000c7685f)

HagiCode

HagiCode 是一套智能体编码工作台:结构化工作流、多 Agent 并行执行与 Hero Dungeon 视图,把想法变成真正交付的软件。

让想法更快变成好用的软件,让智能编码更聪明、更高效,也更有趣。

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