@goodandready/dsh-russian-lang 0.1.8 → 0.1.9
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/README.md +44 -17
- package/lib/client.js +25 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,23 +6,41 @@
|
|
|
6
6
|
|
|
7
7
|
- Регистрирует русские словари для namespace'ов ядра (`common`,
|
|
8
8
|
`conversation`, `settings`, `settings.models`, `workspace`, `subagent`,
|
|
9
|
-
`reference` и другие — **30 namespace'ов ядра, 722 ключа, 100%
|
|
10
|
-
|
|
11
|
-
плагинов (`dsh-market`, `better-sidebar`, `task-board`, `im-hub` и другие —
|
|
12
|
-
**9 namespace'ов, 962 ключа**).
|
|
9
|
+
`reference` и другие — **30 namespace'ов ядра, 722 ключа, 100% покрытия**
|
|
10
|
+
релизной поверхности DSH 0.1.1-rc.2) и для ряда сторонних плагинов.
|
|
13
11
|
- Добавляет **«Русский» третьей позицией** в родной список языков
|
|
14
12
|
(**Настройки → Общие → Язык**). Выбор сохраняется штатным механизмом
|
|
15
13
|
настроек DSH и переживает браузеры.
|
|
16
|
-
- Синхронизирует `<html lang="ru">` при активном русском.
|
|
14
|
+
- Синхронизирует `<html lang="ru-RU">` при активном русском.
|
|
17
15
|
|
|
18
16
|
Непереведённые ключи показываются по-английски (штатный fallback ядра), пустых
|
|
19
17
|
мест в интерфейсе не появляется.
|
|
20
18
|
|
|
19
|
+
### Помимо словарей
|
|
20
|
+
|
|
21
|
+
- **Русские plural-формы.** Обёртка `translate` резолвит `one/few/many` для
|
|
22
|
+
счётных ключей (как с суффиксом `.one/.other`, так и голых — через
|
|
23
|
+
`X.one/X.few/X.many`).
|
|
24
|
+
- **Пользовательские переопределения.** Пространство настроек
|
|
25
|
+
`russian-lang.overrides` — `{ ключ: формулировка }`, применяется верхним
|
|
26
|
+
слоем поверх словарей.
|
|
27
|
+
- **Типографика вывода** (`russian-lang.typography`). Идемпотентный
|
|
28
|
+
постпроцессор текстовых узлов: кавычки-«ёлочки», тире, неразрывные пробелы
|
|
29
|
+
после коротких слов, опциональная ё (флаг `yo`). Код, ссылки и поля ввода не
|
|
30
|
+
трогаются.
|
|
31
|
+
- **Орфография** — браузерный `spellcheck` на текстовых полях при активном
|
|
32
|
+
русском; моноширинные поля (код, команды) исключаются.
|
|
33
|
+
- **Фикс неправильной раскладки.** Если текст набран латиницей вместо
|
|
34
|
+
кириллицы, над инпутом появляется подсказка с превью конвертации; клик
|
|
35
|
+
заменяет. Конверсия кириллицы→латиницы предлагается только для
|
|
36
|
+
slash-команд. Ручной конверт текущего инпута — `Alt+L`.
|
|
37
|
+
|
|
21
38
|
## Как это работает
|
|
22
39
|
|
|
23
40
|
Реестр локалей живёт в браузере: плагин докладывает русские словари в чужие
|
|
24
|
-
namespace'ы через `ctx.locale.register(ns, 'ru', dict)
|
|
25
|
-
|
|
41
|
+
namespace'ы через `ctx.locale.register(ns, 'ru', dict)`. Namespace'ы, которые
|
|
42
|
+
плагины уже локализуют сами на русский, пропускаются (иначе загрузчик падает с
|
|
43
|
+
`already has locale ru`).
|
|
26
44
|
|
|
27
45
|
Список языков штатного селектора (`Настройки → Общие → Язык`) живёт в snapshot
|
|
28
46
|
локаль-runtime; меню строится из него, и `setLocale()` валидирует выбор по
|
|
@@ -47,16 +65,24 @@ dsh plugin --profile web add @goodandready/dsh-russian-lang
|
|
|
47
65
|
## Разработка и проверка
|
|
48
66
|
|
|
49
67
|
```bash
|
|
50
|
-
python3 extract-dicts.py <
|
|
51
|
-
python3 check-coverage.py
|
|
52
|
-
python3 build.py
|
|
53
|
-
python3
|
|
54
|
-
python3
|
|
68
|
+
python3 extract-dicts.py <node_modules ядра> [node_modules профиля] # обновить *-en.json
|
|
69
|
+
python3 check-coverage.py # что не переведено / устарело
|
|
70
|
+
python3 build.py # собрать lib/client.js
|
|
71
|
+
python3 tools/mt_fallback.py --dry-run # непереведённые ключи
|
|
72
|
+
python3 tools/mt_fallback.py --review # очередь ручной выверки MT
|
|
73
|
+
python3 tools/merge_freq.py # обновить freq-словарь для фикса раскладки
|
|
74
|
+
python3 tools/upstream_check.py # ночной апстрим-детектор новых ключей
|
|
75
|
+
python3 tools/top100.py <профиль>/node_modules # отчёт покрытия плагинов
|
|
76
|
+
python3 test/test_extract.py # smoke для extract-dicts/check-coverage
|
|
77
|
+
python3 test/smoke.py # E2E против запущенного контура
|
|
55
78
|
```
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
80
|
+
MT-переводы непереведённых ключей (`mt_fallback.py --apply`) пишутся в
|
|
81
|
+
`mt-registry.json` как обычные строки; ручной перевод в `ru/*.json` всегда
|
|
82
|
+
имеет приоритет. Очередь ручной выверки — `upstream/review-queue.md`.
|
|
83
|
+
|
|
84
|
+
`smoke.py` требует `websocket-client` (`pip install websocket-client`) и Chrome
|
|
85
|
+
на `/usr/bin/google-chrome`. Адрес переопределяется через `DSH_URL`.
|
|
60
86
|
|
|
61
87
|
## Скриншоты
|
|
62
88
|
|
|
@@ -65,8 +91,7 @@ python3 test/smoke.py # E2E против запущ
|
|
|
65
91
|
| Интерфейс на русском | `docs/media/ui-russian.png` |
|
|
66
92
|
| Список языков в Настройки → Общие | `docs/media/language-selector.png` |
|
|
67
93
|
|
|
68
|
-
Скриншоты обновляются через `python3 test/screenshots.py
|
|
69
|
-
запущенного стенда с установленным плагином.
|
|
94
|
+
Скриншоты обновляются через `python3 test/screenshots.py`.
|
|
70
95
|
|
|
71
96
|
## Ограничения
|
|
72
97
|
|
|
@@ -75,6 +100,8 @@ python3 test/smoke.py # E2E против запущ
|
|
|
75
100
|
- Плагины, которые рисуют текст инлайном без locale-слотов, не переводятся.
|
|
76
101
|
- Текст, добавленный сторонним плагином без `ctx.locale.register`, остаётся на
|
|
77
102
|
языке плагина — для перевода нужно обновить сам плагин.
|
|
103
|
+
- Фикс раскладки опирается на встроенный частотный словарь (~9k слов) и может
|
|
104
|
+
не распознать редкую терминологию; ложных замен нет — только подсказка.
|
|
78
105
|
|
|
79
106
|
## Лицензия
|
|
80
107
|
|
package/lib/client.js
CHANGED
|
@@ -279,7 +279,7 @@ window.__ModuleLoader__.load({
|
|
|
279
279
|
"sideChatRetry": "Повторить",
|
|
280
280
|
"sideChatSave": "Сохранить как новую сессию",
|
|
281
281
|
"sideChatSaveTitle": "Повысьте этот тред до уровня отдельной сессии в основном списке сессий",
|
|
282
|
-
"sideChatSaved": "Сохранено как новая сессия
|
|
282
|
+
"sideChatSaved": "Сохранено как новая сессия",
|
|
283
283
|
"sideChatSend": "Отправить",
|
|
284
284
|
"sideChatThink": "Думаю",
|
|
285
285
|
"sideChatThinking": "Глубокое погружение…",
|
|
@@ -755,7 +755,7 @@ window.__ModuleLoader__.load({
|
|
|
755
755
|
"cmdDetails": "Команда установки",
|
|
756
756
|
"compatRiskBanner": "Обнаружен риск несовместимости — откройте Диагностику перед перезапуском или откатите эту операцию.",
|
|
757
757
|
"confirm": "Подтвердить",
|
|
758
|
-
"confirmInstall": "
|
|
758
|
+
"confirmInstall": "Подтвердить установку",
|
|
759
759
|
"confirmRemove": "Подтверждаете?",
|
|
760
760
|
"confirmTitle": "Установка",
|
|
761
761
|
"confirmWarn": "Плагины — сторонний код сообщества. Устанавливая, вы доверяете этому источнику; сборочные скрипты по умолчанию заблокированы.",
|
|
@@ -763,7 +763,7 @@ window.__ModuleLoader__.load({
|
|
|
763
763
|
"conflictDeclined": "Вы сохранили установленные плагины; этот не был установлен",
|
|
764
764
|
"conflictDetails": "Детали",
|
|
765
765
|
"conflictKeep": "Оставить то, что у меня есть",
|
|
766
|
-
"conflictKeepNote": "
|
|
766
|
+
"conflictKeepNote": "Оставить этот",
|
|
767
767
|
"conflictOutcomeInstall": "установить",
|
|
768
768
|
"conflictOutcomeKeep": "оставить",
|
|
769
769
|
"conflictOutcomeRemove": "удалить",
|
|
@@ -771,7 +771,7 @@ window.__ModuleLoader__.load({
|
|
|
771
771
|
"conflictReplaceFailed": "Замена не завершена. Перечисленные ниже плагины были удалены и не восстановлены — проверьте их:",
|
|
772
772
|
"conflictReplacing": "Замена…",
|
|
773
773
|
"conflictReverted": "Отменено автоматически; ничего не было изменено",
|
|
774
|
-
"conflictSwap": "Переключиться на этот
|
|
774
|
+
"conflictSwap": "Переключиться на этот",
|
|
775
775
|
"conflictSwapNote": "Настройки удалённых плагинов сохраняются, чтобы вы могли установить их позже",
|
|
776
776
|
"conflictTitle": "Невозможно установить: конфликт с установленным плагином",
|
|
777
777
|
"conflictWhy": "cordis отклоняет дерево плагинов, содержащее дублирующиеся идентификаторы записей; сохранение этого плагина предотвратит запуск DeepSeek Harness.",
|
|
@@ -878,7 +878,7 @@ window.__ModuleLoader__.load({
|
|
|
878
878
|
"nextPage": "Дальше",
|
|
879
879
|
"noGroups": "Групп пока нет — создайте",
|
|
880
880
|
"notInstalled": "Не установлен",
|
|
881
|
-
"opBlockedCard": "Невозможно установить ·
|
|
881
|
+
"opBlockedCard": "Невозможно установить · подробности",
|
|
882
882
|
"opClear": "Очистить выполненные",
|
|
883
883
|
"opClose": "Свернуть",
|
|
884
884
|
"opDequeue": "Удалить из очереди",
|
|
@@ -886,13 +886,13 @@ window.__ModuleLoader__.load({
|
|
|
886
886
|
"opDoneRefresh": "Установлено · обновите страницу для применения",
|
|
887
887
|
"opEmpty": "Нет операций в процессе выполнения",
|
|
888
888
|
"opEmptyHint": "Здесь отображается прогресс установки, обновления и удаления",
|
|
889
|
-
"opInstalling": "Установка
|
|
889
|
+
"opInstalling": "Установка",
|
|
890
890
|
"opKind_install": "Установить",
|
|
891
|
-
"opKind_uninstall": "Удалить
|
|
891
|
+
"opKind_uninstall": "Удалить",
|
|
892
892
|
"opKind_update": "Обновить",
|
|
893
893
|
"opLeaveHint": "Вы можете покинуть эту страницу; вы получите уведомление, когда процесс завершится",
|
|
894
894
|
"opNeedsChoice": "Не удалось установить · откат выполнен автоматически, ничего не изменилось",
|
|
895
|
-
"opNeedsYou": "нужен
|
|
895
|
+
"opNeedsYou": "нужен вам",
|
|
896
896
|
"opQueued": "В очереди",
|
|
897
897
|
"opQueuedAhead": "впереди:",
|
|
898
898
|
"opRetry": "Повторить",
|
|
@@ -951,7 +951,7 @@ window.__ModuleLoader__.load({
|
|
|
951
951
|
"restorePreviewDone": "Копия загружена. Проверьте вкладку «Установленные» и запускайте восстановление.",
|
|
952
952
|
"restoreStart": "Начать восстановление",
|
|
953
953
|
"restoreUnportable": "указывает на абсолютный путь с другой машины, который здесь не существует — перенаправьте его локально или переустановите плагин",
|
|
954
|
-
"rollbackNow": "Откатить
|
|
954
|
+
"rollbackNow": "Откатить",
|
|
955
955
|
"rollingBack": "Откат изменений…",
|
|
956
956
|
"searchPh": "Поиск плагинов: уведомления, терминал, память…",
|
|
957
957
|
"setCardDesc": "Версия маркета, обновление и удаление.",
|
|
@@ -962,7 +962,7 @@ window.__ModuleLoader__.load({
|
|
|
962
962
|
"setChannelDevHint": "Непроверенные сборки из ветки разработки. Не рекомендуются для общего использования.",
|
|
963
963
|
"setChannelStable": "Стабильный",
|
|
964
964
|
"setChannelStableHint": "Только выпущенные версии.",
|
|
965
|
-
"setChannelSwitch": "Переключиться на
|
|
965
|
+
"setChannelSwitch": "Переключиться на",
|
|
966
966
|
"setChannelSwitchHint": "Эта версия ниже установленной.",
|
|
967
967
|
"setRegion": "Скачать регион",
|
|
968
968
|
"setRegionAuto": "Выбрано на основе проверки сети. Можете изменить в любое время.",
|
|
@@ -984,7 +984,7 @@ window.__ModuleLoader__.load({
|
|
|
984
984
|
"setSelfRestartAfter": "Перезапустить DeepSeek Harness сразу после удаления",
|
|
985
985
|
"setSelfRestartingHint": "Перезапуск DeepSeek Harness…",
|
|
986
986
|
"setSelfUpToDate": "Обновлений нет",
|
|
987
|
-
"setSelfUpToDateHint": "
|
|
987
|
+
"setSelfUpToDateHint": "Актуально, обновление не требуется",
|
|
988
988
|
"setSelfUpdate": "Обновить",
|
|
989
989
|
"setSelfUpdateHint": "Обновление скачает новую версию; она заработает после перезапуска.",
|
|
990
990
|
"setSelfUpdateReady": "Доступна новая версия:",
|
|
@@ -1054,7 +1054,7 @@ window.__ModuleLoader__.load({
|
|
|
1054
1054
|
},
|
|
1055
1055
|
"dsh-subscriptions": {
|
|
1056
1056
|
"accountLabel": "Аккаунт",
|
|
1057
|
-
"addAccount": "+ Добавить
|
|
1057
|
+
"addAccount": "+ Добавить аккаунт",
|
|
1058
1058
|
"cardIntro": "Подписки, ротация и ограничения аккаунтов.",
|
|
1059
1059
|
"connect": "Подключить",
|
|
1060
1060
|
"connected": "Подключено",
|
|
@@ -1067,30 +1067,30 @@ window.__ModuleLoader__.load({
|
|
|
1067
1067
|
"pastePlaceholder": "Вставьте перенаправленный URL или код",
|
|
1068
1068
|
"plan": "План",
|
|
1069
1069
|
"reconnect": "Переподключиться",
|
|
1070
|
-
"removeSlot": "Удалить слот
|
|
1070
|
+
"removeSlot": "Удалить слот",
|
|
1071
1071
|
"save": "Сохранить",
|
|
1072
1072
|
"saved": "Сохранено",
|
|
1073
1073
|
"show": "Показать",
|
|
1074
|
-
"storedAs": "Хранится как
|
|
1074
|
+
"storedAs": "Хранится как",
|
|
1075
1075
|
"submitCode": "Отправить код",
|
|
1076
1076
|
"title": "Подписки",
|
|
1077
1077
|
"usageFull": "Использование 100%",
|
|
1078
1078
|
"useOrigin": "Используйте этот источник Web UI как redirect_uri для OAuth",
|
|
1079
1079
|
"useOriginHint": "Не включайте, если вы не зарегистрировали собственный OAuth-клиент для этого источника. CLI-клиенты поставщиков обычно требуют опубликованный URI перенаправления и шаг вставки.",
|
|
1080
|
-
"verifyAccount": "
|
|
1080
|
+
"verifyAccount": "Подтвердить аккаунт",
|
|
1081
1081
|
"verifyLink": "Откройте ссылку для подтверждения",
|
|
1082
1082
|
"verifyPrefix": "Google требует одноразовой проверки аккаунта.",
|
|
1083
1083
|
"verifySuffix": "затем переподключитесь."
|
|
1084
1084
|
},
|
|
1085
1085
|
"dsh-tts": {
|
|
1086
|
-
"addProvider": "Добавить
|
|
1087
|
-
"announce": "
|
|
1086
|
+
"addProvider": "Добавить провайдера",
|
|
1087
|
+
"announce": "Объявлять одобрения",
|
|
1088
1088
|
"announceHint": "Произнесите вслух и воспроизведите мелодию, когда агент остановится для подтверждения или задаст вопрос.",
|
|
1089
1089
|
"approvalHint": "Сказано, когда запрашивается одобрение; добавляется название инструмента.",
|
|
1090
1090
|
"approvalText": "Формулировка одобрения",
|
|
1091
1091
|
"azureHint": "Необходимо для поставщика Azure, например, eastus.",
|
|
1092
1092
|
"azureRegion": "Регион Azure",
|
|
1093
|
-
"bargeIn": "
|
|
1093
|
+
"bargeIn": "Замолкать, когда вы говорите",
|
|
1094
1094
|
"bargeInHint": "Перестаньте читать, как только микрофон откроется.",
|
|
1095
1095
|
"binHint": "Ищется в PATH, если не указан абсолютный путь.",
|
|
1096
1096
|
"cardHint": "Цепочка провайдеров, голоса и параметры воспроизведения.",
|
|
@@ -1106,7 +1106,7 @@ window.__ModuleLoader__.load({
|
|
|
1106
1106
|
"edgeHint": "Python CLI из пакета edge-tts.",
|
|
1107
1107
|
"espeakBin": "Бинарный файл eSpeak",
|
|
1108
1108
|
"espeakHint": "Обычно espeak-ng.",
|
|
1109
|
-
"fromEnv": "
|
|
1109
|
+
"fromEnv": "Задано в окружении",
|
|
1110
1110
|
"general": "Общие",
|
|
1111
1111
|
"language": "Язык",
|
|
1112
1112
|
"languageHint": "Подсказка для голосов, которым требуется локаль (eSpeak, Azure SSML).",
|
|
@@ -1131,7 +1131,7 @@ window.__ModuleLoader__.load({
|
|
|
1131
1131
|
"up": "Вверх"
|
|
1132
1132
|
},
|
|
1133
1133
|
"dsh-voice": {
|
|
1134
|
-
"addCustom": "
|
|
1134
|
+
"addCustom": "Добавить своего провайдера",
|
|
1135
1135
|
"addProvider": "Добавить поставщика",
|
|
1136
1136
|
"browserFailed": "Браузер не распознал:",
|
|
1137
1137
|
"browserHint": "браузер выполняет распознавание, ключ не требуется",
|
|
@@ -1178,7 +1178,7 @@ window.__ModuleLoader__.load({
|
|
|
1178
1178
|
"openrouterHint": "google/gemini-2.5-flash · ключ OPENROUTER_API_KEY",
|
|
1179
1179
|
"openrouterWarning": "У OpenRouter нет /audio/transcriptions — используйте там шаблон openai-chat-audio",
|
|
1180
1180
|
"pauseHint": "Меньшее значение означает более частые фрагменты и быстрый текст, но выше риск разрыва слова",
|
|
1181
|
-
"pauseMs": "Пауза, завершающая фразу,
|
|
1181
|
+
"pauseMs": "Пауза, завершающая фразу, мс",
|
|
1182
1182
|
"pressKey": "Нажмите клавишу…",
|
|
1183
1183
|
"recognitionError": "распознавание не удалось",
|
|
1184
1184
|
"recordSlot": "Запись голоса",
|
|
@@ -1187,18 +1187,18 @@ window.__ModuleLoader__.load({
|
|
|
1187
1187
|
"saveFailed": "Некоторые поля не были сохранены —",
|
|
1188
1188
|
"saved": "Сохранено ✓",
|
|
1189
1189
|
"secondsShort": "с",
|
|
1190
|
-
"sendingIn": "Отправка агенту
|
|
1190
|
+
"sendingIn": "Отправка агенту через",
|
|
1191
1191
|
"siliconflowHint": "FunAudioLLM/SenseVoiceSmall · ключ SILICONFLOW_API_KEY",
|
|
1192
1192
|
"stop": "Стоп",
|
|
1193
1193
|
"title": "Голос",
|
|
1194
1194
|
"transcribing": "Транскрибируем…",
|
|
1195
1195
|
"undoHint": "Как долго ещё можно отменить автоматическую отправку",
|
|
1196
|
-
"undoMs": "
|
|
1196
|
+
"undoMs": "Окно отмены, мс",
|
|
1197
1197
|
"up": "Вверх",
|
|
1198
|
-
"whisperAutostart": "Автозапуск локального
|
|
1198
|
+
"whisperAutostart": "Автозапуск локального whisper",
|
|
1199
1199
|
"whisperBin": "Локальный шепот: бинарный",
|
|
1200
1200
|
"whisperBinHint": "используется при включённом автозапуске",
|
|
1201
|
-
"whisperEndpoint": "Локальный
|
|
1201
|
+
"whisperEndpoint": "Локальный whisper: адрес",
|
|
1202
1202
|
"whisperEndpointHint": "POST /inference сервера whisper.cpp",
|
|
1203
1203
|
"whisperModel": "Локальная модель Whisper"
|
|
1204
1204
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-russian-lang",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Russian localization for the DeepSeek Harness web UI: adds Русский as the third option in the native Settings - General - Language menu. Translates the full core surface (100% coverage of DSH 0.1.1-rc.2) plus 16 community plugin namespaces - 52 namespaces, 2795 strings (many machine-drafted, queued for manual review), with Russian plural forms, count-key plurals, a typography pass (guillemets, em dash, nbsp), a wrong-layout input hint and browser spellcheck. The locale runtime snapshot is extended at runtime on unpatched cores; no files in the DSH installation are modified. The choice is persisted through the plugin-owned russian-lang namespace.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|