feat: harden local shell, SFTP, and desktop session reliability
Finder-launched terminals now inherit a login PATH so tools like ollama resolve, destructive SFTP/editor actions require confirmation, and terminal search plus window dragging work again. SSH forwards and RDP sessions keep listeners and survive reconnect without FastPath crashes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
188f3556ed
commit
08696896f9
223 files changed
+13493
-3423
No files matched your search
+122
-38
@@ -90,6 +90,8 @@
|
||||
"terminal": "Терминал",
|
||||
"batch": "Пакетное выполнение",
|
||||
"newTerminal": "Новый терминал",
|
||||
"closeAria": "Закрыть {{title}}",
|
||||
"listAria": "Открытые вкладки",
|
||||
"kind": {
|
||||
"terminal": "Терминал",
|
||||
"sftp": "SFTP",
|
||||
@@ -105,7 +107,8 @@
|
||||
"closeRight": "Закрыть вкладки справа",
|
||||
"closeLeft": "Закрыть вкладки слева",
|
||||
"closeAll": "Закрыть все",
|
||||
"clone": "Дублировать вкладку"
|
||||
"clone": "Дублировать вкладку",
|
||||
"openSftp": "Открыть SFTP"
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
@@ -149,9 +152,9 @@
|
||||
"disconnect": "Отключиться"
|
||||
},
|
||||
"pro": {
|
||||
"upgrade": "Обновить Pro",
|
||||
"upgrade": "Обновить до Pro",
|
||||
"feature": "Возможности Pro",
|
||||
"unlock": "Разблокировать {{feature}}",
|
||||
"unlock": "Разблокировать расширенные функции Pro",
|
||||
"comingSoon": "Скоро",
|
||||
"activateSuccess": "Активировано",
|
||||
"activateFailed": "Сбой активации",
|
||||
@@ -160,28 +163,33 @@
|
||||
"invalidLicense": "Сбой активации: недействительная лицензия",
|
||||
"goUpgrade": "Обновить",
|
||||
"haveLicense": "Есть лицензия? Активировать",
|
||||
"title": "OpsXShell Pro · Оперативные возможности Pro",
|
||||
"subtitleComingSoon": "{{feature}} скоро · обновите Pro для раннего доступа",
|
||||
"subtitleUnlock": "Разблокировка: {{feature}}",
|
||||
"subtitleDefault": "Проброс портов, прокси, serial, AI, пакетное выполнение и рассылка",
|
||||
"title": "OpsXShell · Разблокировать Pro",
|
||||
"subtitleComingSoon": "Расширенные функции скоро · обновите до Pro для раннего доступа",
|
||||
"subtitleUnlock": "Разблокируются расширенные функции",
|
||||
"subtitleDefault": "Проброс портов, AI в терминале, пакетные операции, списки хостов и удалённый рабочий стол в Pro",
|
||||
"activated": "Pro активирован",
|
||||
"expiresAt": " · действует до {{date}}",
|
||||
"lifetime": " · бессрочная лицензия",
|
||||
"oneTimeFee": "Разовая покупка · бессрочно на этом устройстве · без подписки",
|
||||
"oneTimeFee": "Бесплатно / Pro год / Pro бессрочно",
|
||||
"pasteLicense": "Вставить лицензию",
|
||||
"activateButton": "Активировать",
|
||||
"clearLicense": "Очистить локальную лицензию",
|
||||
"paymentNote": "Оплата обрабатывается Waffo; это приложение не собирает данные карт.",
|
||||
"testDeviceId": "Тестовая среда · ID устройства: {{deviceId}}",
|
||||
"later": "Может быть позже",
|
||||
"viewPro": "Посмотреть Pro",
|
||||
"wallComingSoonSuffix": " · скоро",
|
||||
"wallUnlock": "Разблокировать {{feature}}",
|
||||
"wallMessageComingSoon": "Эта возможность Pro ещё в разработке. Обновите для раннего доступа.",
|
||||
"wallMessageDefault": "Эта функция требует OpsXShell Pro. Обновите, чтобы использовать её на этом устройстве.",
|
||||
"later": "Позже",
|
||||
"viewPro": "Смотреть тарифы Pro",
|
||||
"wallComingSoonSuffix": "скоро",
|
||||
"wallUnlock": "Разблокировать расширенные функции Pro",
|
||||
"wallMessageComingSoon": "Эта возможность входит в OpsXShell Pro и ещё дорабатывается. Обновите до Pro на год или бессрочно для раннего доступа.",
|
||||
"wallMessageDefault": "Проброс портов, AI в терминале, пакетный запуск, списки хостов и удалённый рабочий стол входят в Pro. Обновите до Pro на год или бессрочно, чтобы использовать на этом устройстве.",
|
||||
"checkoutUnavailable": "Оформление недоступно ({{status}})",
|
||||
"emailLabel": "Email",
|
||||
"emailRequired": "Введите email перед оформлением заказа",
|
||||
"claimPending": "Получение лицензии…",
|
||||
"invalidKeyFormat": "Неверный формат ключа — вставьте лицензию LIC-",
|
||||
"accountEmail": "Аккаунт: {{email}}",
|
||||
"freeTier": "Бесплатно",
|
||||
"proTier": "Pro",
|
||||
"proTier": "Профессиональная",
|
||||
"freeItems": {
|
||||
"ssh": "SSH-терминал",
|
||||
"sftp": "Менеджер файлов SFTP",
|
||||
@@ -191,22 +199,60 @@
|
||||
},
|
||||
"proItems": {
|
||||
"forward": "Проброс портов",
|
||||
"proxy": "Прокси сеанса / SOCKS",
|
||||
"proxy": "Прокси сессии / SOCKS",
|
||||
"serial": "Последовательный терминал",
|
||||
"ai": "Терминальный AI-ассистент",
|
||||
"batch": "Пакетное выполнение / синхронизация рассылки",
|
||||
"broadcast": "Синхронизация ввода рассылки",
|
||||
"importExport": "Массовый импорт/экспорт хостов",
|
||||
"desktop": "Удалённый рабочий стол RDP / VNC"
|
||||
}
|
||||
"ai": "AI-помощник в терминале",
|
||||
"batch": "Пакетный запуск / синхронный broadcast",
|
||||
"broadcast": "Синхронный ввод broadcast",
|
||||
"importExport": "Пакетный импорт/экспорт списка хостов",
|
||||
"desktop": "Удалённый рабочий стол (RDP / VNC)"
|
||||
},
|
||||
"planYearly": "Pro на год",
|
||||
"planYearlyDesc": "¥99 / год · 2 устройства",
|
||||
"planPerpetual": "Pro бессрочно",
|
||||
"planPerpetualDesc": "¥199 · 5 устройств · навсегда",
|
||||
"planTrial": "Pro пробный",
|
||||
"devices": "До {{count}} устройств",
|
||||
"goUpgradeYearly": "Купить Pro на год",
|
||||
"goUpgradePerpetual": "Купить Pro бессрочно",
|
||||
"activatedYearly": "Активирован Pro на год",
|
||||
"activatedPerpetual": "Активирован Pro бессрочно",
|
||||
"activatedTrial": "Активирован Pro пробный",
|
||||
"choosePlan": "Выбор: бесплатно / Pro год / Pro бессрочно",
|
||||
"planFreePrice": "¥0",
|
||||
"planFreeDesc": "SSH · SFTP · локальный терминал",
|
||||
"planFreeCta": "Текущий план",
|
||||
"planIncludesPro": "Все функции Pro",
|
||||
"planFree": "Бесплатно",
|
||||
"subtitleUnlockDetail": "Связанная возможность: {{feature}}",
|
||||
"wallUnlockComingSoon": "Расширенные функции Pro скоро",
|
||||
"wallMessageComingSoonFeature": "«{{feature}}» — расширенная функция Pro, ещё дорабатывается. Обновите до Pro на год или бессрочно для раннего доступа.",
|
||||
"wallMessageFeature": "«{{feature}}» — расширенная функция Pro. Обновите до Pro на год или бессрочно, чтобы использовать на этом устройстве."
|
||||
},
|
||||
"launcher": {
|
||||
"title": "Быстрый запуск",
|
||||
"description": "Сеансы, локальные оболочки и консоли устройств",
|
||||
"description": "Сессии, локальный Shell, рабочий стол, serial",
|
||||
"cards": {
|
||||
"quickConnect": { "title": "Быстрое подключение", "desc": "user@host:port" },
|
||||
"saveSession": { "title": "Сохранить сеанс", "desc": "Учётные данные, группы, прокси" },
|
||||
"serial": { "title": "Последовательный терминал", "desc": "Скорость (baud) и настройки порта" }
|
||||
"quickConnect": {
|
||||
"title": "Быстрое подключение",
|
||||
"desc": "user@host:port"
|
||||
},
|
||||
"saveSession": {
|
||||
"title": "Сохранить сеанс",
|
||||
"desc": "Учётные данные, группы, прокси"
|
||||
},
|
||||
"serial": {
|
||||
"title": "Последовательный терминал",
|
||||
"desc": "Скорость (baud) и настройки порта"
|
||||
},
|
||||
"rdp": {
|
||||
"title": "RDP рабочий стол",
|
||||
"desc": "Удалённый Windows"
|
||||
},
|
||||
"vnc": {
|
||||
"title": "VNC рабочий стол",
|
||||
"desc": "Удалённый графический"
|
||||
}
|
||||
},
|
||||
"sectionLocalShell": "Локальная оболочка",
|
||||
"sectionSavedSessions": "Сохранённые сеансы",
|
||||
@@ -220,6 +266,7 @@
|
||||
"forwardOpenRunning": "SOCKS5 работает (:{{port}}) · клик для управления · правый клик для копирования",
|
||||
"forwardStarted": "Проброс запущен",
|
||||
"forwardStartedDynamic": "SOCKS5 запущен: socks5://127.0.0.1:{{port}}",
|
||||
"forwardResumed": "Восстановлено перенаправлений: {{count}}",
|
||||
"socksStartFailed": "Сбой запуска: {{message}}",
|
||||
"socksStopFailed": "Сбой остановки: {{message}}",
|
||||
"socksCopied": "Скопировано socks5://127.0.0.1:{{port}}"
|
||||
@@ -240,7 +287,7 @@
|
||||
"typeDynamic": "Dynamic",
|
||||
"running": "Выполняется",
|
||||
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
|
||||
"remoteToLocal": "Удалённый {{remote}} → локальный {{local}}",
|
||||
"remoteToLocal": "удалённо {{bind}}:{{remote}} → {{host}}:{{local}}",
|
||||
"stats": "{{connections}} подкл. · ↑{{up}} · ↓{{down}}",
|
||||
"copyProxy": "Копировать прокси",
|
||||
"copyRule": "Дублировать правило",
|
||||
@@ -250,15 +297,15 @@
|
||||
"delete": "Удалить",
|
||||
"editTitle": "Изменить проброс",
|
||||
"addTitle": "Добавить проброс",
|
||||
"typeLocalDesc": "Локальный → удалённый",
|
||||
"typeRemoteDesc": "Удалённый → локальный",
|
||||
"typeLocalDesc": "Доступ к удалённому сервису",
|
||||
"typeRemoteDesc": "Открыть локальный сервис",
|
||||
"typeDynamicDesc": "SOCKS5",
|
||||
"selectType": "Тип",
|
||||
"drawerSubtitle": "Туннель через текущий SSH-сеанс",
|
||||
"ruleFields": "Подробности",
|
||||
"dynamicHint": "Локальный SOCKS5, по умолчанию 127.0.0.1:1080 (можно менять). Трафик выходит через публичный IP этого SSH-сервера.",
|
||||
"dynamicSingleHint": "Одно правило Dynamic на SSH-хост; измените порт прослушивания при остановке.",
|
||||
"dynamicPortHint": "Если порт занят, выберите другой локальный порт (напр. 1081).",
|
||||
"dynamicHint": "Локальный SOCKS5 (по умолчанию :1080). Трафик выходит через этот SSH.",
|
||||
"dynamicSingleHint": "Одно динамическое правило на SSH-хост; порт меняйте, когда остановлено.",
|
||||
"dynamicPortHint": "Если занят — другой порт (напр. 1081).",
|
||||
"ruleList": "Правила",
|
||||
"ruleListEmpty": "Правил Local / Remote пока нет",
|
||||
"addSection": "Добавить новое",
|
||||
@@ -292,17 +339,30 @@
|
||||
"internet": "Интернет",
|
||||
"localCaption": "Local: обращение к удалённому порту как к локальному.",
|
||||
"remoteCaption": "Remote: удалённый доступ пробрасывается к локальному сервису.",
|
||||
"dynamicCaption": "Dynamic: эта машина становится прокси SOCKS5, выходящим через публичный IP текущего SSH-сервера."
|
||||
"dynamicCaption": "Динамический: локальный SOCKS5 через выход этого SSH."
|
||||
},
|
||||
"ruleName": "Название",
|
||||
"ruleNamePlaceholder": "напр. MySQL",
|
||||
"localListenPort": "Локальный порт прослушивания",
|
||||
"localListenPortHint": "По умолчанию localhost — как ssh -L порт:…. Обычно достаточно порта.",
|
||||
"localBindAdvanced": "Дополнительно: сменить локальный bind",
|
||||
"localTargetPort": "Локальный целевой порт",
|
||||
"remoteTargetPort": "Удалённый целевой порт",
|
||||
"remoteTargetPort": "Целевой порт",
|
||||
"remoteListenPort": "Удалённый порт прослушивания",
|
||||
"remoteListenPortHint": "По умолчанию localhost на SSH-сервере — как ssh -R порт:…. Обычно достаточно порта.",
|
||||
"remoteListenAddress": "Удалённый listen",
|
||||
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
|
||||
"remoteListenAddressHint": "127.0.0.1 — только удалённый хост; 0.0.0.0 — удалённая LAN (нужен GatewayPorts).",
|
||||
"errorRemoteListenAddress": "Укажите корректный удалённый listen, напр. 127.0.0.1:18080",
|
||||
"localTargetAddress": "Локальная / LAN цель",
|
||||
"localTargetAddressPlaceholder": "127.0.0.1:8080",
|
||||
"localTargetAddressHint": "На локальный/LAN сервис, напр. 127.0.0.1:8080. Не используйте 0.0.0.0.",
|
||||
"viaSessionRemote": "Слушать на {{target}} (по умолчанию localhost)",
|
||||
"errorRemoteListenPort": "Укажите корректный удалённый порт прослушивания (1–65535)",
|
||||
"errorLocalTargetAddress": "Укажите корректную локальную/LAN цель, напр. 127.0.0.1:8080",
|
||||
"portPlaceholder": "напр. 3306",
|
||||
"remoteHost": "Удалённый хост",
|
||||
"remoteHostPlaceholder": "localhost или IP",
|
||||
"remoteHost": "Целевой хост",
|
||||
"remoteHostPlaceholder": "127.0.0.1",
|
||||
"socksRuleName": "Прокси SOCKS5",
|
||||
"defaultLocalName": "Локальный проброс",
|
||||
"defaultRemoteName": "Удалённый проброс",
|
||||
@@ -316,11 +376,35 @@
|
||||
"deleteConfirm": "Удалить это правило?",
|
||||
"errorNamePort": "Введите имя и корректный порт (1–65535)",
|
||||
"errorTargetPort": "Введите корректный целевой порт (1–65535)",
|
||||
"errorRemoteHost": "Введите удалённый хост",
|
||||
"errorRemoteHost": "Укажите целевой хост (относительно SSH-сервера)",
|
||||
"errorNotConnected": "Нет подключения",
|
||||
"errorStartFailed": "Сбой запуска",
|
||||
"errorStopFailed": "Сбой остановки",
|
||||
"errorSocksRunning": "SOCKS5 уже работает",
|
||||
"copySuffix": "Копировать"
|
||||
"copySuffix": "Копировать",
|
||||
"remoteBindHint": "0.0.0.0 нужен GatewayPorts; иначе часто только 127.0.0.1. Цель не должна быть 0.0.0.0.",
|
||||
"localToRemote": "локально {{bind}}:{{local}} → удалённо {{host}}:{{remote}}",
|
||||
"localToRemotePort": "локально :{{local}} → удалённо {{host}}:{{remote}}",
|
||||
"remoteHostHint": "Относительно SSH-сервера. Сам хост — 127.0.0.1, LAN — достижимый IP. Не 0.0.0.0.",
|
||||
"localBindHost": "Локальный bind",
|
||||
"localBindHostPlaceholder": "127.0.0.1",
|
||||
"localBindHostHint": "По умолчанию только этот ПК. 0.0.0.0 или LAN IP — доступ из сети.",
|
||||
"errorTargetHostInvalid": "Цель не может быть 0.0.0.0 — укажите 127.0.0.1 или достижимый IP",
|
||||
"listenAddress": "Локальный listen",
|
||||
"listenAddressPlaceholder": "127.0.0.1:8080",
|
||||
"listenAddressHint": "По умолчанию только этот ПК; 0.0.0.0 разрешает LAN.",
|
||||
"targetAddress": "Удалённая цель",
|
||||
"targetAddressPlaceholder": "127.0.0.1:80",
|
||||
"targetAddressHint": "С точки зрения SSH-сервера. Сервис на нём — 127.0.0.1:порт.",
|
||||
"errorListenAddress": "Укажите корректный listen, напр. 127.0.0.1:8080",
|
||||
"errorTargetAddress": "Укажите корректную цель, напр. 127.0.0.1:80",
|
||||
"targetAddressHintVia": "Через {{target}}. Сервис на том хосте — 127.0.0.1:порт (новый порт не открывается).",
|
||||
"viaSession": "Через сессию {{target}}",
|
||||
"remoteToLocalPort": "удал. :{{remote}} → {{host}}:{{local}}",
|
||||
"remoteBindAdvanced": "Дополнительно: сменить remote bind",
|
||||
"remoteBindHost": "Remote bind",
|
||||
"remoteBindHostPlaceholder": "127.0.0.1",
|
||||
"remoteBindHostHint": "По умолчанию только на SSH-сервере. 0.0.0.0 требует GatewayPorts; без него sshd часто тихо слушает только 127.0.0.1.",
|
||||
"remoteGatewayPortsWarning": "Запрошен remote-listen 0.0.0.0. Без GatewayPorts sshd часто молча слушает только 127.0.0.1."
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,12 @@
|
||||
"passwordOptional": "Пароль (необязательно)",
|
||||
"width": "Ширина",
|
||||
"height": "Высота",
|
||||
"rdpFootnote": "Нативный IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS; тайм-аут рукопожатия 45 с. Проверка сертификата во время разработки ослаблена.",
|
||||
"vncFootnote": "Нативный vnc-rs RFB с декодированием Tight JPEG; буфер обмена передаётся в UTF-8 (очень старые серверы могут искажать текст).",
|
||||
"rdpFootnote": "В полноэкранном или развёрнутом режиме удалённое разрешение запрашивается под текущую область окна. Начальный размер можно выбрать и до подключения. Проверка сертификата сейчас ослаблена для разработки.",
|
||||
"vncFootnote": "У большинства VNC-серверов удалённое разрешение фиксировано; полноэкранный режим только масштабирует изображение локально. Предпочтительный размер при подключении носит справочный характер. Буфер обмена отправляется в UTF-8.",
|
||||
"errorHostRequired": "Введите адрес хоста",
|
||||
"errorUsernameRequired": "Введите имя пользователя"
|
||||
"errorUsernameRequired": "Введите имя пользователя",
|
||||
"resolution": "Разрешение",
|
||||
"resolutionCustom": "Свой размер"
|
||||
},
|
||||
"toolbar": {
|
||||
"pasteClipboard": "Вставить локальный буфер обмена на удалённый сервер",
|
||||
@@ -28,7 +30,12 @@
|
||||
"openShareDir": "Открыть общую папку локально (Downloads)",
|
||||
"openShareDirAria": "Открыть общую папку",
|
||||
"disconnect": "Отключиться",
|
||||
"disconnectAria": "Отключиться"
|
||||
"disconnectAria": "Отключиться",
|
||||
"fullscreen": "Полный экран",
|
||||
"fullscreenAria": "Развернуть на весь экран",
|
||||
"exitFullscreen": "Выйти из полного экрана",
|
||||
"exitFullscreenAria": "Выйти из полного экрана",
|
||||
"exitFullscreenHint": "Esc / F11 — выход"
|
||||
},
|
||||
"status": {
|
||||
"connecting": "Подключение…",
|
||||
|
||||
@@ -39,7 +39,9 @@
|
||||
"closed": "Подключение закрыто",
|
||||
"dnsFailed": "Не удалось разрешить имя хоста",
|
||||
"refused": "В подключении отказано",
|
||||
"disconnected": "Отключено"
|
||||
"disconnected": "Отключено",
|
||||
"keepaliveFailed": "SSH keep-alive несколько раз не удался; соединение закрыто",
|
||||
"idleKicked": "Удалённая оболочка завершилась по таймауту простоя (TMOUT)"
|
||||
},
|
||||
"auth": {
|
||||
"failed": "Сбой аутентификации. Проверьте имя пользователя и пароль.",
|
||||
@@ -68,7 +70,10 @@
|
||||
"forward": {
|
||||
"failed": "Сбой настройки проброса портов",
|
||||
"bindFailed": "Не удалось привязать порт",
|
||||
"alreadyInUse": "Порт уже занят"
|
||||
"alreadyInUse": "Локальный порт уже занят. Остановите этот проброс или другой процесс на порту, затем запустите снова.",
|
||||
"remoteDenied": "Сервер отклонил удалённый проброс (AllowTcpForwarding / PermitListen, порт занят или ограничение bind). Слушаем только 127.0.0.1 на удалённой стороне.",
|
||||
"remoteDeniedPrivileged": "Отклонён привилегированный порт (<1024). Используйте ≥1024 или root и проверьте AllowTcpForwarding / PermitListen.",
|
||||
"invalidTargetHost": "Цель не может быть 0.0.0.0 — укажите 127.0.0.1 или доступный внутренний IP"
|
||||
},
|
||||
"sftp": {
|
||||
"connectFailed": "Сбой SFTP-подключения",
|
||||
@@ -80,7 +85,15 @@
|
||||
"writeFailed": "Сбой сохранения",
|
||||
"renameFailed": "Сбой переименования",
|
||||
"chmodFailed": "Не удалось обновить права доступа",
|
||||
"apiUnavailable": "SFTP API недоступен"
|
||||
"apiUnavailable": "SFTP API недоступен",
|
||||
"channelFailed": "Не удалось открыть канал SFTP (лимит сервера или занятая сессия). Переподключитесь",
|
||||
"sessionGone": "Сессия SFTP завершена; переподключитесь",
|
||||
"busy": "Идёт передача файла. Повторите позже.",
|
||||
"editTooLarge": "Файл слишком большой для текстового редактора (макс. ~2 МБ). Скачайте и откройте локально.",
|
||||
"editBinary": "Файл похож на двоичный и не открывается в текстовом редакторе",
|
||||
"editNotUtf8": "Удалённый файл не является допустимым текстом UTF-8",
|
||||
"transferCancelled": "Передача отменена",
|
||||
"diskFull": "Недостаточно места на диске (локально или удалённо)"
|
||||
},
|
||||
"session": {
|
||||
"notFound": "Сеанс не найден",
|
||||
|
||||
@@ -69,17 +69,17 @@
|
||||
"confirm": "Удалить"
|
||||
},
|
||||
"welcome": {
|
||||
"tagline": "Удалённый терминал · SFTP · Проброс портов",
|
||||
"tagline": "Просто и по делу · терминал · файлы · рабочий стол",
|
||||
"sectionStart": "Начало работы",
|
||||
"sectionDesktop": "Удалённый рабочий стол",
|
||||
"sectionRecent": "Недавние сеансы",
|
||||
"quickConnect": {
|
||||
"title": "Быстрое подключение",
|
||||
"desc": "Разовое SSH; не сохраняется в библиотеке"
|
||||
"desc": "Разовый SSH — не сохраняется в библиотеке"
|
||||
},
|
||||
"newSession": {
|
||||
"title": "Новый сеанс",
|
||||
"desc": "Сохраняйте хосты; двойной клик в боковой панели для подключения"
|
||||
"desc": "Сохраните хост — двойной клик в сайдбаре для подключения"
|
||||
},
|
||||
"localShell": {
|
||||
"title": "Локальная оболочка",
|
||||
@@ -167,7 +167,9 @@
|
||||
"jumpHost": "Jump-хост (необязательно)",
|
||||
"jumpNone": "Без jump-хоста",
|
||||
"jumpNoneAlt": "Без jump-хоста",
|
||||
"jumpHint": "Сохранённый сеанс можно использовать как jump-хост"
|
||||
"jumpHint": "Сохранённый сеанс можно использовать как jump-хост",
|
||||
"resolution": "Разрешение",
|
||||
"resolutionCustom": "Свой размер"
|
||||
},
|
||||
"batch": {
|
||||
"title": "Пакетное выполнение",
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
{
|
||||
"nav": {
|
||||
"general": "Рабочее пространство",
|
||||
"generalDesc": "Макет и ресурсы",
|
||||
"appearance": "Внешний вид",
|
||||
"appearanceDesc": "Тема и язык",
|
||||
"general": "Основные",
|
||||
"generalDesc": "Тема, язык и макет",
|
||||
"terminal": "Терминал",
|
||||
"terminalDesc": "Шрифт и цвета",
|
||||
"shortcuts": "Горячие клавиши",
|
||||
@@ -15,11 +13,13 @@
|
||||
"ai": "AI-модели",
|
||||
"aiDesc": "AI-провайдеры",
|
||||
"about": "О приложении",
|
||||
"aboutDesc": "Версия и данные"
|
||||
"aboutDesc": "Версия и данные",
|
||||
"account": "Аккаунт",
|
||||
"accountDesc": "Email, лицензия и устройство"
|
||||
},
|
||||
"title": "Настройки",
|
||||
"search": {
|
||||
"placeholder": "Поиск по настройкам..."
|
||||
"placeholder": "Поиск настроек…"
|
||||
},
|
||||
"language": {
|
||||
"label": "Язык",
|
||||
@@ -89,7 +89,7 @@
|
||||
"ssh": {
|
||||
"connection": "Подключение",
|
||||
"keepAlive": "Keep-alive",
|
||||
"keepAliveDesc": "Отправлять keep-alive при простое для уменьшения разрывов",
|
||||
"keepAliveDesc": "Отправлять SSH keep-alive в простое; отключать только после нескольких сбоев",
|
||||
"autoReconnect": "Авто-переподключение",
|
||||
"autoReconnectDesc": "Автоматически повторять после неожиданного разрыва",
|
||||
"timeout": "Тайм-аут подключения",
|
||||
@@ -102,7 +102,9 @@
|
||||
"maxBackground": "Лимит фоновых подключений",
|
||||
"maxBackgroundDesc": "Вытеснять давно не использованные подключения при превышении лимита",
|
||||
"suspend": "Фоновая приостановка",
|
||||
"suspendDesc": "Минуты до освобождения активных каналов, когда вкладка в фоне"
|
||||
"suspendDesc": "Через сколько минут приостанавливать простаивающие фоновые вкладки (активные Shell/SFTP остаются)",
|
||||
"keepAliveInterval": "Интервал keep-alive (сек)",
|
||||
"keepAliveIntervalDesc": "Как часто опрашивать сервер (как ClientAliveInterval). При нестабильной сети — ≤15 с"
|
||||
},
|
||||
"security": {
|
||||
"credentials": "Защита учётных данных",
|
||||
@@ -119,7 +121,7 @@
|
||||
"clearConfirm": "Очистить все известные ключи хостов? При следующем подключении запрос появится снова."
|
||||
},
|
||||
"about": {
|
||||
"tagline": "Лёгкий нативный терминал эксплуатации SSH / SFTP",
|
||||
"tagline": "Простой и удобный нативный терминал для эксплуатации",
|
||||
"appVersion": "Приложение v{{version}}",
|
||||
"copyVersion": "Копировать сведения о версии",
|
||||
"runtime": "Среда выполнения",
|
||||
@@ -127,8 +129,9 @@
|
||||
"localData": "Локальные данные",
|
||||
"sessionsSettings": "Сеансы и настройки",
|
||||
"masterKeyPath": "Мастер-ключ",
|
||||
"privacyNote": "Пароли и парольные фразы ключей шифруются AES-256-GCM в Rust. OpsXShell не сохраняет историю команд терминала.",
|
||||
"license": "Лицензия MIT · Rust · XTerm.js"
|
||||
"privacyNote": "Пароли и passphrase шифруются в Rust (AES-256-GCM). Без истории команд и без аудита-бастиона.",
|
||||
"license": "Лицензия MIT · Rust · XTerm.js",
|
||||
"logPath": "Журнал приложения"
|
||||
},
|
||||
"ai": {
|
||||
"presets": "Пресеты провайдеров",
|
||||
@@ -162,13 +165,42 @@
|
||||
"apiKeySaveFailed": "Не удалось сохранить API-ключ",
|
||||
"providerNotFound": "Провайдер не найден",
|
||||
"modelCatalogReadFailed": "Не удалось прочитать каталог моделей",
|
||||
"catalogUnavailable": "models.dev недоступен"
|
||||
"catalogUnavailable": "models.dev недоступен",
|
||||
"family": {
|
||||
"openai_compatible": "Совместимые с OpenAI",
|
||||
"standalone": "Нативные API",
|
||||
"plan": "Подписки",
|
||||
"local": "Локальные",
|
||||
"custom": "Свой"
|
||||
}
|
||||
},
|
||||
"family": {
|
||||
"openai_compatible": "Совместимый с OpenAI",
|
||||
"standalone": "────────",
|
||||
"plan": "План",
|
||||
"local": "Self-hosted",
|
||||
"custom": "Своё"
|
||||
"account": {
|
||||
"title": "Account",
|
||||
"email": "Email",
|
||||
"emailDesc": "Used for checkout and license claims",
|
||||
"plan": "Current plan",
|
||||
"planFree": "Free",
|
||||
"planYearly": "Pro на год",
|
||||
"planPerpetual": "Pro бессрочно",
|
||||
"planTrial": "Pro пробный",
|
||||
"expires": "Expires {{date}}",
|
||||
"lifetime": "Lifetime",
|
||||
"devices": "Seats: up to {{count}} devices",
|
||||
"deviceId": "This device ID",
|
||||
"saveEmail": "Save email",
|
||||
"activate": "Activate license",
|
||||
"pasteLicense": "Paste LIC- license key",
|
||||
"clear": "Clear local license",
|
||||
"deactivate": "Deactivate this device",
|
||||
"upgrade": "Upgrade",
|
||||
"saved": "Saved",
|
||||
"activateOk": "Activated",
|
||||
"deviceList": "Привязанные устройства",
|
||||
"loadingDevices": "Загрузка устройств…",
|
||||
"noDevices": "Нет привязанных устройств",
|
||||
"thisDevice": "Это устройство",
|
||||
"removeDevice": "Отвязать",
|
||||
"deviceRemoved": "Устройство отвязано",
|
||||
"seatFull": "Все места заняты. Отвяжите другое устройство перед активацией на новой машине."
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,9 @@
|
||||
"local": "Локально",
|
||||
"remote": "Удалённо",
|
||||
"notConnectedTitle": "Нет подключения к удалённому серверу",
|
||||
"notConnectedDesc": "Сначала подключите SSH-сеанс, чтобы использовать SFTP",
|
||||
"ariaLabel": "Панель файлов: {{title}}"
|
||||
"notConnectedDesc": "Сначала подключите SSH — потом файлы и правки",
|
||||
"ariaLabel": "Панель файлов: {{title}}",
|
||||
"reconnectResumeDesc": "Соединение потеряно. Переподключение вернёт в {{path}}"
|
||||
},
|
||||
"connection": {
|
||||
"selectServer": "Выберите сервер",
|
||||
@@ -12,7 +13,9 @@
|
||||
"createSessionHint": "Сначала создайте сеанс на боковой панели",
|
||||
"reconnect": "Переподключиться",
|
||||
"notConnected": "Нет подключения",
|
||||
"connecting": "Подключение..."
|
||||
"connecting": "Подключение...",
|
||||
"resumeHint": "После переподключения вернёмся в {{path}}",
|
||||
"reconnectingResume": "Переподключение и восстановление {{path}}…"
|
||||
},
|
||||
"errors": {
|
||||
"notConnected": "SFTP не подключён",
|
||||
@@ -23,19 +26,14 @@
|
||||
"selectDownloadFiles": "Сначала выберите файлы для скачивания",
|
||||
"uploadFailed": "Сбой загрузки",
|
||||
"downloadFailed": "Сбой скачивания",
|
||||
"fileError": "{{fileName}}: {{message}}"
|
||||
"fileError": "{{fileName}}: {{message}}",
|
||||
"mkdirFailed": "Не удалось создать папку"
|
||||
},
|
||||
"toolbar": {
|
||||
"upload": "Загрузить",
|
||||
"uploadAria": "Загрузить",
|
||||
"download": "Скачать",
|
||||
"downloadAria": "Скачать",
|
||||
"downloadNeedSelection": "Сначала выберите удалённые файлы",
|
||||
"downloadHint": "Скачать выбранные удалённые файлы",
|
||||
"refresh": "Обновить",
|
||||
"refreshAria": "Обновить",
|
||||
"refreshAria": "Обновить эту панель",
|
||||
"newFolder": "Новая папка",
|
||||
"newFolderAria": "Новая папка"
|
||||
"newFolderAria": "Создать папку на этой панели"
|
||||
},
|
||||
"sort": {
|
||||
"name": "Имя",
|
||||
@@ -55,7 +53,8 @@
|
||||
"hideHidden": "Скрыть dot-файлы (.xxx)",
|
||||
"showHiddenAria": "Показать скрытые файлы",
|
||||
"hideHiddenAria": "Скрыть dot-файлы",
|
||||
"searchAria": "Поиск в {{title}}"
|
||||
"searchAria": "Поиск в {{title}}",
|
||||
"upAtRoot": "Уже в корне"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Загрузка...",
|
||||
@@ -63,7 +62,8 @@
|
||||
"filtered": "Показано {{shown}} / {{total}}",
|
||||
"hiddenCount": "{{total}} объектов ({{hidden}} скрыто)",
|
||||
"total": "Объектов: {{count}}",
|
||||
"filterHint": "Фильтр: {{query}}"
|
||||
"filterHint": "Фильтр: {{query}}",
|
||||
"refreshing": "Обновление..."
|
||||
},
|
||||
"empty": {
|
||||
"dirTitle": "Пустой каталог",
|
||||
@@ -99,7 +99,6 @@
|
||||
"download": "Скачать",
|
||||
"edit": "Изменить",
|
||||
"rename": "Переименовать",
|
||||
"copyPath": "Копировать путь",
|
||||
"properties": "Свойства",
|
||||
"permissions": "Права доступа",
|
||||
"delete": "Удалить"
|
||||
@@ -116,7 +115,18 @@
|
||||
"chmodTitle": "Изменить права доступа",
|
||||
"chmodApply": "Применить",
|
||||
"pickUploadTitle": "Выберите файлы или папки для загрузки",
|
||||
"pickUploadRzTitle": "Выберите файл для загрузки (rz)"
|
||||
"pickUploadRzTitle": "Выберите файл для загрузки (rz)",
|
||||
"overwriteTitle": "Перезаписать существующие файлы?",
|
||||
"overwriteConfirm": "Перезаписать",
|
||||
"overwriteSkip": "Пропустить",
|
||||
"overwriteOneRemote": "«{{name}}» уже есть на удалённой стороне. Перезаписать?",
|
||||
"overwriteOneLocal": "«{{name}}» уже есть локально. Перезаписать?",
|
||||
"overwriteManyRemote": "На удалённой стороне уже есть {{count}} одноимённых. Перезаписать все?",
|
||||
"overwriteManyLocal": "Локально уже есть {{count}} одноимённых. Перезаписать все?",
|
||||
"overwriteMore": "…и ещё {{count}}",
|
||||
"deleteTitle": "Подтвердите удаление",
|
||||
"deleteMessage": "Удалить {{count}} элемент(ов): {{names}}",
|
||||
"deleteRecursiveWarn": "Есть каталоги. Удаление рекурсивное и необратимо."
|
||||
},
|
||||
"properties": {
|
||||
"name": "Имя",
|
||||
@@ -152,27 +162,41 @@
|
||||
"statusDone": "Готово",
|
||||
"statusFailed": "Сбой",
|
||||
"statusCancelled": "Отменено",
|
||||
"dropUpload": "Загрузить в {{path}}",
|
||||
"dropDownload": "Скачать в {{path}}"
|
||||
"dropUpload": "Отпустите здесь, чтобы загрузить в {{path}}",
|
||||
"dropDownload": "Отпустите здесь, чтобы скачать в {{path}}",
|
||||
"railAria": "Передача между локальным и удалённым",
|
||||
"railUpload": "Загрузить выбранные локальные файлы (или выбрать файлы, если ничего не выбрано)",
|
||||
"railDownload": "Скачать выбранные удалённые файлы локально",
|
||||
"railUploadAria": "Загрузить на удалённый",
|
||||
"railDownloadAria": "Скачать локально",
|
||||
"railDownloadNeedSelection": "Сначала выберите удалённые файлы",
|
||||
"retry": "Повторить"
|
||||
},
|
||||
"editor": {
|
||||
"readFailed": "Сбой чтения",
|
||||
"saveFailed": "Сбой сохранения",
|
||||
"unsavedClose": "Есть несохранённые изменения. Всё равно закрыть?",
|
||||
"unsavedTitle": "Несохранённые изменения",
|
||||
"discardAndClose": "Отменить и закрыть",
|
||||
"reloadTitle": "Перезагрузить",
|
||||
"discardAndReload": "Отменить и перезагрузить",
|
||||
"saving": "Сохранение...",
|
||||
"save": "Сохранить",
|
||||
"saved": "Файл сохранён",
|
||||
"loadingEditor": "Загрузка редактора...",
|
||||
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S сохранить · максимум ~2 МБ",
|
||||
"loadBlocked": "Не удалось загрузить содержимое файла",
|
||||
"footer": "UTF-8 · ⌘/Ctrl+S сохранить · Esc закрыть · макс. ~2 МБ",
|
||||
"charCount": "Символов: {{count}}",
|
||||
"unsavedMark": " · не сохранено",
|
||||
"savedMark": " · сохранено"
|
||||
"savedMark": " · сохранено",
|
||||
"title": "Редактирование {{name}}",
|
||||
"dirtyBadge": "Не сохранено",
|
||||
"reload": "Перезагрузить",
|
||||
"unsavedReload": "Отменить несохранённые изменения и перезагрузить?"
|
||||
},
|
||||
"toast": {
|
||||
"renamed": "Переименовано в {{name}}",
|
||||
"renameFailed": "Сбой переименования",
|
||||
"pathCopied": "Путь скопирован в буфер обмена",
|
||||
"pathCopyFailed": "Не удалось скопировать путь",
|
||||
"chmodUpdated": "Права доступа изменены на {{mode}}",
|
||||
"chmodFailed": "Не удалось обновить права доступа",
|
||||
"uploadPartial": "{{action}} завершено для {{completed}}, сбой {{failed}}: {{detail}}",
|
||||
@@ -180,7 +204,13 @@
|
||||
"uploadAction": "Загрузка",
|
||||
"downloadAction": "Скачивание",
|
||||
"noFolderUpload": "Сбой загрузки папки",
|
||||
"noDragPath": "Пути перетаскивания недоступны; используйте «Загрузить»",
|
||||
"noFolderRecursive": "Сбой рекурсивной передачи папки; повторите или используйте «Загрузить»"
|
||||
"noDragPath": "Система не предоставила путь при перетаскивании. Используйте стрелку → или выбор файлов.",
|
||||
"noFolderRecursive": "Передача папки не удалась. Повторите или используйте → / выбор файлов.",
|
||||
"dropFailed": "Перетаскивание не удалось: не удалось прочитать файл. Повторите или используйте стрелки.",
|
||||
"folderCreated": "Создана папка {{name}}",
|
||||
"allSkippedExisting": "Все уже существующие файлы пропущены",
|
||||
"skippedExisting": "Пропущено существующих: {{count}}",
|
||||
"deleteFailed": "Не удалось удалить",
|
||||
"deleted": "Удалено"
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
"reopenShell": "Открыть оболочку снова",
|
||||
"reopening": "Открытие…",
|
||||
"disconnected": "Отключено",
|
||||
"disconnectedHint": "SSH-сеанс завершился или сеть упала. Нажмите ниже, чтобы переподключиться.",
|
||||
"disconnectedHint": "SSH-сеанс завершился или сеть упала. Один клик ниже — и можно продолжать работу.",
|
||||
"reconnect": "Переподключиться",
|
||||
"suspended": "Подключение приостановлено",
|
||||
"suspendedHint": "Долгое отсутствие активности; подключение приостановлено для экономии ресурсов",
|
||||
@@ -70,7 +70,8 @@
|
||||
"splitRight": "Разделить справа",
|
||||
"splitDown": "Разделить вниз",
|
||||
"maximizePane": "Развернуть текущую панель",
|
||||
"restoreLayout": "Восстановить разделённый макет"
|
||||
"restoreLayout": "Восстановить разделённый макет",
|
||||
"openSftp": "Открыть SFTP"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Поиск...",
|
||||
|
||||
Reference in new issue
Block a user