@ragnoryok1/dsh-client-locale-ru 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.en.md +10 -3
- package/README.md +10 -3
- package/README.zh.md +9 -4
- package/lib/client.js +26 -5
- package/lib/typography.js +2 -1
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,51 @@
|
|
|
6
6
|
Пакет следует за харнессом: целевая версия — `dsh 0.2.1-alpha.1` и новее
|
|
7
7
|
(`>=0.1.0-rc.2 <0.3.0` для `@deepseek-ai/dsh-client-locale`).
|
|
8
8
|
|
|
9
|
+
## [0.2.7] — 2026-10-19
|
|
10
|
+
|
|
11
|
+
### Исправлено
|
|
12
|
+
|
|
13
|
+
- **Проход типографики больше не правит переписку.** Он переписывал текстовые узлы во всём
|
|
14
|
+
документе, кроме кода, полей ввода и редактируемого содержимого, — а переписка в это
|
|
15
|
+
исключение не попадала: кавычки и тире превращались в «ёлочки» и em dash внутри сообщений,
|
|
16
|
+
и в словах пользователя, и в ответе модели. Пакет правит интерфейс, а чужой текст
|
|
17
|
+
принадлежит автору. Харнесс сам помечает область переписки (`data-conversation-region`), и
|
|
18
|
+
эта метка теперь в списке исключений. Проверено тестом: подпись рядом с перепиской
|
|
19
|
+
превращается в «Нажмите «Сохранить» для продолжения», сообщение остаётся дословным.
|
|
20
|
+
|
|
21
|
+
### Добавлено
|
|
22
|
+
|
|
23
|
+
- **Пакет говорит, когда проиграл язык другому пакету.** Сервис локали отдаёт язык тому, кто
|
|
24
|
+
зарегистрировал его первым, и второй русский пакет раньше терял свои словари молча.
|
|
25
|
+
Теперь в консоли появляется: «[dsh-client-locale-ru] язык ru уже занят другим пакетом; наши
|
|
26
|
+
словари не зарегистрированы в 81 namespace. В интерфейсе останется перевод другого пакета —
|
|
27
|
+
оставьте в профиле один пакет с русским языком.»
|
|
28
|
+
- **Отчёт о плагинах предупреждает о сопернике:** `npm run report:plugins` перечисляет
|
|
29
|
+
пакеты, которые сами претендуют на русский, с их версиями.
|
|
30
|
+
- **Публикация в CI идемпотентна.** Реестр отвечает на запрос с задержкой в минуты, и релиз,
|
|
31
|
+
вырезанный вручную и помеченный тегом, попадал в это окно: страж успевал решить, что
|
|
32
|
+
версии нет, а npm отказывался публиковать поверх существующей. Теперь страж спрашивает
|
|
33
|
+
трижды, а публикация после отказа перепроверяет реестр и заканчивается успешно.
|
|
34
|
+
- **Гейт формы workflow.** Сломанный workflow не падает громко: GitHub сообщает о прогоне по
|
|
35
|
+
имени файла, без единого job, а локальные гейты остаются зелёными. `npm run
|
|
36
|
+
check:workflow-yaml` проверяет отступы, `run:`/`uses:` у каждого шага и табуляции.
|
|
37
|
+
|
|
38
|
+
Цепочка verify выросла до 22 проверок.
|
|
39
|
+
|
|
40
|
+
## [0.2.6] — 2026-10-19
|
|
41
|
+
|
|
42
|
+
### Изменено
|
|
43
|
+
|
|
44
|
+
- **Описание пакета теперь содержит слова, по которым его ищут.** Замер поиска npm: пакет был
|
|
45
|
+
первым по запросу «dsh language pack», но не попадал в первые 250 результатов по «dsh i18n»
|
|
46
|
+
и «dsh russian» — у соседнего пакета эти слова есть в *имени* (`dsh-i18n`), а мы можем
|
|
47
|
+
совпасть только текстом. В описании появились «i18n» и «Russian (ru)», а в блок метаданных
|
|
48
|
+
каталога — «i18n».
|
|
49
|
+
- **В трёх README описана причина отказа установки.** Политика зрелости pnpm не ставит версии,
|
|
50
|
+
опубликованные меньше 48 часов назад: профиль отвечает `ERR_PNPM_NO_MATURE_MATCHING_VERSION`,
|
|
51
|
+
и это выглядит как поломка пакета. Теперь в разделе установки сказано, что это политика и
|
|
52
|
+
что с ней делать.
|
|
53
|
+
|
|
9
54
|
## [0.2.5] — 2026-10-19
|
|
10
55
|
|
|
11
56
|
### Исправлено
|
package/README.en.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!-- deepseek-harness-meta
|
|
2
2
|
{
|
|
3
3
|
"name": "Russian (ru) language pack for DeepSeek Harness",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.7",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "Full Russian interface for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
6
|
+
"description": "Full Russian interface (i18n) for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
7
7
|
"icon": "https://raw.githubusercontent.com/Ragnoryok1/dsh-client-locale-ru/main/assets/icon.png",
|
|
8
8
|
"compatible_versions": ["v0.2.1-rc.2", "v0.2.1-rc.1", "v0.2.1-alpha.5", "v0.2.1-alpha.4", "v0.2.1-alpha.3", "v0.2.1-alpha.2", "v0.2.1-alpha.1", "v0.2.0-rc.2", "v0.2.0-rc.1", "v0.1.7-rc.2", "v0.1.7-rc.1", "v0.1.7-alpha.2"],
|
|
9
9
|
"screenshots": "images",
|
|
@@ -43,6 +43,9 @@ language pack; only `locale/ru.json` files on the harness side can close them.
|
|
|
43
43
|
Plugins outside the harness tree are translated the same way, but their English comes from
|
|
44
44
|
their own publication: `plugins/<namespace>.json` records the package, version, licence and the
|
|
45
45
|
English strings extracted from its bundle (`npm run fetch:plugins`). `npm run report:plugins`
|
|
46
|
+
It also warns about another thing: when the profile holds a second pack that registers
|
|
47
|
+
Russian itself, the language belongs to whoever registered it first — the other one silently
|
|
48
|
+
skips its namespaces, and the interface ends up showing someone else's translation.
|
|
46
49
|
shows what in your installation is still English: it walks the profile's `node_modules`, reads
|
|
47
50
|
each plugin's own dictionary and compares its keys with ours. A plugin without a dictionary is
|
|
48
51
|
reported as such — there is nothing to translate until it asks for one — and a plugin that
|
|
@@ -96,9 +99,13 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
96
99
|
|
|
97
100
|
After that, the next time `dsh web` starts, **Русский** will appear in the settings. A separate `pnpm add` into a built `dsh web` is not needed — the plugin pulls in the built-in locale through the `locale` service.
|
|
98
101
|
|
|
102
|
+
If pnpm answers `ERR_PNPM_NO_MATURE_MATCHING_VERSION`, that is not a broken package but a
|
|
103
|
+
maturity policy: a profile refuses versions published less than 48 hours ago. Wait a day or
|
|
104
|
+
two (the message names the version) or drop the `minimumReleaseAge` limit in the profile
|
|
105
|
+
settings.
|
|
99
106
|
The manifest is checked against the harness's own rules rather than by eye (`npm run check:manifest`, part of `verify`). Each rule was read out of the harness sources and each is a failure the user would otherwise meet first: `parseDshClient` accepts `platform` as any string while the consumers keep only `platform === 'web'`, so a typo like `'Web'` would **silently drop** the client half; a declared `dsh.client` without the `./client` export makes `client-modules` throw; and `dsh.bundle.patch` has to point at a file that exists.
|
|
100
107
|
|
|
101
|
-
Installing from GitHub works too: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (the form the plugin catalogue generates, without the npm scope) installs the repository archive, and the built `lib/` is committed — no build runs on your machine, and none is needed. That is exactly why `npm run check:built` (part of `verify`) rebuilds `lib/` and compares it with the commit: a stale bundle in git would reach the user, while the audit would never see it, because the audit reads the sources. The published package is
|
|
108
|
+
Installing from GitHub works too: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (the form the plugin catalogue generates, without the npm scope) installs the repository archive, and the built `lib/` is committed — no build runs on your machine, and none is needed. That is exactly why `npm run check:built` (part of `verify`) rebuilds `lib/` and compares it with the commit: a stale bundle in git would reach the user, while the audit would never see it, because the audit reads the sources. The published package is 497 kB: the banner ships as JPEG, and the icon and source map stay out of the npm payload.
|
|
102
109
|
|
|
103
110
|
## Why hybrid
|
|
104
111
|
|
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!-- deepseek-harness-meta
|
|
2
2
|
{
|
|
3
3
|
"name": "Russian (ru) language pack for DeepSeek Harness",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.7",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "Full Russian interface for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
6
|
+
"description": "Full Russian interface (i18n) for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
7
7
|
"icon": "https://raw.githubusercontent.com/Ragnoryok1/dsh-client-locale-ru/main/assets/icon.png",
|
|
8
8
|
"compatible_versions": ["v0.2.1-rc.2", "v0.2.1-rc.1", "v0.2.1-alpha.5", "v0.2.1-alpha.4", "v0.2.1-alpha.3", "v0.2.1-alpha.2", "v0.2.1-alpha.1", "v0.2.0-rc.2", "v0.2.0-rc.1", "v0.1.7-rc.2", "v0.1.7-rc.1", "v0.1.7-alpha.2"],
|
|
9
9
|
"screenshots": "images",
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
Плагины за пределами дерева харнесса переводятся так же, но их английский текст берётся
|
|
37
37
|
из их собственной публикации: `plugins/<namespace>.json` хранит пакет, версию, лицензию и
|
|
38
38
|
английские строки, выгруженные из бандла (`npm run fetch:plugins`). Что ещё осталось
|
|
39
|
+
Отдельно он предупреждает и о другом: если в профиле есть ещё один пакет, который сам
|
|
40
|
+
регистрирует русский, язык достаётся тому, кто зарегистрировал его первым, — второй молча
|
|
41
|
+
пропустит свои namespace, и в интерфейсе окажется перевод чужого пакета.
|
|
39
42
|
английским в вашей установке, показывает `npm run report:plugins`: он обходит
|
|
40
43
|
`node_modules` профиля, находит в каждом плагине его собственный словарь и сравнивает
|
|
41
44
|
ключи с нашим. Плагин без словаря он так и называет — переводить нечего, пока плагин не
|
|
@@ -100,6 +103,10 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
100
103
|
|
|
101
104
|
Дальше при следующем старте `dsh web` в настройках появится **Русский**. Отдельно `pnpm add` в собранный `dsh web` не нужен — плагин тянет штатную локаль через сервис `locale`.
|
|
102
105
|
|
|
106
|
+
Если pnpm отвечает `ERR_PNPM_NO_MATURE_MATCHING_VERSION` — это не поломка пакета, а
|
|
107
|
+
политика зрелости: профиль не ставит версии, опубликованные меньше 48 часов назад.
|
|
108
|
+
Подождите сутки-двое (имя версии в сообщении показывает, сколько осталось) или снимите
|
|
109
|
+
ограничение `minimumReleaseAge` в настройках профиля.
|
|
103
110
|
Манифест проверяется по правилам харнесса, а не на глаз (`npm run check:manifest`, входит в
|
|
104
111
|
`verify`). Правила вычитаны из его исходников и каждое — это отказ, который иначе увидел бы
|
|
105
112
|
пользователь: `parseDshClient` принимает `platform` любой строкой, но потребители отбирают
|
|
@@ -107,7 +114,7 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
107
114
|
половину; declared `dsh.client` без экспорта `./client` заставляет `client-modules` бросить
|
|
108
115
|
ошибку; `dsh.bundle.patch` обязан указывать на существующий файл.
|
|
109
116
|
|
|
110
|
-
Установка из GitHub тоже работает: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (в таком виде команду генерирует каталог плагинов, без `@`-скоупа) ставит архив репозитория, а собранный `lib/` лежит в git — сборка на вашей машине не запускается и не требуется. Поэтому `npm run check:built` (входит в `verify`) пересобирает `lib/` и сверяет его с коммитом: устаревший бандл в git иначе получил бы именно пользователь, а аудит этого не увидел бы — он читает исходники. Публикуемый пакет занимает
|
|
117
|
+
Установка из GitHub тоже работает: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (в таком виде команду генерирует каталог плагинов, без `@`-скоупа) ставит архив репозитория, а собранный `lib/` лежит в git — сборка на вашей машине не запускается и не требуется. Поэтому `npm run check:built` (входит в `verify`) пересобирает `lib/` и сверяет его с коммитом: устаревший бандл в git иначе получил бы именно пользователь, а аудит этого не увидел бы — он читает исходники. Публикуемый пакет занимает 497 КБ: баннер отдаётся JPEG, а иконка и карта исходников в npm не входят.
|
|
111
118
|
|
|
112
119
|
## Почему гибрид
|
|
113
120
|
|
package/README.zh.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!-- deepseek-harness-meta
|
|
2
2
|
{
|
|
3
3
|
"name": "Russian (ru) language pack for DeepSeek Harness",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.7",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "Full Russian interface for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
6
|
+
"description": "Full Russian interface (i18n) for the DeepSeek Harness web GUI: 81 namespaces, 4949 translated strings, Russian screen typography, and a locale audit in CI pinned to a harness tag. Includes the automation-task manager and the reminder catalog.",
|
|
7
7
|
"icon": "https://raw.githubusercontent.com/Ragnoryok1/dsh-client-locale-ru/main/assets/icon.png",
|
|
8
8
|
"compatible_versions": ["v0.2.1-rc.2", "v0.2.1-rc.1", "v0.2.1-alpha.5", "v0.2.1-alpha.4", "v0.2.1-alpha.3", "v0.2.1-alpha.2", "v0.2.1-alpha.1", "v0.2.0-rc.2", "v0.2.0-rc.1", "v0.1.7-rc.2", "v0.1.7-rc.1", "v0.1.7-alpha.2"],
|
|
9
9
|
"screenshots": "images",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
|
|
33
33
|
完整清单见 [NAMESPACES.md](NAMESPACES.md):81 个 namespace、4949 条字符串,随包附带的插件词典单独标注。
|
|
34
34
|
|
|
35
|
+
如果 pnpm 报 `ERR_PNPM_NO_MATURE_MATCHING_VERSION`,这不是包坏了,而是成熟度策略:配置文件
|
|
36
|
+
不安装发布不足 48 小时的版本。等一两天(报错信息里写着版本号),或在配置文件设置里去掉
|
|
37
|
+
`minimumReleaseAge` 限制。
|
|
35
38
|
「插件」页面上的插件名称与说明无法由本包提供:harness 把她们放在每个包的 `locale/<语言>.json`
|
|
36
39
|
里并据此拼出翻译映射,而 locale 服务的 `resolveText` 根本不查词典(原文注释:maps do not
|
|
37
40
|
consult registered dictionaries)。221 个 harness 包带有 `locale/en.json`,其中 219 个带有
|
|
@@ -40,6 +43,8 @@ harness 侧的 `locale/ru.json` 文件补上。`scripts/descriptor-coverage.mjs`
|
|
|
40
43
|
不与我们的词典覆盖率混在一起;机制说明与 32 份已备好的译文见 `docs/descriptor-upstream.md`。
|
|
41
44
|
harness 树之外的插件用同样的方式翻译,但英文取自它们自己的发布物:`plugins/<namespace>.json`
|
|
42
45
|
记录包名、版本、许可证,以及从其 bundle 中提取的英文字符串(`npm run fetch:plugins`)。
|
|
46
|
+
它还会提醒另一件事:如果配置文件里还有另一个自己注册俄语的包,语言就归先注册的那个——
|
|
47
|
+
第二个会静默跳过自己的 namespace,界面上出现的就是别人的译文。
|
|
43
48
|
安装里还剩哪些英文,用 `npm run report:plugins` 查看:它遍历 profile 的 `node_modules`,
|
|
44
49
|
读出每个插件自己的词典并与我们的对照。没有词典的插件会照实标注——在它请求翻译之前无从翻译;
|
|
45
50
|
自带俄语的插件单独标出。
|
|
@@ -85,7 +90,7 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
85
90
|
|
|
86
91
|
清单按 harness 自身的规则检查,而不是靠肉眼(`npm run check:manifest`,包含在 `verify` 中)。每一条规则都取自 harness 源码,每一条都对应一种否则会先落到用户头上的失败:`parseDshClient` 接受任意字符串作为 `platform`,但消费方只保留 `platform === 'web'` 的行,因此写成 `'Web'` 这样的笔误会**悄悄关掉**客户端那一半;声明了 `dsh.client` 却没有 `./client` 导出会让 `client-modules` 抛错;`dsh.bundle.patch` 必须指向确实存在的文件。
|
|
87
92
|
|
|
88
|
-
从 GitHub 安装同样可用:`dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru`(插件目录生成的就是这种不带 npm scope 的写法)安装的是仓库归档,而构建好的 `lib/` 已提交进 git——你的机器上不会运行构建,也不需要运行。正因如此,`npm run check:built`(包含在 `verify` 中)会重新构建 `lib/` 并与提交内容比对:git 里过期的构建产物会直接落到用户手里,而审计看不到它——审计读的是源码。发布的包为
|
|
93
|
+
从 GitHub 安装同样可用:`dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru`(插件目录生成的就是这种不带 npm scope 的写法)安装的是仓库归档,而构建好的 `lib/` 已提交进 git——你的机器上不会运行构建,也不需要运行。正因如此,`npm run check:built`(包含在 `verify` 中)会重新构建 `lib/` 并与提交内容比对:git 里过期的构建产物会直接落到用户手里,而审计看不到它——审计读的是源码。发布的包为 497 KB:横幅以 JPEG 提供,图标与源码映射不进入 npm 包。
|
|
89
94
|
|
|
90
95
|
## 为什么是混合插件
|
|
91
96
|
|
|
@@ -140,7 +145,7 @@ npm run diff:harness -- <old> <new> # harness 改写了哪些英文
|
|
|
140
145
|
|
|
141
146
|
审计在 CI(`.github/workflows/verify.yml`)中针对**锁定的 harness 标签**运行,而不是针对随便一份本地 checkout。同一次运行还会**每周按计划**触发一次:即使没人改动,译文也会腐坏——上游继续前进,本地一切正常,而偏差只在用户构建时才浮现。门禁覆盖完整性(key 与 namespace)、复数形式、占位符、英文与中文残留、术语、正文中的拉丁词、文本卫生、首尾空格、风格、取值的排版、«ё»、组合短语、设置侧栏标签的长度以及对外宣称的数字——每一项都已经抓到过真实缺陷。除此之外,审计还会打印**参考报告**——它们不是门禁,因为需要人来判断:比对了多少个 namespace、哪些无法建立对应关系、是否还留有「数字 + 需变格的名词」,以及短字符串是否长到英文的 2.8 倍以上(排版风险——«Effort» → «Уровень рассуждения» 是俄语的正常长度,不是缺陷)。
|
|
142
147
|
|
|
143
|
-
审计按 harness 实际书写的形式读取模板:字符串、**段落数组**(各模式的指南就是这样存储的)以及**常量引用**(`'hint.plan': PLAN_NEXT_ACTION_EN`)。在只读取第一种形式时,有十个 key——其中八个是整篇指南——悄悄退出了所有比对。反过来也一样:空的策略文件(`keep-english.json`、`terminology.json` 的某个分区)现在会让审计失败,而不是在无人察觉的情况下放宽门禁。README 中宣称的数字也按同样方式与包体核对,因为过期的数字就是错误的说法——同样的数字还会从 `package.json` 的 description 中读取,那是 npm 在搜索与包页面上显示的内容(「55 namespaces」正是在那里活得最久)——包括带千位分隔符的写法:旧版开头写的是 `2 489`,而检查此前只读取不带分隔符的形式,所以数字模式现在也接受千位分隔符。紧随其后还核对「针对哪个 harness 版本构建」这句话:它必须与 workflow 中锁定的标签一致,因为真正验证这个包的是那个 workflow(两个 README 的开头都还写着 `0.2.1-alpha.2`,而 CI 早已换成 `dsh-v0.2.1-rc.2`)。发布包的体积也在这里实测:`npm run check:size` 会打包归档,并把声明的千字节数与实际值对比(允许
|
|
148
|
+
审计按 harness 实际书写的形式读取模板:字符串、**段落数组**(各模式的指南就是这样存储的)以及**常量引用**(`'hint.plan': PLAN_NEXT_ACTION_EN`)。在只读取第一种形式时,有十个 key——其中八个是整篇指南——悄悄退出了所有比对。反过来也一样:空的策略文件(`keep-english.json`、`terminology.json` 的某个分区)现在会让审计失败,而不是在无人察觉的情况下放宽门禁。README 中宣称的数字也按同样方式与包体核对,因为过期的数字就是错误的说法——同样的数字还会从 `package.json` 的 description 中读取,那是 npm 在搜索与包页面上显示的内容(「55 namespaces」正是在那里活得最久)——包括带千位分隔符的写法:旧版开头写的是 `2 489`,而检查此前只读取不带分隔符的形式,所以数字模式现在也接受千位分隔符。紧随其后还核对「针对哪个 harness 版本构建」这句话:它必须与 workflow 中锁定的标签一致,因为真正验证这个包的是那个 workflow(两个 README 的开头都还写着 `0.2.1-alpha.2`,而 CI 早已换成 `dsh-v0.2.1-rc.2`)。发布包的体积也在这里实测:`npm run check:size` 会打包归档,并把声明的千字节数与实际值对比(允许 497 KB 误差——不同 Node 构建下的 gzip 压缩结果略有差别,而这句话本身也只精确到整千字节)。
|
|
144
149
|
|
|
145
150
|
- **无效 namespace**——包注册的每一个 namespace 都必须在 harness 中存在。在 0.1.6 中,日程目录的翻译被注册在 `schedule.manager` 名下,而读取它们的是 `schedule.catalog`:此时按 key 做的覆盖率检查还报告「全部已翻译」;
|
|
146
151
|
- **复数形式配对**——`.one`/`.other` 的集合必须一致,因为客户端按 `count === 1 ? '.one' : '.other'` 选择形式。这对俄语还不够:每一对还需要 `.few` 与 `.many`,否则包装层会悄悄退回中性的 `.other`,本该是 «2 дня» 的地方显示成 «2 д»。该检查**按 namespace** 进行——包装层在提问的那个 namespace 里查找形式,因此「某个界面上有、另一个界面上缺」这种情况否则不会被发现。它找到了四个时间单位(`schedule.catalog` 中的 `unit.day/hour/minute/second`)和任务管理器里的 `trigger`;同时这些单位不再是缩写(«д»、«ч»、«мин»),而是带正确格位的完整形式——«через 2 дня»、«через 5 часов»,而 «Каждые 2 дня» 现在写作 «Раз в 2 дня»。同样的要求也覆盖本包自己添加的 key(`terminal.expand` 及其同类:harness 会把计数传给它,却从不配对)——这些形式只由我们维护,少一个不会有任何其他检查发现;
|
package/lib/client.js
CHANGED
|
@@ -5280,7 +5280,8 @@ window.__ModuleLoader__.load({
|
|
|
5280
5280
|
"select",
|
|
5281
5281
|
"option",
|
|
5282
5282
|
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
5283
|
-
"[data-typography=\"off\"]"
|
|
5283
|
+
"[data-typography=\"off\"]",
|
|
5284
|
+
"[data-conversation-region]"
|
|
5284
5285
|
].join(",");
|
|
5285
5286
|
/** Whether the node sits inside content that must not be rewritten. */
|
|
5286
5287
|
function isSkipped(node) {
|
|
@@ -5337,12 +5338,19 @@ window.__ModuleLoader__.load({
|
|
|
5337
5338
|
}
|
|
5338
5339
|
//#endregion
|
|
5339
5340
|
//#region src/client/index.ts
|
|
5340
|
-
/**
|
|
5341
|
-
|
|
5341
|
+
/**
|
|
5342
|
+
* Skip only occupied slots; validation and unexpected service errors still fail.
|
|
5343
|
+
*
|
|
5344
|
+
* A skipped registration is remembered: the caller reports it, because a namespace that
|
|
5345
|
+
* stayed with another pack is a difference the user can only notice by looking at the
|
|
5346
|
+
* interface.
|
|
5347
|
+
*/
|
|
5348
|
+
function skipDuplicate(register, duplicateMessage, onDuplicate) {
|
|
5342
5349
|
try {
|
|
5343
5350
|
return register();
|
|
5344
5351
|
} catch (error) {
|
|
5345
5352
|
if (!(error instanceof Error) || error.message !== duplicateMessage) throw error;
|
|
5353
|
+
onDuplicate(duplicateMessage);
|
|
5346
5354
|
return () => {};
|
|
5347
5355
|
}
|
|
5348
5356
|
}
|
|
@@ -5360,12 +5368,25 @@ window.__ModuleLoader__.load({
|
|
|
5360
5368
|
* @param ctx - client root context.
|
|
5361
5369
|
*/
|
|
5362
5370
|
function apply(ctx) {
|
|
5371
|
+
let languageTaken = false;
|
|
5372
|
+
const lostNamespaces = [];
|
|
5373
|
+
const report = (what) => {
|
|
5374
|
+
if (what.includes("already registered")) {
|
|
5375
|
+
languageTaken = true;
|
|
5376
|
+
return;
|
|
5377
|
+
}
|
|
5378
|
+
lostNamespaces.push(what);
|
|
5379
|
+
};
|
|
5363
5380
|
ctx.effect(() => skipDuplicate(() => ctx.locale.addLanguage({
|
|
5364
5381
|
id: "ru",
|
|
5365
5382
|
label: RU_LABEL,
|
|
5366
5383
|
fallback: "en"
|
|
5367
|
-
}), "locale \"ru\" is already registered"), "locale-ru: language");
|
|
5368
|
-
for (const [ns, dict] of Object.entries(RU_DICTS)) ctx.effect(() => skipDuplicate(() => ctx.locale.register(ns, "ru", dict), `locale namespace "${ns}" already has locale "ru"
|
|
5384
|
+
}), "locale \"ru\" is already registered", report), "locale-ru: language");
|
|
5385
|
+
for (const [ns, dict] of Object.entries(RU_DICTS)) ctx.effect(() => skipDuplicate(() => ctx.locale.register(ns, "ru", dict), `locale namespace "${ns}" already has locale "ru"`, report), `locale-ru: ${ns} dictionary`);
|
|
5386
|
+
if (languageTaken || lostNamespaces.length > 0) {
|
|
5387
|
+
const parts = [languageTaken ? "язык ru уже занят другим пакетом" : null, lostNamespaces.length > 0 ? `наши словари не зарегистрированы в ${lostNamespaces.length} namespace` : null].filter((part) => part !== null);
|
|
5388
|
+
console.warn(`[dsh-client-locale-ru] ${parts.join("; ")}. В интерфейсе останется перевод другого пакета — оставьте в профиле один пакет с русским языком.`);
|
|
5389
|
+
}
|
|
5369
5390
|
ctx.effect(() => startRussianPlurals(ctx.locale), "locale-ru: plurals");
|
|
5370
5391
|
ctx.effect(() => {
|
|
5371
5392
|
const isRussian = () => ctx.locale.getLocale().active === "ru";
|
package/lib/typography.js
CHANGED
|
@@ -50,7 +50,8 @@ const SKIP_SELECTOR = [
|
|
|
50
50
|
"select",
|
|
51
51
|
"option",
|
|
52
52
|
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
53
|
-
"[data-typography=\"off\"]"
|
|
53
|
+
"[data-typography=\"off\"]",
|
|
54
|
+
"[data-conversation-region]"
|
|
54
55
|
].join(",");
|
|
55
56
|
/** Whether the node sits inside content that must not be rewritten. */
|
|
56
57
|
function isSkipped(node) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ragnoryok1/dsh-client-locale-ru",
|
|
3
|
-
"description": "dsh language pack —
|
|
4
|
-
"version": "0.2.
|
|
3
|
+
"description": "dsh language pack — i18n for the DeepSeek Harness Web GUI: Russian (ru) locale, 81 namespaces, 4949 strings, 17 third-party plugin dictionaries, ru plural forms",
|
|
4
|
+
"version": "0.2.7",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
7
7
|
"deepseek-harness",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"check:built": "node scripts/check-built.mjs",
|
|
81
81
|
"check:size": "node scripts/check-size.mjs",
|
|
82
82
|
"audit": "node scripts/audit.mjs",
|
|
83
|
-
"verify": "npm run check:readmes && npm run check:readmes:pairs && npm run check:changelog && npm run check:manifest && npm run check:meta && npm run check:built && npm run check:size && npm run check:tarball && npm run check:typography && npm run check:typography:dom && npm run check:locale && npm run check:plural && npm run check:composition && npm run check:namespaces && npm run check:upstream && npm run check:peers && npm run check:workflows && npm run check:workflow-yaml && npm run check:descriptors && node scripts/audit.mjs",
|
|
83
|
+
"verify": "npm run check:readmes && npm run check:readmes:pairs && npm run check:changelog && npm run check:manifest && npm run check:meta && npm run check:built && npm run check:size && npm run check:tarball && npm run check:typography && npm run check:typography:dom && npm run check:locale && npm run check:plural && npm run check:composition && npm run check:namespaces && npm run check:upstream && npm run check:peers && npm run check:workflows && npm run check:workflow-yaml && npm run check:release-race && npm run check:conflict-notice && npm run check:descriptors && node scripts/audit.mjs",
|
|
84
84
|
"prepublishOnly": "npm run build",
|
|
85
85
|
"check:composition": "node scripts/check-composition.mjs",
|
|
86
86
|
"namespaces": "node scripts/namespaces.mjs",
|
|
@@ -98,7 +98,9 @@
|
|
|
98
98
|
"check:descriptors": "node scripts/apply-descriptor-ru.mjs --check",
|
|
99
99
|
"release:status": "node scripts/release-status.mjs",
|
|
100
100
|
"check:meta": "node scripts/check-meta.mjs",
|
|
101
|
-
"check:workflow-yaml": "node scripts/check-workflow-yaml.mjs"
|
|
101
|
+
"check:workflow-yaml": "node scripts/check-workflow-yaml.mjs",
|
|
102
|
+
"check:release-race": "node scripts/check-release-race.mjs",
|
|
103
|
+
"check:conflict-notice": "node scripts/check-conflict-notice.mjs"
|
|
102
104
|
},
|
|
103
105
|
"license": "MIT",
|
|
104
106
|
"peerDependencies": {
|