DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

syzke /

syzke/dsh-translate-on-select

Verified

DSH 划词翻译插件:鼠标选中非中文内容后,在选区下方就地浮出简体中文译文 | Select-to-translate plugin for DeepSeek Harness (DSH)

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@f779af0c

dsh-translate-on-select

DSH 划词翻译插件:鼠标选中非中文内容后,在选区下方就地浮出一张卡片显示简体中文译文。

选中即翻 —— 不用快捷键、不用装浏览器扩展、不用离开当前页面。

翻译卡片示意图

上图是卡片外观的示意(非真实截图)。实际效果:选中一段外文 → 松手约 200ms → 选区正下方出现译文卡片。


特性

  • 划词即译:松开鼠标约 200ms 后自动翻译,落点在选区正下方(下方空间不够会自动翻到上方)。
  • 自动判断要不要翻:纯中文选区直接跳过(省掉一次「翻完还是原文」的无用请求);日语、韩语因为有假名/谚文会被正确判定为「需要翻译」。
  • 不打扰输入:在输入框、文本域、contenteditable 里的选区不会触发。
  • 自动识别源语言:英文、日文、德文等都能识别,卡片上会显示「英语 → 简体中文」。
  • 缓存:同一段文本第二次选中是瞬时返回(内存 LRU,宿主与前端各一层)。
  • 美观且跟主题:毛玻璃卡片、圆角、柔和投影,自动跟随 DSH / 系统的明暗主题;带骨架屏加载态;尊重 prefers-reduced-motion。
  • 可交互:一键复制译文、重新翻译、Esc / 点空白处关闭。
  • 多后端回退:主用 cn.bing.com,失败自动切 MyMemory。
  • 零依赖、零构建:纯 JavaScript,没有第三方依赖,也没有 prepare/build 脚本。

安装

需要已安装 dsh CLI(DeepSeek Harness 桌面客户端自带,源码运行时用 pnpm dsh)。

方式一:从 GitHub 安装(推荐)

dsh plugin --profile desktop add github:syzke/dsh-translate-on-select
  • 需要本机装了 git(pnpm 通过 git 拉取源码)。
  • desktop 是桌面客户端的 profile;如果你跑的是 dsh web,把 --profile desktop 换成 --profile web。
  • 本插件没有 prepare 脚本,所以 pnpm 不会要求你在 pnpm-workspace.yaml 里追加 allowBuilds 授权,装完即可用。
  • 想锁定版本:先给仓库打 tag(如 v0.1.0),再 dsh plugin --profile desktop add github:syzke/dsh-translate-on-select#v0.1.0。

方式二:本地源码安装(改代码立即生效)

dsh plugin --profile desktop add "link:/absolute/path/to/dsh-translate-on-select"

link: 是软链安装:源码改动立即生效(前端改完硬刷新即可,宿主改完要重启客户端)。 代价是不能移动或重命名该源码目录,移动后要重新 add 一次。 想改成拷贝安装(此后源码改动不再同步)用 file:<路径>。

⚠️ 装完必须重启一次客户端

webserver/index-inject 的注入行不会热生效,需要重启一次 DeepSeek Harness;只刷新页面(F5 / Ctrl+F5)是不够的。

原因:桌面端的注入表由 dsh-desktop-host 在宿主启动时一次性收集(collectIndexInjections()),Electron 主进程把它缓存成数组,之后每次 dsh-desktop:boot IPC 都返回同一份。所以哪怕是整页重载,拿到的还是启动那一刻的旧表 —— 新加的注入行必须靠重启应用才会被重新收集。

重启后自检:

  1. 右下角不应出现任何东西(本插件没有常驻图标,这是正常的)。
  2. 在任意助手回复里用鼠标选中一段英文 → 选区下方应浮出译文卡片。
  3. 若没反应:打开开发者工具看 Console 有没有 /dsh-translate/client.js 的报错;Network 里应能看到该请求返回 200。

配置

配置文件在 $DSH_HOME/.dsh-translate.json(Windows 默认即 C:\Users\<你>\.dsh\.dsh-translate.json),首次改配置时才会创建:

{
  "to": "zh-Hans",
  "enabled": true
}
字段 说明
to 目标语言。zh-Hans=简体中文(默认);也支持 zh-Hant、en、ja 等。Bing 用 BCP-47 码,改这个就能当反向词典用。
enabled 设为 false 可整体关掉翻译(插件仍加载,但接口会直接返回「已关闭」)。

改完不用重启(每次请求都重新读文件)。

环境变量(可选)

变量 用途
DSH_TRANSLATE_CONTACT MyMemory 的联系邮箱。匿名额度约 5000 字符/天,填了可提到 5 万。
DSH_TRANSLATE_TRUSTED_HOSTS 逗号分隔。仅当宿主信任栅栏不可用且你把 DSH 放在了反代/局域网后面时才需要。

