Skip to content

feat: TUI 16-language i18n framework + Dashboard zh coverage / TUI 16 语言国际化框架 + Dashboard 中文覆盖#23243

Open
Vodkakakaka wants to merge 108 commits into
NousResearch:mainfrom
Vodkakakaka:feat/tui-i18n-localization
Open

feat: TUI 16-language i18n framework + Dashboard zh coverage / TUI 16 语言国际化框架 + Dashboard 中文覆盖#23243
Vodkakakaka wants to merge 108 commits into
NousResearch:mainfrom
Vodkakakaka:feat/tui-i18n-localization

Conversation

@Vodkakakaka

@Vodkakakaka Vodkakakaka commented May 10, 2026

Copy link
Copy Markdown

What does this PR do?

Hermes currently has several UI surfaces that assume English: the Ink TUI, gateway-driven TUI status updates, slash-command output, and the Web Dashboard. This PR adds a typed i18n foundation for those surfaces, registers 16 supported locale codes, and ships complete Simplified Chinese (zh) coverage for the user-facing strings touched by this work.

This is not meant to be a one-off Chinese patch. The PR establishes the extension points that future translators need: typed language packs, locale normalization, runtime language resolution, Dashboard language switching, and config-backed propagation through display.language.

Related Issue

Fixes #23224

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • Added a TUI i18n layer in ui-tui/src/i18n/ with a typed English source catalog, a complete zh pack, 16 locale codes, locale aliases, fallback behavior, interpolation, status translation, tool verbs, and language-pack-driven verb layout rules.
  • Wired language resolution from Python/config into the TUI path: agent/i18n.py, tui_gateway/server.py, tui_gateway/ws.py, uiStore, createGatewayEventHandler, and useConfigSync.
  • Replaced hardcoded TUI user-facing strings across slash commands, status chrome, prompts, dialogs, tool labels, model picker, setup copy, and related components with i18n keys.
  • Added Web Dashboard i18n support for the reviewed Dashboard surfaces, including the language switcher, config field labels via schemaZh.ts, plugin nav labelKey handling, OAuth/model/tool-call surfaces, and the new Channels page that landed from upstream.
  • Kept non-Chinese locale packs registered as typed shells/fallback packs so future translation work can fill them without changing the framework again.
  • Added test coverage for locale normalization, catalog parity, fallback behavior, interpolation, toolset labels, gateway language payloads, and Dashboard/TUI build safety.

How to Test

Manual verification

  1. Set display.language: zh in ~/.hermes/config.yaml, start hermes --tui, and verify TUI chrome, slash-command output, status labels, dialogs, and prompts render in Chinese.
  2. Set display.language: en, restart/open the TUI again, and verify the same surfaces return to English.
  3. Open the Web Dashboard with display.language: zh; verify the sidebar, config labels, language picker, plugin nav labels, and Channels page labels/buttons/status badges render from the i18n catalog.
  4. Use the Dashboard language switcher and verify the chosen locale persists locally and syncs back to display.language for embedded TUI sessions.
  5. Try unsupported locale values such as xx and verify the UI falls back to English rather than crashing or rendering blanks.

