@goodandready/dsh-russian-lang 0.3.0 → 0.3.1

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/index.js CHANGED
@@ -1,15 +1,38 @@
1
+ import crypto from 'node:crypto'
1
2
  import { registerPluginUpdater } from './plugin-updater.js'
2
3
  import { registerTranslator } from './translator.js'
3
- import { getCoreDictionaries, getPluginDictionaries, getZhRuMap } from './locales.js'
4
+ import { getCoreDictionaries, getPluginDictionaries, getPluginDictionariesByNames, getZhRuMap } from './locales.js'
4
5
  // dsh-russian-lang — серверная половина.
5
6
  //
6
7
  // Словари и переключатель живут в браузере (lib/client.js). Хосту переводить
7
8
  // нечего, но у выбора языка есть сохраняемая настройка: регистрируем её схему
8
- // в собственном namespace, чтобы запись переживала браузеры и машины через
9
+ // в собственном namespace, чтобы запись переживала браузеры и машины череж
9
10
  // штатный механизм настроек DSH.
10
11
  import z from '@deepseek-ai/schemastery'
11
12
  import { SYSTEM_PROMPT_PRESETS } from './pure.js'
12
13
 
14
+
15
+ const sendJsonWithEtag = (request, response, obj, maxAge = 300) => {
16
+ const body = Buffer.from(JSON.stringify(obj), 'utf-8')
17
+ const etag = '"' + crypto.createHash('md5').update(body).digest('hex') + '"'
18
+ const ifNoneMatch = request?.headers?.['if-none-match']
19
+ if (ifNoneMatch && (ifNoneMatch === etag || ifNoneMatch === '*' || ifNoneMatch === `W/${etag}`)) {
20
+ response.writeHead(304, {
21
+ 'etag': etag,
22
+ 'cache-control': `public, max-age=${maxAge}, must-revalidate`,
23
+ })
24
+ response.end()
25
+ return
26
+ }
27
+ response.writeHead(200, {
28
+ 'content-type': 'application/json; charset=utf-8',
29
+ 'etag': etag,
30
+ 'cache-control': `public, max-age=${maxAge}, must-revalidate`,
31
+ 'content-length': body.length,
32
+ })
33
+ response.end(body)
34
+ }
35
+
13
36
  export const name = '@goodandready/dsh-russian-lang'
14
37
 