安全与隐私

  • 翻译请求在宿主侧发出,只监听 127.0.0.1(DSH 默认绑定),不对外暴露。
  • 所有路由都套了信任栅栏,三层策略:自身校验(拒绝 Sec-Fetch-Site: cross-site;有 Origin 时必须与 Host 同源)→ 委托宿主栅栏 ctx.connection.requestRejection → fail-closed(栅栏抛异常按拒绝处理)。没有宿主栅栏时只放行回环地址 / DSH_TRANSLATE_TRUSTED_HOSTS。
  • 请知悉:翻译走的是公共免费接口,也就是你选中的文本会被发送到 cn.bing.com(必要时还有 MyMemory)。不要用它翻密钥、隐私数据或未公开的代码。

已知限制

  • 译文是「重排版」的:长文本按 4000 字符分片,各片独立翻译后拼接,所以长段的换行可能与原文不完全一致(字符顺序与内容不丢)。
  • 延迟:短句约 0.7–1.4s,2000 字符级别约 4s。没有流式输出,用骨架屏顶着。
  • 公共接口的稳定性不由我们控制:Bing 的 ttranslatev3 靠页面里的 params_AbusePreventionHelper token(1 小时有效,自动续期),页面结构变了就可能失效;MyMemory 匿名额度很小。两者都挂时会显示带原因的失败卡片,可点 ⟳ 重试。
  • 滚动或缩放窗口时卡片会收起(选区会跟着动,钉在原位必然错位)。
  • 选中 20000 字符以上不翻译。

卸载

dsh plugin --profile desktop remove dsh-translate-on-select

然后重启客户端。

实现说明

dsh-translate-on-select/
├── package.json          # dsh.bundle.patch → cordis.patch.yml
├── cordis.patch.yml      # 挂载声明
├── lib/
│   ├── index.js          # 宿主:注入行 + 本地路由 + 信任栅栏 + 配置
│   └── providers.mjs     # 翻译后端:Bing / MyMemory + 分片 + 缓存
├── assets/
│   └── translate.js      # 前端:选区监听 + 卡片(样式内嵌)
├── test/
│   └── providers-test.mjs # 后端自测(会真实联网)
└── docs/preview.svg      # 卡片外观示意

数据流

页面选区 ──► assets/translate.js ──POST /dsh-translate/translate──► lib/index.js
                                                                      │
                                                       lib/providers.mjs
                                                      ├─ Bing(cn.bing.com,主)
                                                      └─ MyMemory(备)

翻译放在宿主侧而不是浏览器里直接调,有三个好处:绕开 CORS、能集中做缓存/分片/多后端回退、能把探测到的真实语言回传给界面显示。

为什么用 webserver/index-inject 而不是 dsh.client

DSH 确实有 dsh.client 客户端插件机制(window.__ModuleLoader__.load({...})),但它是槽位(slot)导向的:UI 只能注册进 DSH 已声明的具名槽位(如 conversation.composer.dock)。本插件要的是覆盖任意页面内容的全局浮层,没有对应槽位,所以走注入行这条路。

注入行必须是内联脚本(kind:'script')而不是 kind:'script-src':页面侧解释器对后者是「加载失败即 reject 掉 __DSH_BOOT_READY__,整个应用起不来」。内联行里由我们自己创建 <script src> 并吞掉 onerror,这样插件被停用、路由注销时只会静默失败,绝不会把宿主拖死。

开发

# 语法检查(离线)
node --check lib/index.js && node --check lib/providers.mjs && node --check assets/translate.js

# 后端自测(会真实请求 cn.bing.com / MyMemory)
node test/providers-test.mjs
  • 改 assets/translate.js(前端 / 样式)→ 卡片不出现或样式不对时,Ctrl+F5 硬刷新即可,不用重启。
  • 改 lib/*.js(宿主 / 路由 / 后端)→ 需要重启客户端。

可能的后续增强

  • 换成 DSH 自带模型:ctx.llm.stream() + ctx.agentDefaultModel.currentSelection() 是公开可用的(dsh-session-title-llm 就是现成范例)。这样质量更好、无需第三方出网、不用公共接口,代价是消耗你自己的模型额度。当前 providers.mjs 的结构就是为这种替换留的(一个 provider 就是 {label, maxChunk, translate})。
  • 命中缓存时右侧显示「原文 → 译文」对照。
  • 加一个快捷键(如 Alt+Shift+T)对当前选区强制翻译,绕过「已是中文则跳过」的判断。

English

A select-to-translate plugin for the DeepSeek Harness (DSH) desktop app. Select any non-Chinese text with the mouse, and a floating card with the Simplified Chinese translation appears right below the selection — no hotkey, no browser extension, no leaving the page.

dsh plugin --profile desktop add github:syzke/dsh-translate-on-select

Then restart the app once (the injection table is collected at host startup and is not hot-reloaded). Text you select is sent to the public cn.bing.com translator (falling back to MyMemory); do not use it on secrets or private data.

许可

MIT。翻译内容来自第三方公共接口,其准确性不作保证。

—/ 5

No ratings yet

Verified DSH bundle

Commit f779af0c8af5

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout