@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 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.16",
4
+ "version": "0.2.17",
5
5
  "tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
6
- "description": "Full Russian (ru) interface for the DeepSeek Harness web GUI: 584 namespaces, 67666 strings, 520 third-party plugin dictionaries, Russian screen typography and Russian plural forms, with a locale audit in CI pinned to a harness tag.",
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
  [![namespaces](https://img.shields.io/badge/namespaces-584-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
25
25
  [![strings](https://img.shields.io/badge/strings-67666-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
26
26
 
27
- Russian (`ru`) language pack for the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) web GUI (`dsh`). It registers `ru` as a selectable client language through the locale service (`ctx.locale.addLanguage`) plus one dictionary per namespace — 584 namespaces, 67,666 strings, built against dsh `0.2.1-rc.2`. Install with `dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru`, then pick **Русский** in Settings → General. Missing keys fall back to English, so a newer harness keeps working. The scope is the harness's own client interface — 64 namespaces (2 996 strings) — plus the dictionaries of 520 third-party plugins, translated from the English each plugin publishes. MIT, community-maintained, not affiliated with DeepSeek.
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 2013 kB: the banner ships as JPEG, and the icon and source map stay out of the npm payload.
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.16",
4
+ "version": "0.2.17",
5
5
  "tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
6
- "description": "Full Russian (ru) interface for the DeepSeek Harness web GUI: 584 namespaces, 67666 strings, 520 third-party plugin dictionaries, Russian screen typography and Russian plural forms, with a locale audit in CI pinned to a harness tag.",
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
  [![namespaces](https://img.shields.io/badge/namespaces-584-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
25
25
  [![strings](https://img.shields.io/badge/strings-67666-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
26
26
 
27
- Русский (`ru`) язык для веб-интерфейса [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`). Пакет регистрирует `ru` как выбираемый язык клиента через сервис локали (`ctx.locale.addLanguage`) и везёт по словарю на каждый namespace — 584 namespace, 67 666 строк, сборка под dsh `0.2.1-rc.2`. Установка: `dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru`, затем **Русский** в Settings → General. Недостающие ключи падают в английский, поэтому более новый харнесс продолжает работать. Область — собственный интерфейс харнесса (64 namespace и 2 996 строк) и словари 521 стороннего плагина, переведённые с английского, который публикует сам плагин. MIT, поддерживается сообществом, не связан с DeepSeek.
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 иначе получил бы именно пользователь, а аудит этого не увидел бы — он читает исходники. Публикуемый пакет занимает 2013 КБ: баннер отдаётся JPEG, а иконка и карта исходников в npm не входят.
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.16",
4
+ "version": "0.2.17",
5
5
  "tags": ["localization", "russian", "i18n", "web-gui", "language-pack"],
6
- "description": "Full Russian (ru) interface for the DeepSeek Harness web GUI: 584 namespaces, 67666 strings, 520 third-party plugin dictionaries, Russian screen typography and Russian plural forms, with a locale audit in CI pinned to a harness tag.",
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
  [![namespaces](https://img.shields.io/badge/namespaces-584-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
25
25
  [![strings](https://img.shields.io/badge/strings-67666-6466f1)](https://github.com/Ragnoryok1/dsh-client-locale-ru)
26
26
 
27
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web 界面(`dsh`)的俄语(`ru`)语言包。它通过 locale 服务(`ctx.locale.addLanguage`)把 `ru` 注册为可选的客户端语言,并为每个 namespace 提供一份词典——共 584 个 namespace、67,666 条翻译,基于 dsh `0.2.1-rc.2` 构建。用 `dsh plugin --profile web add @ragnoryok1/dsh-client-locale-ru` 安装,然后在 Settings → General 中选择 **Русский**。缺失的 key 会回退到英文,因此更新的 harness 也能照常工作。覆盖范围是 harness 自带的客户端界面(64 个 namespace,2 996 条翻译),以及 521 个第三方插件的词典——它们各自发布的英文原文都被取来翻译。MIT 许可,由社区维护,与 DeepSeek 无隶属关系。
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 里过期的构建产物会直接落到用户手里,而审计看不到它——审计读的是源码。发布的包为 2013 kB:横幅以 JPEG 提供,图标与源码映射不进入 npm 包。
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 (ru) interface for the DeepSeek Harness web GUI: 584 namespaces, 67666 strings, 520 third-party plugin dictionaries, ru plural forms and screen typography. Hybrid dsh.bundle + dsh.client plugin.",
4
- "version": "0.2.16",
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",