@goodandready/dsh-russian-lang 0.1.13 → 0.1.15

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.
Files changed (2) hide show
  1. package/lib/client.js +32 -209
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -806,25 +806,6 @@ window.__ModuleLoader__.load({
806
806
  "trend.hint": "Наведите курсор для просмотра деталей, ✂ обозначает уплотнение/удаление, Шаг/Ход переключает детализацию",
807
807
  "trend.title": "История контекста"
808
808
  },
809
- "dsh-gitea": {
810
- "baseUrl": "URL экземпляра",
811
- "baseUrlHint": "например, https://gitea.example.com",
812
- "collapse": "Свернуть",
813
- "description": "Инструменты и учетные данные Gitea или Forgejo.",
814
- "discard": "Отменить",
815
- "expand": "Развернуть",
816
- "intro": "Создайте учетные данные DSH, вставьте туда API-токен, затем введите только название учетных данных ниже (например, GITEA_TOKEN). Никогда не вставляйте токен в эту форму.",
817
- "loading": "Загрузка…",
818
- "save": "Сохранить",
819
- "saveFailed": "Не удалось сохранить",
820
- "saving": "Сохранение…",
821
- "title": "Гитеа",
822
- "tokenEnv": "Имя учетных данных",
823
- "tokenEnvHint": "Название учетных данных DSH, а не самого токена. По умолчанию GITEA_TOKEN.",
824
- "tokenOff": "Токен не настроен",
825
- "tokenOn": "Токен настроен",
826
- "unsaved": "Не сохранено"
827
- },
828
809
  "dsh-image-gen": {
829
810
  "f.apiKeyEnv": "Справка по API-ключу",
830
811
  "f.apiKeyEnvHint": "Ссылка на учетные данные / переменная окружения, содержащая ключ API FAL. Префикс авторизации \"Key \" добавляется автоматически.",
@@ -882,59 +863,6 @@ window.__ModuleLoader__.load({
882
863
  "settings.unavailable": "Обвязка еще не опубликовала настройки этого плагина. Если она только что перезапустилась, раздел появится сам через несколько секунд.",
883
864
  "settings.unsaved": "Несохранённые изменения"
884
865
  },
885
- "dsh-key-rotation": {
886
- "addKey": "+ Добавить ключ",
887
- "addKeyTitle": "Добавить API ключ",
888
- "addProvider": "+ Добавить поставщика",
889
- "brokenKey": "сломано (3× AUTH)",
890
- "cardDesc": "Поворот API-ключей для каждого провайдера: пулы ключей, автоматический переход на резерв при ошибках квоты/ограничения скорости, охлаждение и восстановление.",
891
- "codesTitle": "Включите эти {сбои}",
892
- "cooldown": "Время ожидания после ошибки (мс)",
893
- "desc": "Поворот API-ключей для каждого провайдера. Для каждого провайдера перечислите его API-ключи (имена переменных окружения, хранящиеся в учетных данных DSH). Плагин направляет модель через ключи провайдера по порядку и переключается на следующий при превышении квоты или ограничения скорости.",
894
- "discard": "Отменить",
895
- "exportOne": "Вниз",
896
- "exportPools": "Экспорт",
897
- "hoursAgo": "{n} ч назад",
898
- "importEnv": "Импортировать .env",
899
- "importPools": "Импорт",
900
- "justNow": "только что",
901
- "keyActive": "используется",
902
- "keyCooling": "охлаждение, {s}с",
903
- "keyFromEnv": "из окружения, только для чтения здесь",
904
- "keyHint": "Значение хранится в учетных данных DSH и никогда не отправляется обратно в браузер — отображаются только последние 5 символов. Имена генерируются автоматически; наведите курсор на ключ, чтобы увидеть используемое имя.",
905
- "keyLabel": "Ключ {n}",
906
- "keyMissing": "нет такого учетного {credential}",
907
- "keyReady": "готово",
908
- "keySave": "Сохранить ключ",
909
- "keySaved": "сохранено",
910
- "keyValuePlaceholder": "вставьте ключ, затем {Save}",
911
- "keyWriteFailed": "не удалось сохранить ключ: {msg}",
912
- "loading": "Загрузка…",
913
- "minutesAgo": "{n} мин назад",
914
- "moveDown": "Переместить вниз",
915
- "moveUp": "Переместить вверх",
916
- "noProviders": "Нет зарегистрированных поставщиков в DSH — пока не из чего выбирать.",
917
- "notRegistered": "не зарегистрирован",
918
- "poolExhausted": "пул исчерпан — все ключи охлаждаются",
919
- "providersTitle": "Провайдеры и их ключи",
920
- "removeKey": "Удалить ключ {key}",
921
- "removeProvider": "Удалить провайдера",
922
- "resetCooldown": "Сбросить время восстановления",
923
- "resetting": "Сброс…",
924
- "save": "Сохранить",
925
- "saving": "Сохранение…",
926
- "subtitle": "Поворот API-ключей для каждого провайдера: пулы ключей, автоматический переход на резерв при ошибках квоты/ограничения скорости, охлаждение и восстановление.",
927
- "switchCodes": "Переключить коды (через запятую)",
928
- "switchesNone": "ещё нет переключателей",
929
- "switchesSome": "переключатели: {n} · последний: {reason}, {ago}",
930
- "testAll": "Проверьте все {keys}",
931
- "testFail": "ОШИБКА",
932
- "testKey": "Тест",
933
- "testOk": "ОК",
934
- "testing": "Тестирование…",
935
- "title": "Ротация ключей {placeholders}",
936
- "usedAgo": "{ago} назад"
937
- },
938
866
  "dsh-market": {
939
867
  "actWhy": "Почему не активен?",
940
868
  "agentBusyInstall": "Агент в настоящее время работает — дождитесь завершения (или отмените его) перед установкой. Установка изменяет файлы плагина, поэтому работающий агент может завершиться с ошибкой в процессе.",
@@ -1384,75 +1312,6 @@ window.__ModuleLoader__.load({
1384
1312
  "webdavUrl": "Адрес файла копии",
1385
1313
  "webdavUser": "Имя пользователя (необязательно)"
1386
1314
  },
1387
- "dsh-messenger-gateway": {
1388
- "advanced": "Телеграм опрос",
1389
- "agent": "Агент",
1390
- "allowedIds": "Разрешенные идентификаторы пользователей {placeholders}",
1391
- "allowedIdsHint": "Через запятую. Пусто = все пользователи",
1392
- "botToken": "Токен бота (только для записи)",
1393
- "botTokenHint": "Оставьте пустым, чтобы сохранить текущий токен",
1394
- "description": "Телеграм бот: текст, голос, фото и документы.",
1395
- "disableTelegram": "Отключить Telegram",
1396
- "enableTelegram": "Включить Telegram",
1397
- "groupMention": "Группы требуют @упоминания / ответа / команды",
1398
- "groupsEnable": "Отвечайте в группах",
1399
- "hideAdvanced": "Скрыть дополнительные {параметры}",
1400
- "idleTimeout": "тайм-аут простоя (сек)",
1401
- "instruction": "Дополнительная инструкция для агента",
1402
- "instructionHint": "Добавлено к каждому сообщению в мессенджере",
1403
- "instructionPlaceholder": "Пусто = встроенное реле",
1404
- "loading": "Загрузка…",
1405
- "maxDocMb": "Максимальный размер документа (МБ)",
1406
- "maxImageMb": "Максимальный размер фото (МБ)",
1407
- "maxMessageLength": "Максимальная длина ответа (символов)",
1408
- "maxTextKb": "Максимальный текст из документа (КБ)",
1409
- "media": "Медиа",
1410
- "model": "Модель",
1411
- "modelHint": "Пусто = значение по умолчанию DSH",
1412
- "notifyBridge": "Уведомить → Домашний Telegram",
1413
- "notifyBridgeHint": "ошибка из веб-сессий (не msgw-*)",
1414
- "notifyHome": "Уведомить имя дома",
1415
- "pairing": "Запросы на сопряжение",
1416
- "pairingApprove": "Одобрить",
1417
- "pairingEmpty": "Нет ожидающих кодов",
1418
- "pairingRefresh": "Обновить",
1419
- "pairingReject": "Отклонить",
1420
- "photoOnly": "Фото без подписи",
1421
- "photoPrompt": "Дождитесь вопроса (рекомендуется)",
1422
- "photoRun": "Ответить сразу {placeholder}",
1423
- "pollInterval": "интервал опроса {pollIntervalMs}",
1424
- "pollTimeout": "таймаут опроса {pollTimeoutSeconds} секунд",
1425
- "progressEnable": "Сообщение о прогрессе (размышление → удаление → завершение)",
1426
- "provider": "Провайдер",
1427
- "providerHint": "Пусто = DSH по умолчанию",
1428
- "reactionsEnable": "Реагируйте во время обработки (👀)",
1429
- "save": "Сохранить",
1430
- "saving": "Сохранение…",
1431
- "sessionScope": "Область групповой сессии",
1432
- "sessionScopeChat": "Доступно для общего использования в чате/теме",
1433
- "sessionScopeUser": "На пользователя (рекомендуется)",
1434
- "showAdvanced": "Дополнительные настройки",
1435
- "telegram": "Telegram",
1436
- "textFormat": "Формат текста",
1437
- "textFormatHtml": "Markdown → Telegram HTML",
1438
- "textFormatPlain": "Обычный текст",
1439
- "title": "Шлюз мессенджера",
1440
- "transport": "Транспорт",
1441
- "transportPoll": "Длинный опрос (getUpdates)",
1442
- "transportWebhook": "Вебхук",
1443
- "tts": "Голосовые ответы",
1444
- "ttsEnable": "Голосовые ответы через dsh-tts",
1445
- "ttsMaxChars": "Максимум символов в речи",
1446
- "turnTimeout": "Таймаут хода агента (сек)",
1447
- "voiceMode": "Режим голосовых ответов",
1448
- "voiceModeAlways": "Всегда попробуйте TTS",
1449
- "voiceModeMirror": "Зеркалировать входящий голос",
1450
- "voiceModeOff": "Выкл (кроме случая /voice on)",
1451
- "webhookSecret": "Секрет вебхука (только запись)",
1452
- "webhookSecretHint": "Оставьте пустым, чтобы сохранить текущее",
1453
- "webhookUrl": "Публичный URL вебхука",
1454
- "webhookUrlHint": "Полный HTTPS-URL, на который Telegram будет отправлять POST-запросы"
1455
- },
1456
1315
  "dsh-subscriptions": {
1457
1316
  "accountLabel": "Аккаунт",
1458
1317
  "addAccount": "+ Добавить аккаунт",
@@ -1531,61 +1390,6 @@ window.__ModuleLoader__.load({
1531
1390
  "title": "Речь",
1532
1391
  "up": "Вверх"
1533
1392
  },
1534
- "dsh-vision-bridge": {
1535
- "addChannel": "Добавить канал",
1536
- "advanced": "Продвинутый",
1537
- "apiKey": "API-ключ",
1538
- "auto": "Авто",
1539
- "baseURL": "Базовый URL",
1540
- "bench": "Скамья",
1541
- "channels": "Каналы",
1542
- "channelsHint": "Дополнительные конечные точки зрения (совместимые с OpenAI, Ollama, пользовательские). Пусто — автоматический выбор из каталога.",
1543
- "current": "Текущий: {provider} / {model}",
1544
- "currentAuto": "Авто (автоматический выбор)",
1545
- "describeStrategy": "Опишите стратегию",
1546
- "empty": "Пожалуйста, войдите в свою учетную запись {accountName}",
1547
- "escalation": "Эскалация",
1548
- "escalationAuto": "Автоматическое повышение сложности (повторный анализ сложных изображений)",
1549
- "escalationSimple": "Простой только (один проход)",
1550
- "failed": "Не удалось загрузить/сохранить",
1551
- "filterProviders": "Фильтровать поставщиков…",
1552
- "keyHidden": "неизвестно",
1553
- "keyMissing": "нет ключа",
1554
- "keyOk": "Ключ ОК",
1555
- "loading": "…",
1556
- "mode": "Режим",
1557
- "modeHybrid": "Гибридный (автоперезапись + инструменты)",
1558
- "modeLlm": "Только LLM (автоперезапись, инструменты всё ещё доступны)",
1559
- "modeTools": "Только инструменты (без авто-перезаписи, модель должна вызывать describe_image)",
1560
- "model": "Модель",
1561
- "modelInvalid": "Модель не принимает изображения",
1562
- "noVisionModels": "В каталоге нет моделей для анализа изображений (ввод: [текст, изображение]) — добавьте их в Настройки → Модели.",
1563
- "presetCloud": "Пресет: Облако",
1564
- "presetLocal": "Пресет: Локальный",
1565
- "protocol": "Протокол",
1566
- "protocolOpenaiChat": "чат OpenAI",
1567
- "protocolOpenaiResponses": "ответы от OpenAI",
1568
- "provider": "Поставщик услуг по зрению",
1569
- "remove": "Удалить",
1570
- "reqBoth": "Выберите и провайдера, и модель, или оставьте оба поля пустыми для автоматического выбора",
1571
- "requestTemplate": "Шаблон запроса",
1572
- "reset": "Сбросить (авто)",
1573
- "responsePath": "Путь ответа",
1574
- "save": "Сохранить",
1575
- "saved": "Сохранено",
1576
- "saving": "Сохранение…",
1577
- "strategyAuto": "Авто (использовать LLM для зрения)",
1578
- "strategyCacheOnly": "Только кэш (без сети)",
1579
- "strategyLlm": "Vision {LLM}",
1580
- "strategyOcrLocal": "Локальное OCR (зарезервировано)",
1581
- "subtitle": "Изображения в чате обрабатываются моделью зрения, которую вы выбираете здесь. Оставьте оба поля пустыми, чтобы автоматически выбрать первую модель с поддержкой зрения из каталога.",
1582
- "testFail": "Ошибка: {err}",
1583
- "testOk": "ОК ({ms}мс)",
1584
- "testVision": "Проверка зрения",
1585
- "testing": "Тестирование…",
1586
- "title": "Зрение",
1587
- "type": "Тип"
1588
- },
1589
1393
  "dsh-voice": {
1590
1394
  "addCustom": "Добавить своего провайдера",
1591
1395
  "addProvider": "Добавить поставщика",
@@ -2898,7 +2702,7 @@ window.__ModuleLoader__.load({
2898
2702
  }
2899
2703
 
2900
2704
  // Подписи собственной карточки настроек (namespace russian-lang).
2901
- RU['russian-lang'] = {"cardTitle": "Русская локализация", "cardSub": "Язык интерфейса, типографика, раскладка", "enabled": "Русский язык включён", "typography": "Типографика вывода", "yo": "Буква ё", "overridesCount": "Своих переопределений", "statusLoading": "Настройки загружаются…", "statusUnavailable": "Настройки недоступны на этом хосте", "hint": "Машинные переводы помечены в очереди выверки; ручная правка словарей приоритетна.", "altL": "Alt+L — конвертировать раскладку текущего поля"}
2705
+ RU['russian-lang'] = {"cardTitle": "Русская локализация", "cardSub": "Язык интерфейса, типографика, раскладка", "enabled": "Русский язык включён", "typography": "Типографика вывода", "typographyDesc": "Исправляет типографику в тексте ответов: кавычки-«ёлочки», тире вместо дефисов, неразрывные пробелы после коротких предлогов. Код и ссылки не трогаются.", "yo": "Буква ё", "yoDesc": "Восстанавливать «ё» в частых словах (ещё, чёрный, идёт и др.), написанных через «е». Неоднозначные слова (например «все/всё») не трогаются.", "overridesCount": "Своих переопределений", "statusLoading": "Настройки загружаются…", "statusUnavailable": "Настройки недоступны на этом хосте", "hint": "Машинные переводы помечены в очереди выверки; ручная правка словарей приоритетна.", "altL": "Alt+L — конвертировать раскладку текущего поля"}
2902
2706
 
2903
2707
  const SETTINGS_NS_NAME = 'russian-lang'
2904
2708
 
@@ -3385,31 +3189,49 @@ window.__ModuleLoader__.load({
3385
3189
  const [open, setOpen] = React.useState(false)
3386
3190
  const [snap, setSnap] = React.useState(
3387
3191
  () => (scope && scope.getSnapshot ? scope.getSnapshot() : { status: 'loading', value: {} }))
3192
+ const [ruActive, setRuActive] = React.useState(
3193
+ () => { try { return runtime.getLocale().active === 'ru' } catch (e) { return false } })
3194
+ // Оптимистичное состояние типографики: галочка переключается сразу,
3195
+ // а host-подтверждение (scope.subscribe) лишь синхронизирует его позже.
3196
+ const [typo, setTypoState] = React.useState(() =>
3197
+ (snap.value && snap.value.typography) || {})
3198
+
3388
3199
  React.useEffect(() => {
3389
3200
  if (!scope || !scope.subscribe) return undefined
3390
- const un = scope.subscribe(() => setSnap(scope.getSnapshot()))
3201
+ const un = scope.subscribe(() => {
3202
+ const s = scope.getSnapshot()
3203
+ setSnap(s)
3204
+ if (s.value && s.value.typography) setTypoState(s.value.typography)
3205
+ })
3391
3206
  setSnap(scope.getSnapshot())
3392
3207
  return un
3393
3208
  }, [])
3209
+ React.useEffect(() => {
3210
+ try {
3211
+ const un = runtime.subscribe(() => {
3212
+ try { setRuActive(runtime.getLocale().active === 'ru') } catch (e) { /* ignore */ }
3213
+ })
3214
+ return un
3215
+ } catch (e) { return undefined }
3216
+ }, [])
3394
3217
 
3395
3218
  const status = snap.status || 'loading'
3396
3219
  const value = snap.value || {}
3397
- const typography = value.typography || {}
3220
+ const typography = typo
3398
3221
  const overridesCount = Object.keys(value.overrides || {}).length
3399
3222
 
3400
- const ruActive = (() => {
3401
- try { return runtime.getLocale().active === 'ru' } catch (err) { return false }
3402
- })()
3403
-
3404
3223
  const setTypo = (patch) => {
3405
- const next = Object.assign({}, typography, patch)
3224
+ const next = Object.assign({}, typo, patch)
3225
+ setTypoState(next) // мгновенно
3406
3226
  try { scope.set('typography', next) } catch (err) { /* ignore */ }
3407
3227
  }
3408
3228
  const onEnabled = (ev) => { if (toggleRu) toggleRu(ev.target.checked) }
3409
3229
 
3410
- const row = (label, control) =>
3230
+ const row = (label, control, desc) =>
3411
3231
  React.createElement('div', { className: 'rl-field' },
3412
- React.createElement('span', { className: 'rl-label' }, label), control)
3232
+ React.createElement('span', { className: 'rl-label' }, label),
3233
+ control,
3234
+ desc ? React.createElement('div', { className: 'rl-desc' }, desc) : null)
3413
3235
 
3414
3236
  const checkbox = (checked, onChange, disabled) =>
3415
3237
  React.createElement('input', {
@@ -3435,11 +3257,11 @@ window.__ModuleLoader__.load({
3435
3257
  statusLine || t('cardSub'))),
3436
3258
  React.createElement('span', { className: 'rl-chev' }, open ? '▾' : '▸')),
3437
3259
  open && React.createElement('div', { className: 'rl-body' },
3438
- row(t('enabled'), checkbox(ruActive, onEnabled, false)),
3260
+ row(t('enabled'), checkbox(ruActive, onEnabled, false), null),
3439
3261
  row(t('typography'), checkbox(typography.enabled !== false && ruActive,
3440
- (ev) => setTypo({ enabled: ev.target.checked }), !ruActive)),
3262
+ (ev) => setTypo({ enabled: ev.target.checked }), !ruActive), t('typographyDesc')),
3441
3263
  row(t('yo'), checkbox(typography.yo === true,
3442
- (ev) => setTypo({ yo: ev.target.checked }), !ruActive)),
3264
+ (ev) => setTypo({ yo: ev.target.checked }), !ruActive), t('yoDesc')),
3443
3265
  React.createElement('div', { className: 'rl-note' },
3444
3266
  t('overridesCount') + ': ' + overridesCount),
3445
3267
  React.createElement('div', { className: 'rl-hint' }, t('altL')),
@@ -3457,6 +3279,7 @@ window.__ModuleLoader__.load({
3457
3279
  '.rl-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}',
3458
3280
  '.rl-field{display:flex;flex-direction:column;gap:6px;padding:12px 0}',
3459
3281
  '.rl-label{color:var(--dsw-alias-label-primary);font-size:13px}',
3282
+ '.rl-desc{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.4}',
3460
3283
  '.rl-check{width:16px;height:16px;accent-color:var(--dsw-alias-label-primary)}',
3461
3284
  '.rl-note{color:var(--dsw-alias-label-secondary);font-size:12px;padding:8px 0 4px}',
3462
3285
  '.rl-hint{color:var(--dsw-alias-label-secondary);font-size:12px;padding:4px 0 8px}',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-russian-lang",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
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",