dsh-languages:给 DSH Web UI 装 14 种社区翻译

前言

DSH 的理念是「一切皆插件」,但界面本身只内置了英文和中文两套文案。这两套文案编译在 @deepseek-ai/dsh-client-* 客户端 bundle 里,激活时通过 ctx.locale.register(ns, { zh, en }) 注册;插件没有独立的翻译文件可以覆盖。于是想给团队换成俄文、日文或越南文界面,常见做法是改打包后的 app.asar,或者干脆不改。

dsh-languages 就是针对这个问题的:一个插件包,走 DSH 公开的 ctx.locale API 注册 14 种社区语言,覆盖聊天、设置、插件、调度器、侧边栏、对话框和系统消息。维护者是社区开发者 elims777,项目属于客户端分类,在社区目录里由第三方收录。README 明确写了「非官方项目,与 DeepSeek 无关」。

这是什么

一句话定位:社区维护的语言包,通过 ctx.locale.addLanguage + ctx.locale.register 给 DSH Web UI 注入多语言,不碰 app.asar,也不重新构建客户端。

支持的语言

语言 代码 状态
俄语 ru 已完成,100%
西班牙语 es 社区草稿
巴西葡萄牙语 pt-BR 社区草稿
德语 de 社区草稿
法语 fr 社区草稿
意大利语 it 社区草稿
波兰语 pl 社区草稿
土耳其语 tr 社区草稿
日语 ja 社区草稿
韩语 ko 社区草稿
繁体中文 zh-TW 社区草稿
印尼语 id 社区草稿
越南语 vi 社区草稿
印地语 hi 社区草稿

14 种语言每种 2 886 行,共 63 个 namespace。阿拉伯语(ar)没有纳入,因为 DSH 界面不支持 RTL 布局。已完成的语言会进入构建;只翻译了部分 namespace 的新语言不会自动加入,需要补全后随 PR 提交。

安装与启用

方式一:界面安装

1、打开侧边栏 Plugins,点 Install。
2、填 spec:dsh-languages(npm 包名)或 github:elims777/dsh-languages(GitHub 源码)。README 建议 npm 优先。
3、启用 bundle,按 Ctrl+R 刷新页面。
4、进 Settings → General → Language 选择语言。

方式二:CLI 安装

dsh plugin add dsh-languages
# 或从 git 安装:
dsh plugin add github:elims777/dsh-languages

装完重启应用,再到设置里选语言。

方式三:离线手动安装

从 releases 下载 dsh-languages-<版本>.zip,解压后执行:

powershell -ExecutionPolicy Bypass -File install.ps1

脚本会把包复制到 %USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-languages,并写入 dsh.profile.bundles。-Profile <名称> 指定 profile,-DshHome <路径> 指定主目录。之后重启 DSH。

已验证的兼容版本

README 记录的实测环境是 DSH 0.2.1-rc.5(Windows / Desktop):bundle 方式安装,14 种语言实时切换,未翻译的键回落到英文,卸载干净。反馈贴在 https://github.com/deepseek-ai/deepseek-harness/discussions/12172 。

它是怎么工作的

DSH 没有独立翻译文件,插件做的是在客户端 bundle 之外补注册一套语言。包内文件分工如下:

文件 作用
cordis.patch.yml bundle patch,在组合里插入 locales 行
lib/index.js Node 侧占位,让 Loader 里的字符串合法
lib/client.js browser 侧:注册全部语言和词条
locales/en/*.json 从应用里抽取的英文词条,作为 key 基准
locales/<代码>/*.json 各语言译文,一个 namespace 一个文件
locales.json 语言目录(代码 + 显示名)
locale/*.json 插件列表用的包元数据

lib/client.js 做的事就是官方文档里那两行:

ctx.locale.addLanguage({ id: 'de', label: 'Deutsch', fallback: 'en' });
ctx.locale.register('settings', 'de', { trigger: 'Einstellungen' });

未翻译的键自动取英文(fallback en),所以缺翻译不会整屏空白。包是零依赖的纯 JavaScript,构建产物 bundle 直接随包分发。

典型用法

装好之后就是切语言。设置路径:Settings → General → Language。选了语言即时生效,不需要重新启动;界面刷新后仍是所选语言,因为注册发生在客户端 bundle 激活时。

想加自己的语言:

node tools/new-locale.mjs de "Deutsch"   # 生成 locales/de/ 和 locales.json 记录
# 翻译 locales/de/*.json 里的 value,key 和 {占位符} 不要动
npm run check                            # 校验完整性并重建 lib/client.js

然后提交 locales.json、locales/de/、lib/client.js 并开 PR。详细规则、术语表和质量要求在 CONTRIBUTING.md,PR 里可以把自己写成该语言的 maintainer。语言不必放进这个公共包:做一个自己的语言插件,只要包里有 dsh.client,执行 addLanguage 和 register 即可,本仓库可以当模板,DSH 会同时加载两个插件。

维护现有翻译时,DSH 升级后用下面的命令抽取新英文串:

node tools/extract.mjs "<路径>\resources\app.asar"   # 更新 locales/en/*.json
npm run build

新 key 会出现在 locales/en/<namespace>.json 里,逐个语言补上即可。构建会因为缺 key 或 {占位符} 不一致而失败。

故障排查

  • 列表里没有新加的语言 — bundle 没挂上。检查 dsh.profile.bundles 里有 dsh-languages,然后重启应用;Ctrl+R 不够,组合图是启动时构建的。
  • 部分字符串仍是英文 — 是新版 DSH 带来的新 key。跑 node tools/extract.mjs …,补齐译文,npm run build。
  • 登录成功但显示「账户数据暂不可用」 — 不是本地化问题。该面板从 platform.deepseek.com 请求姓名和邮箱,请求没通过(token 过期,或被网络/WAF 拦了)。重新登录或换网络可恢复。
  • 装完白屏 — 从 dsh.profile.bundles 移除 dsh-languages,重启,然后带 DSH 版本提 issue。

适用场景与注意

适合:团队内部日志和协作要统一成非英、非中界面,又不想改应用包、不想自己维护 fork。也适合想从零做起某个语言插件的开发者——本包的文件结构和 CONTRIBUTING 流程可以直接照着抄。

需要留意的边界,基本都写在 README 的「Ограничения」一节:

  • 插件以当前 dsh 进程的权限运行,装之前要检查源码和许可证(本包是 MIT)。它不联网取翻译,装的是别人仓库里的静态 JSON。
  • 动态元数据(LocalizedText,包名、插件名等由宿主提供的值)仍是英文,因为它们在 app.asar 内的 manifest 里,不在界面 bundle 中。
  • 紧凑单位({count} min、{value} tok/s)和产品名(Cursor、VS Code、PDF)是有意不翻译的。
  • DSH 没有 ICU 复数形式,含 {count} 的字符串统一用中性表述。
  • 译文由社区完成,含机器翻译加人工校对,欢迎母语者提 PR 修正。

结尾

dsh-languages 的价值在于把「DSH 界面只有英文和中文」这个限制收窄为一个可插拔的选项:不改包、不加依赖,装完在设置里选语言。14 种语言里只有俄语标注为 100% 完成,其余是社区草稿,覆盖完整度需要按 namespace 自查。

目录页:https://www.skillhub.cn/plugins/elims777/dsh-languages
代码与安装说明:https://github.com/elims777/dsh-languages

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