@ragnoryok1/dsh-client-locale-ru 0.2.16 → 0.2.17
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 +27 -0
- package/README.en.md +12 -401
- package/README.md +12 -401
- package/README.zh.md +12 -164
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## [0.2.17] — 2026-10-24
|
|
2
|
+
|
|
3
|
+
### Изменено
|
|
4
|
+
|
|
5
|
+
- **Описание пакета написано простым языком.** В npm, в мета-блоке README и в
|
|
6
|
+
описании каталогов стояло «Russian (ru) interface for the DeepSeek Harness web GUI:
|
|
7
|
+
584 namespaces, 67666 strings… **Hybrid dsh.bundle + dsh.client plugin**» — набор
|
|
8
|
+
внутренних терминов, из которого человек, выбирающий перевод, не узнавал ни что он
|
|
9
|
+
получит, ни зачем ему это. Теперь описание говорит о деле: весь интерфейс харнесса
|
|
10
|
+
и меню 520 сторонних плагинов, 584 раздела, 67 666 строк.
|
|
11
|
+
- **README сокращён с 607 строк до 210.** Убраны шесть разделов, написанных для
|
|
12
|
+
разработчика: «Область покрытия», «Разработка», «Релизы», «Содержимое», «Что
|
|
13
|
+
переведено» (118 строк истории версий — она и так в этом файле) и «Проверки» (184
|
|
14
|
+
строки про аудит, снимки словарей и совместимость). Команды сборки остаются в
|
|
15
|
+
git-истории, проверки — в `scripts/audit.mjs`; в README теперь только то, что
|
|
16
|
+
нужно читателю: что это, как поставить, как выглядит, типографика, имена плагинов.
|
|
17
|
+
|
|
18
|
+
### Исправлено
|
|
19
|
+
|
|
20
|
+
- **Ошибка в описании области покрытия.** Русское и китайское вступления говорили
|
|
21
|
+
«521 стороннего плагина», а в пакете 520 — цифра отставала от словаря, который был
|
|
22
|
+
удалён как несуществующий.
|
|
23
|
+
- **Аудит читал группированные числа неправильно.** В «67,666 strings» он видел
|
|
24
|
+
«666 строк» и валил сборку на верной цифре; шаблоны «<число> строк» ловили в тексте
|
|
25
|
+
посторонние числа — пример форматирования и длину самого файла словаря. Сверка
|
|
26
|
+
стала якорной, с поддержкой разрядов через запятую, пробел и неразрывный пробел.
|
|
27
|
+
|
|
1
28
|
## [0.2.16] — 2026-10-23
|
|
2
29
|
|
|
3
30
|
### Добавлено
|
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.17",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "
|
|
6
|
+
"description": "Russian for the DeepSeek Harness web GUI: the whole interface plus the menus of 520 third-party plugins — 584 sections, 67 666 strings.",
|
|
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",
|
|
@@ -24,7 +24,15 @@
|
|
|
24
24
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
25
25
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
The plugin makes the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) interface Russian. Everything you see is translated: settings, side panels, dialogs, hints, error messages — and the menus of third-party plugins that ship no Russian of their own.
|
|
28
|
+
|
|
29
|
+
The pack currently holds 584 sections and 67,666 strings, 520 of them dictionaries of third-party plugins — more than any other Russian pack for the harness I could find.
|
|
30
|
+
|
|
31
|
+
Install is one command: `dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru`; Russian is then picked in the settings, under General.
|
|
32
|
+
|
|
33
|
+
Beyond translation the pack does three things the harness cannot do by itself: it chooses the Russian plural form by the number instead of a neutral label, applies Russian typography («ёлочки», em dashes, ellipses), and translates plugin names whose package ships no locale of its own. Each extra can be turned off with one line in the profile — the translation stays.
|
|
34
|
+
|
|
35
|
+
The pack does not modify harness files and does not touch your data. If a newer harness adds a string the pack does not know yet, it stays English: the interface keeps working. MIT, maintained by the community, not affiliated with DeepSeek.
|
|
28
36
|
|
|
29
37
|
> **If the pack was useful to you, please star the repository.** It is the only signal that a
|
|
30
38
|
> translation is wanted, and it is what decides which parts get worked on next.
|
|
@@ -99,7 +107,7 @@ two (the message names the version) or drop the `minimumReleaseAge` limit in the
|
|
|
99
107
|
settings.
|
|
100
108
|
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.
|
|
101
109
|
|
|
102
|
-
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
|
|
110
|
+
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 1975 kB: the banner ships as JPEG, and the icon and source map stay out of the npm payload.
|
|
103
111
|
|
|
104
112
|
## Why hybrid
|
|
105
113
|
|
|
@@ -194,403 +202,6 @@ translates the title, the description, the accessible name and a bundle row —
|
|
|
194
202
|
it must alone.
|
|
195
203
|
|
|
196
204
|
|
|
197
|
-
## Checks
|
|
198
|
-
|
|
199
|
-
```sh
|
|
200
|
-
npm run build # the three outputs
|
|
201
|
-
npm run check:typography # 18 typography rules, including "leave alone"
|
|
202
|
-
npm run check:locale # dictionaries side by side: 6 checks
|
|
203
|
-
npm run check:plural # plural forms: 1 вызов / 2 вызова / 5 вызовов
|
|
204
|
-
npm run check:composition # composed phrases: «Пн, Ср в 09:00», «Раз в 2 дня»
|
|
205
|
-
npm run check:namespaces # NAMESPACES.md matches the built bundle
|
|
206
|
-
npm run check:tarball # what gets installed: the archive is unpacked and checked
|
|
207
|
-
npm run check:workflows # both workflows run the whole verify chain
|
|
208
|
-
npm run check:readmes:pairs # the three READMEs move together (recorded section hashes)
|
|
209
|
-
npm run check:plugin-names # plugin names in Russian on a real document
|
|
210
|
-
npm run check:descriptor-patch # the harness patch matches the translations
|
|
211
|
-
npm run audit -- <harness tree> # the locale audit
|
|
212
|
-
npm run verify -- <harness tree> # everything together
|
|
213
|
-
|
|
214
|
-
npm run namespaces # regenerate NAMESPACES.md and pack-count.json
|
|
215
|
-
npm run readmes:record # re-record section hashes after editing all three READMEs
|
|
216
|
-
npm run diff:harness -- <old> <new> # what the harness reworded under us
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
A separate check composes phrases the way the harness does and reads the result whole. The
|
|
220
|
-
audit compares a value with its own template, so a phrase that is correct in isolation but
|
|
221
|
-
broken by substitution stays invisible to it: `frequency.weekly` was filled as «По {weekdays}
|
|
222
|
-
в {time} », while the days arrive as «Пн, Ср» — producing «По Пн, Ср в 09:00», which no
|
|
223
|
-
line-by-line check can see. The same way «Каждые 2 дня» (now «Раз в 2 дня»), «Каждый день в
|
|
224
|
-
09:00 (Europe/Moscow)» and a composed interval with the plural forms are pinned. The third find
|
|
225
|
-
of the same kind: `time.locale` is not text but a tag for `Intl`, and it was `en` — a rule
|
|
226
|
-
restricted to a month read «Каждый день в January», and the zone label «Moscow Standard Time»
|
|
227
|
-
inside a Russian interface. The tag is `ru` now (the harness's Chinese dictionary uses `zh-CN`
|
|
228
|
-
the same way), and the month sits in parentheses: «Каждый день (январь, март)».
|
|
229
|
-
|
|
230
|
-
The same part-by-part reading found the cron wording: abbreviations («Каждые {step} мин»,
|
|
231
|
-
«Каждые {count} ч») and bookish turns («в минуту {minutes}», «минуты {minutes} в часы
|
|
232
|
-
{hours}»). The counted parts gained plural forms — «Каждые 3 минуты» / «Каждые 5 минут»,
|
|
233
|
-
«Каждые 2 часа» / «Каждые 6 часов» — and the rest were rewritten into one readable labelled
|
|
234
|
-
style: «Каждый час, минуты: 5, 30», «минуты: 5, часы: 09–17». The whole schedule sentence is
|
|
235
|
-
asserted end to end: «Пн–Пт каждые 5 минут». The date stamps are pinned the same way: «5 окт. 2026 г., 15:51» and the zone label «Москва, стандартное время» come from Intl with our tag, without a single Latin word.
|
|
236
|
-
|
|
237
|
-
The audit runs in CI (`.github/workflows/verify.yml`) against a **pinned harness tag**,
|
|
238
|
-
not against some random local checkout. The same run also fires **weekly on a schedule**: a
|
|
239
|
-
translation rots without anyone editing it — the upstream moves on, everything is green
|
|
240
|
-
locally, and the drift surfaces only when a user builds. The gates cover completeness (keys and
|
|
241
|
-
namespaces), plural forms, placeholders, English and Chinese residue, terminology, Latin words in
|
|
242
|
-
prose, text hygiene, edge spaces, style, typography of values, «ё», composed phrases, the length
|
|
243
|
-
of settings sidebar labels and the advertised numbers — and every one of them has already caught
|
|
244
|
-
real defects. Beside them the audit
|
|
245
|
-
prints **advisory reports**,
|
|
246
|
-
which are not gates because they need a human decision: how many namespaces were compared and
|
|
247
|
-
which could not be linked, whether any «number + inflecting word» is left, and whether a short
|
|
248
|
-
string grew past 2.8× its English (a layout risk — «Effort» → «Уровень рассуждения» is normal
|
|
249
|
-
Russian length, not a defect).
|
|
250
|
-
|
|
251
|
-
The audit reads harness templates in the shape the harness writes them: a literal, an **array of
|
|
252
|
-
paragraphs** (that is how the preset guides are stored) and a **reference to a constant**
|
|
253
|
-
(`'hint.plan': PLAN_NEXT_ACTION_EN`). While only the first shape was read, ten keys — eight of
|
|
254
|
-
them whole guide documents — silently fell out of every comparison. And the other way round: an
|
|
255
|
-
empty policy file (`keep-english.json`, a `terminology.json` section) now fails the audit instead
|
|
256
|
-
of widening a gate unnoticed. The numbers the READMEs advertise are checked against the pack the
|
|
257
|
-
same way, because a stale count is simply a wrong claim — and the same numbers are read from the
|
|
258
|
-
`package.json` description, which is what npm shows in search and on the package page (that is
|
|
259
|
-
where «55 namespaces» lived longest) — including the grouped spelling: the
|
|
260
|
-
old leads said `2 489`, and the gate only read the ungrouped form, so the pattern now accepts
|
|
261
|
-
thousands separators. The sentence naming the harness version the pack was built against is
|
|
262
|
-
checked next to it, against the tag the workflow pins, because that workflow is what verifies
|
|
263
|
-
the pack (both leads claimed `0.2.1-alpha.2` while CI had already moved to
|
|
264
|
-
`dsh-v0.2.1-rc.2`). The published size is measured there too: `npm run check:size` packs the
|
|
265
|
-
archive and compares the advertised kilobytes with the real ones, allowing one kilobyte of slack
|
|
266
|
-
because gzip compresses slightly differently across Node builds while the sentence rounds to
|
|
267
|
-
whole kilobytes.
|
|
268
|
-
|
|
269
|
-
- **dead namespaces** — every namespace the package registers has to
|
|
270
|
-
exist in the harness. In 0.1.6 the schedule catalog translations were registered
|
|
271
|
-
under the name `schedule.manager`, whereas `schedule.catalog` is what reads them: the per-key
|
|
272
|
-
coverage check nonetheless reported «всё переведено»;
|
|
273
|
-
- **plural-form pairs** — the `.one`/`.other` sets have to match, because the client
|
|
274
|
-
chooses the form as `count === 1 ? '.one' : '.other'`. That is not enough for Russian:
|
|
275
|
-
every pair also needs `.few` and `.many`, or the wrapper quietly falls back to the neutral
|
|
276
|
-
`.other` and shows «2 д» where «2 дня» was possible. The check runs **per namespace** —
|
|
277
|
-
the wrapper looks the form up in the namespace that asked, so a pair missing on one screen
|
|
278
|
-
while present on another would otherwise stay invisible. It found the four time units
|
|
279
|
-
(`unit.day/hour/minute/second` in `schedule.catalog`) and `trigger` in the task manager;
|
|
280
|
-
the units stopped being abbreviations («д», «ч», «мин») and gained full forms in the right
|
|
281
|
-
case — «через 2 дня», «через 5 часов», and «Каждые 2 дня» became «Раз в 2 дня». The same
|
|
282
|
-
requirement covers the keys the pack added itself (`terminal.expand` and its kin: the
|
|
283
|
-
harness passes them a count but never pairs them) — their forms rest on us alone, and
|
|
284
|
-
losing one would be invisible to everything else;
|
|
285
|
-
- **placeholders** — a Russian value has to carry exactly the `{name}` placeholders its
|
|
286
|
-
English template carries: an extra one reaches the screen literally
|
|
287
|
-
(`Заняло {duration}7мин 26с`, fixed in #2), a dropped one silently removes the
|
|
288
|
-
interpolated value. Packages that ship only the Chinese dictionary are compared
|
|
289
|
-
against `zh`. Our **own plural forms** — the `.few`/`.many` we add, and the `.one` of a key
|
|
290
|
-
the harness never paired — do not exist upstream, so each is compared with the template of
|
|
291
|
-
a sibling form of the same word (`.one`/`.other`) or of the key itself. Without that, 52
|
|
292
|
-
values were never checked at all: that is exactly how a `{count}` can disappear from a form
|
|
293
|
-
and leave the sentence without its number.
|
|
294
|
-
- **residue** — a value has to be Russian: an exact copy of the English template, a leftover
|
|
295
|
-
Chinese character, or an empty string where the template has text is a defect. English
|
|
296
|
-
copies are allowed only by a decision recorded in `scripts/keep-english.json` (addresses,
|
|
297
|
-
format-only strings, protocol and tool names, abbreviations), so a new untranslated line
|
|
298
|
-
cannot slip through unnoticed. The decisions themselves are checked too: an entry that no
|
|
299
|
-
longer excuses anything fails the build — either its key left the pack, or the value was
|
|
300
|
-
translated and the decision went stale. This is how the `deepSeekBaseUrl` entry was found:
|
|
301
|
-
the English template gained a note about `DEEPSEEK_BASE_URL`, while the input placeholder
|
|
302
|
-
has to be a bare example URL, so that note would have been noise inside the field. The entry
|
|
303
|
-
is gone, the value stays. A decision may also name a closed list: `chat · app.*` allows
|
|
304
|
-
thirty application names in one line, because a dictionary of application names is a list of
|
|
305
|
-
names. And a value with no word outside its placeholders (`{from}–{to}`, `{percent}%`, `, `)
|
|
306
|
-
needs no decision at all: there is nothing in it to translate, so the policy stays about
|
|
307
|
-
words rather than about punctuation. The residue rule reads **every** template of a key, not
|
|
308
|
-
only the `en` block: 60 values in dictionaries with an unrecognised block used to go
|
|
309
|
-
unexamined, while now 2911 values are compared, 68 of them covered by decisions (38 entries,
|
|
310
|
-
one of them a pattern), and the zone is gone as a class. The rule did not become wider:
|
|
311
|
-
an empty value is a defect only where no template is empty either, since Russian justly
|
|
312
|
-
drops the prefix that English drops too (`message.stepProcess.sharedPrefix`).
|
|
313
|
-
- **dead keys** — a key no harness dictionary defines and no harness source names is a
|
|
314
|
-
leftover from an older version: it shows nothing and only misleads. Such keys fail the
|
|
315
|
-
build. A key a component still asks for stays in the advisory report, because the pack's
|
|
316
|
-
value is what reaches the screen.
|
|
317
|
-
- **terminology** — one concept, one rendering. Forbidden variants («кеш» for «кэш», «сеанс»
|
|
318
|
-
for «сессия», «этап» for «шаг») fail the build, and `scripts/terminology.json` keeps both
|
|
319
|
-
the decision and counts of the chosen forms, so drift shows up before it becomes a defect.
|
|
320
|
-
The check immediately found `confirm.description` translated two ways in two namespaces —
|
|
321
|
-
«шаги» and «этапы». One word may not be spelled both with and without «ё»: «ещё» next to
|
|
322
|
-
«еще» reads as machine translation, so the check folds «ё» to «е» and fails on two spellings
|
|
323
|
-
of one folded form. Real distinct pairs such as «все» and «всё» are declared in
|
|
324
|
-
`scripts/yo-pairs.json`, and a declaration whose spellings left the pack fails as well. The
|
|
325
|
-
same report covers Latin words inside Russian phrases: a product,
|
|
326
|
-
command or code token is allowed, an ordinary English word in a sentence is not. A product name
|
|
327
|
-
has to be spelled the way the harness spells it: «Github Desktop» for «GitHub Desktop» reads as a
|
|
328
|
-
typo in the product's own name, and the pack is the only place it can appear. The reference is
|
|
329
|
-
the English templates; a word the harness writes only in lowercase («cursor», «desktop») does not
|
|
330
|
-
count, because there a capital is exactly the product name. Next to it
|
|
331
|
-
comes mechanical hygiene: double spaces, a space before punctuation, unpaired «ёлочки» and
|
|
332
|
-
brackets, a non-breaking space inside a value, and edge spaces — a value that starts or ends
|
|
333
|
-
with one is glued to a neighbour by the component, so it has to match the English template
|
|
334
|
-
of its own namespace. The same template checks style: a terminator the English carries must
|
|
335
|
-
not disappear (this is how `registryCustomHint` was found without its period), and the case
|
|
336
|
-
of the first letter has to match — except for acronyms like `JSON` and templates that open
|
|
337
|
-
with a placeholder. The address to the reader is checked on its own: inside a sentence the
|
|
338
|
-
Russian interface writes «вы» lowercase, and «Вы» with a capital letter only at the start of
|
|
339
|
-
a sentence, where it is nothing but spelling. Finally the pack is compared with itself: one
|
|
340
|
-
English sentence has to come back as one Russian sentence. When two namespaces render it
|
|
341
|
-
differently — templates of four words or more are compared, because a short label legitimately
|
|
342
|
-
follows its context — the build fails. This is how `confirm.description` was found: one
|
|
343
|
-
rendering promised to «пропускать шаги подтверждения», the other to «уменьшать число шагов»,
|
|
344
|
-
and the English «subsequent tasks» had become «текущей задаче» in the second. A deliberate
|
|
345
|
-
divergence is declared in `scripts/one-rendering.json` with its reason, and an exception that
|
|
346
|
-
no longer matches anything fails as well — otherwise the list of decisions would quietly widen
|
|
347
|
-
the check. The opposite direction is printed as an advisory: the same Russian answer to
|
|
348
|
-
**different** English sentences of four words or more hints at a copy-paste — a hint carried
|
|
349
|
-
over from a neighbouring key, or two distinct facts collapsed into one phrase. It cannot be a
|
|
350
|
-
gate, because Russian legitimately merges words English keeps apart, so both sides are printed
|
|
351
|
-
together and a human decides.
|
|
352
|
-
|
|
353
|
-
A separate workflow watches the tag itself: `watch-upstream` compares the pinned tag with
|
|
354
|
-
the harness tags once a week, opens an issue with the steps when a newer one exists, and turns
|
|
355
|
-
the run red — so lagging behind is found on a schedule rather than in a user's screenshot. The
|
|
356
|
-
version comparison is checked without the network (`npm run check:upstream`: prerelease order,
|
|
357
|
-
equal versions, a move between lines) and is
|
|
358
|
-
part of `verify`: a release has to outrank its own prereleases, or the watch would fire forever.
|
|
359
|
-
|
|
360
|
-
The coverage number is not a gate: some sections are deliberately left in English. Next to it
|
|
361
|
-
the audit prints a **per-namespace** report: it rebuilds the namespace-to-dictionary link from
|
|
362
|
-
whoever registers it (`NS`, or a literal in `locale.register`; `bind` and `PropsLocale` only read
|
|
363
|
-
a namespace) and lists keys missing from both their own namespace and the shared `common`
|
|
364
|
-
dictionary the runtime falls back to. A global name comparison cannot see those holes: a
|
|
365
|
-
translation filed under another namespace counts as coverage while the screen shows English.
|
|
366
|
-
The report is advisory — the same key name can mean different things in different namespaces
|
|
367
|
-
(`list.aria` is "Active reminders" in the catalog and "Background jobs" in jobs), so a
|
|
368
|
-
translation is copied across namespaces only where one dictionary serves both. On the pinned
|
|
369
|
-
tag the report is empty: every string the harness renders in a namespace we register lives in
|
|
370
|
-
that namespace. All 584 of the pack's namespaces are compared — the link comes both from a
|
|
371
|
-
dictionary imported beside the registration and from the names that registration passes
|
|
372
|
-
(`locale.register(NS, { zh, en })`); without the second rule `common` and `settings.locale`,
|
|
373
|
-
whose dictionaries sit in a neighbouring directory, would stay uncovered. The other direction is
|
|
374
|
-
a failure rather than a report: a namespace the harness registers and fills with keys, which the
|
|
375
|
-
pack never registers, leaves that screen in English while key coverage still looks complete.
|
|
376
|
-
This is how `settings.sessionLog` was found — the “Upload Session Log” switch on the general
|
|
377
|
-
settings page.
|
|
378
|
-
|
|
379
|
-
## Coverage scope: the harness and plugin dictionaries
|
|
380
|
-
The package translates **the harness client's own namespaces** — 64 namespaces reconciled
|
|
381
|
-
against the pinned tag — and **the dictionaries of third-party plugins**: 520 plugins whose
|
|
382
|
-
English text is vendored from their own publication, with the version and the licence.
|
|
383
|
-
|
|
384
|
-
Searching the npm registry — six queries instead of one «dsh» — found 40 more plugins with
|
|
385
|
-
a dictionary of their own. 39 are translated; three names (`dsh-automation`, `remote`,
|
|
386
|
-
`settings.ip-pool`) are already taken by other plugins' dictionaries and stay with their
|
|
387
|
-
owners, so that nobody's product gets somebody else's translation. As of 22 October 2026:
|
|
388
|
-
**584 namespaces, 67 666 values, 520 dictionaries, 47 700 distinct Russian strings** in the
|
|
389
|
-
built package. The competitor measurement, by the same method —
|
|
390
|
-
[docs/competitors.md](https://github.com/Ragnoryok1/dsh-client-locale-ru/blob/main/docs/competitors.md).
|
|
391
|
-
|
|
392
|
-
Plugin dictionaries were out of scope before, and there was a reason: `dshmarket` is already
|
|
393
|
-
at version 1.66.44, its keys change independently of the harness, and a silent promise of
|
|
394
|
-
«everything is covered» is not a promise but a debt nobody can collect. The answer turned
|
|
395
|
-
out to be simple: the foreign English text is **vendored** (`npm run fetch:plugins`) and
|
|
396
|
-
stored next to the translation, with the package name, the version and the licence, and the
|
|
397
|
-
audit holds our translation to that snapshot rather than to somebody else's Russian. We
|
|
398
|
-
checked the 17 most-downloaded plugins in the ecosystem (npm, `keywords:dsh-plugin`, monthly
|
|
399
|
-
downloads) and looked at which of them ship strings of their own at all:
|
|
400
|
-
|
|
401
|
-
| What we found | Plugins |
|
|
402
|
-
|---|---|
|
|
403
|
-
| **No strings of their own** — the interface takes its text from harness namespaces | **11 of 17** |
|
|
404
|
-
| A large dictionary of their own (confirmed by hand) | 2 — `dshmarket` (733 keys), `@nanmicoder/dsh-agent-teams` (420) |
|
|
405
|
-
| `.d.ts` types only, no strings | 1 — `dsh-plugin-model-proxy` |
|
|
406
|
-
| Needs a separate check | 3 |
|
|
407
|
-
|
|
408
|
-
For 11 of the 17 most popular plugins the Russian interface already works without a
|
|
409
|
-
dictionary of their own: their text lives in the shared harness namespaces, which the package
|
|
410
|
-
translates in full. Dictionaries exist where a plugin carries strings of its own — there
|
|
411
|
-
are 32 of them, and each records the version its English text was vendored from.
|
|
412
|
-
|
|
413
|
-
Such a dictionary is a commitment to track someone else's releases, but it is now a
|
|
414
|
-
checkable one: a new version of the plugin with different keys shows up as a difference from
|
|
415
|
-
the snapshot instead of as silence. Need a specific plugin? Open an issue: a dictionary for
|
|
416
|
-
it is possible as a separate layer pinned to a version, rather than as a silent promise that
|
|
417
|
-
«everything is covered».
|
|
418
|
-
|
|
419
|
-
## Development
|
|
420
|
-
|
|
421
|
-
```sh
|
|
422
|
-
pnpm install
|
|
423
|
-
pnpm run build # tsdown -> lib/index.js (node half) + lib/client.js (client bundle)
|
|
424
|
-
npm pack # -> ragnoryok1-dsh-client-locale-ru-<version>.tgz
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
`lib/client.js` is built in the format the `dsh` client loader understands (`__ModuleLoader__.load`) and exports `inject`/`apply`.
|
|
428
|
-
|
|
429
|
-
## Releases
|
|
430
|
-
|
|
431
|
-
Publishing to npm is done by the `publish` workflow on a tag — the credentials live in a repository
|
|
432
|
-
secret (`NPM_TOKEN`), so the token never has to be typed into a terminal or passed around.
|
|
433
|
-
Publishing by hand from a machine is possible, but unnecessary.
|
|
434
|
-
|
|
435
|
-
```
|
|
436
|
-
npm version 0.3.0 --no-git-tag-version # поднять версию в package.json
|
|
437
|
-
# …и синхронно обновить версию в блоке deepseek-harness-meta в этом README
|
|
438
|
-
git commit -am "release: 0.3.0" && git tag v0.3.0 && git push origin v0.3.0
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
Before publishing, the workflow checks:
|
|
442
|
-
|
|
443
|
-
1. the version in the tag matches the version in `package.json`;
|
|
444
|
-
2. the version in the `deepseek-harness-meta` block matches `package.json` — the marketplace takes it from there,
|
|
445
|
-
and reads it **only on first indexing**, so a mismatch does not fix itself;
|
|
446
|
-
3. the typography (18 rules);
|
|
447
|
-
4. the localization audit against the pinned harness tag — dead namespaces, duplicates and plural-form
|
|
448
|
-
pairs will fail and stop the publication;
|
|
449
|
-
5. **compatibility with every version in `compatible_versions`**: each one's locale runtime is
|
|
450
|
-
downloaded from npm and three suites — language coexistence, plural forms and composed phrases
|
|
451
|
-
— run against it (`npm run check:compat`, part of CI), so the promise in the meta block is
|
|
452
|
-
checked rather than assumed.
|
|
453
|
-
|
|
454
|
-
The declaration itself is checked separately (`npm run check:peers`, part of `verify`): the harness
|
|
455
|
-
reads our `peerDependencies` for `@deepseek-ai/dsh*` not as package versions but as a range of
|
|
456
|
-
**runtime versions**, with `includePrerelease`, and a range that fails to satisfy the running dsh
|
|
457
|
-
makes the user see an incompatibility warning and an exemption prompt. The script runs that rule
|
|
458
|
-
over every claimed version — all eight pass today.
|
|
459
|
-
|
|
460
|
-
To check all the same things locally, without publishing:
|
|
461
|
-
|
|
462
|
-
```
|
|
463
|
-
npm run verify -- путь/к/дереву/харнесса
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
The workflow also has a manual run with a «только проверки, без публикации» toggle
|
|
467
|
-
(`workflow_dispatch` → `dry-run`).
|
|
468
|
-
|
|
469
|
-
## Contents
|
|
470
|
-
|
|
471
|
-
- `src/client/dicts.ts` — the Russian dictionaries: 584 namespaces, 67,666 strings, 71,506 lines of file. This is where the main value lies.
|
|
472
|
-
- `src/client/index.ts` — the client plugin entry point (registration of `ru` + the dictionaries).
|
|
473
|
-
- `src/index.ts` — the empty host half (`apply()`).
|
|
474
|
-
- `cordis.patch.yml` — the profile patch (`- insert:` of the client entry `locale-ru`).
|
|
475
|
-
|
|
476
|
-
## What is translated
|
|
477
|
-
|
|
478
|
-
The current set follows the harness tags: the keys were taken from the matching commit, and keys
|
|
479
|
-
added later fall back to `en` on lookup, so the package does not break the interface on newer versions.
|
|
480
|
-
|
|
481
|
-
### 0.1.7 — dead namespace fixed, task manager translated, plural forms rewritten
|
|
482
|
-
|
|
483
|
-
The headline item in the release is **a fix for a mistake from 0.1.6**. At the time it was recorded
|
|
484
|
-
that the namespace `schedule.catalog` had been retired and that `schedule.manager` had taken its place.
|
|
485
|
-
In reality **both** namespaces live in the harness, separately: `schedule.catalog` is the reminder
|
|
486
|
-
catalog in the session header with frequencies and units, `schedule.manager` is the new automation-task
|
|
487
|
-
manager. Because of that wrong conclusion, ~30 translation strings (reminders, frequency, time
|
|
488
|
-
units) were registered under a name nobody reads and were **never shown** in the interface. The
|
|
489
|
-
catalog is now registered as `schedule.catalog`.
|
|
490
|
-
|
|
491
|
-
- **fixed:** the schedule catalog translations are visible again — `trigger.*`, `list.*`,
|
|
492
|
-
`delete.*`, `frequency.*`, `cron.*`, `unit.*`, `relative.*`, `mark.aria`, `hover.more`;
|
|
493
|
-
- **`schedule.manager` added** (188 keys) — the automation-task manager entirely in
|
|
494
|
-
Russian: the task panel and catalog, search, status filter, task details and its tabs,
|
|
495
|
-
the **run log** with retention rules, the schedule editor (date, time, hour, minute,
|
|
496
|
-
second, time zone, repeat interval), repeat rules (once, every N minutes/hours/
|
|
497
|
-
seconds, daily, Mon–Fri, weekly, custom cron), the cron form with date and minute
|
|
498
|
-
pickers, deletion with confirmation, notifications and cards;
|
|
499
|
-
- **plural forms rewritten** (17 key pairs): forms that broke on the numbers 2–4
|
|
500
|
-
were replaced with ones that are correct for any `n ≥ 2` — for example «2 субагентов» → «Субагентов: 2»,
|
|
501
|
-
«каждые 2 часов» → «каждые 2 ч». Another 8 strings with `{count}` before an inflected word
|
|
502
|
-
were switched to abbreviations: «ещё 3 строк» → «ещё 3 стр.»;
|
|
503
|
-
- **7 missing keys added**: `blocked.composer`,
|
|
504
|
-
`defaultWorkspace.title`, `schedule.active`, `settings.transcript.expanded`,
|
|
505
|
-
`status.scheduled`, `status.overdue` and the namespace `shortcuts.layout` (the label for
|
|
506
|
-
the command that shows the left panel);
|
|
507
|
-
- **a new check in the project:** a namespace-name audit. The previous coverage check
|
|
508
|
-
compared keys inside a namespace but never compared the names themselves, so an entire
|
|
509
|
-
namespace could be registered under a non-existent name and quietly do nothing. Names
|
|
510
|
-
are now extracted from every way they can be declared (`const NS`/`SETTINGS_NS`/`namespace`,
|
|
511
|
-
`locale.register`, `locale.bind`, `PropsLocale<…>`) and compared as sets.
|
|
512
|
-
|
|
513
|
-
0.1.2 added sections that 0.1.1 did not have: `open-in-app` («Открыть в
|
|
514
|
-
приложении»), `sidebarFiles`, `sidebarRight` (the right sidebar with files) and
|
|
515
|
-
`sidebarCodePreview` (code preview). It also updated the keys that changed in
|
|
516
|
-
harness 0.1.5 and removed 21 keys that no longer exist there.
|
|
517
|
-
|
|
518
|
-
In 0.1.3 the package caught up with harness 0.1.6-alpha.1: 139 keys and 7 new
|
|
519
|
-
sections were added — `sidebarTerminal` (the terminal in the right sidebar), `settings.archivedSessions`
|
|
520
|
-
(archived sessions) and the document-preview family (`sidebarDocumentPreview`,
|
|
521
|
-
`documentHtml`, `sidebarImage`, `documentMarkdown`, `sidebarPdf`). Besides that, the experimental
|
|
522
|
-
«Автопроверка» was translated (`permission.access`: `auto.*`), along with the command-palette
|
|
523
|
-
labels and tokens, the endpoint fields in the model settings, and the
|
|
524
|
-
changes in `conversation`, `trajectory`, `chat`, `session-log-download`.
|
|
525
|
-
28 keys that had disappeared from the harness were removed.
|
|
526
|
-
|
|
527
|
-
The coverage check runs against the harness sources: for each namespace the
|
|
528
|
-
key sets are compared, so the next release starts from an exact
|
|
529
|
-
“add / check / remove” list.
|
|
530
|
-
|
|
531
|
-
In 0.1.6 the package caught up with harness **0.1.7-rc.2**: **252 keys** added, 18 updated,
|
|
532
|
-
26 removed, and two new namespaces added. The changes:
|
|
533
|
-
|
|
534
|
-
- **`shortcuts`** (new namespace, 56 keys) — the hotkey editor: recording
|
|
535
|
-
a combination, conflicts, reserved combinations, hints for macOS and
|
|
536
|
-
Windows, restoring the default values;
|
|
537
|
-
- **`schedule.manager`** (70 keys at the time) — the automation-task manager: list,
|
|
538
|
-
deletion, repeat, run history, Cron expressions. **It was wrongly recorded that
|
|
539
|
-
the namespace `schedule.catalog` had been retired by this; 0.1.7 fixed that — both
|
|
540
|
-
namespaces exist side by side**;
|
|
541
|
-
- **`settings.account`** (50 keys) — the app's first launch: the welcome,
|
|
542
|
-
the choice of purpose and of how much of the work is shown, topping up the balance, signing out of
|
|
543
|
-
the account while tasks are running;
|
|
544
|
-
- added the labels for adding and removing tools on the fly
|
|
545
|
-
(`message.tools*`, `trajectory.layout.*`), the right sidebar commands
|
|
546
|
-
(`sidebarRight`), the «сначала выберите сессию» states in the panels, and updated
|
|
547
|
-
the name of the settings section: «Инструменты для кода» instead of «Инструментов
|
|
548
|
-
разработчика»;
|
|
549
|
-
- 18 keys updated to match the changed English text, 26 removed. A single term,
|
|
550
|
-
«рабочая папка», instead of «рабочей области» in one place.
|
|
551
|
-
|
|
552
|
-
In 0.1.5 the package caught up with harness **0.1.7-rc.1**: **49 keys** added, 13 updated,
|
|
553
|
-
16 removed, and the namespace `directory-browser` dropped (it is gone in rc.1). There appeared
|
|
554
|
-
the labels for the steps tools go through (`message.stepProcess.prepare.*` and `done.*` —
|
|
555
|
-
reading images, writing files, preparing for code search, web search,
|
|
556
|
-
subagent coordination and others), full-screen image viewing
|
|
557
|
-
(`image.*`), the «Стандартный» and «Подробный» modes for showing the work, installing plugins
|
|
558
|
-
from GitHub with a timeout and a Chinese mirror, the warning about an incompatible
|
|
559
|
-
plugin version, the choice of model download source for voice input, and `Cordis` command
|
|
560
|
-
messages. The wording was tightened where upstream replaced “teammate/agent”
|
|
561
|
-
with “subagent” and “Beta” with “Experimental”.
|
|
562
|
-
|
|
563
|
-
0.1.5 also fixed the counting unit in the plugin inventory: it was «187 плагины»,
|
|
564
|
-
now it is «187 плагинов». The built-in interface screenshots were translated too, npm
|
|
565
|
-
keywords were added, and the peer range of `@deepseek-ai/dsh-client-locale`
|
|
566
|
-
(`>=0.1.0-rc.2 <0.2.0`) was fixed — previously `^0.1.0` did not resolve, because the package
|
|
567
|
-
is published only under prerelease versions.
|
|
568
|
-
|
|
569
|
-
In 0.1.4 the package caught up with harness **0.1.7-alpha.2** — the biggest jump:
|
|
570
|
-
**905 keys** added, 29 changed, 126 removed. New sections:
|
|
571
|
-
|
|
572
|
-
- **`pluginManager`** — the built-in plugin panel: installation, removal,
|
|
573
|
-
enabling and disabling components, versions, registries and install hints;
|
|
574
|
-
- **`settings.account`** — the DeepSeek account: sign-in, balance, spend,
|
|
575
|
-
API key;
|
|
576
|
-
- the separate settings sections the former `settings.plugins` split into:
|
|
577
|
-
**`settings.agentLoop`**, **`settings.shell`**, **`settings.subagent`**,
|
|
578
|
-
**`settings.webSearch`**;
|
|
579
|
-
- **`sidebarBrowser`** — the built-in browser in the right panel (address, sandbox,
|
|
580
|
-
restoring the page);
|
|
581
|
-
- **`sidebarExcel`** and **`sidebarOffice`** — preview of Office spreadsheets and
|
|
582
|
-
documents; zooming (`zoom.*`) was added to PDFs and images;
|
|
583
|
-
- **`voice-input`** — experimental voice input.
|
|
584
|
-
|
|
585
|
-
Also translated were the new texts in `conversation` (+194), `chat` (+53),
|
|
586
|
-
`workspace` (+43: session archive, pinning), `deliverables` (+31: the review of
|
|
587
|
-
work changes), `job` (+24: live output of background tasks), `settings` (+22:
|
|
588
|
-
desktop app update), `plan`, `open-in-app`, `trajectory`,
|
|
589
|
-
`model`, `reference`, `session-log-download`, and in the agent-mode
|
|
590
|
-
guides (`settings.agentPreset`, 12 long texts). The section
|
|
591
|
-
`settings.archivedSessions` was removed: in 0.1.7 upstream dropped that package, and the session
|
|
592
|
-
archive moved to `workspace`.
|
|
593
|
-
|
|
594
205
|
## License
|
|
595
206
|
|
|
596
207
|
MIT
|
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.17",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "
|
|
6
|
+
"description": "Russian for the DeepSeek Harness web GUI: the whole interface plus the menus of 520 third-party plugins — 584 sections, 67 666 strings.",
|
|
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",
|
|
@@ -24,7 +24,15 @@
|
|
|
24
24
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
25
25
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Плагин делает интерфейс [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) русским. Переводится всё, что вы видите: настройки, боковые панели, диалоги, подсказки, сообщения об ошибках — и меню сторонних плагинов, у которых нет своего русского перевода.
|
|
28
|
+
|
|
29
|
+
Сейчас в пакете 584 раздела и 67 666 строк, из них 520 словарей сторонних плагинов — больше, чем у любого другого русского пакета для харнесса, который я смог найти.
|
|
30
|
+
|
|
31
|
+
Установка — одна команда: `dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru`, дальше русский выбирается в настройках, в разделе General.
|
|
32
|
+
|
|
33
|
+
Кроме перевода плагин делает три вещи, которых харнесс сам не умеет: подставляет русские формы числа («1 вызов», «2 вызова», «5 вызовов»), приводит текст к русской типографике («ёлочки», длинное тире, многоточие) и переводит названия плагинов, у которых нет своей локали. Каждую из этих надстроек можно выключить одной строкой в профиле — перевод при этом останется.
|
|
34
|
+
|
|
35
|
+
Пакет не меняет файлы харнесса и не трогает ваши данные. Если в новой версии харнесса появится строка, которой в пакете ещё нет, она останется английской: интерфейс продолжит работать. Лицензия MIT, пакет поддерживается сообществом и не связан с DeepSeek.
|
|
28
36
|
|
|
29
37
|
> **If the pack was useful to you, please star the repository.** It is the only signal that a
|
|
30
38
|
> translation is wanted, and it is what decides which parts get worked on next.
|
|
@@ -98,7 +106,7 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
98
106
|
половину; declared `dsh.client` без экспорта `./client` заставляет `client-modules` бросить
|
|
99
107
|
ошибку; `dsh.bundle.patch` обязан указывать на существующий файл.
|
|
100
108
|
|
|
101
|
-
Установка из GitHub тоже работает: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (в таком виде команду генерирует каталог плагинов, без `@`-скоупа) ставит архив репозитория, а собранный `lib/` лежит в git — сборка на вашей машине не запускается и не требуется. Поэтому `npm run check:built` (входит в `verify`) пересобирает `lib/` и сверяет его с коммитом: устаревший бандл в git иначе получил бы именно пользователь, а аудит этого не увидел бы — он читает исходники. Публикуемый пакет занимает
|
|
109
|
+
Установка из GitHub тоже работает: `dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru` (в таком виде команду генерирует каталог плагинов, без `@`-скоупа) ставит архив репозитория, а собранный `lib/` лежит в git — сборка на вашей машине не запускается и не требуется. Поэтому `npm run check:built` (входит в `verify`) пересобирает `lib/` и сверяет его с коммитом: устаревший бандл в git иначе получил бы именно пользователь, а аудит этого не увидел бы — он читает исходники. Публикуемый пакет занимает 1975 КБ: баннер отдаётся JPEG, а иконка и карта исходников в npm не входят.
|
|
102
110
|
|
|
103
111
|
## Почему гибрид
|
|
104
112
|
|
|
@@ -193,403 +201,6 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
193
201
|
должен.
|
|
194
202
|
|
|
195
203
|
|
|
196
|
-
## Проверки
|
|
197
|
-
|
|
198
|
-
```sh
|
|
199
|
-
npm run build # сборка трёх выходов
|
|
200
|
-
npm run check:typography # 18 правил типографики, включая «не трогать»
|
|
201
|
-
npm run check:locale # сосуществование словарей: 6 проверок
|
|
202
|
-
npm run check:plural # формы числа: 1 вызов / 2 вызова / 5 вызовов
|
|
203
|
-
npm run check:composition # собранные фразы: «Пн, Ср в 09:00», «Раз в 2 дня»
|
|
204
|
-
npm run check:namespaces # NAMESPACES.md совпадает с собранным бандлом
|
|
205
|
-
npm run check:tarball # что установят: архив распаковывается и проверяется
|
|
206
|
-
npm run check:workflows # оба workflow запускают всю цепочку verify
|
|
207
|
-
npm run check:readmes:pairs # три README двигаются вместе (хеши разделов)
|
|
208
|
-
npm run check:plugin-names # названия плагинов по-русски на настоящем документе
|
|
209
|
-
npm run check:descriptor-patch # патч для харнесса совпадает с переводами
|
|
210
|
-
npm run audit -- <дерево харнеса> # аудит локали
|
|
211
|
-
npm run verify -- <дерево харнеса> # всё вместе
|
|
212
|
-
|
|
213
|
-
npm run namespaces # перегенерировать NAMESPACES.md и pack-count.json
|
|
214
|
-
npm run readmes:record # перезаписать хеши разделов после правки трёх README
|
|
215
|
-
npm run diff:harness -- <старое> <новое> # что харнесс переформулировал
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Отдельная проверка складывает фразы так, как это делает харнесс, и читает результат
|
|
219
|
-
целиком. Аудит сверяет значение с его собственным шаблоном, поэтому фраза, верная в
|
|
220
|
-
одиночку, но сломанная подстановкой, для него невидима: `frequency.weekly` был переведён
|
|
221
|
-
как «По {weekdays} в {time}», а дни приходят как «Пн, Ср» — получалось «По Пн, Ср в 09:00»,
|
|
222
|
-
чего не увидит ни одна построчная проверка. Так же проверяются «Каждые 2 дня» (теперь «Раз в
|
|
223
|
-
2 дня»), «Каждый день в 09:00 (Europe/Moscow)» и составной интервал с формами числа.
|
|
224
|
-
Третье, что нашлось этим же способом: `time.locale` — не текст, а тег для `Intl`, и он был
|
|
225
|
-
`en`. Правило с ограничением по месяцу показывало «Каждый день в January», а подпись
|
|
226
|
-
часового пояса — «Moscow Standard Time» в русском интерфейсе. Теперь тег `ru` (у китайского
|
|
227
|
-
словаря харнесса точно так же `zh-CN`), а месяц встаёт в скобки: «Каждый день (январь,
|
|
228
|
-
март)».
|
|
229
|
-
|
|
230
|
-
Тот же разбор по частям нашёлся в описании cron. Там были сокращения («Каждые {step} мин»,
|
|
231
|
-
«Каждые {count} ч») и книжные обороты («в минуту {minutes}», «минуты {minutes} в часы
|
|
232
|
-
{hours}»). Счётные части получили формы числа — «Каждые 3 минуты» / «Каждые 5 минут»,
|
|
233
|
-
«Каждые 2 часа» / «Каждые 6 часов», — а остальные части переписаны в один читаемый вид с
|
|
234
|
-
метками: «Каждый час, минуты: 5, 30», «минуты: 5, часы: 09–17». Вся фраза расписания
|
|
235
|
-
складывается проверкой целиком: «Пн–Пт каждые 5 минут». Тем же способом закреплены даты: отметка «5 окт. 2026 г., 15:51» и подпись пояса «Москва, стандартное время» — из Intl с нашим тегом, без единого латинского слова.
|
|
236
|
-
|
|
237
|
-
Аудит выполняется в CI (`.github/workflows/verify.yml`) против **закреплённого тега**
|
|
238
|
-
харнеса, а не против случайного локального чекаута. Раз в неделю тот же прогон запускается
|
|
239
|
-
по расписанию: перевод гниёт и без наших правок — харнесс уезжает вперёд, локально всё
|
|
240
|
-
зелено, а расхождение всплывает только при сборке у пользователя. Гейтами проверяются
|
|
241
|
-
полнота (ключи и namespace), формы числа, плейсхолдеры, остатки английского и китайского,
|
|
242
|
-
терминология, латиница в прозе, гигиена текста, краевые пробелы, стиль, типографика значений,
|
|
243
|
-
«ё», составные фразы, длина подписей в боковой панели и заявленные числа — и каждая из этих
|
|
244
|
-
проверок уже ловила настоящие дефекты. Рядом аудит печатает **справочные
|
|
245
|
-
отчёты**, которые гейтом не являются, потому что требуют решения человека: сколько
|
|
246
|
-
namespace сверено и какие не удалось привязать, остались ли места «число + склоняемое
|
|
247
|
-
слово», и не выросли ли короткие строки больше чем в 2,8 раза от английского (риск для
|
|
248
|
-
вёрстки — «Effort» → «Уровень рассуждения» это нормальная длина русского, а не дефект).
|
|
249
|
-
|
|
250
|
-
Шаблоны харнесса аудит читает в том виде, в каком их пишут: строкой, **массивом абзацев**
|
|
251
|
-
(так хранятся руководства режимов) и **ссылкой на константу** (`'hint.plan':
|
|
252
|
-
PLAN_NEXT_ACTION_EN`). Пока читался только первый вид, десять ключей — восемь из них целые
|
|
253
|
-
руководства — молча выпадали из сверки. И наоборот: пустой файл политики (`keep-english.json`,
|
|
254
|
-
пустой раздел `terminology.json`) теперь валит аудит, а не ослабляет гейт незаметно. Так же
|
|
255
|
-
сверяются и числа, которые README о себе заявляют: устаревший счётчик — это просто неверное
|
|
256
|
-
утверждение, и аудит читает его из бейджа, описания и текста всех трёх README, а также из
|
|
257
|
-
описания в `package.json` — того, что npm показывает в поиске и на странице пакета (там
|
|
258
|
-
дольше всех жило «55 namespaces»), включая
|
|
259
|
-
разряды («2,542 строки») — именно эта запись дольше всех держала в себе число 2,489, пока
|
|
260
|
-
гейт видел только форму без разрядов. Там же сверяется и фраза о том, против какой версии
|
|
261
|
-
харнесса пакет собран: она сравнивается с тегом, закреплённым в workflow, потому что
|
|
262
|
-
проверяет пакет именно он (оба README обещали `0.2.1-alpha.2`, когда CI уже стоял на
|
|
263
|
-
`dsh-v0.2.1-rc.2`). Там же меряется и размер публикуемого пакета: `npm run check:size`
|
|
264
|
-
собирает архив и сравнивает заявленные килобайты с настоящими (допуск в один килобайт — gzip
|
|
265
|
-
на разных сборках Node сжимает чуть иначе, а сама фраза округлена до целых килобайт).
|
|
266
|
-
|
|
267
|
-
- **мёртвые namespace** — каждый namespace, который регистрирует пакет, обязан
|
|
268
|
-
существовать в харнессе. В 0.1.6 переводы каталога расписания были зарегистрированы
|
|
269
|
-
под именем `schedule.manager`, тогда как читает их `schedule.catalog`: проверка покрытия
|
|
270
|
-
по ключам при этом рапортовала «всё переведено»;
|
|
271
|
-
- **пары форм числа** — множества `.one`/`.other` должны совпадать, потому что клиент
|
|
272
|
-
выбирает форму как `count === 1 ? '.one' : '.other'`. Этого мало для русского: каждой
|
|
273
|
-
паре нужны ещё `.few` и `.many`, иначе обёртка молча вернётся к нейтральному `.other` и
|
|
274
|
-
вместо «2 дня» покажет «2 д». Проверка сверяет это **по namespace** — обёртка ищет форму
|
|
275
|
-
в том namespace, который спросил, поэтому пара, забытая в одном экране при наличии в
|
|
276
|
-
другом, иначе осталась бы незамеченной. Так нашлись четыре единицы времени
|
|
277
|
-
(`unit.day/hour/minute/second` в `schedule.catalog`) и `trigger` в менеджере задач;
|
|
278
|
-
заодно единицы перестали быть сокращениями («д», «ч», «мин») и получили полные формы в
|
|
279
|
-
нужном падеже — «через 2 дня», «через 5 часов», а «Каждые 2 дня» стало «Раз в 2 дня».
|
|
280
|
-
То же требование действует и для ключей, которые пакет добавил сам (`terminal.expand` и
|
|
281
|
-
родственные: харнесс передаёт им счёт, но пары не заводит) — их формы держатся только
|
|
282
|
-
нами, и потеря одной ничем больше не обнаружилась бы;
|
|
283
|
-
- **плейсхолдеры** — русское значение обязано нести ровно те `{name}`, что и английский
|
|
284
|
-
шаблон ключа: лишний плейсхолдер попадает на экран буквально (`Заняло {duration}7мин 26с`,
|
|
285
|
-
исправлено в #2), а потерянный молча убирает подставленное значение. Для пакетов,
|
|
286
|
-
которые везут только китайский словарь, шаблоном служит `zh`. Наши **собственные формы
|
|
287
|
-
числа** — добавленные `.few`/`.many` и `.one` у ключа, который харнесс не паровал, — в
|
|
288
|
-
харнессе отсутствуют, поэтому сверяются с шаблоном соседней формы того же слова (`.one`/
|
|
289
|
-
`.other`) или самого ключа. Без этого 52 значения не проверялись вовсе: именно так из
|
|
290
|
-
формы может пропасть `{count}`, и на экране останется фраза без числа.
|
|
291
|
-
- **остатки** — значение обязано быть русским: точная копия английского шаблона, китайский
|
|
292
|
-
иероглиф или пустая строка там, где шаблон не пуст, — это ошибка. Копии английского
|
|
293
|
-
допускаются только по решению, записанному в `scripts/keep-english.json` (адреса,
|
|
294
|
-
форматные строки без слов, названия протоколов и инструментов, аббревиатуры), поэтому
|
|
295
|
-
новая недопереведённая строка не проедет молча. Сами решения тоже проверяются: запись,
|
|
296
|
-
которая больше ничего не разрешает, валит сборку — либо ключа в пакете уже нет, либо
|
|
297
|
-
значение перевели и решение устарело. Так нашлась запись про `deepSeekBaseUrl`: английский
|
|
298
|
-
шаблон обзавёлся пояснением про `DEEPSEEK_BASE_URL`, а подсказка в поле ввода — пример
|
|
299
|
-
адреса, поэтому пояснение на экране было бы мусором внутри поля. Запись убрана, значение
|
|
300
|
-
оставлено. Решение может называть и целый закрытый список: `chat · app.*` разрешает
|
|
301
|
-
тридцать названий приложений одной строкой — словарь имён приложений и есть список имён.
|
|
302
|
-
А значения без слов вне плейсхолдеров (`{from}–{to}`, `{percent}%`, `, `) решения не
|
|
303
|
-
требуют вовсе: переводить в них нечего, и политика остаётся про слова, а не про
|
|
304
|
-
пунктуацию. Сверка остатков читает **все** шаблоны ключа, а не только блок `en`: раньше
|
|
305
|
-
60 значений в словарях с неопознанным блоком не проверялись вовсе, теперь сверено 2911
|
|
306
|
-
значения, 68 из них покрыты решениями (38 записей, одна из них — шаблон), и зона исчезла
|
|
307
|
-
как класс. Шире от этого правило не стало: пустое значение — ошибка только там, где ни
|
|
308
|
-
один шаблон не пуст, иначе русский справедливо опускает префикс, который английский тоже
|
|
309
|
-
опускает (`message.stepProcess.sharedPrefix`). И точное совпадение — не единственный вид
|
|
310
|
-
копии: значение, отличающееся от шаблона только регистром или краевыми пробелами
|
|
311
|
-
(`Cancel` при шаблоне `cancel`), — это тот же непереведённый текст, и оно тоже требует
|
|
312
|
-
решения. Иначе такая строка читалась бы как английская, а все проверки оставались бы
|
|
313
|
-
зелёными.
|
|
314
|
-
- **мёртвые ключи** — ключ, которого нет ни в одном словаре харнесса и на который не
|
|
315
|
-
ссылается ни один его исходник, — это остаток от прежней версии: он ничего не показывает
|
|
316
|
-
и только путает. Такие ключи валят сборку. Ключ, который компонент всё ещё спрашивает,
|
|
317
|
-
остаётся в справочном отчёте: его значение — единственное, что может попасть на экран.
|
|
318
|
-
- **терминология** — одно понятие переводится одним способом. Запрещённые варианты («кеш»
|
|
319
|
-
вместо «кэш», «сеанс» вместо «сессия», «этап» вместо «шаг») валят сборку, а
|
|
320
|
-
`scripts/terminology.json` хранит и решение, и счётчики выбранных форм, чтобы дрейф был
|
|
321
|
-
виден раньше, чем станет дефектом. Проверка сразу нашла ключ `confirm.description`,
|
|
322
|
-
переведённый в двух namespace по-разному — «шаги» и «этапы». Слово не может писаться с «ё»
|
|
323
|
-
и без него: «ещё» и «еще» в одном пакете читаются как машинный перевод, поэтому «ё» внутри
|
|
324
|
-
проверки сводится к «е», и два написания одной формы валят сборку. Исключения — настоящие
|
|
325
|
-
разные слова вроде «все» и «всё»: они объявлены в `scripts/yo-pairs.json`, а запись, чьи
|
|
326
|
-
написания из пакета ушли, тоже валит сборку. Там же проверяется латиница
|
|
327
|
-
внутри русских фраз: имя продукта, команды или код-токен допустимы, простое английское
|
|
328
|
-
слово в предложении — нет. Название продукта обязано писаться так, как его пишет харнесс:
|
|
329
|
-
«Github Desktop» вместо «GitHub Desktop» читается как опечатка в имени продукта, и
|
|
330
|
-
появляется она только у нас. Ориентир — английские шаблоны; слово, которое харнесс пишет
|
|
331
|
-
только строчными («cursor», «desktop»), не считается — там заглавная буква как раз и
|
|
332
|
-
означает имя продукта. Рядом проверяется механическая гигиена: двойные пробелы,
|
|
333
|
-
пробел перед знаком препинания, непарные «ёлочки» и скобки, неразрывный пробел внутри
|
|
334
|
-
значения, а также краевые пробелы — значение, которое начинается или кончается пробелом,
|
|
335
|
-
компонент склеивает с соседним, поэтому оно обязано совпадать с английским шаблоном
|
|
336
|
-
своего namespace. Тем же шаблоном сверяется стиль: если английский кончается знаком,
|
|
337
|
-
русский не должен его терять (на этом проверка нашла `registryCustomHint` без точки),
|
|
338
|
-
а регистр первой буквы обязан совпадать — кроме сокращений вроде `JSON` и шаблонов,
|
|
339
|
-
начинающихся с плейсхолдера. Отдельно проверяется обращение к пользователю: внутри фразы
|
|
340
|
-
русский интерфейс пишет «вы» со строчной, а «Вы» с заглавной — только в начале предложения,
|
|
341
|
-
где это просто орфография. Наконец, пакет сверяется сам с собой: одну и ту же английскую
|
|
342
|
-
фразу он обязан переводить одним способом. Если два namespace дают разные русские
|
|
343
|
-
предложения (считаются шаблоны от четырёх слов — короткая подпись законно зависит от
|
|
344
|
-
контекста), сборка падает. Так нашёлся `confirm.description`: один вариант обещал
|
|
345
|
-
«пропускать шаги подтверждения», другой — «уменьшать число шагов», а английское
|
|
346
|
-
«subsequent tasks» во втором стало «текущей задачей». Намеренное расхождение объявляется
|
|
347
|
-
в `scripts/one-rendering.json` вместе с причиной, и устаревшее исключение тоже валит
|
|
348
|
-
сборку — иначе список решений тихо расширял бы проверку. Обратное направление печатается
|
|
349
|
-
справочно: одинаковый русский ответ на **разные** английские фразы от четырёх слов — это
|
|
350
|
-
след копипасты (подсказка, приехавшая от соседнего ключа) либо два разных факта, слитых в
|
|
351
|
-
одну фразу. Гейтом это быть не может: русский законно сливает слова, которые английский
|
|
352
|
-
различает, — поэтому обе стороны печатаются рядом, и решение принимает человек.
|
|
353
|
-
|
|
354
|
-
За свежестью тега следит отдельный workflow: `watch-upstream` раз в неделю сравнивает
|
|
355
|
-
закреплённый тег с тегами харнесса, при новом открывает issue со списком шагов и красит
|
|
356
|
-
прогон — чтобы отставание находилось по расписанию, а не по чужому скриншоту. Сравнение
|
|
357
|
-
версий проверяется без сети (`npm run check:upstream`: порядок предрелизов, равенство версий,
|
|
358
|
-
переход между линиями) и входит в `verify`:
|
|
359
|
-
релиз должен быть новее собственных предрелизов, иначе дозор срабатывал бы вечно.
|
|
360
|
-
|
|
361
|
-
Число покрытия не является гейтом: часть разделов пакет сознательно оставляет на английском.
|
|
362
|
-
Рядом печатается отчёт **по namespace**: аудит восстанавливает связь «namespace → словарь»
|
|
363
|
-
по тому, кто его регистрирует (`NS` или литерал в `locale.register`; `bind` и `PropsLocale`
|
|
364
|
-
только читают namespace), и показывает ключи, которых нет ни в своём namespace, ни в общем
|
|
365
|
-
`common`, куда рантайм падает при поиске. Глобальное сравнение имён такие дыры не видит:
|
|
366
|
-
перевод, лежащий под чужим namespace, считается покрытием, а экран в это время показывает
|
|
367
|
-
английский. Отчёт справочный — одинаковое имя в разных namespace может значить разное
|
|
368
|
-
(`list.aria` — «Активные напоминания» в каталоге и «Фоновые задачи» в задачах), поэтому
|
|
369
|
-
перевод переносится в чужой namespace только там, где оба namespace обслуживает один и
|
|
370
|
-
тот же словарь. На закреплённом теге отчёт пуст: каждая строка, которую харнесс рисует в
|
|
371
|
-
нашем namespace, лежит именно в нём. Сверяются все 584 namespace пака — привязка строится и по
|
|
372
|
-
импорту словаря рядом с регистрацией, и по именам, которые передаёт сама регистрирующая
|
|
373
|
-
строка (`locale.register(NS, { zh, en })`); без второго правила `common` и `settings.locale`,
|
|
374
|
-
чьи словари лежат в соседнем каталоге, оставались бы вне сверки. Обратная сторона проверяется
|
|
375
|
-
жёстко: namespace, который харнесс регистрирует и наполняет ключами, а пак не регистрирует, —
|
|
376
|
-
это отказ сборки, потому что такой экран остаётся английским, а покрытие по именам ключей
|
|
377
|
-
этого не видит. Так нашёлся `settings.sessionLog` — строка «Загружать журнал сессии» на
|
|
378
|
-
странице общих настроек.
|
|
379
|
-
|
|
380
|
-
## Область покрытия: харнесс и словари плагинов
|
|
381
|
-
Пакет переводит **собственные namespace клиента харнесса** — 64 namespace сверенных с
|
|
382
|
-
закреплённым тегом, — и **словари сторонних плагинов**: 520 плагинов, чей английский текст
|
|
383
|
-
выгружен из их собственной публикации вместе с версией и лицензией.
|
|
384
|
-
|
|
385
|
-
Поиск по реестру npm — шесть запросов вместо одного «dsh» — нашёл ещё 40 плагинов со своим
|
|
386
|
-
словарём. 39 из них переведены; три имени (`dsh-automation`, `remote`, `settings.ip-pool`)
|
|
387
|
-
уже заняты словарями других плагинов и оставлены прежним владельцам, чтобы не подменить
|
|
388
|
-
перевод чужого продукта. Итог на 22 октября 2026: **584 namespace, 67 666 значений,
|
|
389
|
-
520 словарей, 47 700 различных русских строк** в собранном пакете. Замер конкурентов тем же
|
|
390
|
-
методом — [docs/competitors.md](https://github.com/Ragnoryok1/dsh-client-locale-ru/blob/main/docs/competitors.md).
|
|
391
|
-
|
|
392
|
-
Раньше словари плагинов в область не входили, и на то была причина: у `dshmarket` уже
|
|
393
|
-
версия 1.66.44, её ключи меняются независимо от харнесса, а молчаливое обещание «покрыто
|
|
394
|
-
всё» — это не обещание, а долг, который нельзя предъявить. Ответ оказался простым: чужой
|
|
395
|
-
английский текст **выгружается** (`npm run fetch:plugins`) и хранится рядом с переводом —
|
|
396
|
-
с именем пакета, версией и лицензией, а аудит сверяет наш перевод именно с этим снимком, а
|
|
397
|
-
не с чужим русским. Мы проверили 17 самых скачиваемых плагинов экосистемы (npm,
|
|
398
|
-
`keywords:dsh-plugin`, скачивания за месяц) и посмотрели, какие из них вообще поставляют
|
|
399
|
-
собственные строки:
|
|
400
|
-
|
|
401
|
-
| Что обнаружено | Плагинов |
|
|
402
|
-
|---|---|
|
|
403
|
-
| **Своих строк нет** — интерфейс берёт текст из namespace харнесса | **11 из 17** |
|
|
404
|
-
| Крупный собственный словарь (подтверждено вручную) | 2 — `dshmarket` (733 ключа), `@nanmicoder/dsh-agent-teams` (420) |
|
|
405
|
-
| Только типы `.d.ts`, строк нет | 1 — `dsh-plugin-model-proxy` |
|
|
406
|
-
| Требует отдельной проверки | 3 |
|
|
407
|
-
|
|
408
|
-
У 11 из 17 популярнейших плагинов русский интерфейс уже работает без отдельного словаря:
|
|
409
|
-
их текст лежит в общих namespace харнесса, которые пакет переводит полностью. Словари
|
|
410
|
-
есть там, где плагин везёт свои строки, — их 32, и у каждого зафиксирована версия, с
|
|
411
|
-
которой выгружен английский текст.
|
|
412
|
-
|
|
413
|
-
Такой словарь — обязательство следить за чужими релизами, но теперь оно проверяемое:
|
|
414
|
-
новая версия плагина с другими ключами видна как расхождение снимка, а не как тишина.
|
|
415
|
-
Нужен конкретный плагин — заведите issue: словарь для него возможен как отдельный слой,
|
|
416
|
-
привязанный к версии, а не как молчаливое обещание «покрыто всё».
|
|
417
|
-
|
|
418
|
-
## Разработка
|
|
419
|
-
|
|
420
|
-
```sh
|
|
421
|
-
pnpm install
|
|
422
|
-
pnpm run build # tsdown -> lib/index.js (node half) + lib/client.js (client bundle)
|
|
423
|
-
npm pack # -> ragnoryok1-dsh-client-locale-ru-<version>.tgz
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
`lib/client.js` собирается в формате, который понимает клиентский загрузчик `dsh` (`__ModuleLoader__.load`), и экспортирует `inject`/`apply`.
|
|
427
|
-
|
|
428
|
-
## Релизы
|
|
429
|
-
|
|
430
|
-
Публикация в npm выполняется workflow `publish` по тегу — учётные данные лежат в секрете
|
|
431
|
-
репозитория (`NPM_TOKEN`), поэтому токен не нужно ни вводить в терминал, ни пересылать.
|
|
432
|
-
Ручная публикация с машины возможна, но не нужна.
|
|
433
|
-
|
|
434
|
-
```
|
|
435
|
-
npm version 0.3.0 --no-git-tag-version # поднять версию в package.json
|
|
436
|
-
# …и синхронно обновить версию в блоке deepseek-harness-meta в этом README
|
|
437
|
-
git commit -am "release: 0.3.0" && git tag v0.3.0 && git push origin v0.3.0
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Перед публикацией workflow проверяет:
|
|
441
|
-
|
|
442
|
-
1. версия в теге совпадает с версией в `package.json`;
|
|
443
|
-
2. версия в блоке `deepseek-harness-meta` совпадает с `package.json` — маркетплейс берёт её оттуда,
|
|
444
|
-
причём читает **только при первой индексации**, поэтому расхождение не исправляется само;
|
|
445
|
-
3. типографику (18 правил);
|
|
446
|
-
4. аудит локализации против закреплённого тега харнесса — мёртвые namespace, дубли и пары форм
|
|
447
|
-
числа упадут и остановят публикацию;
|
|
448
|
-
5. **совместимость со всеми версиями из `compatible_versions`**: для каждой скачивается её
|
|
449
|
-
рантайм локали с npm и против него прогоняются три набора — сосуществование языков, формы
|
|
450
|
-
числа и собранные фразы (`npm run check:compat`, входит в CI) — обещание в meta-блоке
|
|
451
|
-
проверяется, а не подразумевается.
|
|
452
|
-
|
|
453
|
-
Отдельно проверяется само **объявление** совместимости (`npm run check:peers`, входит в
|
|
454
|
-
`verify`): харнесс читает наши `peerDependencies` для `@deepseek-ai/dsh*` не как версии пакетов,
|
|
455
|
-
а как диапазон **версий рантайма** и с `includePrerelease` — и если диапазон не удовлетворит
|
|
456
|
-
работающий dsh, пользователь увидит предупреждение о несовместимости и запрос на исключение.
|
|
457
|
-
Скрипт прогоняет это правило харнесса по всем заявленным версиям: сейчас проходят все восемь.
|
|
458
|
-
|
|
459
|
-
Проверить всё то же локально, без публикации:
|
|
460
|
-
|
|
461
|
-
```
|
|
462
|
-
npm run verify -- путь/к/дереву/харнесса
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
Для workflow есть ручной запуск с переключателем «только проверки, без публикации»
|
|
466
|
-
(`workflow_dispatch` → `dry-run`).
|
|
467
|
-
|
|
468
|
-
## Содержимое
|
|
469
|
-
|
|
470
|
-
- `src/client/dicts.ts` — русские словари: 584 namespace и 67 666 строк, файл 71 453 строки. Это и есть основная ценность.
|
|
471
|
-
- `src/client/index.ts` — точка входа клиентского плагина (регистрация `ru` + словарей).
|
|
472
|
-
- `src/index.ts` — пустая host-половина (`apply()`).
|
|
473
|
-
- `cordis.patch.yml` — профиль-патч (`- insert:` клиентской строки `locale-ru`).
|
|
474
|
-
|
|
475
|
-
## Что переведено
|
|
476
|
-
|
|
477
|
-
Актуальный набор — по тегам харнеса: ключи сняты с профильного коммита, а добавленные
|
|
478
|
-
позже падают на `en` при поиске, поэтому пакет не ломает интерфейс на новых версиях.
|
|
479
|
-
|
|
480
|
-
### 0.1.7 — исправлен мёртвый namespace, переведён менеджер задач, переписаны числительные
|
|
481
|
-
|
|
482
|
-
Главное в релизе — **исправление ошибки из 0.1.6**. Тогда было записано, что namespace
|
|
483
|
-
`schedule.catalog` упразднён, а его место занял `schedule.manager`. На деле в харнесе
|
|
484
|
-
**оба** namespace живут и по отдельности: `schedule.catalog` — это каталог напоминаний в
|
|
485
|
-
шапке сессии с частотами и единицами, `schedule.manager` — новый менеджер задач
|
|
486
|
-
автоматизации. Из-за неверного вывода ~30 строк переводов (напоминания, частота, единицы
|
|
487
|
-
времени) были зарегистрированы под именем, которое никто не читает, и **никогда не
|
|
488
|
-
показывались** в интерфейсе. Теперь каталог зарегистрирован как `schedule.catalog`.
|
|
489
|
-
|
|
490
|
-
- **исправлено:** переводы каталога расписания снова видны — `trigger.*`, `list.*`,
|
|
491
|
-
`delete.*`, `frequency.*`, `cron.*`, `unit.*`, `relative.*`, `mark.aria`, `hover.more`;
|
|
492
|
-
- **добавлен `schedule.manager`** (188 ключей) — менеджер задач автоматизации целиком на
|
|
493
|
-
русском: панель и каталог задач, поиск, фильтр состояний, сведения о задаче и её вкладки,
|
|
494
|
-
**журнал запусков** с правилами хранения, редактор расписания (дата, время, час, минута,
|
|
495
|
-
секунда, часовой пояс, интервал повтора), правила повтора (разово, каждые N минут/часов/
|
|
496
|
-
секунд, ежедневно, пн–пт, еженедельно, свой cron), cron-форма с выбором дат и минуты,
|
|
497
|
-
удаление с подтверждением, уведомления и карточки;
|
|
498
|
-
- **числительные переписаны** (17 пар ключей): формы, которые ломались на числах 2–4,
|
|
499
|
-
заменены на корректные при любом `n ≥ 2` — например «2 субагентов» → «Субагентов: 2»,
|
|
500
|
-
«каждые 2 часов» → «каждые 2 ч». Ещё 8 строк с `{count}` перед склоняемым словом
|
|
501
|
-
переведены на сокращения: «ещё 3 строк» → «ещё 3 стр.»;
|
|
502
|
-
- **добавлено 7 ключей**, которые отсутствовали: `blocked.composer`,
|
|
503
|
-
`defaultWorkspace.title`, `schedule.active`, `settings.transcript.expanded`,
|
|
504
|
-
`status.scheduled`, `status.overdue` и namespace `shortcuts.layout` (подпись команды
|
|
505
|
-
показа левой панели);
|
|
506
|
-
- **новая проверка в проекте:** аудит имён namespace. Прежняя проверка покрытия
|
|
507
|
-
сверяла ключи внутри namespace, но не сверяла сами имена, поэтому целый namespace
|
|
508
|
-
мог быть зарегистрирован под несуществующим именем и тихо не работать. Теперь имена
|
|
509
|
-
извлекаются из всех способов их объявления (`const NS`/`SETTINGS_NS`/`namespace`,
|
|
510
|
-
`locale.register`, `locale.bind`, `PropsLocale<…>`) и сравниваются множествами.
|
|
511
|
-
|
|
512
|
-
В 0.1.2 добавлены разделы, которых не было в 0.1.1: `open-in-app` («Открыть в
|
|
513
|
-
приложении»), `sidebarFiles`, `sidebarRight` (правый сайдбар с файлами) и
|
|
514
|
-
`sidebarCodePreview` (предпросмотр кода). Также обновлены ключи, изменившиеся в
|
|
515
|
-
харнесе 0.1.5, и удалены 21 ключ, которых в нём больше нет.
|
|
516
|
-
|
|
517
|
-
В 0.1.3 пакет догнал харнес 0.1.6-alpha.1: добавлено 139 ключей и 7 новых
|
|
518
|
-
разделов — `sidebarTerminal` (терминал в правом сайдбаре), `settings.archivedSessions`
|
|
519
|
-
(архивные сессии) и семейство предпросмотра документов (`sidebarDocumentPreview`,
|
|
520
|
-
`documentHtml`, `sidebarImage`, `documentMarkdown`, `sidebarPdf`). Кроме этого
|
|
521
|
-
переведена экспериментальная «Автопроверка» (`permission.access`: `auto.*`),
|
|
522
|
-
подписи и токены палитры команд, поля эндпоинтов в настройках моделей и
|
|
523
|
-
изменения в `conversation`, `trajectory`, `chat`, `session-log-download`.
|
|
524
|
-
28 ключей, исчезнувших из харнеса, удалены.
|
|
525
|
-
|
|
526
|
-
Проверка покрытия выполняется по исходникам харнеса: для каждого namespace
|
|
527
|
-
сравниваются множества ключей, поэтому следующий выпуск начинается с точного
|
|
528
|
-
списка «добавить / проверить / удалить».
|
|
529
|
-
|
|
530
|
-
В 0.1.6 пакет догнал харнес **0.1.7-rc.2**: добавлено **252 ключа**, 18 обновлены,
|
|
531
|
-
26 удалены, добавлены два новых namespace. Изменения:
|
|
532
|
-
|
|
533
|
-
- **`shortcuts`** (новый namespace, 56 ключей) — редактор горячих клавиш: запись
|
|
534
|
-
сочетания, конфликты, зарезервированные комбинации, подсказки для macOS и
|
|
535
|
-
Windows, восстановление значений по умолчанию;
|
|
536
|
-
- **`schedule.manager`** (70 ключей на тот момент) — менеджер задач автоматизации: список,
|
|
537
|
-
удаление, повтор, история запусков, выражения Cron. **Ошибочно было записано, что
|
|
538
|
-
namespace `schedule.catalog` при этом упразднён; в 0.1.7 это исправлено — оба
|
|
539
|
-
namespace существуют параллельно**;
|
|
540
|
-
- **`settings.account`** (50 ключей) — первый запуск приложения: приветствие,
|
|
541
|
-
выбор назначения и глубины показа хода работы, пополнение баланса, выход из
|
|
542
|
-
учётной записи во время выполнения задач;
|
|
543
|
-
- добавлены подписи добавления и удаления инструментов на ходу
|
|
544
|
-
(`message.tools*`, `trajectory.layout.*`), команды правой боковой панели
|
|
545
|
-
(`sidebarRight`), состояния «сначала выберите сессию» в панелях, обновлено
|
|
546
|
-
название раздела настроек: «Инструменты для кода» вместо «Инструментов
|
|
547
|
-
разработчика»;
|
|
548
|
-
- 18 ключей обновлены под изменившийся английский текст, 26 удалены. Единый термин
|
|
549
|
-
«рабочая папка» вместо «рабочей области» в одном месте.
|
|
550
|
-
|
|
551
|
-
В 0.1.5 пакет догнал харнес **0.1.7-rc.1**: добавлено **49 ключей**, 13 обновлены,
|
|
552
|
-
16 удалены, namespace `directory-browser` убран (в rc.1 его больше нет). Появились
|
|
553
|
-
подписи шагов работы инструментов (`message.stepProcess.prepare.*` и `done.*` —
|
|
554
|
-
чтение изображений, запись файлов, подготовка к поиску по коду, веб-поиску,
|
|
555
|
-
координации субагентов и другие), просмотр изображений во весь экран
|
|
556
|
-
(`image.*`), режимы показа ходов «Стандартный» и «Подробный», установка плагинов
|
|
557
|
-
из GitHub с таймаутом и китайским зеркалом, предупреждение о несовместимой версии
|
|
558
|
-
плагина, выбор источника загрузки моделей для голосового ввода и сообщения
|
|
559
|
-
команды `Cordis`. Уточнены формулировки, где upstream заменил «teammate/agent»
|
|
560
|
-
на «subagent», а «Beta» — на «Experimental».
|
|
561
|
-
|
|
562
|
-
Также в 0.1.5 исправлена единица счёта в инвентаре плагинов: было «187 плагины»,
|
|
563
|
-
стало «187 плагинов». Переведены и встроенные снимки интерфейса, добавлены npm
|
|
564
|
-
keywords и исправлен peer-диапазон `@deepseek-ai/dsh-client-locale`
|
|
565
|
-
(`>=0.1.0-rc.2 <0.2.0`) — раньше `^0.1.0` не разрешался, потому что пакет
|
|
566
|
-
публикуется только под prerelease-версиями.
|
|
567
|
-
|
|
568
|
-
В 0.1.4 пакет догнал харнес **0.1.7-alpha.2** — самый крупный скачок: добавлено
|
|
569
|
-
**905 ключей**, 29 изменены, 126 удалены. Новые разделы:
|
|
570
|
-
|
|
571
|
-
- **`pluginManager`** — встроенная панель плагинов: установка, удаление,
|
|
572
|
-
включение и отключение компонентов, версии, реестры и подсказки по установке;
|
|
573
|
-
- **`settings.account`** — учётная запись DeepSeek: вход, баланс, расход,
|
|
574
|
-
API-ключ;
|
|
575
|
-
- отдельные разделы настроек, на которые разъехался прежний `settings.plugins`:
|
|
576
|
-
**`settings.agentLoop`**, **`settings.shell`**, **`settings.subagent`**,
|
|
577
|
-
**`settings.webSearch`**;
|
|
578
|
-
- **`sidebarBrowser`** — встроенный браузер в правой панели (адрес, песочница,
|
|
579
|
-
восстановление страницы);
|
|
580
|
-
- **`sidebarExcel`** и **`sidebarOffice`** — предпросмотр таблиц и документов
|
|
581
|
-
Office; масштабирование (`zoom.*`) добавлено в PDF и изображения;
|
|
582
|
-
- **`voice-input`** — экспериментальный голосовой ввод.
|
|
583
|
-
|
|
584
|
-
Также переведены новые тексты в `conversation` (+194), `chat` (+53),
|
|
585
|
-
`workspace` (+43: архив сессий, закрепление), `deliverables` (+31: обзор
|
|
586
|
-
изменений хода), `job` (+24: живой вывод фоновых задач), `settings` (+22:
|
|
587
|
-
обновление десктопного приложения), `plan`, `open-in-app`, `trajectory`,
|
|
588
|
-
`model`, `reference`, `session-log-download` и в руководствах по режимам
|
|
589
|
-
агента (`settings.agentPreset`, 12 длинных текстов). Раздел
|
|
590
|
-
`settings.archivedSessions` удалён: в 0.1.7 upstream убрал этот пакет, а архив
|
|
591
|
-
сессий переехал в `workspace`.
|
|
592
|
-
|
|
593
204
|
## Лицензия
|
|
594
205
|
|
|
595
206
|
MIT
|
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.17",
|
|
5
5
|
"tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
|
|
6
|
-
"description": "
|
|
6
|
+
"description": "Russian for the DeepSeek Harness web GUI: the whole interface plus the menus of 520 third-party plugins — 584 sections, 67 666 strings.",
|
|
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",
|
|
@@ -24,7 +24,15 @@
|
|
|
24
24
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
25
25
|
[](https://github.com/Ragnoryok1/dsh-client-locale-ru)
|
|
26
26
|
|
|
27
|
-
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
27
|
+
插件把 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的界面变成俄语。你看到的一切都会被翻译:设置、侧边栏、对话框、提示、错误信息——以及没有自带俄语的三方插件菜单。
|
|
28
|
+
|
|
29
|
+
目前包里有 584 个分区、67 666 条文案,其中 520 份是第三方插件的词典——比我能找到的任何其他俄语包都多。
|
|
30
|
+
|
|
31
|
+
安装只需一条命令:`dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru`,然后在设置 General 里选择俄语。
|
|
32
|
+
|
|
33
|
+
除了翻译,插件还做三件 harness 自己做不到的事:按数字选择俄语复数形式(而不是中性标签)、套用俄语排版(«ёлочки»、长破折号、省略号),以及翻译没有自带 locale 的插件名称。每一项都能在配置里用一行关闭——翻译本身保留。
|
|
34
|
+
|
|
35
|
+
插件不会修改 harness 的文件,也不会碰你的数据。如果新版 harness 出现包里还没有的文案,它会保持英文:界面照常工作。MIT 许可,由社区维护,与 DeepSeek 无关联。
|
|
28
36
|
|
|
29
37
|
> **如果这个包对你有用,请给仓库点一颗 star。** 这是表明「有人需要这份翻译」的唯一信号,它也决定了接下来优先做哪些部分。
|
|
30
38
|
|
|
@@ -87,7 +95,7 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
87
95
|
|
|
88
96
|
清单按 harness 自身的规则检查,而不是靠肉眼(`npm run check:manifest`,包含在 `verify` 中)。每一条规则都取自 harness 源码,每一条都对应一种否则会先落到用户头上的失败:`parseDshClient` 接受任意字符串作为 `platform`,但消费方只保留 `platform === 'web'` 的行,因此写成 `'Web'` 这样的笔误会**悄悄关掉**客户端那一半;声明了 `dsh.client` 却没有 `./client` 导出会让 `client-modules` 抛错;`dsh.bundle.patch` 必须指向确实存在的文件。
|
|
89
97
|
|
|
90
|
-
从 GitHub 安装同样可用:`dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru`(插件目录生成的就是这种不带 npm scope 的写法)安装的是仓库归档,而构建好的 `lib/` 已提交进 git——你的机器上不会运行构建,也不需要运行。正因如此,`npm run check:built`(包含在 `verify` 中)会重新构建 `lib/` 并与提交内容比对:git 里过期的构建产物会直接落到用户手里,而审计看不到它——审计读的是源码。发布的包为
|
|
98
|
+
从 GitHub 安装同样可用:`dsh plugin --profile web add Ragnoryok1/dsh-client-locale-ru`(插件目录生成的就是这种不带 npm scope 的写法)安装的是仓库归档,而构建好的 `lib/` 已提交进 git——你的机器上不会运行构建,也不需要运行。正因如此,`npm run check:built`(包含在 `verify` 中)会重新构建 `lib/` 并与提交内容比对:git 里过期的构建产物会直接落到用户手里,而审计看不到它——审计读的是源码。发布的包为 1975 kB:横幅以 JPEG 提供,图标与源码映射不进入 npm 包。
|
|
91
99
|
|
|
92
100
|
## 为什么是混合插件
|
|
93
101
|
|
|
@@ -127,166 +135,6 @@ dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru
|
|
|
127
135
|
同样这 32 个名称会作为补丁(`docs/harness-descriptors-ru.patch`)送到 harness:在 harness 自己的界面里插件也有俄文名称,而这个补丁先到。补丁是构建产物——它由翻译和 harness 目录树生成,门禁 `npm run check:descriptor-patch` 在生成的补丁与仓库里那份不一致时失败。第三方插件的名称放在 `src/client/plugin-names-ru.json`:这个文件由插件词典生成(`npm run build:plugin-names`),门禁 `npm run check:plugin-names:map` 在它与词典不一致时失败。同一个英文名称不能有两种译法——harness 与插件各说各话。`npm run check:plugin-names` 在真实文档上证明(jsdom,12 个用例)这个流程会翻译标题、说明、朗读名称和 bundle 的一行,而该不动的它不动。
|
|
128
136
|
|
|
129
137
|
|
|
130
|
-
## 检查
|
|
131
|
-
|
|
132
|
-
```sh
|
|
133
|
-
npm run build # 三个产物的构建
|
|
134
|
-
npm run check:typography # 18 条排版规则,含「不要动」
|
|
135
|
-
npm run check:locale # 词典共存:6 项检查
|
|
136
|
-
npm run check:plural # 复数形式:1 вызов / 2 вызова / 5 вызовов
|
|
137
|
-
npm run check:composition # 组合短语:«Пн, Ср в 09:00»、«Раз в 2 дня»
|
|
138
|
-
npm run check:namespaces # NAMESPACES.md 与构建出的 bundle 一致
|
|
139
|
-
npm run check:tarball # 用户实际安装的:解开归档并检查
|
|
140
|
-
npm run check:workflows # 两个 workflow 都运行完整的 verify 链
|
|
141
|
-
npm run check:readmes:pairs # 三个 README 同步推进(记录各节哈希)
|
|
142
|
-
npm run check:plugin-names # 插件名称在真实文档上变成俄文
|
|
143
|
-
npm run check:descriptor-patch # harness 补丁与翻译一致
|
|
144
|
-
npm run audit -- <harness tree> # 本地化审计
|
|
145
|
-
npm run verify -- <harness tree> # 全部一起
|
|
146
|
-
|
|
147
|
-
npm run namespaces # 重新生成 NAMESPACES.md 与 pack-count.json
|
|
148
|
-
npm run readmes:record # 三个 README 都改完后重新记录各节哈希
|
|
149
|
-
npm run diff:harness -- <old> <new> # harness 改写了哪些英文
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
另有一项检查按 harness 的方式把短语拼起来,再整句阅读。审计只把取值与它自己的模板比对,因此「单独看正确、被替换后就错了」的句子它看不见:`frequency.weekly` 曾填成 «По {weekdays} в {time}»,而星期是 «Пн, Ср»——得到 «По Пн, Ср в 09:00»,任何逐值检查都发现不了。同样被钉住的还有 «Каждые 2 дня»(现为 «Раз в 2 дня»)、«Каждый день в 09:00 (Europe/Moscow)»,以及带复数形式的组合间隔。同一种方式还找出了第三处:`time.locale` 不是文案,而是给 `Intl` 的语言标签,它的取值曾是 `en`——限制到某个月的规则显示成 «Каждый день в January»,俄语界面里的时区标签是 «Moscow Standard Time»。现在是 `ru`(harness 的中文词典同样用 `zh-CN`),月份放在括号里:«Каждый день (январь, март)»。
|
|
153
|
-
|
|
154
|
-
同样按部分拆读还发现了 cron 描述的写法问题:缩写(«Каждые {step} мин»、«Каждые {count} ч»)和书卷气的表达(«в минуту {minutes}»、«минуты {minutes} в часы {hours}»)。带计数的部分补上了复数形式——«Каждые 3 минуты» / «Каждые 5 минут»、«Каждые 2 часа» / «Каждые 6 часов»——其余改写成统一的带标注写法:«Каждый час, минуты: 5, 30»、«минуты: 5, часы: 09–17»。整句日程描述也整句断言:«Пн–Пт каждые 5 минут»。日期同样被钉住:«5 окт. 2026 г., 15:51» 与时区标签 «Москва, стандартное время» 都由 Intl 用我们的标签生成,不含任何拉丁词。
|
|
155
|
-
|
|
156
|
-
审计在 CI(`.github/workflows/verify.yml`)中针对**锁定的 harness 标签**运行,而不是针对随便一份本地 checkout。同一次运行还会**每周按计划**触发一次:即使没人改动,译文也会腐坏——上游继续前进,本地一切正常,而偏差只在用户构建时才浮现。门禁覆盖完整性(key 与 namespace)、复数形式、占位符、英文与中文残留、术语、正文中的拉丁词、文本卫生、首尾空格、风格、取值的排版、«ё»、组合短语、设置侧栏标签的长度以及对外宣称的数字——每一项都已经抓到过真实缺陷。除此之外,审计还会打印**参考报告**——它们不是门禁,因为需要人来判断:比对了多少个 namespace、哪些无法建立对应关系、是否还留有「数字 + 需变格的名词」,以及短字符串是否长到英文的 2.8 倍以上(排版风险——«Effort» → «Уровень рассуждения» 是俄语的正常长度,不是缺陷)。
|
|
157
|
-
|
|
158
|
-
审计按 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` 会打包归档,并把声明的千字节数与实际值对比(允许 2013 kB 误差——不同 Node 构建下的 gzip 压缩结果略有差别,而这句话本身也只精确到整千字节)。
|
|
159
|
-
|
|
160
|
-
- **无效 namespace**——包注册的每一个 namespace 都必须在 harness 中存在。在 0.1.6 中,日程目录的翻译被注册在 `schedule.manager` 名下,而读取它们的是 `schedule.catalog`:此时按 key 做的覆盖率检查还报告「全部已翻译」;
|
|
161
|
-
- **复数形式配对**——`.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 会把计数传给它,却从不配对)——这些形式只由我们维护,少一个不会有任何其他检查发现;
|
|
162
|
-
- **占位符**——俄语值必须携带与英文模板完全相同的 `{name}`:多出的占位符会原样出现在界面上(`Заняло {duration}7мин 26с`,已在 #2 修复),缺失的则会让插值内容悄悄消失。对于只提供中文词典的包,模板以 `zh` 为准。我们**自己添加的复数形式**——补充的 `.few`/`.many`,以及 harness 从未配对的 key 上的 `.one`——在上游并不存在,因此改为与同一词相邻形式(`.one`/`.other`)或该 key 本身的模板比对。没有这条规则时,有 52 个取值从未被检查过:`{count}` 正是可能从某个形式里丢失,让句子少了数字。
|
|
163
|
-
- **残留**——取值必须是俄语:与英文模板完全相同的副本、残留的中文字符,或模板有文本而取值为空,都是缺陷。只有记录在 `scripts/keep-english.json` 中的决定才允许保留英文(地址、无文字的格式串、协议与工具名称、缩写),因此新出现的未翻译字符串无法悄悄通过。这些决定本身也会被检查:已经不再排除任何东西的条目同样会让构建失败——要么包里已经没有这个 key,要么取值已经翻译、决定随之作废。`deepSeekBaseUrl` 正是这样被发现的:英文模板多了一句关于 `DEEPSEEK_BASE_URL` 的说明,而输入框的占位符必须是纯示例地址,把说明塞进输入框只会变成噪音。条目已删除,取值保留。决定也可以覆盖一个封闭列表:`chat · app.*` 用一行允许三十个应用名——应用名词典本身就是一份名单。而占位符之外没有词的值(`{from}–{to}`、`{percent}%`、`, `)根本不需要决定:里面没有可翻译的内容,策略因此只谈词,不谈标点。残留检查现在读取 key 的**全部**模板,而不只是 `en` 块:以前有 60 个取值落在未被识别的词典块里、完全没有被检查;现在比对 2911 个取值,其中 68 个由决定覆盖(38 条记录,其中一条是模式),这个盲区作为一类已经消失。规则并没有因此变宽:只有当没有任何模板为空时,空取值为缺陷——否则俄语正当地省略英文同样省略的前缀(`message.stepProcess.sharedPrefix`)。而精确相等也不是唯一的副本:与模板仅相差大小写或首尾空格的取值(模板 `cancel` 而取值为 `Cancel`)同样是未翻译的文本,同样需要决定——否则这样的行会以英文显示,而所有检查却都是绿的。
|
|
164
|
-
- **失效 key**——既不在任何 harness 词典中、也没有任何 harness 源码引用的 key,是旧版本留下的残余:它什么也不显示,只会误导。这类 key 会让构建失败。组件仍会请求的 key 只出现在参考报告中,因为真正显示在界面上的是我们提供的值。
|
|
165
|
-
- **术语**——一个概念只有一种译法。被禁用的变体(«кеш» 而非 «кэш»、«сеанс» 而非 «сессия»、«этап» 而非 «шаг»)会让构建失败;`scripts/terminology.json` 同时保存决定与所选形式的计数,因此漂移在变成缺陷之前就能看到。该检查立刻发现 `confirm.description` 在两个 namespace 下被译成两种写法——«шаги» 和 «этапы»。同一个词也不能既带 «ё» 又不带:同一个包里同时出现 «ещё» 和 «еще» 读起来就是机器翻译,因此检查会把 «ё» 折叠成 «е»,同一种折叠形式出现两种写法就让构建失败。真正不同的词(如 «все» 与 «всё»)在 `scripts/yo-pairs.json` 中声明;声明里的写法若已从包中消失,同样让构建失败。同一份检查也覆盖俄语短语中的拉丁词:产品名、命令名或代码记号可以保留,句子里的普通英文单词则不行。产品名必须与 harness 的写法一致:把 «GitHub Desktop» 写成 «Github Desktop» 读起来就是产品名里的错字,而这种错只会出现在我们这里。参照物是英文模板;harness 只以小写书写的词(«cursor»、«desktop»)不算——在那里大写正好表示产品名。此外还检查机械性文本卫生:连续空格、标点前的空格、不成对的 «ёлочки» 与括号、取值内部的不断行空格,以及首尾空格——以空格开头或结尾的取值会被组件与相邻内容拼接,因此必须与所属 namespace 的英文模板一致。同一个模板还用来核对风格:英文结尾有的标点,俄语不能丢掉(该检查正是这样发现 `registryCustomHint` 少了句点);首字母大小写也必须一致——但 `JSON` 这类缩写,以及以占位符开头的模板除外。对读者的称呼单独检查:句子内部俄语界面写作小写 «вы»,而大写的 «Вы» 只出现在句首,那里只是普通的正字法。最后,本包还会与自身比对:同一句英文只能对应一句俄文。若两个 namespace 给出不同的俄文句子(只比较四个词以上的模板——短标签合法地取决于上下文),构建即失败。`confirm.description` 正是这样被发现的:一种写法承诺 «пропускать шаги подтверждения»,另一种写作 «уменьшать число шагов»,而英文的 «subsequent tasks» 在后者里变成了 «текущей задаче»。有意的差异需要在 `scripts/one-rendering.json` 中连同理由一起声明;已经不再排除任何东西的例外同样会让构建失败,否则这份决定清单会悄悄放宽检查。反方向只作参考输出:同一个俄语答案对应**不同**的英文句子(四个词以上)往往是复制粘贴的痕迹——提示从相邻 key 串了过来,或两件不同的事被并成一句。它不能作为门禁,因为俄语正当地合并英文分开的词,所以两侧会并排打印,由人来判断。
|
|
166
|
-
|
|
167
|
-
标签的新旧由单独的 workflow 盯守:`watch-upstream` 每周把锁定的标签与 harness 的标签比对一次,出现更新的标签就开一个 issue(内含操作步骤)并把运行标红——让「落后」按计划被发现,而不是靠用户的截图。版本比较无需网络即可验证(`npm run check:upstream`,五个用例),并且纳入 `verify`:正式版本必须比自己的预发布版本更新,否则盯守会永远报警。
|
|
168
|
-
|
|
169
|
-
覆盖率数字不是门禁:有些分区是有意保留英文的。紧随其后,审计会打印**按 namespace** 的报告:它根据注册方重建「namespace → 词典」的对应关系(`NS` 声明,或 `locale.register` 里的字面量;`bind` 与 `PropsLocale` 只是读取 namespace),并列出既不在自己 namespace、也不在运行时回退所用的 `common` 词典中的 key。全局比较 key 名称看不到这类空洞:放在别的 namespace 下的翻译会被算作已覆盖,而那个界面实际显示英文。该报告仅供参考——同名 key 在不同 namespace 下含义可能不同(`list.aria` 在提醒目录里是「活动提醒」,在任务里是「后台任务」),因此只有在两个 namespace 由同一份词典提供服务时才会跨 namespace 搬运翻译。在锁定的标签上,该报告为空:harness 在我们注册的 namespace 里渲染的每一条字符串,都位于该 namespace。本包的全部 584 个 namespace 都会被比对——对应关系既来自紧邻注册处的词典导入,也来自注册语句本身传入的名称(`locale.register(NS, { zh, en })`);若没有第二条规则,词典位于相邻目录的 `common` 与 `settings.locale` 就会落在检查之外。反方向是硬失败而不是参考报告:harness 注册并填充了 key、而本包从不注册的 namespace,会让那个界面停留在英文,而按 key 名称统计的覆盖率看起来依然完整。`settings.sessionLog` 正是这样被发现的——通用设置页上的「上传 Session Log」开关。
|
|
170
|
-
|
|
171
|
-
## 覆盖范围:harness 与插件词典
|
|
172
|
-
本包翻译 **harness 客户端自有的 namespace**——共 64 个 namespace,已与锁定标签核对——以及
|
|
173
|
-
**第三方插件的词典**:520 个插件,其英文文本连同版本与许可证一起从它们自己的发布物中提取。
|
|
174
|
-
|
|
175
|
-
我们按六个关键词(而不是只用「dsh」一个)检索 npm,又找到 40 个自带词典的插件:其中 39 个
|
|
176
|
-
已翻译,三个名字(`dsh-automation`、`remote`、`settings.ip-pool`)已被别的插件的词典占用,
|
|
177
|
-
仍归原来的所有者,以免把别人的翻译安到另一个产品上。截至 2026 年 10 月 22 日:**584 个
|
|
178
|
-
namespace、67 666 条、520 个词典、构建产物中 47 700 条不同的俄文**。用同样方法做
|
|
179
|
-
的竞争对手测量见 [docs/competitors.md](https://github.com/Ragnoryok1/dsh-client-locale-ru/blob/main/docs/competitors.md)。
|
|
180
|
-
|
|
181
|
-
此前插件词典不在范围内,理由是:`dshmarket` 已经到 1.66.44 版本,它的 key 变化与 harness
|
|
182
|
-
无关,而「全部都覆盖了」这种无声承诺不是承诺,是一笔没人能讨的债。答案其实很简单:把
|
|
183
|
-
别人的英文文本**提取出来**(`npm run fetch:plugins`),与翻译放在一起——带上包名、版本与
|
|
184
|
-
许可证,审计比对的正是这份快照,而不是别人的俄语。我们检查了生态中下载量最高的 17 个
|
|
185
|
-
插件(npm、`keywords:dsh-plugin`、月下载量),看其中哪些会提供自己的字符串:
|
|
186
|
-
|
|
187
|
-
| 发现的情况 | 插件数 |
|
|
188
|
-
|---|---|
|
|
189
|
-
| **没有自己的字符串**——界面文本取自 harness 的 namespace | **17 个中的 11 个** |
|
|
190
|
-
| 较大的自有词典(已人工确认) | 2 个——`dshmarket`(733 个 key)、`@nanmicoder/dsh-agent-teams`(420) |
|
|
191
|
-
| 只有 `.d.ts` 类型,没有字符串 | 1 个——`dsh-plugin-model-proxy` |
|
|
192
|
-
| 需要单独检查 | 3 个 |
|
|
193
|
-
|
|
194
|
-
在最流行的 17 个插件里,有 11 个的俄语界面无需单独词典即可工作——它们的文本位于 harness
|
|
195
|
-
的公共 namespace 中,而本包已把这些 namespace 完整翻译。词典存在于插件自带字符串的地方,
|
|
196
|
-
共 32 个,每个都记着提取英文文本时所依据的版本。
|
|
197
|
-
|
|
198
|
-
这样的词典意味着要跟进别人的发布节奏,但现在这份责任是可核查的:插件的新版本带来不同的
|
|
199
|
-
key 时,表现为与快照的差异,而不是一片沉默。需要某个具体插件——请开 issue:可以为它做一个
|
|
200
|
-
绑定版本的独立层词典,而不是默默地承诺「全部都覆盖了」。
|
|
201
|
-
|
|
202
|
-
## 开发
|
|
203
|
-
|
|
204
|
-
```sh
|
|
205
|
-
pnpm install
|
|
206
|
-
pnpm run build # tsdown -> lib/index.js (node half) + lib/client.js (client bundle)
|
|
207
|
-
npm pack # -> ragnoryok1-dsh-client-locale-ru-<version>.tgz
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
`lib/client.js` 会编译成 `dsh` 客户端加载器(`__ModuleLoader__.load`)能够识别的格式,并导出 `inject`/`apply`。
|
|
211
|
-
|
|
212
|
-
## 发布
|
|
213
|
-
|
|
214
|
-
发布到 npm 由 `publish` workflow 按标签执行——凭据保存在仓库 secret(`NPM_TOKEN`)中,因此既不需要在终端里输入 token,也不需要转发它。从本机手动发布是可行的,但没有必要。
|
|
215
|
-
|
|
216
|
-
```
|
|
217
|
-
npm version 0.3.0 --no-git-tag-version # поднять версию в package.json
|
|
218
|
-
# …и синхронно обновить версию в блоке deepseek-harness-meta в этом README
|
|
219
|
-
git commit -am "release: 0.3.0" && git tag v0.3.0 && git push origin v0.3.0
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
发布前 workflow 会检查:
|
|
223
|
-
|
|
224
|
-
1. 标签中的版本与 `package.json` 中的版本一致;
|
|
225
|
-
2. `deepseek-harness-meta` 块中的版本与 `package.json` 一致——marketplace 从那里读取版本,而且**只在首次索引时**读取,因此版本不一致不会自行修正;
|
|
226
|
-
3. 排版(18 条规则);
|
|
227
|
-
4. 针对锁定 harness 标签的本地化审计——无效 namespace、重复项、复数形式配对和占位符不一致会报错并中止发布;
|
|
228
|
-
5. **与 `compatible_versions` 中每个版本的兼容性**:从 npm 下载该版本的 locale 运行时,并对它运行三套测试——语言共存、复数形式与组合短语(`npm run check:compat`,已纳入 CI)——meta 块里的承诺是被验证的,而不是被假定的。
|
|
229
|
-
|
|
230
|
-
声明本身也单独检查(`npm run check:peers`,包含在 `verify` 中):harness 并不把我们对 `@deepseek-ai/dsh*` 的 `peerDependencies` 当作包的版本,而是当作**运行时版本**的范围,并带上 `includePrerelease`;若该范围不满足正在运行的 dsh,用户就会看到不兼容警告与豁免提示。脚本把这条 harness 规则套用到所有被声明的版本上——目前八个都通过。
|
|
231
|
-
|
|
232
|
-
在本地做完全相同的检查,但不发布:
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
npm run verify -- путь/к/дереву/харнесса
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
该 workflow 还支持手动触发,并带有「只检查、不发布」的开关(`workflow_dispatch` → `dry-run`)。
|
|
239
|
-
|
|
240
|
-
## 内容
|
|
241
|
-
|
|
242
|
-
- `src/client/dicts.ts`——俄语词典:584 个 namespace、67,666 条字符串,文件 71,506 行。这正是本包的核心价值。
|
|
243
|
-
- `src/client/index.ts`——客户端插件入口(注册 `ru` 和词典)。
|
|
244
|
-
- `src/index.ts`——空的宿主部分(`apply()`)。
|
|
245
|
-
- `cordis.patch.yml`——profile 补丁(`- insert:` 客户端条目 `locale-ru`)。
|
|
246
|
-
|
|
247
|
-
## 翻译内容
|
|
248
|
-
|
|
249
|
-
当前键集按 harness 的标签确定:key 取自对应 profile 的提交,之后新增的 key 在查找时会回退到 `en`,因此本包不会在新版本上弄坏界面。
|
|
250
|
-
|
|
251
|
-
### 0.1.7 — 修复无效 namespace,翻译任务管理器,重写复数形式
|
|
252
|
-
|
|
253
|
-
本版本的重点是**修复 0.1.6 中的错误**。当时记录说 namespace `schedule.catalog` 已被取消,位置由 `schedule.manager` 取代。实际上 harness 中**两个** namespace 各自独立存在:`schedule.catalog` 是会话头部带有频率和单位的提醒目录,`schedule.manager` 则是新的自动化任务管理器。由于这个错误结论,约 30 条翻译字符串(提醒、频率、时间单位)被注册在一个无人读取的名称下,**从未显示**在界面中。现在该目录注册为 `schedule.catalog`。
|
|
254
|
-
|
|
255
|
-
- **已修复:**日程目录的翻译重新可见——`trigger.*`、`list.*`、`delete.*`、`frequency.*`、`cron.*`、`unit.*`、`relative.*`、`mark.aria`、`hover.more`;
|
|
256
|
-
- **新增 `schedule.manager`**(188 个 key)——完全俄语化的自动化任务管理器:任务面板与任务目录、搜索、状态筛选、任务详情及其标签页、带保留规则的**运行日志**、日程编辑器(日期、时间、时、分、秒、时区、重复间隔)、重复规则(一次性、每 N 分钟/小时/秒、每天、周一至周五、每周、自定义 cron)、可选择日期和分钟的 cron 表单、带确认的删除、通知与卡片;
|
|
257
|
-
- **重写复数形式**(17 组 key):把在 2–4 这些数字上出错的写法,换成在任意 `n ≥ 2` 下都正确的写法——例如 «2 субагентов» → «Субагентов: 2»、«каждые 2 часов» → «каждые 2 ч»。另有 8 条把 `{count}` 放在需要变格的词之前的字符串改用缩写:«ещё 3 строк» → «ещё 3 стр.»;
|
|
258
|
-
- **新增 7 个此前缺失的 key**:`blocked.composer`、`defaultWorkspace.title`、`schedule.active`、`settings.transcript.expanded`、`status.scheduled`、`status.overdue`,以及 namespace `shortcuts.layout`(显示左侧面板的命令标签);
|
|
259
|
-
- **项目中的新检查:**namespace 名称审计。此前的覆盖率检查只比对 namespace 内部的 key,却不比对名称本身,因此整个 namespace 可能注册在一个不存在的名称下并悄悄失效。现在会从所有声明方式(`const NS`/`SETTINGS_NS`/`namespace`、`locale.register`、`locale.bind`、`PropsLocale<…>`)中提取名称,并按集合比较。
|
|
260
|
-
|
|
261
|
-
0.1.2 新增了 0.1.1 中没有的分区:`open-in-app`(«Открыть в приложении»)、`sidebarFiles`、`sidebarRight`(带文件的右侧边栏)和 `sidebarCodePreview`(代码预览)。同时更新了在 harness 0.1.5 中发生变化的 key,并删除了其中已不存在的 21 个 key。
|
|
262
|
-
|
|
263
|
-
0.1.3 让本包跟上了 harness 0.1.6-alpha.1:新增 139 个 key 和 7 个新分区——`sidebarTerminal`(右侧边栏中的终端)、`settings.archivedSessions`(已归档会话)以及文档预览系列(`sidebarDocumentPreview`、`documentHtml`、`sidebarImage`、`documentMarkdown`、`sidebarPdf`)。此外还翻译了实验性的「自动检查」(`permission.access`:`auto.*`)、命令面板的标签与 token、模型设置中的端点字段,以及 `conversation`、`trajectory`、`chat`、`session-log-download` 中的变更。已从 harness 中消失的 28 个 key 已删除。
|
|
264
|
-
|
|
265
|
-
覆盖率检查基于 harness 的源码进行:对每个 namespace 比较 key 集合,因此下一个版本总是从一份精确的「新增 / 检查 / 删除」清单开始。
|
|
266
|
-
|
|
267
|
-
0.1.6 让本包跟上了 harness **0.1.7-rc.2**:新增 **252 个 key**,更新 18 个,删除 26 个,并新增两个 namespace。变更如下:
|
|
268
|
-
|
|
269
|
-
- **`shortcuts`**(新 namespace,56 个 key)——快捷键编辑器:录制组合键、冲突、保留组合、macOS 与 Windows 的提示、恢复默认值;
|
|
270
|
-
- **`schedule.manager`**(当时为 70 个 key)——自动化任务管理器:列表、删除、重复、运行历史、Cron 表达式。**当时错误地记录说 namespace `schedule.catalog` 就此被取消;0.1.7 已修正——两个 namespace 并存**;
|
|
271
|
-
- **`settings.account`**(50 个 key)——应用首次启动:欢迎语、选择用途与工作过程展示的详细程度、充值余额、在任务执行期间退出账号;
|
|
272
|
-
- 新增了运行中增删工具的标签(`message.tools*`、`trajectory.layout.*`)、右侧边栏命令(`sidebarRight`)、面板中的「请先选择会话」状态,并更新了设置分区名称:由 «Инструментов разработчика» 改为 «Инструменты для кода»;
|
|
273
|
-
- 18 个 key 按变更后的英文文本更新,26 个删除。有一处把 «рабочей области» 统一改为 «рабочая папка»。
|
|
274
|
-
|
|
275
|
-
0.1.5 让本包跟上了 harness **0.1.7-rc.1**:新增 **49 个 key**,更新 13 个,删除 16 个,移除了 namespace `directory-browser`(rc.1 中已不再有它)。新增了工具执行步骤的标签(`message.stepProcess.prepare.*` 和 `done.*`——读取图像、写入文件、准备代码搜索、网页搜索、子代理协同等)、全屏查看图像(`image.*`)、«Стандартный» 与 «Подробный» 两种过程展示模式、从 GitHub 安装插件(带超时与中国镜像)、插件版本不兼容警告、语音输入的模型下载源选择,以及 `Cordis` 命令的消息。还修订了 upstream 把 «teammate/agent» 改为 «subagent»、把 «Beta» 改为 «Experimental» 的那些措辞。
|
|
276
|
-
|
|
277
|
-
另外,0.1.5 修复了插件清单中的计数单位:原来是 «187 плагины»,现在是 «187 плагинов»。内置界面截图也已翻译,补充了 npm keywords,并修正了 `@deepseek-ai/dsh-client-locale` 的 peer 范围(`>=0.1.0-rc.2 <0.2.0`)——此前 `^0.1.0` 无法解析,因为该包只以 prerelease 版本发布。
|
|
278
|
-
|
|
279
|
-
0.1.4 让本包跟上了 harness **0.1.7-alpha.2**——这是跨度最大的一次:新增 **905 个 key**,修改 29 个,删除 126 个。新增分区:
|
|
280
|
-
|
|
281
|
-
- **`pluginManager`**——内置插件面板:安装、删除、启用与停用组件、版本、注册表以及安装提示;
|
|
282
|
-
- **`settings.account`**——DeepSeek 账号:登录、余额、消费、API 密钥;
|
|
283
|
-
- 原先的 `settings.plugins` 拆分成的几个独立设置分区:**`settings.agentLoop`**、**`settings.shell`**、**`settings.subagent`**、**`settings.webSearch`**;
|
|
284
|
-
- **`sidebarBrowser`**——右侧面板中的内置浏览器(地址、沙箱、恢复页面);
|
|
285
|
-
- **`sidebarExcel`** 和 **`sidebarOffice`**——表格与 Office 文档的预览;PDF 和图像中新增了缩放(`zoom.*`);
|
|
286
|
-
- **`voice-input`**——实验性语音输入。
|
|
287
|
-
|
|
288
|
-
此外还翻译了 `conversation`(+194)、`chat`(+53)、`workspace`(+43:会话归档、置顶)、`deliverables`(+31:过程变更概览)、`job`(+24:后台任务的实时输出)、`settings`(+22:桌面应用更新)、`plan`、`open-in-app`、`trajectory`、`model`、`reference`、`session-log-download` 中的新文本,以及代理模式指南中的文本(`settings.agentPreset`,12 段长文本)。`settings.archivedSessions` 分区已删除:0.1.7 中 upstream 去掉了这个包,会话归档迁移到了 `workspace`。
|
|
289
|
-
|
|
290
138
|
## 许可证
|
|
291
139
|
|
|
292
140
|
MIT
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ragnoryok1/dsh-client-locale-ru",
|
|
3
|
-
"description": "Russian
|
|
4
|
-
"version": "0.2.
|
|
3
|
+
"description": "Russian for the DeepSeek Harness web GUI: the whole interface plus the menus of 520 third-party plugins — 584 sections, 67 666 strings.",
|
|
4
|
+
"version": "0.2.17",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
7
7
|
"deepseek-harness",
|