@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/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.11",
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 5688 keys (1225 core UI keys + 4463 keys across 40+ ecosystem plugins) with zero machine drafts. Features Smart Russian UX (localized Markdown export, turn translation, live typography, slash command aliases, Alt+L layout fix), Skin Center & Wallpaper Engine support, Workshop market integration, sidebar previewers, and runtime snapshot extension without modifying core files.",
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
+ }