@goodandready/dsh-russian-lang 0.2.11 → 0.2.13
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 +7 -7
- package/docs/media/banner.jpg +0 -0
- package/lib/client.js +229 -92
- package/lib/pure.js +6 -2
- package/package.json +2 -2
- package/ru-plugins/17-dsh-context.json +3 -1
- package/ru-plugins/34-key-rotation.json +25 -2
- package/ru-plugins/36-cost-meter.json +24 -1
- package/ru-plugins/39-shadow-auditor.json +20 -1
- package/ru-plugins/53-remote-workspace.json +35 -2
package/lib/pure.js
CHANGED
|
@@ -184,16 +184,20 @@ export const ERROR_MAP = {
|
|
|
184
184
|
EACCES: { title: 'Отказано в доступе', message: 'Недостаточно прав для чтения или записи', hint: 'Проверьте права доступа к файлу или директории (chmod/chown).' },
|
|
185
185
|
EPERM: { title: 'Операция запрещена', message: 'Недостаточно системных привилегий', hint: 'Запустите процесс с соответствующими правами.' },
|
|
186
186
|
ECONNREFUSED: { title: 'Соединение отклонено', message: 'Целевой сервер или сервис не отвечает', hint: 'Убедитесь, что локальный или удаленный сервис запущен и слушает порт.' },
|
|
187
|
+
ECONNRESET: { title: 'Сброс соединения', message: 'Соединение было принудительно разорвано удаленной стороной', hint: 'Проверьте стабильность сети и работу целевого сервера.' },
|
|
187
188
|
ETIMEDOUT: { title: 'Таймаут соединения', message: 'Превышено время ожидания ответа', hint: 'Проверьте стабильность сети или увеличьте лимит ожидания.' },
|
|
188
189
|
ENOTFOUND: { title: 'Хост не найден', message: 'Не удалось разрешить сетевой адрес', hint: 'Проверьте правильность URL или настройки DNS.' },
|
|
189
190
|
EADDRINUSE: { title: 'Порт уже занят', message: 'Сетевой порт используется другим процессом', hint: 'Остановите конфликтующий процесс или выберите другой порт.' },
|
|
191
|
+
ENOSPC: { title: 'Недостаточно места на диске', message: 'На устройстве закончилось свободное пространство', hint: 'Освободите место на диске и повторите операцию.' },
|
|
192
|
+
400: { title: 'Некорректный запрос (Bad Request)', message: 'Параметры запроса не соответствуют ожидаемому формату', hint: 'Проверьте синтаксис команды или переданные аргументы.' },
|
|
190
193
|
401: { title: 'Требуется авторизация', message: 'API-ключ или токен отсутствуют или недействительны', hint: 'Проверьте настройки учетных данных и актуальность токена.' },
|
|
191
194
|
403: { title: 'Доступ запрещен', message: 'Недостаточно прав для выполнения операции', hint: 'Проверьте область действия токена или права роли.' },
|
|
192
195
|
404: { title: 'Ресурс не найден', message: 'Запрошенный адрес или объект не существует', hint: 'Проверьте правильность пути или идентификатора ресурса.' },
|
|
193
196
|
429: { title: 'Превышен лимит запросов', message: 'Слишком много запросов (Rate Limit)', hint: 'Подождите несколько минут перед повторным запросом.' },
|
|
194
197
|
500: { title: 'Внутренняя ошибка сервера', message: 'На стороне сервера произошел сбой', hint: 'Попробуйте повторить запрос позже или проверьте серверные логи.' },
|
|
195
198
|
502: { title: 'Ошибочный шлюз (Bad Gateway)', message: 'Промежуточный прокси не получил корректный ответ', hint: 'Проверьте работу нижележащей службы или upstream-сервера.' },
|
|
196
|
-
503: { title: 'Служба временно недоступна', message: 'Сервер перегружен или находится на обслуживании', hint: 'Попробуйте повторить операцию через некоторое время.' }
|
|
199
|
+
503: { title: 'Служба временно недоступна', message: 'Сервер перегружен или находится на обслуживании', hint: 'Попробуйте повторить операцию через некоторое время.' },
|
|
200
|
+
504: { title: 'Шлюз не отвечает (Gateway Timeout)', message: 'Превышено время ожидания ответа от upstream-сервера', hint: 'Попробуйте повторить запрос позже.' }
|
|
197
201
|
}
|
|
198
202
|
|
|
199
203
|
const fromMap = (key, rawMsg) => ({
|
|
@@ -204,7 +208,7 @@ export const humanizeError = (err) => {
|
|
|
204
208
|
if (!err) return null
|
|
205
209
|
const rawMsg = typeof err === 'string' ? err : (err.message || String(err))
|
|
206
210
|
const code = err.code || (rawMsg.match(/\b(E[A-Z]{2,20})\b/) || [])[1]
|
|
207
|
-
const status = err.status || err.statusCode || (rawMsg.match(/\b([45]\d{2})\b/) || [])[1]
|
|
211
|
+
const status = err.status || err.statusCode || (err.response && err.response.status) || (rawMsg.match(/\b([45]\d{2})\b/) || [])[1]
|
|
208
212
|
const lookupKey = code || status
|
|
209
213
|
if (lookupKey && ERROR_MAP[lookupKey]) return fromMap(lookupKey, rawMsg)
|
|
210
214
|
if (/rate limit|too many requests/i.test(rawMsg)) return fromMap(429, rawMsg)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-russian-lang",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Russian localization for DeepSeek Harness (DSH v0.1.5-rc.1+) web UI: adds Русский as the native language option in Settings - General - Language. 100.0% coverage across
|
|
3
|
+
"version": "0.2.13",
|
|
4
|
+
"description": "Russian localization for DeepSeek Harness (DSH v0.1.5-rc.1+) web UI: adds Русский as the native language option in Settings - General - Language. 100.0% coverage across 5,765 keys (1,225 core UI keys + 4,540 keys across 40+ ecosystem plugins) with zero machine drafts. Features unified dsh-clinebot visual design standard for Settings Card, full translations for updated ecosystem plugins (Cost Meter, Key Rotation, Remote Workspace SSH Tunnels, Shadow Auditor SAST & Diff Gate, Context), Smart Russian UX (localized Markdown export, turn translation, live typography, slash command aliases, Alt+L layout fix), expanded error humanizer (POSIX, HTTP 4xx/5xx), Skin Center & Wallpaper Engine support, Workshop market integration, sidebar previewers, and runtime snapshot extension without modifying core files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -294,6 +294,8 @@
|
|
|
294
294
|
"trend.adaptiveHint": "Масштабировать высоту столбцов под видимый диапазон с учётом прокрутки",
|
|
295
295
|
"timing.reasoning": "Размышление",
|
|
296
296
|
"timing.text": "Ответ",
|
|
297
|
-
"timing.toolArgs": "Аргументы инструментов"
|
|
297
|
+
"timing.toolArgs": "Аргументы инструментов",
|
|
298
|
+
"rich.copy": "Скопировать исходный текст",
|
|
299
|
+
"rich.copied": "Скопировано"
|
|
298
300
|
}
|
|
299
301
|
}
|
|
@@ -145,6 +145,29 @@
|
|
|
145
145
|
"testOk": "OK",
|
|
146
146
|
"testing": "Тестирование…",
|
|
147
147
|
"usedAgo": "{ago} назад",
|
|
148
|
-
"weightHint": "вес в round-robin: сколько раз ключ участвует в цикле (1 = равная доля)"
|
|
148
|
+
"weightHint": "вес в round-robin: сколько раз ключ участвует в цикле (1 = равная доля)",
|
|
149
|
+
"sectionStats": "Здоровье пула и телеметрия",
|
|
150
|
+
"sectionStatsDesc": "Телеметрия активных пулов ключей в реальном времени, доступные учётные данные и статус переключения.",
|
|
151
|
+
"sectionFailover": "Триггеры отказа и коды ошибок",
|
|
152
|
+
"sectionFailoverDesc": "Выбор условий и ошибок, вызывающих автоматическое переключение на следующий доступный ключ.",
|
|
153
|
+
"sectionTiming": "Тайминги и расписание ротации",
|
|
154
|
+
"sectionTimingDesc": "Настройка длительности периода охлаждения (cooldown) и окон периодической ротации.",
|
|
155
|
+
"sectionBackup": "Резервные копии и снимки",
|
|
156
|
+
"sectionBackupDesc": "Экспорт и импорт пулов провайдеров и создание полных снимков конфигурации плагина.",
|
|
157
|
+
"statPools": "Настроенных пулов",
|
|
158
|
+
"statKeys": "Всего ключей",
|
|
159
|
+
"statHealthy": "Исправны / Готовы",
|
|
160
|
+
"loadDistribution": "Распределение трафика",
|
|
161
|
+
"statRequests": "запросов",
|
|
162
|
+
"noTrafficYet": "Трафик пока не зафиксирован",
|
|
163
|
+
"confirm": "Подтвердить",
|
|
164
|
+
"cancel": "Отмена",
|
|
165
|
+
"confirmResetTitle": "Сбросить охлаждение для {p}?",
|
|
166
|
+
"confirmResetDesc": "Это немедленно сбросит счётчики сбоев, таймеры охлаждения и переведёт автоматический выключатель (circuit breaker) в исходное состояние.",
|
|
167
|
+
"confirmRemoveProvTitle": "Удалить провайдера {p}?",
|
|
168
|
+
"confirmRemoveProvDesc": "Вы уверены, что хотите удалить этого провайдера и все настроенные ключи из ротации?",
|
|
169
|
+
"undoProvider": "Провайдер удалён",
|
|
170
|
+
"undoKey": "Ключ удалён",
|
|
171
|
+
"undo": "Отменить"
|
|
149
172
|
}
|
|
150
|
-
}
|
|
173
|
+
}
|
|
@@ -37,6 +37,29 @@
|
|
|
37
37
|
"settings.saved": "Сохранено",
|
|
38
38
|
"settings.saving": "Сохранение…",
|
|
39
39
|
"settings.unavailable": "Настройки недоступны (namespace ещё не зарегистрирован).",
|
|
40
|
-
"subtitle": "Стоимость сессии в шапке, тарифы токенов и детализация по моделям"
|
|
40
|
+
"subtitle": "Стоимость сессии в шапке, тарифы токенов и детализация по моделям",
|
|
41
|
+
"header.title": "Счётчик расходов",
|
|
42
|
+
"header.sub": "Мониторинг расхода токенов, автоматический расчёт тарифов и скидочные интервалы",
|
|
43
|
+
"badge.catalog_ok": "Каталог: моделей — {count}",
|
|
44
|
+
"badge.catalog_empty": "Каталог: загрузка…",
|
|
45
|
+
"badge.catalog_off": "Каталог: отключён",
|
|
46
|
+
"badge.catalog_err": "Каталог: ошибка",
|
|
47
|
+
"badge.deepseek": "Тариф DeepSeek: активен",
|
|
48
|
+
"section.general": "Основные параметры",
|
|
49
|
+
"section.general_desc": "Отображение валюты, коэффициент конвертации и настройка часового пояса",
|
|
50
|
+
"section.openrouter": "Каталог тарифов OpenRouter",
|
|
51
|
+
"section.openrouter_desc": "Публичный каталог для динамического расчёта стоимости моделей и скидочных интервалов",
|
|
52
|
+
"section.diagnostics": "Диагностика и статус",
|
|
53
|
+
"section.diagnostics_desc": "Текущее состояние фоновой синхронизации и кэша тарифов",
|
|
54
|
+
"diag.models_count": "Моделей в каталоге",
|
|
55
|
+
"diag.last_sync": "Последняя синхронизация",
|
|
56
|
+
"diag.route": "Активный маршрут",
|
|
57
|
+
"diag.tariff_source": "Источник тарифов",
|
|
58
|
+
"field.useOpenRouter": "Использовать каталог OpenRouter",
|
|
59
|
+
"hint.useOpenRouter": "Динамически получать тарифы и окна скидок через публичный API OpenRouter.",
|
|
60
|
+
"field.refreshHours": "Интервал обновления каталога (в часах)",
|
|
61
|
+
"hint.refreshHours": "Интервал фонового запроса каталога в часах (от 1 до 168).",
|
|
62
|
+
"settings.retry": "Повторить попытку",
|
|
63
|
+
"offpeak": "ночной тариф"
|
|
41
64
|
}
|
|
42
65
|
}
|
|
@@ -20,6 +20,25 @@
|
|
|
20
20
|
"maxFileSizeMbDesc": "Размер, при котором выполняется ротация файла аудита",
|
|
21
21
|
"retentionDays": "Срок хранения логов (дней)",
|
|
22
22
|
"retentionDaysDesc": "Удалять записи аудита старше указанного количества дней",
|
|
23
|
-
"unavailable": "Настройки аудитора временно недоступны"
|
|
23
|
+
"unavailable": "Настройки аудитора временно недоступны",
|
|
24
|
+
"header.sub": "Аудит безопасности в реальном времени, защита от утечки секретов, перехват деструктивных команд и гейтинг diff-изменений.",
|
|
25
|
+
"sec.guards_title": "Безопасность выполнения и гарды",
|
|
26
|
+
"sec.guards_desc": "Упреждающая проверка границ для перехвата опасных системных операций до выполнения команды.",
|
|
27
|
+
"sec.diff_gate_title": "Контроль изменений кода и SAST",
|
|
28
|
+
"sec.diff_gate_desc": "Многофакторный предварительный анализ изменений исходного кода, уязвимостей SAST и попыток внедрения промптов.",
|
|
29
|
+
"sec.audit_log_title": "Журнал аудита и хранение",
|
|
30
|
+
"sec.audit_log_desc": "Постоянный журнал телеметрии JSONL с автоматической gzip-ротацией и политикой хранения.",
|
|
31
|
+
"diffGateMode": "Политика контроля изменений (Diff Gate)",
|
|
32
|
+
"diffGateModeDesc": "Политика барьера одобрения diff: предупреждение или блокировка при высоком и критическом уровне риска",
|
|
33
|
+
"diffGate.disabled": "Отключено",
|
|
34
|
+
"diffGate.warning": "Предупреждение (Аудит)",
|
|
35
|
+
"diffGate.block": "Блокировка (Строгая)",
|
|
36
|
+
"enableSast": "Небезопасные паттерны кода (SAST)",
|
|
37
|
+
"enableSastDesc": "Проверка diff-изменений на SQL-инъекции, командные инъекции, path traversal и вызовы eval()",
|
|
38
|
+
"enablePromptInjection": "Сканер внедрения промптов",
|
|
39
|
+
"enablePromptInjectionDesc": "Сканирование diff-изменений на попытки переопределения системного промпта и джейлбрейка",
|
|
40
|
+
"shield.green": "Безопасно",
|
|
41
|
+
"shield.yellow": "Внимание",
|
|
42
|
+
"shield.red": "Тревога"
|
|
24
43
|
}
|
|
25
44
|
}
|
|
@@ -44,6 +44,39 @@
|
|
|
44
44
|
"pullBtn": "⬇️ Скачать с сервера (Pull)",
|
|
45
45
|
"pushBtn": "⬆️ Загрузить на сервер (Push)",
|
|
46
46
|
"syncSuccess": "Синхронизация успешно выполнена",
|
|
47
|
-
"syncFailed": "Ошибка синхронизации: "
|
|
47
|
+
"syncFailed": "Ошибка синхронизации: ",
|
|
48
|
+
"badgeOnline": "Активный хост: {name} ({latency} мс)",
|
|
49
|
+
"badgeOffline": "Хост не выбран",
|
|
50
|
+
"badgeTunnels": "Туннелей: {count}",
|
|
51
|
+
"badgeKey": "🔑 Вход по ключу",
|
|
52
|
+
"badgePassword": "🔒 Вход по паролю",
|
|
53
|
+
"pinBtn": "Закрепить активный",
|
|
54
|
+
"editBtn": "Изменить",
|
|
55
|
+
"delBtn": "Удалить",
|
|
56
|
+
"delConfirm": "Удалить профиль хоста «{name}»?",
|
|
57
|
+
"fKeyPathHint": "Путь к ~/.ssh/id_rsa или /home/user/.ssh/id_ed25519",
|
|
58
|
+
"fLocalMirror": "Локальная папка зеркала",
|
|
59
|
+
"fLocalMirrorHint": "Локальная директория для зеркалирования файлов при быстрой трёхсторонней синхронизации",
|
|
60
|
+
"testOk": "✅ Соединение установлено! Задержка: {latency} мс | ОС: {os}",
|
|
61
|
+
"testFail": "❌ Ошибка подключения: {err}",
|
|
62
|
+
"diagProbeBtn": "⚡ Быстрая диагностика",
|
|
63
|
+
"pulling": "Получение файлов…",
|
|
64
|
+
"pushing": "Отправка файлов…",
|
|
65
|
+
"syncOk": "Синхронизация завершена! Обновлено файлов: {count}.",
|
|
66
|
+
"syncConflict": "Предупреждение о конфликте: изменено с обеих сторон файлов — {count}.",
|
|
67
|
+
"syncErr": "Ошибка синхронизации: {err}",
|
|
68
|
+
"tunnelsTitle": "🔀 Проброс портов SSH (туннели)",
|
|
69
|
+
"tunnelsDesc": "Проброс удалённых портов (базы данных, веб-серверы, API) на локальный компьютер через зашифрованные SSH-туннели.",
|
|
70
|
+
"tLocalPort": "Локальный порт",
|
|
71
|
+
"tRemotePort": "Удалённый порт",
|
|
72
|
+
"tOpenBtn": "+ Открыть туннель",
|
|
73
|
+
"tOpening": "Открытие…",
|
|
74
|
+
"tStopBtn": "Остановить",
|
|
75
|
+
"tNoTunnels": "Нет активных туннелей проброса портов.",
|
|
76
|
+
"tunnelsColId": "ID туннеля",
|
|
77
|
+
"tunnelsColRoute": "Маршрут проброса",
|
|
78
|
+
"tunnelsColActions": "Действия",
|
|
79
|
+
"tOpenOk": "Туннель открыт: 127.0.0.1:{localPort} -> Удалённый:{remotePort}",
|
|
80
|
+
"tOpenErr": "Не удалось открыть туннель: {err}"
|
|
48
81
|
}
|
|
49
|
-
}
|
|
82
|
+
}
|