15
38
  const RussianLangSettingsSchema = z.object({
@@ -36,7 +59,7 @@ export function apply(ctx) {
36
59
  })
37
60
 
38
61
  // #68: русский системный промпт агента (опционально). Регистрируем секцию
39
- // промпта, которая задаёт стиль ответов по-русски, когда включён флаг
62
+ // промпта, которая задёт стиль ответов по-русски, когда включён флаг
40
63
  // russian-lang.agentPrompt. Секция — официальная точка расширения ядра.
41
64
  ctx.inject(['settings', 'systemPrompt'], (settingsCtx, prompt) => {
42
65
  const NS = 'russian-lang'
@@ -57,7 +80,7 @@ export function apply(ctx) {
57
80
  sync()
58
81
  })
59
82
 
60
- // Web endpoints: One-click plugin updater, modular plugin dictionary serving, & translator gateway
83
+ // Web endpoints: One-click plugin updater, modular lazy-plugin dictionary serving, & translator gateway
61
84
  if (typeof ctx.inject === 'function') {
62
85
  ctx.inject(['webServer'], (wctx) => {
63
86
  try {
@@ -73,9 +96,44 @@ export function apply(ctx) {
73
96
  let ws = null
74
97
  try { ws = wctx?.webServer } catch (_) { ws = null }
75
98
 
76
- let unregDict = () => {}
99
+ const unregsDict = []
77
100
  if (ws && typeof ws.register === 'function') {
78
- unregDict = ws.register({
101
+ // 1. Core dictionary only (fast-boot, ~135 KB)
102
+ unregsDict.push(ws.register({
103
+ kind: 'exact',
104
+ path: '/api/dsh-russian-lang/dict/core',
105
+ handler: async (request, response) => {
106
+ try {
107
+ const core = getCoreDictionaries()
108
+ const zhRu = getZhRuMap()
109
+ sendJsonWithEtag(request, response, { core, zhRu })
110
+ } catch (err) {
111
+ response.writeHead(500, { 'content-type': 'application/json; charset=utf-8' })
112
+ response.end(JSON.stringify({ error: String(err) }))
113
+ }
114
+ },
115
+ }))
116
+
117
+ // 2. On-demand plugins dictionary serving (query: ?names=p1,p2...)
118
+ unregsDict.push(ws.register({
119
+ kind: 'prefix',
120
+ path: '/api/dsh-russian-lang/dict/plugins',
121
+ handler: async (request, response) => {
122
+ try {
123
+ const url = new URL(request.url, 'http://localhost')
124
+ const namesParam = url.searchParams.get('names') || url.searchParams.get('list') || ''
125
+ const names = namesParam ? namesParam.split(',').map((s) => s.trim()).filter(Boolean) : null
126
+ const plugins = getPluginDictionariesByNames(names)
127
+ sendJsonWithEtag(request, response, { plugins })
128
+ } catch (err) {
129
+ response.writeHead(500, { 'content-type': 'application/json; charset=utf-8' })
130
+ response.end(JSON.stringify({ error: String(err) }))
131
+ }
132
+ },
133
+ }))
134
+
135
+ // 3. Backward compatibility all-dictionaries endpoint
136
+ unregsDict.push(ws.register({
79
137
  kind: 'exact',
80
138
  path: '/api/dsh-russian-lang/dict/all',
81
139
  handler: async (request, response) => {
@@ -83,23 +141,21 @@ export function apply(ctx) {
83
141
  const core = getCoreDictionaries()
84
142
  const plugins = getPluginDictionaries()
85
143
  const zhRu = getZhRuMap()
86
- response.writeHead(200, {
87
- 'content-type': 'application/json; charset=utf-8',
88
- 'cache-control': 'public, max-age=300',
89
- })
90
- response.end(JSON.stringify(Object.assign({}, core, plugins, { core, plugins, zhRu })))
144
+ sendJsonWithEtag(request, response, Object.assign({}, core, plugins, { core, plugins, zhRu }))
91
145
  } catch (err) {
92
146
  response.writeHead(500, { 'content-type': 'application/json; charset=utf-8' })
93
147
  response.end(JSON.stringify({ error: String(err) }))
94
148
  }
95
149
  },
96
- })
150
+ }))
97
151
  }
98
152
 
99
153
  return () => {
100
154
  if (typeof unregUpdater === 'function') unregUpdater()
101
155
  if (typeof unregTranslator === 'function') unregTranslator()
102
- if (typeof unregDict === 'function') unregDict()
156
+ for (const u of unregsDict) {
157
+ if (typeof u === 'function') u()
158
+ }
103
159
  }
104
160
  }
105
161
  if (typeof wctx.effect === 'function') wctx.effect(mount, 'russian-lang: web routes')
@@ -1 +1 @@
1
- {"dsh-messenger-gateway":{"adminIds":"ID администраторов","adminIdsHint":"ID пользователей с правами выполнения привилегированных команд","advanced":"Опрос Telegram (Long Polling)","agent":"Агент","agentSub":"Назначение модели и системных инструкций для Telegram-сессий","allowDirectMessages":"Разрешить личные сообщения","allowGroupMessages":"Разрешить работу в группах","allowedIds":"Разрешённые ID пользователей","allowedIdsHint":"Через запятую. Пусто = доступ разрешён всем","artifactPreviews":"Генерировать превью диаграмм и таблиц","autoSummarize":"Автосводка длинных сообщений","badge.cron_count":"Cron: {count}","badge.offline":"Telegram отключен","badge.online":"Telegram онлайн (@{username})","badge.pairing_count":"Сопряжено устройств: {count}","badge.pending":"Ожидание подключения бота…","badge.running":"Шлюз запущен","badge.stopped":"Шлюз остановлен","badge.token_missing":"Токен отсутствует","badge.token_ok":"Токен настроен","badge.transport":"Транспорт: Long Polling","botToken":"Токен бота (только запись)","botTokenHint":"Оставьте пустым, чтобы сохранить текущий токен","botUsername":"Имя пользователя бота (@username)","btn.disconnect":"Отключить бота","btn.ping":"Проверить связь (Ping)","btn.regenerate_code":"Новый код сопряжения","cmd.update":"Проверить или установить обновление плагина","debugLogs":"Подробные логи отладки","description":"Telegram-бот: обмен текстом, голосом, фото и документами.","diag.desc":"Проверка доступности Telegram Bot API, пинга и прав бота","diag.smoke_btn":"Запустить Smoke-тест","diag.smoke_err":"Smoke-тест завершился с ошибкой: {error}","diag.smoke_ok":"Smoke-тест пройден успешно! Бот готов к работе.","diag.smoke_testing":"Тестирование шлюза…","diag.title":"Диагностика связи и Smoke-тест","disableDiscord":"Отключить Discord","disableSlack":"Отключить Slack","disableTelegram":"Отключить Telegram","discord":"Шлюз Discord","discordChannels":"Разрешённые ID каналов Discord","discordChannelsHint":"Список ID каналов через запятую. Оставьте пустым, чтобы разрешить все настроенные.","discordSub":"Настройки бота и исходящих вебхуков Discord.","discordToken":"Токен бота Discord","discordTokenHint":"Из Discord Developer Portal. Оставьте пустым для сохранения текущего.","discordWebhook":"URL вебхука Discord","discordWebhookHint":"Входящий вебхук для отправки сообщений/уведомлений.","enableDiscord":"Включить Discord","enableSlack":"Включить Slack","enableTelegram":"Включить Telegram","endpoint":"Webhook URL / Endpoint","endpointHint":"URL для приёма входящих вебхуков от Telegram","errorNotification":"Уведомлять об ошибках выполнения","field.allowed_users":"Разрешённые ID пользователей","field.allowed_users_hint":"Список Telegram ID через запятую (оставьте пустым для сопряжения по коду)","field.notify_on_error":"Оповещать об ошибках выполнения","field.notify_on_error_hint":"Срочные уведомления о падении агента или превышении лимитов","field.notify_on_turn":"Уведомлять о завершении хода","field.notify_on_turn_hint":"Отправлять сообщение в Telegram, когда модель закончила длинный ответ","field.pairing_code":"Код сопряжения (Pairing Code)","field.pairing_code_hint":"Введите этот 6-значный код боту для авторизации нового устройства","field.token":"Bot Token (Telegram)","field.token_hint":"Токен бота от @BotFather (хранится безопасно в DSH Credentials)","fileHandling":"Обработка файлов","fileHandlingDesc":"Автоматически передавать прикреплённые документы и изображения в рабочую область","groupMention":"Отвечать только при упоминании в группах","groupsEnable":"Разрешить работу в группах","header.sub":"Мост между DeepSeek Harness и Telegram: сессии, управление, уведомления и доступ с мобильных","header.title":"Шлюз Telegram и мессенджеров","hideAdvanced":"Скрыть расширенные настройки","idleTimeout":"Таймаут неактивности сессии (мин)","instruction":"Пользовательская инструкция","instructionHint":"Дополнительная системная инструкция для сообщений из Telegram","instructionPlaceholder":"Отвечай кратко и лаконично…","loading":"Загрузка настроек шлюза…","maxDocMb":"Макс. размер документа (МБ)","maxFileSize":"Максимальный размер файла (МБ)","maxFileSizeHint":"Лимит размера файлов, принимаемых от пользователей","maxHistory":"Глубина истории контекста (сообщений)","maxImageMb":"Макс. размер фото (МБ)","maxMessageLength":"Максимальная длина сообщения","maxTextKb":"Макс. текст из документа (КБ)","maxVoiceSec":"Макс. длительность голосового (сек)","media":"Медиа","mediaCaption":"Подпись к медиа","mediaGroup":"Группировка медиа","mediaGroupDesc":"Объединять серии фото и документов в одно сообщение","mediaSub":"Приём и отправка голосовых сообщений, фото и файлов","messageChunkSize":"Размер фрагмента при разбиении сообщений","messageRateLimit":"Лимит сообщений в секунду","mode":"Режим работы","modeHelp":"Режимы доставки входящих сообщений от Telegram API","modePolling":"Опрос (Long Polling)","modeWebhook":"Вебхук (Webhook)","model":"Модель","modelHint":"Пусто = по умолчанию в DSH","msg.ping_failed":"Не удалось связаться с Telegram API: {error}","msg.ping_ok":"Связь с Telegram API установлена ({ms} мс)","notifications":"Уведомления","notificationsDesc":"Отправлять системные оповещения в Telegram","notifyBridge":"Уведомления → Telegram-чат","notifyBridgeHint":"task_done/error из веб-сессий (не msgw-*)","notifyHome":"Имя домашнего чата уведомлений","pairing":"Привязка аккаунта","pairingApprove":"Одобрить","pairingCode":"Код привязки: {code}","pairingDesc":"Отправьте этот код боту для авторизации вашего Telegram-аккаунта","pairingEmpty":"Нет ожидающих кодов","pairingRefresh":"Обновить","pairingReject":"Отклонить","pairingSub":"Управление авторизованными пользователями и разовыми кодами","parseMode":"Режим парсинга разметки","parseModeHtml":"HTML","parseModeMarkdown":"MarkdownV2","parseModeNone":"Без разметки (Plain text)","photoOnly":"Фото без подписи","photoPrompt":"Ждать вопроса (рекомендуется)","photoQuality":"Качество фото","photoQualityHigh":"Высокое (несжатое)","photoQualityNormal":"Обычное (сжатое Telegram)","photoRun":"Отвечать немедленно","pollInterval":"Интервал опроса (мс)","pollTimeout":"Таймаут опроса (сек)","pollingInterval":"Интервал опроса (мс)","pollingIntervalHint":"Задержка между запросами getUpdates в режиме polling","privacyMode":"Режим приватности","privacyModeDesc":"Не сохранять вложения и медиафайлы на диск","progressEnable":"Сообщение о ходе выполнения (рассуждение → удаление → финал)","provider":"Провайдер","providerHint":"Пусто = по умолчанию в DSH","proxy":"HTTPS прокси","proxyAuth":"Авторизация прокси (user:pass)","proxyHint":"например http://127.0.0.1:10808 для обхода сетевых ограничений","proxyType":"Тип прокси","proxyTypeHttp":"HTTP","proxyTypeHttps":"HTTPS","proxyTypeSocks5":"SOCKS5","queueSize":"Размер очереди сообщений","quickActions":"Клавиатура быстрых действий (/new, /stop, /voice, /status)","rateLimitExceeded":"Превышен лимит сообщений, попробуйте позже","reactionsEnable":"Реакции во время обработки (👀)","reconnectDelay":"Задержка переподключения (сек)","renderMarkdown":"Форматирование Markdown","renderMarkdownDesc":"Преобразовывать ответы модели в красивую разметку Telegram HTML/MarkdownV2","resetToken":"Сбросить токен","retryAttempts":"Количество попыток отправки","save":"Сохранить","saved":"Настройки сохранены","saving":"Сохранение…","sec.access_desc":"Ограничение доступа по Telegram User ID или разовым кодам сопряжения","sec.access_title":"Контроль доступа и белый список","sec.bot_desc":"Укажите токен бота от @BotFather для приёма сообщений и запуска сессий DSH","sec.bot_title":"Параметры Telegram-бота","sec.notify_desc":"Оповещения в Telegram о завершении ответов и ошибках","sec.notify_title":"Уведомления о событиях","secretToken":"Секретный токен вебхука","secretTokenHint":"Случайная строка для заголовка X-Telegram-Bot-Api-Secret-Token","sendPhotoAsFile":"Всегда отправлять фото как документ (без сжатия)","sendTyping":"Отправлять действие чата","sendVoiceNote":"Отправлять аудио как голосовое сообщение","sessionMode":"Режим диалога","sessionModeGroup":"Один общий диалог на группу","sessionModeUser":"Отдельный диалог для каждого пользователя","sessionScope":"Область действия групповых сессий","sessionScopeChat":"Общая для чата/темы","sessionScopeUser":"Для каждого пользователя (рекомендуется)","sessionTimeout":"Таймаут сессии диалога","settings.loading":"Загрузка настроек шлюза мессенджеров…","settings.retry":"Повторить","settings.unavailable":"Настройки недоступны (хостовый модуль не готов).","showAdvanced":"Показать расширенные настройки","slack":"Шлюз Slack","slackDefaultChannel":"Канал по умолчанию Slack","slackDefaultChannelHint":"Канал или ID участника для исходящих сообщений (напр. #general или C12345).","slackSub":"Настройки бота и входящих вебхуков Slack.","slackToken":"Токен бота Slack (xoxb-…)","slackTokenHint":"Bot User OAuth Token. Оставьте пустым для сохранения текущего.","slackWebhook":"URL вебхука Slack","slackWebhookHint":"Входящий вебхук для отправки сообщений/уведомлений в канал.","splitMessages":"Автоматически разбивать длинные сообщения","stat.active_chats":"Активных чатов","stat.avg_latency":"Пинг до Telegram API","stat.messages_relayed":"Передано сообщений","stats.active_chats":"Активных чатов","stats.desc":"Текущая статистика передаваемых сообщений и времени аптайма","stats.errors":"Ошибок шлюза","stats.sent":"Отправлено сообщений","stats.title":"Метрики шлюза","stats.uptime":"Время работы","status":"Статус подключения","statusConnected":"Telegram-бот подключён и работает","statusDisabled":"Telegram-шлюз отключён","statusError":"Ошибка подключения бота: {error}","statusIndicator":"Статус indicator (Online/Offline)","statusIndicatorHint":"Задаёт краткое описание бота; у ботов нет индикатора присутствия.","statusWaiting":"Ожидание подключения к Telegram…","streamResponse":"Потоковая передача ответа","sttEngine":"Движок распознавания речи (STT)","sttEngineLocal":"Локальный Whisper","sttEngineOpenAI":"OpenAI Whisper API","sttLanguage":"Язык распознавания речи","telegram":"Telegram","telegramApiUrl":"Пользовательский URL Telegram Bot API","telegramApiUrlHint":"Для локального сервера telegram-bot-api","telegramSub":"Настройки Telegram Bot API и интеграции","textFormat":"Формат текста","textFormatHtml":"Markdown → Telegram HTML","textFormatPlain":"Простой текст","title":"Шлюз Telegram (Messenger Gateway)","transport":"Транспорт","transportPoll":"Длинный опрос (getUpdates)","transportWebhook":"Вебхук (Webhook)","tts":"Голосовые ответы","ttsEnable":"Голосовые ответы через dsh-tts","ttsEngine":"Движок синтеза речи (TTS)","ttsEngineEdge":"Edge TTS","ttsEngineOpenAI":"OpenAI TTS","ttsMaxChars":"Макс. символов для озвучки","ttsSpeed":"Скорость речи","ttsSub":"Синтез речи (TTS) для голосовых ответов бота","ttsVoice":"Голос синтеза","turnTimeout":"Таймаут хода агента (сек)","typingIndicator":"Индикатор набора текста","typingIndicatorDesc":"Показывать «печатает…» во время генерации ответа моделью","unauthorizedMessage":"Сообщение при отказе в доступе","unauthorizedMessageHint":"Отправляется пользователям, не входящим в белый список","update.already_latest":"✅ Плагин уже обновлён до актуальной версии (<code>v{version}</code>).","update.available":"📦 <b>Доступно обновление!</b>\nТекущая версия: <code>v{current}</code>\nНовый релиз: <code>v{latest}</code>\n\nЗапустите <code>/update now</code> для установки.","update.check_failed":"⚠️ Не удалось проверить обновления: {error}","update.current":"✅ <b>Messenger Gateway актуален.</b>\nТекущая версия: <code>v{version}</code>.","update.failed":"❌ <b>Ошибка обновления:</b> {error}","update.installing":"⏳ <b>Обновление плагина…</b>\nЗапущена фоновая установка пакета DSH…","update.success":"🎉 <b>Успешно обновлено до v{version}!</b>\nПожалуйста, перезапустите службу: <code>sudo systemctl restart dsh-web.service</code>","updater.available":"Доступно обновление: v{version}","updater.btn_check":"Проверить обновления","updater.btn_update":"Обновить до v{version}","updater.check_failed":"Ошибка проверки обновлений: {error}","updater.checking":"Проверка обновлений…","updater.current":"Текущая версия: {version}","updater.desc":"Проверка обновлений в реестре npmjs и обновление на месте.","updater.failed":"Сбой обновления: {error}","updater.success":"Обновлено до v{version}! Перезапустите службу DSH при необходимости.","updater.title":"Автообновление плагина","updater.upToDate":"Актуальная версия","updater.updating":"Обновление…","userLanguage":"Язык ответов пользователю","voiceBitrate":"Битрейт аудио","voiceFormat":"Формат голосовых сообщений","voiceFormatMp3":"MP3","voiceFormatOgg":"OGG Opus","voiceInput":"Приём голосовых сообщений","voiceInputDesc":"Распознавать входящие голосовые аудиосообщения через Whisper / STT","voiceMode":"Режим голосовых ответов","voiceModeAlways":"Всегда использовать TTS","voiceModeMirror":"В ответ на входящие голосовые","voiceModeOff":"Выключено (если не включён /voice)","voiceOutput":"Голосовые ответы","voiceOutputDesc":"Озвучивать ответы модели с помощью модуля синтеза речи (TTS)","voiceSpeed":"Скорость озвучки","voiceVoice":"Голос синтеза речи","webhookHost":"Хост вебхука","webhookPath":"Путь вебхука","webhookPort":"Порт вебхука","webhookSecret":"Секретный токен","webhookSecretConfigured":"Секретный ключ вебхука настроен","webhookSecretHint":"Оставьте пустым для сохранения текущего","webhookSecretRequired":"Требуется секретный ключ вебхука","webhookUrl":"Публичный URL вебхука","webhookUrlHint":"Полный HTTPS URL, на который Telegram отправляет POST-запросы","welcomeMessage":"Приветственное сообщение","welcomeMessageHint":"Текст сообщения при команде /start","whitelist":"Белый список пользователей","whitelistDesc":"Ограничить доступ к боту только указанными Telegram ID","wrapCode":"Оформление блоков кода","wrapCodeDesc":"Автоматически оборачивать фрагменты кода в моноширинные блоки с подсветкой"}}
1
+ {"dsh-messenger-gateway":{"adminIds":"ID администраторов","adminIdsHint":"ID пользователей с правами выполнения привилегированных команд","advanced":"Опрос Telegram (Long Polling)","agent":"Агент","agentSub":"Назначение модели и системных инструкций для Telegram-сессий","allowDirectMessages":"Разрешить личные сообщения","allowGroupMessages":"Разрешить работу в группах","allowedIds":"Разрешённые ID пользователей","allowedIdsHint":"Через запятую. Пусто = доступ разрешён всем","artifactPreviews":"Генерировать превью диаграмм и таблиц","autoSummarize":"Автосводка длинных сообщений","badge.api_degraded":"Сбои Telegram API ({count})","badge.cron_count":"Cron: {count}","badge.offline":"Telegram отключен","badge.online":"Telegram онлайн (@{username})","badge.pairing_count":"Сопряжено устройств: {count}","badge.pending":"Ожидание подключения бота…","badge.running":"Шлюз запущен","badge.stopped":"Шлюз остановлен","badge.token_missing":"Токен отсутствует","badge.token_ok":"Токен настроен","badge.transport":"Транспорт: Long Polling","botToken":"Токен бота (только запись)","botTokenHint":"Оставьте пустым, чтобы сохранить текущий токен","botUsername":"Имя пользователя бота (@username)","btn.disconnect":"Отключить бота","btn.ping":"Проверить связь (Ping)","btn.regenerate_code":"Новый код сопряжения","cmd.update":"Проверить или установить обновление плагина","debugLogs":"Подробные логи отладки","description":"Telegram-бот: обмен текстом, голосом, фото и документами.","diag.desc":"Проверка доступности Telegram Bot API, пинга и прав бота","diag.smoke_btn":"Запустить Smoke-тест","diag.smoke_err":"Smoke-тест завершился с ошибкой: {error}","diag.smoke_ok":"Smoke-тест пройден успешно! Бот готов к работе.","diag.smoke_testing":"Тестирование шлюза…","diag.title":"Диагностика связи и Smoke-тест","disableDiscord":"Отключить Discord","disableSlack":"Отключить Slack","disableTelegram":"Отключить Telegram","discord":"Шлюз Discord","discordChannels":"Разрешённые ID каналов Discord","discordChannelsHint":"Список ID каналов через запятую. Оставьте пустым, чтобы разрешить все настроенные.","discordSub":"Настройки бота и исходящих вебхуков Discord.","discordToken":"Токен бота Discord","discordTokenHint":"Из Discord Developer Portal. Оставьте пустым для сохранения текущего.","discordWebhook":"URL вебхука Discord","discordWebhookHint":"Входящий вебхук для отправки сообщений/уведомлений.","enableDiscord":"Включить Discord","enableSlack":"Включить Slack","enableTelegram":"Включить Telegram","endpoint":"Webhook URL / Endpoint","endpointHint":"URL для приёма входящих вебхуков от Telegram","errorNotification":"Уведомлять об ошибках выполнения","field.allowed_users":"Разрешённые ID пользователей","field.allowed_users_hint":"Список Telegram ID через запятую (оставьте пустым для сопряжения по коду)","field.notify_on_error":"Оповещать об ошибках выполнения","field.notify_on_error_hint":"Срочные уведомления о падении агента или превышении лимитов","field.notify_on_turn":"Уведомлять о завершении хода","field.notify_on_turn_hint":"Отправлять сообщение в Telegram, когда модель закончила длинный ответ","field.pairing_code":"Код сопряжения (Pairing Code)","field.pairing_code_hint":"Введите этот 6-значный код боту для авторизации нового устройства","field.token":"Bot Token (Telegram)","field.token_hint":"Токен бота от @BotFather (хранится безопасно в DSH Credentials)","fileHandling":"Обработка файлов","fileHandlingDesc":"Автоматически передавать прикреплённые документы и изображения в рабочую область","groupMention":"Отвечать только при упоминании в группах","groupsEnable":"Разрешить работу в группах","header.sub":"Мост между DeepSeek Harness и Telegram: сессии, управление, уведомления и доступ с мобильных","header.title":"Шлюз Telegram и мессенджеров","hideAdvanced":"Скрыть расширенные настройки","idleTimeout":"Таймаут неактивности сессии (мин)","instruction":"Пользовательская инструкция","instructionHint":"Дополнительная системная инструкция для сообщений из Telegram","instructionPlaceholder":"Отвечай кратко и лаконично…","loading":"Загрузка настроек шлюза…","maxDocMb":"Макс. размер документа (МБ)","maxFileSize":"Максимальный размер файла (МБ)","maxFileSizeHint":"Лимит размера файлов, принимаемых от пользователей","maxHistory":"Глубина истории контекста (сообщений)","maxImageMb":"Макс. размер фото (МБ)","maxMessageLength":"Максимальная длина сообщения","maxTextKb":"Макс. текст из документа (КБ)","maxVoiceSec":"Макс. длительность голосового (сек)","media":"Медиа","mediaCaption":"Подпись к медиа","mediaGroup":"Группировка медиа","mediaGroupDesc":"Объединять серии фото и документов в одно сообщение","mediaSub":"Приём и отправка голосовых сообщений, фото и файлов","messageChunkSize":"Размер фрагмента при разбиении сообщений","messageRateLimit":"Лимит сообщений в секунду","mode":"Режим работы","modeHelp":"Режимы доставки входящих сообщений от Telegram API","modePolling":"Опрос (Long Polling)","modeWebhook":"Вебхук (Webhook)","model":"Модель","modelHint":"Пусто = по умолчанию в DSH","msg.ping_failed":"Не удалось связаться с Telegram API: {error}","msg.ping_ok":"Связь с Telegram API установлена ({ms} мс)","notifications":"Уведомления","notificationsDesc":"Отправлять системные оповещения в Telegram","notifyBridge":"Уведомления → Telegram-чат","notifyBridgeHint":"task_done/error из веб-сессий (не msgw-*)","notifyHome":"Имя домашнего чата уведомлений","pairing":"Привязка аккаунта","pairingApprove":"Одобрить","pairingCode":"Код привязки: {code}","pairingDesc":"Отправьте этот код боту для авторизации вашего Telegram-аккаунта","pairingEmpty":"Нет ожидающих кодов","pairingRefresh":"Обновить","pairingReject":"Отклонить","pairingSub":"Управление авторизованными пользователями и разовыми кодами","parseMode":"Режим парсинга разметки","parseModeHtml":"HTML","parseModeMarkdown":"MarkdownV2","parseModeNone":"Без разметки (Plain text)","photoOnly":"Фото без подписи","photoPrompt":"Ждать вопроса (рекомендуется)","photoQuality":"Качество фото","photoQualityHigh":"Высокое (несжатое)","photoQualityNormal":"Обычное (сжатое Telegram)","photoRun":"Отвечать немедленно","pollInterval":"Интервал опроса (мс)","pollTimeout":"Таймаут опроса (сек)","pollingInterval":"Интервал опроса (мс)","pollingIntervalHint":"Задержка между запросами getUpdates в режиме polling","privacyMode":"Режим приватности","privacyModeDesc":"Не сохранять вложения и медиафайлы на диск","progressEnable":"Сообщение о ходе выполнения (рассуждение → удаление → финал)","provider":"Провайдер","providerHint":"Пусто = по умолчанию в DSH","proxy":"HTTPS прокси","proxyAuth":"Авторизация прокси (user:pass)","proxyHint":"например http://127.0.0.1:10808 для обхода сетевых ограничений","proxyType":"Тип прокси","proxyTypeHttp":"HTTP","proxyTypeHttps":"HTTPS","proxyTypeSocks5":"SOCKS5","queueSize":"Размер очереди сообщений","quickActions":"Клавиатура быстрых действий (/new, /stop, /voice, /status)","rateLimitExceeded":"Превышен лимит сообщений, попробуйте позже","reactionsEnable":"Реакции во время обработки (👀)","reconnectDelay":"Задержка переподключения (сек)","renderMarkdown":"Форматирование Markdown","renderMarkdownDesc":"Преобразовывать ответы модели в красивую разметку Telegram HTML/MarkdownV2","resetToken":"Сбросить токен","retryAttempts":"Количество попыток отправки","save":"Сохранить","saved":"Настройки сохранены","saving":"Сохранение…","sec.access_desc":"Ограничение доступа по Telegram User ID или разовым кодам сопряжения","sec.access_title":"Контроль доступа и белый список","sec.bot_desc":"Укажите токен бота от @BotFather для приёма сообщений и запуска сессий DSH","sec.bot_title":"Параметры Telegram-бота","sec.notify_desc":"Оповещения в Telegram о завершении ответов и ошибках","sec.notify_title":"Уведомления о событиях","secretToken":"Секретный токен вебхука","secretTokenHint":"Случайная строка для заголовка X-Telegram-Bot-Api-Secret-Token","sendPhotoAsFile":"Всегда отправлять фото как документ (без сжатия)","sendTyping":"Отправлять действие чата","sendVoiceNote":"Отправлять аудио как голосовое сообщение","sessionMode":"Режим диалога","sessionModeGroup":"Один общий диалог на группу","sessionModeUser":"Отдельный диалог для каждого пользователя","sessionScope":"Область действия групповых сессий","sessionScopeChat":"Общая для чата/темы","sessionScopeUser":"Для каждого пользователя (рекомендуется)","sessionTimeout":"Таймаут сессии диалога","settings.loading":"Загрузка настроек шлюза мессенджеров…","settings.retry":"Повторить","settings.unavailable":"Настройки недоступны (хостовый модуль не готов).","showAdvanced":"Показать расширенные настройки","slack":"Шлюз Slack","slackDefaultChannel":"Канал по умолчанию Slack","slackDefaultChannelHint":"Канал или ID участника для исходящих сообщений (напр. #general или C12345).","slackSub":"Настройки бота и входящих вебхуков Slack.","slackToken":"Токен бота Slack (xoxb-…)","slackTokenHint":"Bot User OAuth Token. Оставьте пустым для сохранения текущего.","slackWebhook":"URL вебхука Slack","slackWebhookHint":"Входящий вебхук для отправки сообщений/уведомлений в канал.","splitMessages":"Автоматически разбивать длинные сообщения","stat.active_chats":"Активных чатов","stat.avg_latency":"Пинг до Telegram API","stat.messages_relayed":"Передано сообщений","stats.active_chats":"Активных чатов","stats.desc":"Текущая статистика передаваемых сообщений и времени аптайма","stats.errors":"Ошибок шлюза","stats.sent":"Отправлено сообщений","stats.title":"Метрики шлюза","stats.uptime":"Время работы","status":"Статус подключения","statusConnected":"Telegram-бот подключён и работает","statusDisabled":"Telegram-шлюз отключён","statusError":"Ошибка подключения бота: {error}","statusIndicator":"Статус indicator (Online/Offline)","statusIndicatorHint":"Задаёт краткое описание бота; у ботов нет индикатора присутствия.","statusWaiting":"Ожидание подключения к Telegram…","streamResponse":"Потоковая передача ответа","sttEngine":"Движок распознавания речи (STT)","sttEngineLocal":"Локальный Whisper","sttEngineOpenAI":"OpenAI Whisper API","sttLanguage":"Язык распознавания речи","telegram":"Telegram","telegramApiUrl":"Пользовательский URL Telegram Bot API","telegramApiUrlHint":"Для локального сервера telegram-bot-api","telegramSub":"Настройки Telegram Bot API и интеграции","textFormat":"Формат текста","textFormatHtml":"Markdown → Telegram HTML","textFormatPlain":"Простой текст","title":"Шлюз Telegram (Messenger Gateway)","transport":"Транспорт","transportPoll":"Длинный опрос (getUpdates)","transportWebhook":"Вебхук (Webhook)","tts":"Голосовые ответы","ttsEnable":"Голосовые ответы через dsh-tts","ttsEngine":"Движок синтеза речи (TTS)","ttsEngineEdge":"Edge TTS","ttsEngineOpenAI":"OpenAI TTS","ttsMaxChars":"Макс. символов для озвучки","ttsSpeed":"Скорость речи","ttsSub":"Синтез речи (TTS) для голосовых ответов бота","ttsVoice":"Голос синтеза","turnTimeout":"Таймаут хода агента (сек)","typingIndicator":"Индикатор набора текста","typingIndicatorDesc":"Показывать «печатает…» во время генерации ответа моделью","unauthorizedMessage":"Сообщение при отказе в доступе","unauthorizedMessageHint":"Отправляется пользователям, не входящим в белый список","update.already_latest":"✅ Плагин уже обновлён до актуальной версии (<code>v{version}</code>).","update.available":"📦 <b>Доступно обновление!</b>\nТекущая версия: <code>v{current}</code>\nНовый релиз: <code>v{latest}</code>\n\nЗапустите <code>/update now</code> для установки.","update.check_failed":"⚠️ Не удалось проверить обновления: {error}","update.current":"✅ <b>Messenger Gateway актуален.</b>\nТекущая версия: <code>v{version}</code>.","update.failed":"❌ <b>Ошибка обновления:</b> {error}","update.installing":"⏳ <b>Обновление плагина…</b>\nЗапущена фоновая установка пакета DSH…","update.success":"🎉 <b>Успешно обновлено до v{version}!</b>\nПожалуйста, перезапустите службу: <code>sudo systemctl restart dsh-web.service</code>","updater.available":"Доступно обновление: v{version}","updater.btn_check":"Проверить обновления","updater.btn_update":"Обновить до v{version}","updater.check_failed":"Ошибка проверки обновлений: {error}","updater.checking":"Проверка обновлений…","updater.current":"Текущая версия: {version}","updater.desc":"Проверка обновлений в реестре npmjs и обновление на месте.","updater.failed":"Сбой обновления: {error}","updater.success":"Обновлено до v{version}! Перезапустите службу DSH при необходимости.","updater.title":"Автообновление плагина","updater.upToDate":"Актуальная версия","updater.updating":"Обновление…","userLanguage":"Язык ответов пользователю","voiceBitrate":"Битрейт аудио","voiceFormat":"Формат голосовых сообщений","voiceFormatMp3":"MP3","voiceFormatOgg":"OGG Opus","voiceInput":"Приём голосовых сообщений","voiceInputDesc":"Распознавать входящие голосовые аудиосообщения через Whisper / STT","voiceMode":"Режим голосовых ответов","voiceModeAlways":"Всегда использовать TTS","voiceModeMirror":"В ответ на входящие голосовые","voiceModeOff":"Выключено (если не включён /voice)","voiceOutput":"Голосовые ответы","voiceOutputDesc":"Озвучивать ответы модели с помощью модуля синтеза речи (TTS)","voiceSpeed":"Скорость озвучки","voiceVoice":"Голос синтеза речи","webhookHost":"Хост вебхука","webhookPath":"Путь вебхука","webhookPort":"Порт вебхука","webhookSecret":"Секретный токен","webhookSecretConfigured":"Секретный ключ вебхука настроен","webhookSecretHint":"Оставьте пустым для сохранения текущего","webhookSecretRequired":"Требуется секретный ключ вебхука","webhookUrl":"Публичный URL вебхука","webhookUrlHint":"Полный HTTPS URL, на который Telegram отправляет POST-запросы","welcomeMessage":"Приветственное сообщение","welcomeMessageHint":"Текст сообщения при команде /start","whitelist":"Белый список пользователей","whitelistDesc":"Ограничить доступ к боту только указанными Telegram ID","wrapCode":"Оформление блоков кода","wrapCodeDesc":"Автоматически оборачивать фрагменты кода в моноширинные блоки с подсветкой"}}
@@ -1 +1 @@
1
- {"dsh-gitea":{"activePr":"Активный Pull Request: #{number}","badgeOffline":"Не в сети","badgeOnline":"В сети","baseUrl":"URL сервера Gitea","baseUrlHint":"например https://gitea.example.com","bgSchedulerEnabled":"Включить фоновый планировщик триажа","bgSchedulerEnabledHint":"Периодически проверять открытые задачи и пул-реквесты в фоне","bgSchedulerIntervalMin":"Интервал планировщика (минуты)","bgSchedulerIntervalMinHint":"Частота выполнения фонового триажа","bgSchedulerOwner":"Владелец для фонового триажа","bgSchedulerOwnerHint":"Пользователь или организация для фонового сканирования","bgSchedulerRepo":"Репозиторий для фонового триажа","bgSchedulerRepoHint":"Имя репозитория для фонового сканирования","bgSchedulerWebhook":"Вебхук для отчётов триажа","bgSchedulerWebhookHint":"URL для отправки дайджестов проверки задач","branch":"Ветка","btn.save_settings":"Сохранить параметры Gitea","btn.trigger_triage":"Запустить триаж сейчас","ciFail":"CI завершился с ошибкой","ciPass":"CI пройден успешно","ciPending":"CI выполняется","collapse":"Свернуть","daysAgo":"дн. назад","defaultOwner":"Владелец / Организация по умолчанию","defaultOwnerHint":"Организация или пользователь в Gitea для создания репозиториев","defaultRepo":"Репозиторий по умолчанию","defaultRepoHint":"Основной репозиторий проекта","description":"Инструменты и учётные данные Gitea или Forgejo.","discard":"Сбросить","dodReminder":"Напоминания Definition of Done (DoD)","dodReminderHint":"Напоминать о критериях приёмки перед открытием или слиянием PR","drawerClose":"Закрыть панель","drawerRefresh":"Обновить состояние Git","drawerTitle":"Инспектор Git и Worktree","eventsTitle":"События","expand":"Развернуть","forceHttpsUrls":"Принудительный HTTPS для URL репозиториев","forceHttpsUrlsHint":"Преобразовывать http:// ссылки в безопасный https://","gitAhead":"Впереди","gitBehind":"Позади","gitChanges":"Изменения","gitClean":"Чисто","gitCommits":"ПОСЛЕДНИЕ КОММИТЫ","gitDirty":"Есть незакоммиченные изменения","gitEmpty":"В репозитории нет коммитов","gitHint":"Сведения о состоянии локального git-репозитория и удалённой ветки","gitNoChanges":"Нет изменений","gitNoCommits":"Нет коммитов для отправки","gitNoRemote":"Удалённый репозиторий не настроен","gitPulled":"Ветка обновлена из удалённого репозитория","gitPushed":"Коммиты успешно отправлены в Gitea","gitRemote":"Удалённый репозиторий (Remote)","gitStatus":"Статус Git","gitSync":"Синхронизация","gitSynced":"Ветка синхронизирована с Gitea","gitUpToDate":"Синхронизировано с удалённым репозиторием","gitWrapper":"Пользовательский Git-враппер","gitWrapperHint":"Имя бинарника/скрипта-обёртки для Git (например, git-antigravity)","giteaBranch":"Ветка","giteaCommit":"Коммит","giteaOwner":"Владелец / Организация","giteaRepo":"Репозиторий","giteaToken":"Персональный токен","giteaUrl":"URL сервера","giteaUser":"Пользователь","graph.ci_failing":"CI: Ошибки сборки","graph.ci_passing":"CI: Тесты пройдены","graph.ci_pending":"CI: Выполняется…","graph.desc":"Визуальный граф веток, слияний и результатов автоматических тестов","graph.refresh":"Обновить граф","graph.title":"История коммитов и статус CI","graphClose":"Закрыть граф","graphEmpty":"В репозитории не найдено коммитов","graphLoadMore":"Загрузить ещё коммиты","graphLoading":"Загрузка графа коммитов…","graphTitle":"Граф коммитов Git","hoursAgo":"ч назад","inspector.branch":"Текущая ветка: {name}","inspector.clean_state":"Рабочее дерево чисто (Clean)","inspector.desc":"Просмотр активных веток, коммитов, worktree и незафиксированных изменений","inspector.empty":"Рабочие деревья и изменения не найдены","inspector.last_commit":"Последний коммит: {hash} — {msg}","inspector.loading":"Считывание состояния репозитория…","inspector.refresh":"Обновить дерево Git","inspector.staged":"Файлы в индексе (Staged) ({count})","inspector.title":"Инспектор Git и репозиториев","inspector.unstaged":"Незафиксированные файлы ({count})","inspector.worktrees":"Активные Worktree ({count}):","intro":"Создайте учётные данные DSH, вставьте туда токен API, затем укажите только имя учётных данных ниже (например, GITEA_TOKEN).","issues":"Задачи (Issues)","justNow":"только что","loading":"Загрузка данных Gitea…","minutesAgo":"мин назад","msg.saved":"Настройки Gitea успешно сохранены","msg.triage_started":"Фоновый триаж запущен","noChangesDesc":"В рабочем каталоге нет изменённых или неотслеживаемых файлов.","noEvents":"События не зафиксированы","noInstances":"Дополнительные инстансы Gitea не настроены","noIssues":"Нет открытых задач","noPulls":"Нет открытых pull request","noRepos":"Репозитории не найдены","notifyWebhook":"URL вебхука для уведомлений","notifyWebhookHint":"Внешний вебхук для отправки статусов триажа и событий","openGraph":"Граф коммитов","openInGitea":"Открыть в Gitea","password":"Пароль / Токен доступа","passwordHint":"Персональный токен доступа Gitea с правами api, repo, issue","pullRequests":"Запросы на слияние (Pull Requests)","recentEvents":"Недавние события репозитория","refresh":"Обновить","repoCloned":"Репозиторий успешно клонирован","repoCloning":"Клонирование репозитория…","repos":"Репозитории","save":"Сохранить","saveFailed":"Сохранить failed","saved":"Настройки сохранены","saving":"Сохранение…","scheduler.auto_triage":"Автоматический триаж новых Issue","scheduler.desc":"Автоматическая проверка новых задач (issues), напоминания DoD и ревью","scheduler.dod_hint":"Проверять чек-листы готовности перед закрытием PR и задач","scheduler.dod_reminder":"Напоминания Definition of Done (DoD)","scheduler.enabled":"Включить фоновый планировщик","scheduler.interval":"Интервал проверки (минуты)","scheduler.last_run":"Последний запуск: {time}","scheduler.next_run":"Следующий запуск: через {mins} мин","scheduler.title":"Фоновый триаж и задачи по расписанию","sectionDefaults":"Значения по умолчанию и Git Worktrees","sectionInstance":"Подключение и основные настройки","sectionInstances":"Дополнительные инстансы","sectionScheduler":"Фоновый планировщик триажа","sectionWebhooks":"Вебхуки и уведомления","settingsUnavailable":"Настройки unavailable (namespace not registered).","status":"Статус подключения","statusClean":"Рабочее дерево чисто (Clean)","statusConnected":"Подключено к Gitea","statusDirty":"Есть незафиксированные изменения","statusDisconnected":"Не подключено","statusError":"Ошибка подключения","tabEvents":"События и PR","tabGraph":"Граф и CI","tabInspector":"Git Inspector","tabScheduler":"Планировщик задач","tabStatus":"Статус","tabWebhooks":"Входящие вебхуки","timeoutMs":"Таймаут API запросов (мс)","timeoutMsHint":"Максимальное время ожидания ответа Gitea API","title":"Интеграция с Gitea","toggleAdvanced":"Расширенные настройки","token":"Токен API","tokenEnv":"Имя учётных данных","tokenEnvHint":"Имя учётных данных DSH, а не сам токен. По умолчанию GITEA_TOKEN.","tokenHint":"Токен авторизации Gitea API","tokenOff":"Токен не настроен","tokenOn":"Токен настроен","unsaved":"Не сохранено","updaterAvailable":"Доступно обновление: v{version}","updaterBtnCheck":"Проверить обновления","updaterBtnUpdate":"Обновить до v{version}","updaterCheckFailed":"Ошибка проверки реестра","updaterChecking":"Проверка реестра...","updaterCurrent":"Текущая версия: v{version}","updaterDesc":"Проверка npm-реестра на новые версии и обновление в один клик.","updaterSuccess":"Успешно обновлено до v{version}. Перезапустите DSH для применения.","updaterTitle":"Обновление плагина","updaterUpToDate":"Актуальная версия","updaterUpdating":"Обновление плагина...","upstream":"Ветка upstream:","username":"Имя пользователя","usernameHint":"Логин вашей учётной записи в Gitea","viewCommit":"Посмотреть коммит","viewInGitea":"Открыть в Gitea ↗","viewIssue":"Посмотреть задачу","viewPull":"Посмотреть PR","viewRepo":"Посмотреть репозиторий","webhookSecretEnv":"Переменная окружения для HMAC-секрета","webhookSecretEnvHint":"Имя переменной с секретным ключом для валидации входящих вебхуков","webhooks.desc":"Приём событий push, pull_request, issue с проверкой HMAC-SHA256 подписи","webhooks.endpoint":"URL вебхука: {url}","webhooks.no_events":"События вебхуков ещё не поступали","webhooks.recent":"Недавние события ({count})","webhooks.secret":"Секретный ключ (HMAC Secret)","webhooks.secret_hint":"Секрет для верификации подписи X-Gitea-Signature","webhooks.title":"Входящие вебхуки Gitea","worktreeBranch":"Ветка worktree"}}
1
+ {"dsh-gitea":{"activePr":"Активный Pull Request: #{number}","badgeOffline":"Не в сети","badgeOnline":"В сети","baseUrl":"URL сервера Gitea","baseUrlHint":"например https://gitea.example.com","bgSchedulerEnabled":"Включить фоновый планировщик триажа","bgSchedulerEnabledHint":"Периодически проверять открытые задачи и пул-реквесты в фоне","bgSchedulerIntervalMin":"Интервал планировщика (минуты)","bgSchedulerIntervalMinHint":"Частота выполнения фонового триажа","bgSchedulerOwner":"Владелец для фонового триажа","bgSchedulerOwnerHint":"Пользователь или организация для фонового сканирования","bgSchedulerRepo":"Репозиторий для фонового триажа","bgSchedulerRepoHint":"Имя репозитория для фонового сканирования","bgSchedulerWebhook":"Вебхук для отчётов триажа","bgSchedulerWebhookHint":"URL для отправки дайджестов проверки задач","branch":"Ветка","btn.save_settings":"Сохранить параметры Gitea","btn.trigger_triage":"Запустить триаж сейчас","ciFail":"CI завершился с ошибкой","ciPass":"CI пройден успешно","ciPending":"CI выполняется","collapse":"Свернуть","daysAgo":"дн. назад","defaultOwner":"Владелец / Организация по умолчанию","defaultOwnerHint":"Организация или пользователь в Gitea для создания репозиториев","defaultRepo":"Репозиторий по умолчанию","defaultRepoHint":"Основной репозиторий проекта","description":"Инструменты и учётные данные Gitea или Forgejo.","discard":"Сбросить","dodReminder":"Напоминания Definition of Done (DoD)","dodReminderHint":"Напоминать о критериях приёмки перед открытием или слиянием PR","drawerClose":"Закрыть панель","drawerRefresh":"Обновить состояние Git","drawerTitle":"Инспектор Git и Worktree","eventsEmptyHint":"Вебхуки не настроены или событий пока нет. Настройте вебхук на адрес {url}.","eventsTitle":"События","expand":"Развернуть","forceHttpsUrls":"Принудительный HTTPS для URL репозиториев","forceHttpsUrlsHint":"Преобразовывать http:// ссылки в безопасный https://","gitAhead":"Впереди","gitBehind":"Позади","gitChanges":"Изменения","gitClean":"Чисто","gitCommits":"ПОСЛЕДНИЕ КОММИТЫ","gitDirty":"Есть незакоммиченные изменения","gitEmpty":"В репозитории нет коммитов","gitHint":"Сведения о состоянии локального git-репозитория и удалённой ветки","gitNoChanges":"Нет изменений","gitNoCommits":"Нет коммитов для отправки","gitNoRemote":"Удалённый репозиторий не настроен","gitPulled":"Ветка обновлена из удалённого репозитория","gitPushed":"Коммиты успешно отправлены в Gitea","gitRemote":"Удалённый репозиторий (Remote)","gitStatus":"Статус Git","gitSync":"Синхронизация","gitSynced":"Ветка синхронизирована с Gitea","gitUpToDate":"Синхронизировано с удалённым репозиторием","gitWrapper":"Пользовательский Git-враппер","gitWrapperHint":"Имя бинарника/скрипта-обёртки для Git (например, git-antigravity)","giteaBranch":"Ветка","giteaCommit":"Коммит","giteaOwner":"Владелец / Организация","giteaRepo":"Репозиторий","giteaToken":"Персональный токен","giteaUrl":"URL сервера","giteaUser":"Пользователь","graph.ci_failing":"CI: Ошибки сборки","graph.ci_passing":"CI: Тесты пройдены","graph.ci_pending":"CI: Выполняется…","graph.desc":"Визуальный граф веток, слияний и результатов автоматических тестов","graph.refresh":"Обновить граф","graph.title":"История коммитов и статус CI","graphClose":"Закрыть граф","graphEmpty":"В репозитории не найдено коммитов","graphLoadMore":"Загрузить ещё коммиты","graphLoading":"Загрузка графа коммитов…","graphTitle":"Граф коммитов Git","hoursAgo":"ч назад","inspector.branch":"Текущая ветка: {name}","inspector.clean_state":"Рабочее дерево чисто (Clean)","inspector.desc":"Просмотр активных веток, коммитов, worktree и незафиксированных изменений","inspector.empty":"Рабочие деревья и изменения не найдены","inspector.last_commit":"Последний коммит: {hash} — {msg}","inspector.loading":"Считывание состояния репозитория…","inspector.refresh":"Обновить дерево Git","inspector.staged":"Файлы в индексе (Staged) ({count})","inspector.title":"Инспектор Git и репозиториев","inspector.unstaged":"Незафиксированные файлы ({count})","inspector.worktrees":"Активные Worktree ({count}):","intro":"Создайте учётные данные DSH, вставьте туда токен API, затем укажите только имя учётных данных ниже (например, GITEA_TOKEN).","issues":"Задачи (Issues)","justNow":"только что","loading":"Загрузка данных Gitea…","minutesAgo":"мин назад","msg.saved":"Настройки Gitea успешно сохранены","msg.triage_started":"Фоновый триаж запущен","noChangesDesc":"В рабочем каталоге нет изменённых или неотслеживаемых файлов.","noEvents":"События не зафиксированы","noInstances":"Дополнительные инстансы Gitea не настроены","noIssues":"Нет открытых задач","noPulls":"Нет открытых pull request","noRepos":"Репозитории не найдены","notifyWebhook":"URL вебхука для уведомлений","notifyWebhookHint":"Внешний вебхук для отправки статусов триажа и событий","openGraph":"Граф коммитов","openInGitea":"Открыть в Gitea","password":"Пароль / Токен доступа","passwordHint":"Персональный токен доступа Gitea с правами api, repo, issue","pullRequests":"Запросы на слияние (Pull Requests)","recentEvents":"Недавние события репозитория","refresh":"Обновить","repoCloned":"Репозиторий успешно клонирован","repoCloning":"Клонирование репозитория…","repos":"Репозитории","save":"Сохранить","saveFailed":"Сохранить failed","saved":"Настройки сохранены","saving":"Сохранение…","scheduler.auto_triage":"Автоматический триаж новых Issue","scheduler.desc":"Автоматическая проверка новых задач (issues), напоминания DoD и ревью","scheduler.dod_hint":"Проверять чек-листы готовности перед закрытием PR и задач","scheduler.dod_reminder":"Напоминания Definition of Done (DoD)","scheduler.enabled":"Включить фоновый планировщик","scheduler.interval":"Интервал проверки (минуты)","scheduler.last_run":"Последний запуск: {time}","scheduler.next_run":"Следующий запуск: через {mins} мин","scheduler.title":"Фоновый триаж и задачи по расписанию","sectionDefaults":"Значения по умолчанию и Git Worktrees","sectionInstance":"Подключение и основные настройки","sectionInstances":"Дополнительные инстансы","sectionScheduler":"Фоновый планировщик триажа","sectionWebhooks":"Вебхуки и уведомления","settingsUnavailable":"Настройки unavailable (namespace not registered).","status":"Статус подключения","statusClean":"Рабочее дерево чисто (Clean)","statusConnected":"Подключено к Gitea","statusDirty":"Есть незафиксированные изменения","statusDisconnected":"Не подключено","statusError":"Ошибка подключения","tabEvents":"События и PR","tabGraph":"Граф и CI","tabInspector":"Git Inspector","tabScheduler":"Планировщик задач","tabStatus":"Статус","tabWebhooks":"Входящие вебхуки","timeoutMs":"Таймаут API запросов (мс)","timeoutMsHint":"Максимальное время ожидания ответа Gitea API","title":"Интеграция с Gitea","toggleAdvanced":"Расширенные настройки","token":"Токен API","tokenEnv":"Имя учётных данных","tokenEnvHint":"Имя учётных данных DSH, а не сам токен. По умолчанию GITEA_TOKEN.","tokenHint":"Токен авторизации Gitea API","tokenOff":"Токен не настроен","tokenOn":"Токен настроен","unsaved":"Не сохранено","updaterAvailable":"Доступно обновление: v{version}","updaterBtnCheck":"Проверить обновления","updaterBtnUpdate":"Обновить до v{version}","updaterCheckFailed":"Ошибка проверки реестра","updaterChecking":"Проверка реестра...","updaterCurrent":"Текущая версия: v{version}","updaterDesc":"Проверка npm-реестра на новые версии и обновление в один клик.","updaterSuccess":"Успешно обновлено до v{version}. Перезапустите DSH для применения.","updaterTitle":"Обновление плагина","updaterUpToDate":"Актуальная версия","updaterUpdating":"Обновление плагина...","upstream":"Ветка upstream:","username":"Имя пользователя","usernameHint":"Логин вашей учётной записи в Gitea","viewCommit":"Посмотреть коммит","viewInGitea":"Открыть в Gitea ↗","viewIssue":"Посмотреть задачу","viewPull":"Посмотреть PR","viewRepo":"Посмотреть репозиторий","webhookSecretEnv":"Переменная окружения для HMAC-секрета","webhookSecretEnvHint":"Имя переменной с секретным ключом для валидации входящих вебхуков","webhooks.desc":"Приём событий push, pull_request, issue с проверкой HMAC-SHA256 подписи","webhooks.endpoint":"URL вебхука: {url}","webhooks.no_events":"События вебхуков ещё не поступали","webhooks.recent":"Недавние события ({count})","webhooks.secret":"Секретный ключ (HMAC Secret)","webhooks.secret_hint":"Секрет для верификации подписи X-Gitea-Signature","webhooks.title":"Входящие вебхуки Gitea","worktreeBranch":"Ветка worktree"}}
@@ -1 +1 @@
1
- {"dsh-clinebot":{"accounts.active_badge":"Активен","accounts.add_btn":"Добавить аккаунт","accounts.apiBase":"Базовый URL API","accounts.apiKey":"API-ключ","accounts.cancel":"Отмена","accounts.cooldown":"Охлаждение: {s}с","accounts.delete":"Удалить","accounts.delete_confirm":"Удалить аккаунт «{name}»?","accounts.desc":"Управление учётными записями и API-ключами провайдеров для ClineBot.","accounts.edit":"Редактировать","accounts.empty":"Нет настроенных аккаунтов. Добавьте первый аккаунт выше.","accounts.env_placeholder":"Имя переменной окружения (напр. CLINE_API_KEY)","accounts.label_placeholder":"Название аккаунта (напр. Рабочий)","accounts.model":"Модель по умолчанию","accounts.pin_btn":"Сделать основным","accounts.pinned_badge":"Основной","accounts.provider":"Провайдер","accounts.quota":"Остаток квоты","accounts.rateLimit":"Лимит запросов","accounts.save":"Сохранить аккаунт","accounts.status":"Статус","accounts.title":"Аккаунты ClineBot","badge.key_missing":"Ключ отсутствует","badge.key_ok":"Ключ ✓ ({source})","badge.not_registered":"Не зарегистрирован","badge.offline":"Узел недоступен","badge.online":"Узел онлайн ({latency} мс)","badge.registered":"Зарегистрирован в DSH ({count} моделей)","diag.desc":"ClineBot автоматически регистрируется в моделях DSH при настройке ключа. Вы можете выполнить проверку связи или принудительную синхронизацию.","diag.resync_btn":"Принудительно синхронизировать с DSH","diag.resynced_msg":"Провайдер синхронизирован с моделями DSH ({count} моделей)","diag.resyncing":"Синхронизация…","diag.smoke_btn":"Выполнить экспресс-тест (Ping)","diag.smoke_ok":"Экспресс-тест пройден успешно! Задержка: {latency} мс","diag.smoke_testing":"Тестирование…","diag.title":"⚡ Диагностика и авторегистрация","diag.unregister_btn":"Снять регистрацию в DSH","diag.unregistered_msg":"Провайдер удалён из моделей DSH","diag.unregistering":"Удаление…","header.sub":"Подключение моделей подписки ClinePass ($9.99/мес). Совместимость с OpenAI API, автоматическое отслеживание скользящих лимитов и мгновенная авторегистрация в DSH.","header.title":"Провайдер ClineBot (ClinePass)","key.desc":"Ключ сохраняется непосредственно в хранилище учётных данных DSH (~/.dsh/.credentials.yaml) и никогда не отображается в открытом виде в конфигурациях.","key.empty_err":"Пожалуйста, введите API-ключ перед сохранением","key.env_label":"Имя переменной окружения: ","key.get_key":"Получить ключ в консоли app.cline.bot ↗","key.hide":"Скрыть","key.login_fast":"🚀 Быстрый вход через веб","key.login_fast: ":"🚀 Быстрый вход через веб","key.login_waiting":"Ожидание авторизации в браузере…","key.placeholder_empty":"Вставьте ключ ClinePass (cline_...)","key.placeholder_has":"••••••••••••••••••••••••","key.save":"Сохранить ключ","key.saved_msg":"Ключ сохранён в учётных данных DSH. Валидация: {status}","key.saving":"Сохранение…","key.show":"Показать","key.title":"🔑 Авторизация и API-ключ","models.all":"Все","models.auto_new":"Новинки","models.coding":"Только кодинг","models.desc":"Каталог синхронизируется напрямую с подпиской ClinePass. Модели новых тарифов подключаются автоматически. Снимите выбор, чтобы скрыть модель из выбора в чате DSH.","models.recommended":"Рекомендуемые","models.star":"Избранное","models.sync":"🔄 Проверить модели тарифа","models.synced_msg":"Модели подписки синхронизированы: {total} ({discovered} обнаружено из ClinePass)","models.syncing":"Проверка…","models.th_active":"Вкл","models.th_caps":"Возможности","models.th_ctx":"Контекст","models.th_id":"ID модели","models.th_name":"Имя модели","models.title":"🎯 Выбор моделей в DSH (активно {enabled} из {total})","models.vision":"Только с зрением","profiles.add":"Создать профиль","profiles.contextLimit":"Лимит контекста","profiles.default":"По умолчанию","profiles.delete":"Удалить профиль","profiles.desc":"Готовые наборы настроек, системных инструкций и разрешений.","profiles.maxTokens":"Максимум токенов","profiles.name":"Имя профиля","profiles.prompt":"Системный промпт","profiles.save":"Сохранить профиль","profiles.select":"Выбрать профиль","profiles.temperature":"Температура","profiles.title":"Профили настроек","quota.account":"Аккаунт: {email} · Тариф: {plan}","quota.desc":"Официальные скользящие лимиты запросов от ClinePass","quota.refresh":"Обновить квоты","quota.refreshed_msg":"Квоты подписки обновлены","quota.refreshing":"Обновление…","quota.remaining":"Осталось: {pct}%","quota.reset_at":"Сброс: {time}","quota.title":"📊 Квоты и лимиты запросов ClinePass","quota.used":"Использовано {pct}%","quota.window_5h":"⏱ 5-часовой скользящий лимит","quota.window_weekly":"📅 Еженедельный лимит","settings.advanced":"Дополнительно","settings.autoApprove":"Автоодобрение безопасных действий","settings.autoApproveDesc":"Автоматически выполнять команды чтения и безопасные операции без запроса подтверждения","settings.diffViewer":"Встроенный просмотрщик diff","settings.diffViewerDesc":"Отображать подробные различия кода перед применением правок","settings.general":"Основные","settings.loading":"Загрузка настроек ClineBot…","settings.models":"Модели","settings.retry":"Повторить","settings.saveFailed":"Не удалось сохранить настройки","settings.saved":"Настройки сохранены","settings.saving":"Сохранение…","settings.security":"Безопасность","settings.soundNotifications":"Звуковые уведомления","settings.soundNotificationsDesc":"Воспроизводить сигнал при завершении длительной задачи или ожидании ввода","settings.subtitle":"Интеграция автономного кодинг-ассистента ClineBot в DeepSeek Harness.","settings.telemetry":"Анонимная телеметрия","settings.telemetryDesc":"Отправлять отчёты о сбоях для улучшения стабильности","settings.title":"Настройки ClineBot","settings.unavailable":"Настройки ClineBot временно недоступны","stats.desc":"Локальный мониторинг запросов, сетевой задержки и расхода токенов через ClinePass.","stats.last_req":"Время последнего запроса","stats.latency":"Задержка последнего запроса","stats.requests":"Успешных / Всего запросов","stats.title":"📈 Телеметрия текущей сессии DSH","stats.tokens":"Оценочные токены сессии","status.connecting":"Подключение к ClineBot…","status.disconnected":"Связь с ClineBot отключена","status.error":"Ошибка инициализации ClineBot","status.idle":"Ожидание задачи","status.ready":"ClineBot готов к работе","status.running":"Выполняется задача ClineBot","subtitle":"Автономный агент ClineBot для глубокого рефакторинга и парного программирования","title":"ClineBot","tools.bash":"Выполнение команд терминала","tools.browser":"Управление браузером","tools.desc":"Разрешённые системные инструменты для выполнения задач агентом.","tools.disableAll":"Отключить все","tools.editor":"Умная правка кода","tools.enableAll":"Включить все","tools.fs":"Чтение и запись файлов","tools.mcp":"Внешние MCP-серверы","tools.title":"Инструменты ClineBot","update.btn":"Обновить сейчас","update.checking":"Проверка обновлений…","update.up_to_date":"Актуальная версия","update.updating":"Обновление…"}}
1
+ {"dsh-clinebot":{"accounts.active_badge":"Активен","accounts.add_btn":"Добавить аккаунт","accounts.apiBase":"Базовый URL API","accounts.apiKey":"API-ключ","accounts.cancel":"Отмена","accounts.cooldown":"Охлаждение: {s}с","accounts.delete":"Удалить","accounts.delete_confirm":"Удалить аккаунт «{name}»?","accounts.desc":"Управление учётными записями и API-ключами провайдеров для ClineBot.","accounts.edit":"Редактировать","accounts.empty":"Нет настроенных аккаунтов. Добавьте первый аккаунт выше.","accounts.env_placeholder":"Имя переменной окружения (напр. CLINE_API_KEY)","accounts.label_placeholder":"Название аккаунта (напр. Рабочий)","accounts.model":"Модель по умолчанию","accounts.pin_btn":"Сделать основным","accounts.pinned_badge":"Основной","accounts.provider":"Провайдер","accounts.quota":"Остаток квоты","accounts.rateLimit":"Лимит запросов","accounts.save":"Сохранить аккаунт","accounts.status":"Статус","accounts.title":"Аккаунты ClineBot","badge.key_missing":"Ключ отсутствует","badge.key_ok":"Ключ ✓ ({source})","badge.not_registered":"Не зарегистрирован","badge.offline":"Узел недоступен","badge.online":"Узел онлайн ({latency} мс)","badge.registered":"Зарегистрирован в DSH ({count} моделей)","diag.desc":"ClineBot автоматически регистрируется в моделях DSH при настройке ключа. Вы можете выполнить проверку связи или принудительную синхронизацию.","diag.resync_btn":"Принудительно синхронизировать с DSH","diag.resynced_msg":"Провайдер синхронизирован с моделями DSH ({count} моделей)","diag.resyncing":"Синхронизация…","diag.smoke_btn":"Выполнить экспресс-тест (Ping)","diag.smoke_ok":"Экспресс-тест пройден успешно! Задержка: {latency} мс","diag.smoke_testing":"Тестирование…","diag.title":"⚡ Диагностика и авторегистрация","diag.unregister_btn":"Снять регистрацию в DSH","diag.unregistered_msg":"Провайдер удалён из моделей DSH","diag.unregistering":"Удаление…","header.sub":"Подключение моделей подписки ClinePass ($9.99/мес). Совместимость с OpenAI API, автоматическое отслеживание скользящих лимитов и мгновенная авторегистрация в DSH.","header.title":"Провайдер ClineBot (ClinePass)","key.desc":"Ключ сохраняется непосредственно в хранилище учётных данных DSH (~/.dsh/.credentials.yaml) и никогда не отображается в открытом виде в конфигурациях.","key.empty_err":"Пожалуйста, введите API-ключ перед сохранением","key.env_label":"Имя переменной окружения: ","key.get_key":"Получить ключ в консоли app.cline.bot ↗","key.hide":"Скрыть","key.login_fast":"🚀 Быстрый вход через веб","key.login_fast: ":"🚀 Быстрый вход через веб","key.login_waiting":"Ожидание авторизации в браузере…","key.placeholder_empty":"Вставьте ключ ClinePass (cline_...)","key.placeholder_has":"••••••••••••••••••••••••","key.save":"Сохранить ключ","key.saved_msg":"Ключ сохранён в учётных данных DSH. Валидация: {status}","key.saving":"Сохранение…","key.show":"Показать","key.title":"🔑 Авторизация и API-ключ","models.all":"Все","models.auto_new":"Новинки","models.coding":"Только кодинг","models.desc":"Каталог синхронизируется напрямую с подпиской ClinePass. Модели новых тарифов подключаются автоматически. Снимите выбор, чтобы скрыть модель из выбора в чате DSH.","models.recommended":"Рекомендуемые","models.star":"Избранное","models.sync":"🔄 Проверить модели тарифа","models.synced_msg":"Модели подписки синхронизированы: {total} ({discovered} обнаружено из ClinePass)","models.syncing":"Проверка…","models.th_active":"Вкл","models.th_caps":"Возможности","models.th_ctx":"Контекст","models.th_id":"ID модели","models.th_name":"Имя модели","models.title":"🎯 Выбор моделей в DSH (активно {enabled} из {total})","models.vision":"Только с зрением","profiles.add":"Создать профиль","profiles.contextLimit":"Лимит контекста","profiles.default":"По умолчанию","profiles.delete":"Удалить профиль","profiles.desc":"Готовые наборы настроек, системных инструкций и разрешений.","profiles.maxTokens":"Максимум токенов","profiles.name":"Имя профиля","profiles.prompt":"Системный промпт","profiles.save":"Сохранить профиль","profiles.select":"Выбрать профиль","profiles.temperature":"Температура","profiles.title":"Профили настроек","quota.account":"Аккаунт: {email} · Тариф: {plan}","quota.desc":"Официальные скользящие лимиты запросов от ClinePass","quota.refresh":"Обновить квоты","quota.refreshed_msg":"Квоты подписки обновлены","quota.refreshing":"Обновление…","quota.remaining":"Осталось: {pct}%","quota.reset_at":"Сброс: {time}","quota.title":"📊 Квоты и лимиты запросов ClinePass","quota.used":"Использовано {pct}%","quota.window_5h":"⏱ 5-часовой скользящий лимит","quota.window_weekly":"📅 Еженедельный лимит","settings.advanced":"Дополнительно","settings.autoApprove":"Автоодобрение безопасных действий","settings.autoApproveDesc":"Автоматически выполнять команды чтения и безопасные операции без запроса подтверждения","settings.diffViewer":"Встроенный просмотрщик diff","settings.diffViewerDesc":"Отображать подробные различия кода перед применением правок","settings.general":"Основные","settings.loading":"Загрузка настроек ClineBot…","settings.models":"Модели","settings.retry":"Повторить","settings.saveFailed":"Не удалось сохранить настройки","settings.saved":"Настройки сохранены","settings.saving":"Сохранение…","settings.security":"Безопасность","settings.soundNotifications":"Звуковые уведомления","settings.soundNotificationsDesc":"Воспроизводить сигнал при завершении длительной задачи или ожидании ввода","settings.subtitle":"Интеграция автономного кодинг-ассистента ClineBot в DeepSeek Harness.","settings.telemetry":"Анонимная телеметрия","settings.telemetryDesc":"Отправлять отчёты о сбоях для улучшения стабильности","settings.title":"Настройки ClineBot","settings.unavailable":"Настройки ClineBot временно недоступны","stats.desc":"Локальный мониторинг запросов, сетевой задержки и расхода токенов через ClinePass.","stats.last_req":"Время последнего запроса","stats.latency":"Задержка последнего запроса","stats.requests":"Успешных / Всего запросов","stats.title":"📈 Телеметрия текущей сессии DSH","stats.tokens":"Оценочные токены сессии","status.connecting":"Подключение к ClineBot…","status.disconnected":"Связь с ClineBot отключена","status.error":"Ошибка инициализации ClineBot","status.idle":"Ожидание задачи","status.ready":"ClineBot готов к работе","status.running":"Выполняется задача ClineBot","subtitle":"Автономный агент ClineBot для глубокого рефакторинга и парного программирования","title":"ClineBot","tools.bash":"Выполнение команд терминала","tools.browser":"Управление браузером","tools.desc":"Разрешённые системные инструменты для выполнения задач агентом.","tools.disableAll":"Отключить все","tools.editor":"Умная правка кода","tools.enableAll":"Включить все","tools.fs":"Чтение и запись файлов","tools.mcp":"Внешние MCP-серверы","tools.title":"Инструменты ClineBot","update.available":"Доступно обновление: v{latestVersion} (текущая: v{currentVersion})","update.btn":"Обновить сейчас","update.checking":"Проверка обновлений…","update.done":"Успешно обновлено до v{version}! Перезапустите DSH для применения.","update.failed":"Ошибка обновления: {error}","update.up_to_date":"Актуальная версия","update.updating":"Обновление…"}}
@@ -1 +1 @@
1
- {"dsh-lanmode":{"activeMdns":"активен","adminAllowLabel":"Подсети с правами администратора (adminAllow)","adminAllowPh":"192.168.1.100, 10.0.0.0/24 (настройки и плагины)","allowLabel":"Разрешённые подсети IP (allow)","allowPh":"192.168.1.0/24, 127.0.0.1 (пусто = разрешить всем)","approvalNotification":"Требуется подтверждение действия","authPasswordLabel":"Пароль администратора (authPassword)","authPasswordPh":"Пароль для входа","authPasswordRefLabel":"Ссылка на секрет пароля (authPasswordRef)","authPasswordRefPh":"DSH_AUTH_PASSWORD или имя секрета в Credentials","authSessionDaysLabel":"Срок действия сессии в днях (authSessionDays)","authUserLabel":"Имя пользователя администратора (authUser)","badge.active":"LAN активен ({ip})","badge.local_only":"Только localhost","bindHostLabel":"Сетевой интерфейс для прослушивания (bindHost)","bindHostPh":"0.0.0.0 (все адаптеры), 192.168.1.x или 127.0.0.1","btn.refresh_ips":"Обновить список IP","btn.regenerate_pin":"Сгенерировать новый PIN","btn.save":"Сохранить настройки LAN","cardError":"⚠️ Ошибка карточки LanMode:","clipboardLabel":"Фолбэк navigator.clipboard.writeText для обычного HTTP","copied":"Скопировано ✔","copyUrl":"Скопировать URL","desktopMode":"Принудительный десктопный режим","desktopModeSub":"Отключает мобильную адаптацию и показывает полный десктопный UI","deviceCurrent":"Текущее устройство","deviceNoDevices":"Подключённых мобильных устройств не обнаружено","deviceRevoke":"Отозвать доступ","deviceRevokeAllConfirm":"Отозвать доступ всем мобильным устройствам, кроме текущего?","deviceRevokeAllOthers":"Отозвать доступ всем остальным","deviceRevokeConfirm":"Вы уверены, что хотите отозвать доступ для этого устройства?","devicesActions":"Действия","devicesIp":"IP-адрес","devicesLastSeen":"Последняя активность","devicesSub":"Список мобильных устройств и браузеров, авторизованных в LAN-режиме","devicesTitle":"Подключённые устройства","devicesUa":"Устройство / Браузер","diagnosticsLabel":"Включить эндпоинты диагностики (/dsh-lanmode/health, /probe)","directPortLabel":"Порт прямого подключения","downloadCa":"Корневой сертификат (.crt)","downloadProfile":"Профиль iOS (.mobileconfig)","err.bind_failed":"Не удалось занять порт {port}: {error}","err.invalid_pin":"Неверный PIN-код","field.bind_address":"Сетевой интерфейс (IP)","field.bind_address_hint":"IP-адрес в локальной сети (обычно 192.168.x.x или 10.x.x.x)","field.https_proxy":"Использовать HTTPS / reverse proxy","field.https_proxy_hint":"Включите, если используете Nginx/Caddy с SSL-сертификатом","field.pin_auth":"Защита PIN-кодом","field.pin_auth_hint":"Требовать 4-значный PIN-код при первом входе с мобильного устройства","field.pin_code":"Установленный PIN-код","field.port":"Порт","field.port_hint":"Порт веб-сервера (по умолчанию 3000)","field.token_ttl":"Срок действия сессии (часы)","field.token_ttl_hint":"Время хранения авторизации на мобильном устройстве","guestAllowLabel":"Подсети с гостевым доступом (guestAllow)","guestAllowPh":"192.168.2.0/24 (только чат, настройки заблокированы)","header.sub":"Удобный доступ к DeepSeek Harness из локальной сети Wi-Fi/LAN с мобильных устройств","header.title":"Локальный доступ (LAN Mode)","healthLink":"Открыть страницу диагностики (/dsh-lanmode/health) ↗","interfacesLabel":"Сетевой адаптер:","lanPinRefLabel":"Ссылка на секрет LAN PIN","lanPinRefPh":"LAN_PIN или имя секрета в Credentials","logout":"Выйти из системы","logoutConfirm":"Вы уверены, что хотите выйти из DSH?","mdnsAnnounceLabel":"Анонсировать домен через mDNS (Zeroconf / Bonjour)","mdnsNameLabel":"Имя домена mDNS (mdnsName)","mdnsNamePh":"dsh.local (обязательно оканчивается на .local)","mobileEnterLabel":"Клавиша Enter отправляет сообщение на сенсорной клавиатуре","modal.close":"Закрыть","modal.qr_sub":"Убедитесь, что смартфон подключен к той же Wi-Fi сети","modal.qr_title":"Сканируйте для подключения","modal.url_label":"Адрес для браузера:","modeAuto":"auto (автоопределение интерфейса)","modeDirect":"direct (прямое подключение)","modeLabel":"Режим локального доступа (mode)","modeLan":"lan (только локальная сеть)","modeLoopback":"loopback (только локальный компьютер)","modeProxy":"proxy (через реверс-прокси Nginx/Caddy)","ms":"мс","msg.pin_changed":"Новый PIN-код установлен: {pin}","msg.saved":"Параметры LAN-доступа сохранены","notifDenied":"Заблокированы пользователем","notifEnable":"Включить уведомления","notifGranted":"Разрешены ✔","notifStatus":"Статус уведомлений в браузере:","openQr":"Открыть QR-код","passwordAuthLabel":"Требовать обязательную авторизацию по логину и паролю","phoneConnected":"📱 Готов к работе со смартфона","portLabel":"Порт веб-сервера (port)","portPh":"По умолчанию 3000 (оставьте пустым для авто)","privilegedExtraLabel":"Дополнительные доверенные IP","privilegedExtraPh":"192.168.1.50, 10.0.0.5","pwaLabel":"Внедрять манифест PWA и мобильные мета-теги viewport","quickConnect":"Быстрое подключение со смартфона или планшета","quickQrTitle":"📱 Вход с мобильного устройства","randomUuidLabel":"Полифил crypto.randomUUID для обычного HTTP","retry":"Повторить","rttLabel":"Пинг","saveError":"Ошибка сохранения настроек: ","saveSettings":"Сохранить настройки LAN","saveSuccess":"Настройки успешно сохранены ✔","saving":"Сохранение…","secAccess":"Политика авторизации и LAN PIN","secAccessDesc":"Требование ввода PIN-кода для новых устройств в локальной сети","secAuth":"Аутентификация и защита входа","secAuthDesc":"Защита DSH логином и паролем для многопользовательских сетей","secMobile":"Мобильный интерфейс, mDNS и PWA","secMobileDesc":"Локальное обнаружение, мобильные жесты и веб-приложение (PWA)","secNetwork":"Сетевые интерфейсы и привязка портов","secNetworkDesc":"Настройка локальных сетевых адаптеров, портов и режимов привязки","secPolyfills":"Полифилы браузерных Web API (HTTP Shims)","secPolyfillsDesc":"Восстанавливает работу ограниченных API браузера на незащищённом HTTP","secRouting":"Маршрутизация и проксирование","secRoutingDesc":"Параметры прямого доступа и проксирования запросов локальной сети","secSecurity":"Безопасность и фильтрация IP","secSecurityDesc":"Разграничение прав по подсетям и контроль привилегированных действий","secTls":"Безопасное соединение (TLS / SSL)","secTlsDesc":"Шифрование трафика для работы аудио/видео и PWA на мобильных устройствах","secTunnel":"Удалённый доступ (Cloudflare Tunnel)","secTunnelDesc":"Безопасный доступ из интернета без белого IP и проброса портов","section.network":"Сетевые интерфейсы и адреса","section.network_desc":"Выберите сетевой адаптер для трансляции интерфейса в локальную сеть","section.qr":"Подключение по QR-коду","section.qr_desc":"Отсканируйте код камерой смартфона для мгновенного перехода в чат DSH","section.security":"Безопасность и пароли доступа","section.security_desc":"Защита входа в LAN-режиме с помощью PIN-кода или токена сессии","shareUrl":"Поделиться ↗","stat.connected_devices":"Подключено устройств","stat.last_device":"Последнее устройство","stat.traffic":"LAN трафик","status.listening":"Слушает на http://{ip}:{port}","status.stopped":"Остановлен","streamTimeoutLabel":"Таймаут стриминга ответов (сек)","streamTimeoutPh":"По умолчанию 120","sub":"mDNS (dsh.local), полифилы Web API, TLS для микрофона и PWA","subtitle":"Доступ по локальной сети и управление подключением","telemetryConns":"Активных WebSocket-соединений","telemetryRecv":"Принято данных","telemetryRtt":"Сетевая задержка (RTT)","telemetrySent":"Передано данных","telemetryTitle":"Телеметрия локальной сети","title":"Локальный и мобильный доступ (dsh-lanmode)","tlsCertLabel":"Путь к файлу сертификата (.crt)","tlsFiles":"files (пользовательские файлы сертификата и ключа)","tlsHostsLabel":"Домены и IP в сертификате","tlsHostsPh":"dsh.local, 192.168.1.111","tlsKeyLabel":"Путь к файлу закрытого ключа (.key)","tlsModeLabel":"Режим TLS","tlsOff":"off (обычный незашифрованный HTTP)","tlsSelfSigned":"self-signed (автоматический самоподписанный сертификат)","toolPrefix":"Инструмент: ","tunnelModeLabel":"Режим туннеля (tunnel)","tunnelNamed":"named (постоянный туннель по токену)","tunnelOff":"off (выключен)","tunnelPinLabel":"Требовать LAN PIN при входе через WAN-туннель Cloudflare","tunnelQuick":"quick (быстрый временный trycloudflare.com)","tunnelTokenRefLabel":"Ссылка на токен туннеля (tunnelTokenRef)","tunnelTokenRefPh":"CF_TUNNEL_TOKEN или имя секрета в Credentials","turnEndNotification":"Ассистент завершил ответ","unblockSettingsLabel":"Разблокировать ограничение настроек для loopback","unlockPrivilegedLabel":"Разрешить привилегированные вызовы (настройки, ключи) из LAN"}}
1
+ {"dsh-lanmode":{"activeMdns":"активен","adminAllowLabel":"Подсети с правами администратора (adminAllow)","adminAllowPh":"192.168.1.100, 10.0.0.0/24 (настройки и плагины)","allowLabel":"Разрешённые подсети IP (allow)","allowPh":"192.168.1.0/24, 127.0.0.1 (пусто = разрешить всем)","approvalNotification":"Требуется подтверждение действия","authPasswordLabel":"Пароль администратора (authPassword)","authPasswordPh":"Пароль для входа","authPasswordRefLabel":"Ссылка на секрет пароля (authPasswordRef)","authPasswordRefPh":"DSH_AUTH_PASSWORD или имя секрета в Credentials","authSessionDaysLabel":"Срок действия сессии в днях (authSessionDays)","authUserLabel":"Имя пользователя администратора (authUser)","badge.active":"LAN активен ({ip})","badge.local_only":"Только localhost","bindHostLabel":"Сетевой интерфейс для прослушивания (bindHost)","bindHostPh":"0.0.0.0 (все адаптеры), 192.168.1.x или 127.0.0.1","btn.refresh_ips":"Обновить список IP","btn.regenerate_pin":"Сгенерировать новый PIN","btn.save":"Сохранить настройки LAN","cardError":"⚠️ Ошибка карточки LanMode:","clipboardLabel":"Фолбэк navigator.clipboard.writeText для обычного HTTP","copied":"Скопировано ✔","copyUrl":"Скопировать URL","desktopMode":"Принудительный десктопный режим","desktopModeSub":"Отключает мобильную адаптацию и показывает полный десктопный UI","deviceCurrent":"Текущее устройство","deviceNicknamePrompt":"Введите псевдоним устройства:","deviceNoDevices":"Подключённых мобильных устройств не обнаружено","devicePlatformAndroid":"Android","devicePlatformIos":"iOS","devicePlatformLinux":"Linux","devicePlatformMacos":"macOS","devicePlatformWindows":"Windows","deviceRevoke":"Отозвать доступ","deviceRevokeAllConfirm":"Отозвать доступ всем мобильным устройствам, кроме текущего?","deviceRevokeAllOthers":"Отозвать доступ всем остальным","deviceRevokeConfirm":"Вы уверены, что хотите отозвать доступ для этого устройства?","deviceSetNickname":"Задать псевдоним","devicesActions":"Действия","devicesIp":"IP-адрес","devicesLastSeen":"Последняя активность","devicesSub":"Список мобильных устройств и браузеров, авторизованных в LAN-режиме","devicesTitle":"Подключённые устройства","devicesUa":"Устройство / Браузер","diagnosticsLabel":"Включить эндпоинты диагностики (/dsh-lanmode/health, /probe)","directPortLabel":"Порт прямого подключения","downloadCa":"Корневой сертификат (.crt)","downloadProfile":"Профиль iOS (.mobileconfig)","err.bind_failed":"Не удалось занять порт {port}: {error}","err.invalid_pin":"Неверный PIN-код","field.bind_address":"Сетевой интерфейс (IP)","field.bind_address_hint":"IP-адрес в локальной сети (обычно 192.168.x.x или 10.x.x.x)","field.https_proxy":"Использовать HTTPS / reverse proxy","field.https_proxy_hint":"Включите, если используете Nginx/Caddy с SSL-сертификатом","field.pin_auth":"Защита PIN-кодом","field.pin_auth_hint":"Требовать 4-значный PIN-код при первом входе с мобильного устройства","field.pin_code":"Установленный PIN-код","field.port":"Порт","field.port_hint":"Порт веб-сервера (по умолчанию 3000)","field.token_ttl":"Срок действия сессии (часы)","field.token_ttl_hint":"Время хранения авторизации на мобильном устройстве","guestAllowLabel":"Подсети с гостевым доступом (guestAllow)","guestAllowPh":"192.168.2.0/24 (только чат, настройки заблокированы)","header.sub":"Удобный доступ к DeepSeek Harness из локальной сети Wi-Fi/LAN с мобильных устройств","header.title":"Локальный доступ (LAN Mode)","healthLink":"Открыть страницу диагностики (/dsh-lanmode/health) ↗","interfacesLabel":"Сетевой адаптер:","lanPinRefLabel":"Ссылка на секрет LAN PIN","lanPinRefPh":"LAN_PIN или имя секрета в Credentials","logout":"Выйти из системы","logoutConfirm":"Вы уверены, что хотите выйти из DSH?","mdnsAnnounceLabel":"Анонсировать домен через mDNS (Zeroconf / Bonjour)","mdnsNameLabel":"Имя домена mDNS (mdnsName)","mdnsNamePh":"dsh.local (обязательно оканчивается на .local)","mobileEnterLabel":"Клавиша Enter отправляет сообщение на сенсорной клавиатуре","modal.close":"Закрыть","modal.qr_sub":"Убедитесь, что смартфон подключен к той же Wi-Fi сети","modal.qr_title":"Сканируйте для подключения","modal.url_label":"Адрес для браузера:","modeAuto":"auto (автоопределение интерфейса)","modeDirect":"direct (прямое подключение)","modeLabel":"Режим локального доступа (mode)","modeLan":"lan (только локальная сеть)","modeLoopback":"loopback (только локальный компьютер)","modeProxy":"proxy (через реверс-прокси Nginx/Caddy)","ms":"мс","msg.pin_changed":"Новый PIN-код установлен: {pin}","msg.saved":"Параметры LAN-доступа сохранены","notifDenied":"Заблокированы пользователем","notifEnable":"Включить уведомления","notifGranted":"Разрешены ✔","notifStatus":"Статус уведомлений в браузере:","openQr":"Открыть QR-код","passwordAuthLabel":"Требовать обязательную авторизацию по логину и паролю","phoneConnected":"📱 Готов к работе со смартфона","portLabel":"Порт веб-сервера (port)","portPh":"По умолчанию 3000 (оставьте пустым для авто)","privilegedExtraLabel":"Дополнительные доверенные IP","privilegedExtraPh":"192.168.1.50, 10.0.0.5","pwaLabel":"Внедрять манифест PWA и мобильные мета-теги viewport","quickConnect":"Быстрое подключение со смартфона или планшета","quickQrTitle":"📱 Вход с мобильного устройства","randomUuidLabel":"Полифил crypto.randomUUID для обычного HTTP","retry":"Повторить","rttLabel":"Пинг","saveError":"Ошибка сохранения настроек: ","saveSettings":"Сохранить настройки LAN","saveSuccess":"Настройки успешно сохранены ✔","saving":"Сохранение…","secAccess":"Политика авторизации и LAN PIN","secAccessDesc":"Требование ввода PIN-кода для новых устройств в локальной сети","secAuth":"Аутентификация и защита входа","secAuthDesc":"Защита DSH логином и паролем для многопользовательских сетей","secMobile":"Мобильный интерфейс, mDNS и PWA","secMobileDesc":"Локальное обнаружение, мобильные жесты и веб-приложение (PWA)","secNetwork":"Сетевые интерфейсы и привязка портов","secNetworkDesc":"Настройка локальных сетевых адаптеров, портов и режимов привязки","secPolyfills":"Полифилы браузерных Web API (HTTP Shims)","secPolyfillsDesc":"Восстанавливает работу ограниченных API браузера на незащищённом HTTP","secRouting":"Маршрутизация и проксирование","secRoutingDesc":"Параметры прямого доступа и проксирования запросов локальной сети","secSecurity":"Безопасность и фильтрация IP","secSecurityDesc":"Разграничение прав по подсетям и контроль привилегированных действий","secTls":"Безопасное соединение (TLS / SSL)","secTlsDesc":"Шифрование трафика для работы аудио/видео и PWA на мобильных устройствах","secTunnel":"Удалённый доступ (Cloudflare Tunnel)","secTunnelDesc":"Безопасный доступ из интернета без белого IP и проброса портов","section.network":"Сетевые интерфейсы и адреса","section.network_desc":"Выберите сетевой адаптер для трансляции интерфейса в локальную сеть","section.qr":"Подключение по QR-коду","section.qr_desc":"Отсканируйте код камерой смартфона для мгновенного перехода в чат DSH","section.security":"Безопасность и пароли доступа","section.security_desc":"Защита входа в LAN-режиме с помощью PIN-кода или токена сессии","settingsUnavailable":"Сервис настроек недоступен или не готов","shareUrl":"Поделиться ↗","stat.connected_devices":"Подключено устройств","stat.last_device":"Последнее устройство","stat.traffic":"LAN трафик","status.listening":"Слушает на http://{ip}:{port}","status.stopped":"Остановлен","streamTimeoutLabel":"Таймаут стриминга ответов (сек)","streamTimeoutPh":"По умолчанию 120","sub":"mDNS (dsh.local), полифилы Web API, TLS для микрофона и PWA","subtitle":"Доступ по локальной сети и управление подключением","telemetryConns":"Активных WebSocket-соединений","telemetryRecv":"Принято данных","telemetryRtt":"Сетевая задержка (RTT)","telemetrySent":"Передано данных","telemetryTitle":"Телеметрия локальной сети","title":"Локальный и мобильный доступ (dsh-lanmode)","tlsCertLabel":"Путь к файлу сертификата (.crt)","tlsFiles":"files (пользовательские файлы сертификата и ключа)","tlsHostsLabel":"Домены и IP в сертификате","tlsHostsPh":"dsh.local, 192.168.1.111","tlsKeyLabel":"Путь к файлу закрытого ключа (.key)","tlsModeLabel":"Режим TLS","tlsOff":"off (обычный незашифрованный HTTP)","tlsSelfSigned":"self-signed (автоматический самоподписанный сертификат)","toolPrefix":"Инструмент: ","tunnelModeLabel":"Режим туннеля (tunnel)","tunnelNamed":"named (постоянный туннель по токену)","tunnelOff":"off (выключен)","tunnelPinLabel":"Требовать LAN PIN при входе через WAN-туннель Cloudflare","tunnelQuick":"quick (быстрый временный trycloudflare.com)","tunnelTokenRefLabel":"Ссылка на токен туннеля (tunnelTokenRef)","tunnelTokenRefPh":"CF_TUNNEL_TOKEN или имя секрета в Credentials","turnEndNotification":"Ассистент завершил ответ","unblockSettingsLabel":"Разблокировать ограничение настроек для loopback","unlockPrivilegedLabel":"Разрешить привилегированные вызовы (настройки, ключи) из LAN","updaterCheckBtn":"Проверить обновления","updaterChecking":"Проверка…","updaterCurrentVersion":"Текущая версия:","updaterDesc":"Проверка и обновление @goodandready/dsh-lanmode до актуального релиза","updaterError":"Сбой проверки/установки обновления: ","updaterLatestVersion":"Последняя версия:","updaterRestartNote":"Перезапустите dsh-web (или процесс хоста DSH) для активации.","updaterSuccess":"Успешно обновлено! Перезапустите DSH для применения.","updaterTitle":"Обновления плагина","updaterUpToDate":"Актуальная версия ✔","updaterUpdateAvailable":"Доступно обновление!","updaterUpdateBtn":"Обновить сейчас","updaterUpdating":"Обновление…"}}
@@ -1 +1 @@
1
- {"dsh-task-tracker":{"field.base":"URL сервера Task Tracker","field.pass":"Пароль / Токен","field.passFile":"Путь к файлу пароля","field.user":"Пользователь","loading":"Загрузка настроек трекера…","passHint":"Токен доступа к API Task Tracker","passPlaceholder":"Секретный токен","save":"Сохранить","saved":"Настройки сохранены","saving":"Сохранение…","sub":"Интеграция с внутренним трекером задач и тикетов","subtitle":"API входящих задач (базовый URL и Basic-аутентификация)","title":"Трекер задач (Task Tracker)","unavailable":"Область настроек недоступна","userHint":"Логин сервисного аккаунта"}}
1
+ {"dsh-task-tracker":{"board.back":"В чат","board.backHint":"Закрыть трекер задач и вернуться в чат","field.base":"URL сервера Task Tracker","field.filePath":"Пользовательский путь к файлу tasks.json (необязательно)","field.filePathPlaceholder":"~/.dsh/task-tracker/tasks.json","field.pass":"Пароль / Токен","field.passFile":"Путь к файлу пароля","field.user":"Пользователь","filePath":"Путь к файлу","loading":"Загрузка настроек трекера…","passHint":"Токен доступа к API Task Tracker","passPlaceholder":"Секретный токен","save":"Сохранить","saved":"Настройки сохранены","saving":"Сохранение…","sessions":"Сессии","sub":"Интеграция с внутренним трекером задач и тикетов","subtitle":"API входящих задач (базовый URL и Basic-аутентификация)","tasks.active":"Активные","tasks.add":"+ Добавить","tasks.addTask":"+ Добавить задачу","tasks.all":"Все","tasks.backToChat":"К чату","tasks.cancel":"Отмена","tasks.changeIcon":"Сменить иконку","tasks.chatWithAgent":"Чат с агентом","tasks.close":"Закрыть","tasks.completed":"Выполнено","tasks.confirmDelete":"Удалить эту задачу?","tasks.create":"+ Создать","tasks.createFolder":"Создать папку","tasks.delete":"Удалить","tasks.descPlaceholder":"Подробное описание задачи…","tasks.description":"Описание","tasks.empty":"Задачи не найдены","tasks.emptyInFolder":"В папке нет задач ","tasks.folder":"Папка","tasks.folderBtn":"Папка","tasks.folders":"Папки","tasks.form.desc":"Описание","tasks.form.descPlaceholder":"Подробное описание задачи…","tasks.form.folder":"Папка","tasks.form.priority":"Приоритет","tasks.form.title":"Название","tasks.form.titlePlaceholder":"Название задачи","tasks.loadingTasks":"Загрузка задач…","tasks.markComplete":"Отметить как выполненную","tasks.markIncomplete":"Вернуть в работу","tasks.meta.author":"Автор:","tasks.meta.created":"Создано:","tasks.modal.title":"Задача","tasks.newFolderPrompt":"Название новой папки:","tasks.newPlaceholder":"Что нужно сделать?","tasks.newTask":"Новая задача","tasks.openAgentChat":"💬 Обсудить задачу с агентом","tasks.priority":"Приоритет","tasks.priority.high":"Высокий","tasks.priority.low":"Низкий","tasks.priority.medium":"Средний","tasks.priority.normal":"Обычный","tasks.priorityHigh":"Высокий","tasks.priorityLow":"Низкий","tasks.priorityMedium":"Средний","tasks.priorityNone":"Обычный","tasks.promptTemplate":"Шаблон промпта","tasks.quickAddPlaceholder":"Что нужно сделать? Нажмите Enter для добавления","tasks.search":"Поиск задач…","tasks.showAllFolders":"Показать все папки","tasks.startChatWithAgent":"💬 Начать чат с агентом","tasks.status":"Статус","tasks.status.completed":"Завершено","tasks.statusActive":"Активно","tasks.statusCompleted":"Выполнено","tasks.taskDetails":"Детали задачи","tasks.tasksCountSuffix":"задач","tasks.title":"Задачи","tasks.titleLabel":"Название *","title":"Трекер задач (Task Tracker)","unavailable":"Область настроек недоступна","updater.available":"Доступно обновление: v{v}","updater.checkFailed":"Не удалось проверить обновления","updater.checking":"Проверка обновлений…","updater.upToDate":"Актуальная версия","updater.updateFailed":"Ошибка при обновлении","updater.updateNow":"Обновить сейчас","updater.updated":"Успешно обновлено до v{v}. Перезапустите DSH для применения.","updater.updating":"Обновление…","updater.version":"Версия","userHint":"Логин сервисного аккаунта"}}
@@ -1 +1 @@
1
- {"@dsh-external/dsh-plugin-workshop":{"install":"Установить","installed":"Установлено","loading":"Загрузка…","search":"Поиск плагинов…","settings.description":"Просматривайте плагины и устанавливайте их в один клик.","settings.enable":"Включить мастерскую плагинов","settings.enableHint":"Отображать раздел мастерской плагинов в интерфейсе.","settings.title":"Мастерская плагинов (Workshop)","subtitle":"Каталог и поиск сторонних плагинов DSH","title":"Мастерская плагинов (Workshop)","uninstall":"Удалить"},"dsh-plugin-workshop":{"install":"Установить","installed":"Установлено","loading":"Загрузка…","search":"Поиск плагинов…","settings.description":"Просматривайте плагины и устанавливайте их в один клик.","settings.enable":"Включить мастерскую плагинов","settings.enableHint":"Отображать раздел мастерской плагинов в интерфейсе.","settings.title":"Мастерская плагинов (Workshop)","subtitle":"Каталог и поиск сторонних плагинов DSH","title":"Мастерская плагинов (Workshop)","uninstall":"Удалить"},"dsh-web-ui-market":{"badge.market":"dsh-market.com","cancel":"Отмена","command.title":"Скопируйте эту команду в терминал хоста DSH","conflict.text":"Каталог {dest} уже существует. Продолжение перезапишет файлы старой версией (действие необратимо).","conflict.title":"Каталог с таким именем уже существует","copied":"Скопировано","copyCommand":"Скопировать команду установки","empty":"Список витрины пуст (нет подключения к сети? нажмите «Повторить»)","install":"Установить","install.path":"Каталог установки: {path}","installFailed":"Ошибка установки: {reason}","installNow":"Установить сейчас","installSpecInvalid":"Неверный источник установки; поддерживаются только имена npm-пакетов и git-ссылки https://","installed":"Установлено","installedAt":"Установлено в {path}","installing":"Установка…","like":"Нравится","likeFailed":"Не удалось поставить лайк","liked":"Понравилось","loading":"Загрузка…","noMatch":"Ничего не найдено","offline":"Данные витрины недоступны","online":null,"openSite":"Открыть сайт витрины","preview":"Предпросмотр","remote.note":"В удалённых браузерах доступен только просмотр и копирование команд; установка в один клик требует локального браузера (loopback).","replace":"Заменить и установить","repository":"Исходный репозиторий","result.count":"Показано {shown} из {total}","retry":"Повторить","search.label":"Поиск по названию, автору или описанию…","settings.collapse":"Свернуть","settings.description":"Просматривайте скины, питомцев и плагины сообщества с dsh-market.com и устанавливайте их локально в один клик.","settings.discard":"Отменить изменения","settings.enable":"Включить карточку витрины","settings.enableHint":"Скрывает содержимое витрины, оставляя только переключатель.","settings.expand":"Развернуть","settings.inherit":"Наследовать","settings.invalidNumber":"Недопустимое значение","settings.notExposed":"Раздел недоступен (отсутствует пространство имён хоста)","settings.off":"Выкл","settings.on":"Вкл","settings.overridden":"Переопределяет умолчание","settings.readOnly":"Только чтение","settings.reset":"Сбросить","settings.save":"Сохранить","settings.saveFailed":"Не удалось сохранить","settings.saving":"Сохранение…","settings.title":"Витрина (Workshop)","settings.unsaved":"Несохранённые изменения","tab.pet":"Питомцы","tab.plugin":"Плагины","tab.skin":"Скины","votes":"{count} голосов"}}
1
+ {"@dsh-external/dsh-plugin-workshop":{"install":"Установить","installed":"Установлено","loading":"Загрузка…","search":"Поиск плагинов…","settings.description":"Просматривайте плагины и устанавливайте их в один клик.","settings.enable":"Включить мастерскую плагинов","settings.enableHint":"Отображать раздел мастерской плагинов в интерфейсе.","settings.title":"Мастерская плагинов (Workshop)","subtitle":"Каталог и поиск сторонних плагинов DSH","title":"Мастерская плагинов (Workshop)","uninstall":"Удалить"},"dsh-plugin-workshop":{"install":"Установить","installed":"Установлено","loading":"Загрузка…","search":"Поиск плагинов…","settings.description":"Просматривайте плагины и устанавливайте их в один клик.","settings.enable":"Включить мастерскую плагинов","settings.enableHint":"Отображать раздел мастерской плагинов в интерфейсе.","settings.title":"Мастерская плагинов (Workshop)","subtitle":"Каталог и поиск сторонних плагинов DSH","title":"Мастерская плагинов (Workshop)","uninstall":"Удалить"},"dsh-web-ui-market":{"badge.market":"dsh-market.com","cancel":"Отмена","command.title":"Скопируйте эту команду в терминал хоста DSH","conflict.text":"Каталог {dest} уже существует. Продолжение перезапишет файлы старой версией (действие необратимо).","conflict.title":"Каталог с таким именем уже существует","copied":"Скопировано","copyCommand":"Скопировать команду установки","empty":"Список витрины пуст (нет подключения к сети? нажмите «Повторить»)","install":"Установить","install.path":"Каталог установки: {path}","installFailed":"Ошибка установки: {reason}","installNow":"Установить сейчас","installSpecInvalid":"Неверный источник установки; поддерживаются только имена npm-пакетов и git-ссылки https://","installed":"Установлено","installedAt":"Установлено в {path}","installing":"Установка…","like":"Нравится","likeFailed":"Не удалось поставить лайк","liked":"Понравилось","loading":"Загрузка…","noMatch":"Ничего не найдено","offline":"Данные витрины недоступны","online":"В сети","openSite":"Открыть сайт витрины","preview":"Предпросмотр","remote.note":"В удалённых браузерах доступен только просмотр и копирование команд; установка в один клик требует локального браузера (loopback).","replace":"Заменить и установить","repository":"Исходный репозиторий","result.count":"Показано {shown} из {total}","retry":"Повторить","search.label":"Поиск по названию, автору или описанию…","settings.collapse":"Свернуть","settings.description":"Просматривайте скины, питомцев и плагины сообщества с dsh-market.com и устанавливайте их локально в один клик.","settings.discard":"Отменить изменения","settings.enable":"Включить карточку витрины","settings.enableHint":"Скрывает содержимое витрины, оставляя только переключатель.","settings.expand":"Развернуть","settings.inherit":"Наследовать","settings.invalidNumber":"Недопустимое значение","settings.notExposed":"Раздел недоступен (отсутствует пространство имён хоста)","settings.off":"Выкл","settings.on":"Вкл","settings.overridden":"Переопределяет умолчание","settings.readOnly":"Только чтение","settings.reset":"Сбросить","settings.save":"Сохранить","settings.saveFailed":"Не удалось сохранить","settings.saving":"Сохранение…","settings.title":"Витрина (Workshop)","settings.unsaved":"Несохранённые изменения","tab.pet":"Питомцы","tab.plugin":"Плагины","tab.skin":"Скины","votes":"{count} голосов"}}