Automated verification run for this PR

  • cd ui-tui && npm run type-check — passed.
  • cd ui-tui && npm run build — passed.
  • cd ui-tui && npm run test — passed: 88 test files, 974 tests passed, 1 skipped.
  • cd web && npm run build — passed.
  • cd web && npx eslint src/components/LanguageSwitcher.tsx src/pages/ChannelsPage.tsx src/i18n/*.ts — passed.
  • python -m py_compile agent/i18n.py tui_gateway/ws.py tui_gateway/server.py tui_gateway/entry.py hermes_cli/web_server.py — passed.
  • python -m pytest tests/agent/test_i18n.py tests/tui_gateway/test_wait_for_mcp_discovery.py tests/test_tui_gateway_server.py -q — passed: 243 tests passed, 1 warning.
  • git diff --check — passed.

Full Python suite note

  • python -m pytest tests/ -q -x was attempted. It stops at tests/acp/test_approval_isolation.py::TestAcpExecAskGate::test_interactive_env_var_routes_to_callback.
  • The same ACP directory-order failure reproduces on current origin/main (pytest tests/acp -q -> 1 failed, 274 passed), while the specific test file passes alone (pytest tests/acp/test_approval_isolation.py -q -> 7 passed). Because this is an upstream order-dependent ACP test issue and not introduced by this i18n PR, the full-suite checklist item below is intentionally not checked.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (Python i18n tests, gateway language tests, and TUI Vitest coverage)
  • I've tested on my platform: Ubuntu/WSL2 on Windows 11

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A (display.language already exists)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (string/catalog/config propagation only)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A — this PR does not add a skill.

Screenshots / Logs

No screenshot is attached in this body. The verification commands above cover the typed catalogs, TUI build/test path, Dashboard build path, and gateway language payload path.


这个 PR 做了什么?

Hermes 目前有多处 UI 默认假设英文:Ink TUI、gateway 驱动的 TUI 状态更新、slash 命令输出,以及 Web Dashboard。这个 PR 为这些表面建立一套类型安全的国际化基础,注册 16 个受支持 locale,并为本次覆盖到的用户可见文案提供完整简体中文(zh)翻译。

这不是一次性的中文补丁。这个 PR 建的是以后翻译者能继续扩展的入口:类型化语言包、locale 归一化、运行时语言解析、Dashboard 语言切换,以及通过 display.language 在配置和 UI 之间传播语言选择。

关联 Issue

Fixes #23224

变更类型

  • ✨ 新功能(非破坏性新增能力)
  • ✅ 测试(新增或改进测试覆盖)

具体变更

  • ui-tui/src/i18n/ 新增 TUI i18n 层:类型化英文源目录、完整 zh 包、16 个 locale、locale 别名、fallback、插值、状态翻译、工具动词,以及由语言包声明的动词布局规则。
  • 打通 Python/config 到 TUI 的语言链路:agent/i18n.pytui_gateway/server.pytui_gateway/ws.pyuiStorecreateGatewayEventHandleruseConfigSync
  • 将 slash 命令、状态栏、提示词、弹窗、工具标签、模型选择器、setup 文案等 TUI 用户可见硬编码文案替换为 i18n key。
  • 为 Web Dashboard 接入本次审查范围内的 i18n 支持,包括语言切换器、schemaZh.ts 配置字段标签、插件导航 labelKey、OAuth/model/tool-call 相关表面,以及上游新合入的 Channels 页面。
  • 其他非中文 locale 作为类型化 shell/fallback 包注册,后续翻译者可以直接填充语言包,不需要再改框架。
  • 新增测试覆盖 locale 归一化、目录完整性、fallback、插值、toolset 标签、gateway language payload,以及 Dashboard/TUI 构建安全性。

如何测试

手工验证

  1. ~/.hermes/config.yaml 设置 display.language: zh,启动 hermes --tui,确认 TUI chrome、slash 命令输出、状态标签、弹窗和提示词显示中文。
  2. 设置 display.language: en,重新打开 TUI,确认同一批表面恢复英文。
  3. display.language: zh 打开 Web Dashboard,确认侧边栏、配置字段标签、语言切换器、插件导航标签和 Channels 页面按钮/状态 badge 都来自 i18n 目录。
  4. 使用 Dashboard 语言切换器,确认选择会在本地持久化,并同步回 display.language,供嵌入式 TUI 会话读取。
  5. 尝试 xx 这类不支持的 locale,确认 UI 回退英文,不崩溃、不空白。

本 PR 已跑自动化验证

  • cd ui-tui && npm run type-check — 通过。
  • cd ui-tui && npm run build — 通过。
  • cd ui-tui && npm run test — 通过:88 个测试文件,974 个测试通过,1 个 skipped。
  • cd web && npm run build — 通过。
  • cd web && npx eslint src/components/LanguageSwitcher.tsx src/pages/ChannelsPage.tsx src/i18n/*.ts — 通过。
  • python -m py_compile agent/i18n.py tui_gateway/ws.py tui_gateway/server.py tui_gateway/entry.py hermes_cli/web_server.py — 通过。
  • python -m pytest tests/agent/test_i18n.py tests/tui_gateway/test_wait_for_mcp_discovery.py tests/test_tui_gateway_server.py -q — 通过:243 个测试通过,1 个 warning。
  • git diff --check — 通过。

Python 全量测试说明

  • 已尝试 python -m pytest tests/ -q -x,会停在 tests/acp/test_approval_isolation.py::TestAcpExecAskGate::test_interactive_env_var_routes_to_callback
  • 同一个 ACP 目录顺序失败在当前 origin/main 也能复现(pytest tests/acp -q -> 1 failed, 274 passed),而该测试文件单独运行通过(pytest tests/acp/test_approval_isolation.py -q -> 7 passed)。这是上游当前已有的 ACP 顺序依赖问题,不是本 i18n PR 引入,所以官方全量 pytest checklist 项保持未勾选。

Checklist

Code

  • 已阅读 Contributing Guide
  • Commit 信息遵循 Conventional Commitsfix(scope):feat(scope): 等)
  • 已搜索 existing PRs,确认不是重复 PR
  • 本 PR 只包含与此修复/功能相关的变更
  • 已运行 pytest tests/ -q 且全部测试通过
  • 已为本次变更新增测试(Python i18n、gateway language,以及 TUI Vitest 覆盖)
  • 已在本机平台测试:Windows 11 上的 Ubuntu/WSL2

Documentation & Housekeeping

  • 已更新相关文档(README、docs/、docstrings)— 或不适用
  • 如果新增/修改 config key,已更新 cli-config.yaml.example — 或不适用(display.language 已存在)
  • 如果改变架构或工作流,已更新 CONTRIBUTING.mdAGENTS.md — 或不适用
  • 已按兼容性指南考虑跨平台影响(Windows、macOS)— 或不适用(仅字符串/目录/config 传播)
  • 如果改变工具行为,已更新工具描述/schema — 或不适用

For New Skills

不适用 — 本 PR 没有新增 skill。

Screenshots / Logs

正文中不附截图。上面的验证命令覆盖了类型化目录、TUI 构建/测试路径、Dashboard 构建路径,以及 gateway language payload 路径。

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels May 10, 2026
@Vodkakakaka Vodkakakaka force-pushed the feat/tui-i18n-localization branch from 0b390ff to 3e6b05f Compare May 10, 2026 15:31
1. 新增 web/src/i18n/schemaZh.ts,含 283 个配置字段的完整中文标签和描述映射
2. AutoField 组件接入 useI18n,根据 locale 自动切换中文标签和描述
3. 补完 TUI i18n 遗漏文本映射(thinking.tsx、text.ts、gateway 事件处理)
4. 新增 i18n-consts.ts 辅助模块
1. 汉化 prompts.tsx: approval/clarify/confirm 所有快捷键提示
2. 汉化 helpHint.tsx: 帮助面板命令和快捷键描述
3. 汉化 hotkeys.ts: 18条快捷键描述全部中文化
4. 汉化 session.ts voice 状态消息
5. 汉化 thinking.tsx: Spawned/Spawn tree
6. 汉化 agentsOverlay.tsx: Budget/Files/Tool calls/Output/Progress/Summary
7. 汉化 branding.tsx: Available Tools/Skills/System Prompt
8. 汉化 appLayout.tsx: Ctrl+C to interrupt…
9. 汉化 tui_gateway/server.py: slash命令补全提示翻译
10. i18n.tsx 新增 39 条翻译条目
1. thinking.tsx: 修复 ToolTrail 折叠标签两处硬编码 Thinking
2. modelPicker/sessionPicker/skillsHub: 所有 Esc/q cancel 等提示中文化
3. queuedMessages: 队列编辑提示中文化
4. agentsOverlay: Spawn tree 标签中文化
5. i18n.tsx: 新增 picker/queue 相关翻译条目
保持英文原文作为默认,通过 translate() 在 zh locale 下显示中文。
新增 40+ i18n 条目覆盖常用 sys 消息。
保持英文原文默认,zh locale 下显示中文
@Vodkakakaka Vodkakakaka force-pushed the feat/tui-i18n-localization branch from 3e6b05f to d3e26d4 Compare May 10, 2026 15:42
Vodkakakaka and others added 3 commits May 11, 2026 09:28
- 修复 help 面板中 tz('sys.helpSkillCount') 被错误包裹在模板字符串中
- sys.helpDetailGlobal / sys.helpFortune / sys.clipboardCopyFailed 补齐翻译调用
- 标题硬编码改为 tz('sys.titleSet', ...) 走 i18n
- hotkeys.ts: 描述从硬编码文本改为 i18n key 引用,导出 HOTKEY_DEFS
- i18n.tsx: 添加 20 条 hotkey.* 中英文翻译
- helpHint.tsx / core.ts: 适配 HOTKEY_DEFS + ti()/tz() 翻译
- appChrome.tsx: padVerb 改用 dispWidth 替代 .length,
  修复中文 verb 状态下状态栏出现多余空白的问题
- clipboard.ts: WSL PowerShell 输出 UTF-8 编码修复,
  解决粘贴中文被误识别为图像的问题
- constants.test.ts: 测试更新
ChatPage.tsx 的三个硬编码字符串(title/aria-label/按钮文字)
改为走 dashboard i18n 系统,中英文翻译已添加。
- package.json: 添加 packageManager,prebuild/predev 改用 pnpm
- 删除 package-lock.json,新增 pnpm-lock.yaml
- 14 种语言文件补齐 copyLastResponse/copyLastResponseTitle/copyLastResponseAria/copied(英文占位)
- core.ts/ops.ts: tz() 硬编码 'zh' 改为动态 ctx.ui.locale,支持语言切换
- hotkeys.ts: 修复 \\+Enter 转义错误
- prompts.tsx: LABELS 硬编码英文改为 i18n 翻译 (prompt.approval*)
- i18n.tsx: 新增 approval 相关中英翻译 key
@Vodkakakaka Vodkakakaka requested a review from a team May 12, 2026 10:14
- ChatSidebar: 状态/标签等硬编码英文改走翻译
- AutoField: 提示文本接入 i18n
- ConfigPage: 配置页面文本汉化
- en/zh/types: 新增 33+ 翻译字段
- Agent 2 子任务产出
- messageLine.tsx: 5处硬编码接入i18n (emptyToolResult/systemMsg/longMessage/chars)
- prompts.tsx: Mac快捷键提示接入i18n (copyPasteHint)
- core.ts: 8处硬编码中文标题和已有key替换 (TUI命令/快捷键/日志/历史记录)
- i18n.tsx: 新增 transcript.*(3) prompt.copyPasteHint section.*(4) 共8个key中英对照
- debug.ts: 全面接入i18n,12处硬编码消除 (堆转储/诊断/内存面板)
- session.ts: Usage面板标签中英文化 (Model/Input tokens/API calls等)
- todoPanel.tsx: 待办标题和状态标签接入翻译
- appOverlays.tsx: sudo密码提示/密钥变量/pager导航汉化
- i18n.tsx: 新增 debug.* usage.* todo.* pager.* 等29个翻译key
- thinking.tsx: queued/running 状态标签接入 STATUS 翻译表
- i18n.tsx: 扩展 STATUS_EN/ZH 表,补充 setup/ops/section 相关 key
- setup.ts: done 提示文本改用 translate() 走 i18n
- i18n.tsx: 补 setup.complete/setup.help 中文翻译
- FaceTicker 中文模式跳过 padVerb,直接输出「动词…」
- 英文模式保持原 padding 对齐逻辑
- 修复「计算…[8空格]·2m15s」的显示 bug
Vodkakakaka and others added 8 commits May 23, 2026 13:30
1. 补齐浅克隆历史后正常合并 origin/main,避免 unrelated histories 误判。

2. 解决 Web Dashboard 6 个真实 i18n/UI 冲突,保留上游样式 token 与本地翻译调用。

3. 修复 hermes-ink execFileNoThrow 的 Node 24 stdio 类型推断问题,恢复 TUI type-check。

Co-authored-by: Codex <noreply@openai.com>
Vodkakakaka and others added 2 commits May 26, 2026 13:08
…i18n

- web: LanguageSwitcher calls api.saveConfig({display.language}) so
  embedded TUI picks up locale changes via useConfigSync mtime polling
- tui: move voiceLabel computation from useMainApp into StatusRule
  (useMainApp runs outside I18nProvider so useI18n() always returned
  default 'en' context — voice idle/on/off labels never translated)
- 同步 upstream/main(+303 提交)
- 解决 12 个冲突文件,保留所有 i18n 翻译调用
- 适配:live session switcher / BottomSheet / SidebarIconWithTooltip
- 更新 Ctrl+X 热键翻译
@Vodkakakaka Vodkakakaka force-pushed the feat/tui-i18n-localization branch from 685c547 to 267b496 Compare May 29, 2026 11:29
Vodkakakaka and others added 10 commits May 29, 2026 19:29
Conflict resolution kept feat branch's simpler absolute positioning
but left main branch's createPortal import, causing TS6133 build error.
…ide-Text crash

拆分 StatusRule 中的单 <Text> 包裹为多个独立 <Text> 元素,
对齐上游 main 的结构,消除 sessionCountNode 的 <Box> 被嵌套
在外层 <Text> 中导致的 Ink 运行时错误。
# Conflicts:
#	tui_gateway/ws.py
1. 从 display.language 恢复 Dashboard 初始 locale。

2. 统一处理标准 locale、地区后缀和常见语言名别名。

3. 清理翻译文件尾随空白,保证 diff check 通过。

Co-authored-by: Codex <noreply@openai.com>
1. 合并 upstream/main 81dd43a 的最新更新。

2. 解析 TUI 状态栏、帮助提示、模型选择器和会话选择器冲突。

3. 保留国际化路径,新增过滤提示翻译 key,并让布局宽度按翻译文案计算。

4. 更新相关测试以匹配当前 wrapping 与 hook 边界。

Co-authored-by: Codex <noreply@openai.com>
合并 origin/main 至 3c1d066,接入 Dashboard Channels 页面等最新上游变更。

Co-authored-by: Codex <noreply@openai.com>
1. 将上游新增 Channels Dashboard 页面接入现有 useI18n 翻译体系。

2. 为内置导航和 Channels 状态、提示、操作文案补齐 16 语言 key。

3. 保持 display.language 场景下 Dashboard 新页面不会回退到英文硬编码。

Co-authored-by: Codex <noreply@openai.com>
1. 按官方模板重写 PR 正文为英文/中文双语结构。

2. 补充最新实际验证结果,明确全量 pytest 的上游 ACP 顺序失败。

3. 收紧 Channels 页面占位符替换并整理语言切换器缩进。

Co-authored-by: Codex <noreply@openai.com>
@Vodkakakaka

Copy link
Copy Markdown
Author

Hi @austinpickett, quick ping since you were the reviewer who left the previous requested changes and this PR is still assigned to you for review.

I synced the branch with the latest main, resolved the follow-up merge churn, and rewrote the PR body to match .github/PULL_REQUEST_TEMPLATE.md in a clearer bilingual format. I also re-checked the i18n/Dashboard/TUI changes after the latest upstream Channels page landed.

Current validation:

  • ui-tui: type-check, build, and full Vitest pass (974 passed, 1 skipped)
  • web: build passes
  • i18n/gateway Python tests pass (243 passed)
  • git diff --check passes

The PR is mergeable again, and I believe the earlier requested changes are addressed. When you have time, could you take another look or let me know if anything else is needed?

Thanks.

Vodkakakaka and others added 4 commits June 3, 2026 22:33
1. 同步 origin/main 最新变更到 feat/tui-i18n-localization。

2. 解决 dashboard fixture、TUI app layout 和 Web model info card 的合并冲突。

3. 保留上游 UI/fixture 调整,同时保留本分支 i18n 行为。

Co-authored-by: Codex <noreply@openai.com>
1. 合并 origin/main@8077e7d2f 到 feat/tui-i18n-localization。

2. 解决 ui-tui session lifecycle 冲突,保留上游 live session 行为和 PR 本地化错误提示。

3. 清理合并内容中的 trailing blank line,保证 diff 检查通过。

Co-authored-by: Codex <noreply@openai.com>
1. 合并 NousResearch/main 最新提交。

2. 解决 ui-tui clarify 取消提示与 web Channels 页面 Telegram onboarding 的合并冲突。

3. 清理合并引入的 Markdown 行尾空格。

Co-authored-by: Codex <noreply@openai.com>
1. 合并 upstream main 的 credits/profile 相关更新。

2. 保留 TUI 状态栏 i18n 文案宽度计算,同时接入 credits notice/dev credits 渲染逻辑。

3. 修正状态栏 credits 测试入口,适配 i18n-aware StatusRuleView。

Co-authored-by: Codex <noreply@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Chinese i18n for Dashboard & embedded TUI / Dashboard 及内嵌 TUI 中文本地化

5 participants