<!-- deepseek-harness-meta
{
  "name": "Community Russian dictionaries for DeepSeek Harness plugins",
  "version": "0.1.0",
  "tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
  "description": "Translates third-party DeepSeek Harness plugins without forking them: the missing Russian dictionary is contributed as data. It fills only the namespaces nobody has claimed and steps aside as soon as a plugin ships its own translation. Ships the plugin market's Russian dictionary as its first payload.",
  "compatible_versions": ["v0.2.1-alpha.1", "v0.2.0-rc.2", "v0.1.7-rc.2", "v0.1.7-rc.1"],
  "install_method": "dsh plugin --profile web add @ragnoryok1/dsh-locale-bridge"
}
-->

# @ragnoryok1/dsh-locale-bridge

[Русский](README.md) | [English](README.en.md) | **中文**

为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的**第三方**插件提供俄语词典——以数据形式接入，无需 fork。

第三方插件注册自己的 locale namespace 时只提供 `zh`/`en`，通常不带俄语。过去要翻译它们，只能 fork 插件。本包换了一种做法：把缺失的词典作为数据贡献出去——先尝试为某个 namespace 注册俄语，如果该 namespace 空闲就保留注册结果，一旦插件自带翻译就让位。首个载荷是插件市场（`dsh-market`）。对于不询问 locale 服务、自己绘制文本的插件，本包无能为力——这条限制是真实存在的，经过实测，下文有说明。

## 为什么需要它

社区插件通过 locale 服务（`ctx.locale.register`）注册自己的字符串，语言是中文和英文。它们通常没有俄语，而唯一的办法是 **fork 插件**——也就是从此永远接手它的更新。

桥接的做法不同：词典以**数据**形式注入。

## 它的行为方式

三条规则，而且三条都是 locale 契约的结果，而不是我们的偏好：

1. **只填充空闲的位置。** 如果 namespace 已经有这门语言，`locale.register(ns, locale, dict)` 会抛异常。桥接会尝试注册，并把**拒绝视为正常结果**。
2. **让位给作者。** 插件一旦发布自己的俄语，桥接的注册就会被拒绝，什么都不会覆盖。没有版本冲突，也没有 namespace 之争。
3. **如实报告，而不是沉默。** 契约没有公开的方式查询哪些 namespace 已被占用——词典映射是私有的。所以「没有抛异常」这一事实本身就证明词典是我们填充的，它会写进日志，而不是消失在捕获到的异常里。

## 首个载荷：插件市场

![俄语界面的插件市场](images/market-ru.png)

`dsh-market` 词典就是插件 [dshmarket](https://www.npmjs.com/package/dshmarket) 的界面。

**687 行中的 687 行已完成翻译**——市场的整个界面。

**已在真实 harness 上检查通过。** 市场在设置中的标题取自词典
（`t('nav')`），安装桥接之后它变成了俄语——«Маркет плагинов»，
界面中不再有英文的 «Plugin Market»，控制台也没有任何报错。

覆盖率是在屏幕上测出来的，而不是看文件：在 357 个可能逐字出现的英文短值中，
**有 350 个以俄语显示**。剩下七个
是误报——它们是**目录数据，而不是界面文本**：

| 出现在哪里 | 实际是什么 |
|---|---|
| «local»、«official»、«source»、«files» | 市场从自己的 API 获取的插件描述 |
| «Themes»、«Theme» | 来自同一个 API 的类别名称（«Themes & Appearance»） |

不能翻译它们：这是目录内容，它属于数据源，并且会在我们没有参与的情况下变化。
界面本身则已完整翻译。

## 它做不到什么

**自带字符串的插件，桥接够不到。** 例如 `@zseven-w/dsh-android`：它自己选择语言（`androidCopy(locale)`，只有 `zh`/`en`），根本不询问 locale 服务。任何词典都触不到这样的插件——只能由作者修改。

这不是桥接的缺陷，而是契约的边界。它经过了实测：测试 profile 中的十个第三方包，四个使用 locale 契约，一个自己绘制文本，五个没有自己的字符串。

## 如何添加词典

添加翻译是**改数据**，而不是改代码：

1. 把 JSON 放在 `src/client/dicts/` 里其他词典旁边（扁平的「键 → 字符串」对象）；
2. 在 `src/client/index.ts` 的 `DICTIONARIES` 列表里补一行。

键必须与插件自带的词典一致：多余的键不会生效，缺失的键会以英文显示（契约自带的回退行为），所以不完整的词典是安全的。

## 安装

```
dsh plugin --profile web add @ragnoryok1/dsh-locale-bridge
```

如果主本地化包还没有添加俄语，俄语会被自动添加——桥接既能单独工作，也能与它一起工作。

## 构建

```
npm install
npm run build     # tsdown -> lib/index.js (host half) + lib/client.js (client bundle, словари внутри)
npm pack
```

## 内容

- `src/client/index.ts` — 桥接：添加语言、注册词典、报告；
- `src/client/dicts/*.json` — 「原文」和「译文」词典；
- `src/index.ts` — 空的 host 部分；
- `cordis.patch.yml` — profile 补丁。

## 许可证

MIT。社区包，**与 DeepSeek 无关**。第三方插件的翻译由社区完成，可能不准确——请在 issues 中报告错误。
