Skip to content
yebuwudongPublic

About

No description, website, or topics provided.

Resources

Stars

28 stars

Watchers

0 watching

Forks

Repository files navigation

omp 中文界面汉化

LINUX DO

把已安装的官方 omp 界面汉化为简体中文,不改变版本、不替换安装、不动运行时结构。 补丁器跟随上游持续适配,不绑定具体版本号——上游发新版后重跑一条命令即可。 本项目已链接认可 LINUX DO 社区,并参与其 开源推广。

~/.omp-zh/
├── install.sh                    一行命令入口(curl | bash)
├── omp-zh.sh                     一键入口:apply / restore / verify / report / status
├── patch.ts                      补丁器(AST 分类 + 词典替换 + 锚点自动适配 + 校验)
├── dict.json                     2129 条英→中映射(源自 oh-my-pi-cn 汉化分支)
├── dict-extra.json               2700 条补充映射
├── analysis/                     侦察与词典构建脚本
└── tools/                        审计、实测、回退验证脚本
    ├── loose-anchor.ts           锚点通配匹配(重打包重命名自动适配)
    └── patch-templates.ts        模板字面量包裹(拼接式提示)

备份位于 <omp>/dist/.omp-zh-backup/(跟着安装走,多份 clone 共享)
bin/、runtime/ 为本地生成物(启动器与侧载运行时),不入库

支持的安装方式

omp 安装方式 汉化做法
bun install -g / npm / nix 直接改写包内 dist/cli.js,omp 启动即中文
官方预编译二进制(curl https://omp.sh/install | sh) 二进制内嵌字节码不可改写,改为侧载同版本 JS 运行时并生成 omp-zh 启动器;原 omp 不动
Homebrew 通常指向 npm 包,同第一种
源码构建 直接改写构建产物

侧载目录 ~/.omp-zh/runtime/<版本>/,启动器 ~/.omp-zh/bin/omp-zh。补丁器会按 omp --version 自动选择路径,无需手工配置。

二进制安装请用 omp-zh 启动(官方 omp 保持原样,仍是英文——这是设计如此,不是补丁失败)。 补丁器会自动把启动器软链到 ~/.local/bin/omp-zh(已存在则不覆盖),所以新开终端后直接敲 omp-zh 即可,无需手改 shell 配置。 启动器内部用绝对路径调用 bun,不依赖 ~/.bun/bin 是否在 PATH 中。 若 ~/.local/bin 也不在你的 PATH 中,会打印一行 export PATH=... 提示,或改用 ~/.omp-zh/bin/omp-zh 绝对路径。

不确定该敲哪个命令?./omp-zh.sh status 最后一行会写明「启动方式」。

快速开始(一行命令,始终用最新补丁)

curl -fsSL https://raw.githubusercontent.com/yebuwudong/omp-zh/main/install.sh | bash

自动 clone/更新补丁仓库到 ~/.omp-zh、补齐依赖并应用汉化。omp 升级后重跑同一行命令即可—— 每次都会拉取最新补丁(含新版本适配),无需手动改任何东西。

# 查看状态 / 还原英文 / 完整校验
curl -fsSL https://raw.githubusercontent.com/yebuwudong/omp-zh/main/install.sh | bash -s -- status
curl -fsSL https://raw.githubusercontent.com/yebuwudong/omp-zh/main/install.sh | bash -s -- restore
curl -fsSL https://raw.githubusercontent.com/yebuwudong/omp-zh/main/install.sh | bash -s -- test

或手动 clone(等价):

git clone https://github.com/yebuwudong/omp-zh.git ~/.omp-zh
cd ~/.omp-zh && ./omp-zh.sh apply

更新补丁

补丁会持续跟进上游版本,更新方式二选一(等价,第二条内部就是 git pull):

# 方式一:重跑安装命令(自动 pull + 应用)
curl -fsSL https://raw.githubusercontent.com/yebuwudong/omp-zh/main/install.sh | bash

# 方式二:手动更新已 clone 的目录
cd ~/.omp-zh && git pull && ./omp-zh.sh apply

git pull 只对已经 clone 过的目录有效(默认位置 ~/.omp-zh,可用 OMP_ZH_HOME 改)。 第一次使用请走上方的安装命令。

日常使用

cd ~/.omp-zh
./omp-zh.sh status     # 查看当前汉化状态
./omp-zh.sh restore    # 还原成官方英文版
./omp-zh.sh apply      # 重新应用汉化

临时切回英文(不改文件):

OMP_ZH=0 omp-zh     # 二进制安装
OMP_ZH=0 omp        # npm / bun -g 就地安装

不确定该用哪个命令?跑一次 ./omp-zh.sh status,最后一行会写明启动方式。

omp 升级后怎么办

omp upgrade / bun install -g 会覆盖 dist/cli.js,汉化随之丢失。重跑一条命令即可:

cd ~/omp-zh && ./omp-zh.sh apply

补丁器自带两层自动适配,绝大多数上游发版无需人工介入:

一、标识符重命名(通配匹配) —— 官方每次重打包都会重命名压缩后的内部变量 (如 Ke→$e、$3e→Sje),补丁会在精确匹配失败时切换到通配匹配, 自动捕获新变量名并代入替换文本:

anchor adapted: help epilogue block ($3e→Sje)
anchor adapted: thinking flag description (S5→U5)
...
anchors: 61/61 applied

二、文案改为动态渲染(多形态锚点) —— 有时上游会把写死的提示文字改成按快捷键表拼装, 字面量彻底消失,通配匹配也无能为力:

// 旧:字面量
`${n}j/k:select  Enter:open  t:${s}  Tab:details  r/x:manage  Esc:close`
// 新:按键名运行时渲染
`${n}${keys(["j","k"])}:select  ${key("enter")}:open  ...`

这类情况由锚点的 alts 字段承载:同一处 UI 的多种上游形态并列声明, 精确匹配逐形态尝试、通配匹配兜底,取第一个命中者。设置页脚的模板包裹同理。

只有上游改动文案或删除代码(而非重命名、也非形态变化)时才会真正失配,此时 apply 会报错退出且不写出坏产物(英文版原样保留),把报错发 issue 即可。

模板目标(设置页脚等字面量改写够不到的界面)失配属硬失败, check 会以 exit 1 拦截,避免某块 UI 悄悄停留在英文。

大版本升级后建议顺便跑一次 ./omp-zh.sh report, 命中数量若骤降说明产物结构大改,需要同步补丁规则。

维护者工具:一键补译

上游每次发版都会带来十几条新界面文案。补译只需一条命令:

cd ~/.omp-zh
bun tools/translate.ts

它会依次执行(每步都有进度提示):

步骤 动作
1/6 扫描 对照词典找出版本里未翻译的界面英文
2/6 翻译 调用 OpenAI 兼容端点批量翻译 + 模型自查(带着上下文和校验标记复核草稿并修订;--no-review 可关)
3/6 打印 输出全部候选(审计留痕,不打断流程)
4/6 并入 写进 dict-extra.json
5/6 验证 自动跑 apply + 完整断言(锚点、游离中文、回退)
6/6 发布 需显式 --push 才提交推送

默认全自动:初译后由同一模型复核(看到原句、调用上下文、机械校验标记),修订结果重新过一遍校验才允许并入; 候选文件 dict-candidates.json 保留完整记录供事后追溯。

常用参数:

bun tools/translate.ts --review           # 停在审阅(只打候选,不写词典)
bun tools/translate.ts --no-review        # 关闭模型自查(单遍翻译)
bun tools/translate.ts --dry-run          # 只扫描+翻译,不写任何文件
bun tools/translate.ts --push             # 验证通过后自动 commit + push
bun tools/translate.ts --model cn:glm-5.3 # 换翻译模型
bun tools/translate.ts --endpoint https://api.openai.com/v1   # 换端点

端点与凭据解析顺序(密钥永不入库):

--endpoint / OMP_ZH_ENDPOINT 环境变量
  ↓ 未设置时
~/.omp/agent/models.yml 里记录的本地网关
  ↓ 都没有
报错提示你配置

自动质量保障(无需人工):

  1. 结构校验(硬门禁):占位符 ${x}、数字形态不一致 → 拒绝并入(词典里没有该键,界面保持原文,不会出错)
  2. 术语锁(软提示):原文含 Compact/Vibe/Advisor/Prewalk… 时检查译文是否用了既定译法,违反则标记但仍并入,在输出里提示
  3. 审计留痕:全部候选写入 dict-candidates.json,随时可回看

需要手工介入时,底层工具可单独使用: bun tools/extract-gaps.ts --json report-gaps.json 扫描缺口, bun tools/auto-translate.ts 生成候选,--accept 并入。

扫描/翻译工具自己解析补丁目标(含二进制安装的侧载目录),无需设置任何环境变量; 需要指定时用 OMP_ZH_SRC(直接给 cli.js 路径)或 OMP_PKG(给包目录)。

汉化范围

已汉化:

  • 设置面板:分组标题、条目名称、描述、页脚提示(按 Enter/空格修改 · 按 Tab 跳转分区 · ←/→ 切换标签 · 输入以搜索 · 按 Esc 关闭)
  • 欢迎屏:欢迎回来!、提示、LSP 服务器、最近会话、快捷键说明
  • 首次启动向导与供应商登录流程的说明文字
  • 状态栏通知、错误与警告文案、斜杠命令描述与状态(loop 循环:关闭、循环:已暂停…)
  • 欢迎屏随机 Tip 正文(27 条全部)
  • 约 4200 处调用点、3200 余条词条(随上游发版持续增长)

不汉化(有意保留英文):

类别 例子 原因
面向模型的提示词 工具 JSON-Schema 的 description、summary 属于 prompt,翻译会改变 agent 行为
枚举与协议值 low/high/xhigh、braille、rebuild、true/false 参与 === 比较、switch 分支与持久化,翻译会破坏逻辑
设置分组标识 TAB_GROUPS 数组与 ui.group 排序用 indexOf 字符串匹配,必须两侧一致
命令与参数名 --auto-approve、/settings 输入标识符
用户数据 模型名、提供商名、版本号、工作目录 运行时数据,非界面文案

安全设计

补丁器只改写能证明是展示用途的字符串字面量,判定基于 AST 上下文:

  • ✅ 翻译:label:/description:/title: 等属性值、主题样式函数参数(fg/bold/showStatus…)、 设置分组名(属性侧与 TAB_GROUPS 数组侧同时翻译)、return 语句中的短状态标签
  • ❌ 跳过:对象键、import 源、比较运算、switch 分支、正则、计算属性、枚举数组、 集合构造调用、模型侧 schema 子树

任何字符串只要在某处出现在"逻辑/身份位",就整条跳过——避免同一文本半英半中出现不一致。

拼接模板(如页脚 Enter/Space to change · ${x}Type to search)单独处理:整段模板包裹进 运行时片段翻译函数 __omp_i18n_f,在字符串拼装完成后替换静态片段。

./omp-zh.sh verify 会重新解析产物并断言:

  • 产物语法完整(约 27 MB,零解析错误)
  • 所有 CJK 字面量都经由翻译函数,无游离中文落入逻辑位置
  • 每次翻译调用的参数都在词典内
  • 无标识符粘连(minified 代码 return"…" 改写后不得变成 return__omp_i18n_t)
  • 无原型属性名被包裹(见下)

原型链陷阱(已修复)

JS 里 dict["__proto__"] 返回 Object.prototype 而非 undefined,会骗过 !== undefined 守卫。 修复前有 25 处上游原型污染防护被静默破坏:

// 上游源码:跳过原型污染键
if (k === "__proto__" || k === "constructor") continue;
// 错误改写后:__omp_i18n_t("__proto__") 返回 Object.prototype
if (k === __omp_i18n_t("__proto__") || ...) continue;  // 恒为 false,防护失效

修复:所有查表改用 Object.hasOwn 隔离原型链 + FORBIDDEN_KEYS 显式拒绝 13 个 JS 原型属性名, verify 断言这两类键永不出现在调用点。

更新日志

补译流程修复:静默丢批、静默成功、无效词条

一轮补译暴露出三个问题,都影响「翻译结果是否可信」:

  1. 整批静默丢失(最严重) chat() 固定传 max_tokens: 4000。20 条 UI 文案的 JSON 回包会超过这个上限而被截断, 解析器用 lastIndexOf("}") 取到的是中间某个括号,于是整批 20 条全部丢失, 表现为「模型返回了非法 JSON」。现在不再传 max_tokens,用端点自己的默认值: 推理模型会先把预算花在隐藏思考上,任何我们选的上限要么截断 JSON、要么让 content 直接为空 (finish_reason: "length")。实测同一条请求:传 400 → 空内容;不传 → 完整返回。

  2. 全部批次失败却报成功 批次异常被 continue 吞掉,死端点也能跑完并输出「完成」、exit=0。 现在累计失败数,一条候选都没产出时直接硬失败并给出端点地址。

  3. 翻译注定无效的词条 有些缺口键的同一文本也出现在逻辑/身份位,补丁器会整条跳过(decideAll 的 ban 规则), 给它们加词条永远不生效。新增 patch.ts probe --keys <file> 批量判定, translate.ts 在花钱翻译之前先剔除这些键,并打印被排除的清单。

解析器同时改为括号配对扫描:截断会明确报 response was truncated,而不是含混的 model returned no JSON;chat() 还会区分「端点返回空内容」与「输出预算耗尽」。

补译工具路径解析 + 被救回锚点的验证误报

bun tools/translate.ts 在二进制安装上报 ENOENT: ~/.bun/install/global/...:扫描工具写死了 npm 全局安装路径,而本机汉化产物在侧载目录。现在扫描/翻译工具自动向补丁器询问目标路径, 二进制安装、npm/bun 全局安装、OMP_PKG / OMP_ZH_SRC 显式指定都能正确解析。

同时修掉一个会卡住整个补译流程的验证误报:上游把面板标题从 super("History") 改成 常量对象后,锚点找不到,但键本身仍能被字面量扫描翻译到 —— 这类「救回」的锚点已正确写入产物, verify 却仍报 anchor not applied,使 translate.ts 第 5 步(自动验证)失败、无法发布。 现在 planAnchors 显式返回被救回的锚点名,写入 manifest,verify 与 obsolete 同等对待。

顺带修掉两处易误判的地方:

  • check --code <已打补丁文件> 现在自动回退到旁边的原始备份,不再把「已汉化」误报成 「锚点全部失配」(CI 里表现为假的硬失败)。
  • check 摘要改为按条目名去重统计(61/61 entries ok)。此前把 all: true 锚点的多个 写入点相加,会出现 63/61 这种自相矛盾的数字。

动态渲染锚点适配 + PATH 自动补全

修掉「补丁显示成功、界面仍是英文」这一整类问题,共三处根因:

  1. 锚点失配导致 apply 整体失败(上游某次重构后开始) 上游把 Agent Hub 快捷键提示与设置页脚从字面量改为按键表动态渲染, 6 处锚点/模板目标失效。新增 alts 多形态锚点机制:同一 UI 的多种上游形态并列声明, 精确匹配逐形态尝试、通配匹配兜底。回归测试覆盖新旧多种产物形态,均 61/61 anchors applied。

  2. 启动器不在 PATH 二进制安装的汉化产物在侧载目录,必须用 omp-zh 启动;而 ~/.omp-zh/bin 默认不在 PATH, 用户敲 omp 看到英文,误以为补丁失败。现在补丁器自动软链到 ~/.local/bin(不覆盖已有文件), status 与 doctor 都会报告启动方式与 PATH 状态。

  3. 启动器依赖 bun 在 PATH 改用 process.execPath 记录的绝对路径调用 bun,最小环境(无 ~/.bun/bin)也能启动。

另外修掉一个静默失败:patch.ts path 在首次侧载新版本时会把 bun add 的进度输出混进 stdout, 使 omp-zh.sh 里的 $CLI 变成多行、[[ -f ]] 判定失败后直接退出,补丁从未应用。 现进度输出一律走 stderr,且 omp-zh.sh 取最后一行并显式校验。

CI 门禁同步收紧:模板目标失配从「软警告(exit 2)」升为「硬失败(exit 1)」, 因为它和锚点一样会让某块 UI 悄悄停留在英文。

已知限制

  • 极少数词典未收录的条目仍为英文(如 Agent Reactions、Mouse Click-to-Focus)。
  • 翻译来自社区分支 yequ172672/oh-my-pi-cn,个别术语可能与上游新增功能不完全对齐。
  • 已实测:--version、欢迎屏、设置面板(含页脚与右列值)、slash 补全描述、OMP_ZH=0 回退、TUI 冒烟零残留。

设置行右列的值显示

设置面板每行右侧显示的是原始配置值(true/false/rebuild/braille/none…),官方英文版同样直显。 这里复刻了上游汉化分支的 valueLabels 机制(该分支在组件层实现;官方产物没有这个字段, 所以在字符串层等价重建):

  1. defToItem 构建行时,__omp_i18n_vlm(e.options) 把该设置自己的选项标签映射成 {原值 → 显示标签}(标签走词典,例如 Rebuild→重建)。设置里 none 在不同条目下含义不同 (关/无/隐藏),所以必须按设置各自的选项表解析,不能全局一刀切。
  2. 无选项的行(布尔值与少数就地循环的枚举,如 discard/keep、per-call)回退到全局表 __omp_i18n_vd(true→是 等),这些取值集合无歧义。
  3. 行渲染时 __omp_i18n_vr(e) 先查第 1 步的表,再查全局表;文本框、多选、提供商限额等自由文本 行原样显示(代码里只对带 values 集合的行做映射,路径、API key、模型 id 不会被误翻)。
  4. 搜索索引同步收录映射后的标签,因此输入 重建 能搜到「调整滚动历史」条目。

运行时可断言验证(无需截图):

./omp-zh.sh test            # verify + 值标签断言(译文、歧义消解、自由文本原样)
OMP_ZH=0 bun tools/test-value-labels.ts   # 回退断言(全英文)

来源与许可

译文取自 yequ172672/oh-my-pi-cn(MIT,与上游 can1357/oh-my-pi 同许可)。本地仅做版本适配与安全裁剪,未改动译文语义。

About

No description, website, or topics provided.

Resources

Stars

28 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages