feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection

- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru
- Auto-detect system language via navigator.languages; fallback to English
- Add BCP47 locale mapping for date formatting and sorting
- Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each)
- Update language selector with native language names
- Extend locale key parity test to cover all 7 languages (70 assertions)
- Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features
- Add credential encryption, host metrics, session backup crypto, and zmodem bridge
- Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
This commit is contained in:
Logan.Li committed 2026-08-12 00:07:48 +08:00
1 parent fea6d8db04
commit b0d0e3a5f3
301 files changed
+28002 -2705

No files matched your search

+174
View File
@@ -0,0 +1,174 @@
{
"nav": {
"general": "Workspace",
"generalDesc": "Layout and resources",
"appearance": "Appearance",
"appearanceDesc": "Theme and language",
"terminal": "Terminal",
"terminalDesc": "Font and colors",
"shortcuts": "Shortcuts",
"shortcutsDesc": "Key bindings",
"ssh": "SSH",
"sshDesc": "Connection and pool",
"security": "Security",
"securityDesc": "Credentials and host keys",
"ai": "AI models",
"aiDesc": "AI providers",
"about": "About",
"aboutDesc": "Version and data"
},
"title": "Settings",
"search": {
"placeholder": "Search settings..."
},
"language": {
"label": "Language",
"description": "Applies immediately",
"zhCN": "简体中文",
"zhTW": "繁體中文",
"en": "English",
"ja": "日本語",
"ko": "한국어",
"vi": "Tiếng Việt",
"ru": "Русский"
},
"general": {
"layout": "Workspace layout",
"sidebarWidth": "Sidebar width",
"sidebarWidthDesc": "Default width of the session sidebar",
"collapseSidebar": "Collapse sidebar",
"collapseSidebarDesc": "Hide the session tree to focus on the terminal; toggle with Ctrl/Cmd+B"
},
"appearance": {
"themeGroup": "Theme",
"theme": "Theme",
"themeDesc": "App UI colors (independent of terminal colors)",
"dark": "Dark",
"light": "Light",
"system": "System"
},
"terminal": {
"fontGroup": "Font and size",
"fontFamily": "Font",
"fontFamilyDesc": "Use a Nerd Font for Zsh prompt icons",
"fontSize": "Size",
"fontSizeDesc": "Terminal text size",
"scrollback": "Scrollback",
"scrollbackDesc": "Lines of history kept per terminal",
"keywordHighlight": "Keyword highlight",
"keywordHighlightDesc": "Highlight errors, warnings, and success states",
"colorTheme": "Color theme"
},
"shortcuts": {
"resetAll": "Reset all to defaults",
"custom": "Custom",
"pressKeys": "Press keys...",
"resetDefault": "Reset to default",
"conflict": "Conflicts with \"{{label}}\"",
"setTo": "Set to {{keys}}",
"hint": "Click a shortcut to rebind · Esc to cancel",
"category": {
"tabs": "Tabs",
"view": "View",
"session": "Session",
"tools": "Tools"
},
"actions": {
"tabNext": "Next tab",
"tabPrev": "Previous tab",
"tabGotoN": "Go to tab N",
"tabClose": "Close current tab",
"tabNew": "New tab",
"viewFullscreen": "Toggle fullscreen",
"viewToggleSidebar": "Toggle sidebar",
"sessionNew": "New session",
"sessionQuickConnect": "Quick connect",
"toolsCommandPalette": "Command palette"
}
},
"ssh": {
"connection": "Connection",
"keepAlive": "Keep-alive",
"keepAliveDesc": "Send keep-alive when idle to reduce disconnects",
"autoReconnect": "Auto reconnect",
"autoReconnectDesc": "Automatically retry after unexpected disconnects",
"timeout": "Connection timeout",
"timeoutDesc": "Maximum wait time when establishing SSH (seconds)",
"maxReconnect": "Reconnect attempts",
"maxReconnectDesc": "Maximum retries after unexpected disconnect",
"pool": "Connection pool",
"maxConnections": "Max connections",
"maxConnectionsDesc": "Shared cap for SSH, SFTP, and batch connections",
"maxBackground": "Background connection limit",
"maxBackgroundDesc": "Evict least recently used connections when over limit",
"suspend": "Background suspend",
"suspendDesc": "Minutes before releasing active channels when a tab is in background"
},
"security": {
"credentials": "Credential protection",
"sessionPassword": "Session passwords and key passphrases",
"sessionPasswordDesc": "Encrypted with AES-256-GCM in Rust before save; cannot be disabled",
"enabled": "Enabled",
"masterKey": "Local master key",
"masterKeyDesc": "Readable only by the current system user; path ~/.opsxshell/master.key (legacy ~/.opsxshsell is migrated automatically)",
"knownHosts": "Known hosts",
"knownHostsHint": "First connect prompts for the host fingerprint. If a reinstall or clone changes the key, choose “Trust and update” in the prompt to replace the old record. Remove one entry or clear all here.",
"clearAll": "Clear all",
"removeHost": "Remove this host record",
"empty": "No records",
"clearConfirm": "Clear all known host keys? You will be prompted again on next connect."
},
"about": {
"tagline": "A lightweight native SSH / SFTP ops terminal",
"appVersion": "App v{{version}}",
"copyVersion": "Copy version info",
"runtime": "Runtime",
"system": "System",
"localData": "Local data",
"sessionsSettings": "Sessions and settings",
"masterKeyPath": "Master key",
"privacyNote": "Passwords and key passphrases are encrypted with AES-256-GCM in Rust. OpsXShell does not save terminal command history.",
"license": "MIT License · Rust · XTerm.js"
},
"ai": {
"presets": "Provider presets",
"add": "Add",
"configured": "Configured",
"configuredHint": "Choose a provider and click Add",
"emptyHint": "Add a provider to get started",
"noModel": "No model selected",
"name": "Name",
"model": "Model",
"protocol": "Protocol",
"auth": "Auth",
"authNone": "None",
"test": "Test",
"testing": "Testing",
"testingMessage": "Testing...",
"saved": "Saved",
"retest": "Please re-test",
"testFailed": "Connection test failed",
"available": "OK · {{latency}} ms",
"savedKeepBlank": "Saved — leave blank to keep",
"notRequired": "Not required",
"otherModels": "Other models…",
"customModel": "Custom model",
"backToList": "Back to list",
"apiKeyOptional": "API Key (not required)",
"advanced": "Advanced",
"allowHttp": "Allow HTTP (localhost/LAN)",
"setActive": "Set as active",
"deleteTitle": "Delete",
"apiKeySaveFailed": "Failed to save API key",
"providerNotFound": "Provider not found",
"modelCatalogReadFailed": "Failed to read model catalog",
"catalogUnavailable": "models.dev is unavailable"
},
"family": {
"openai_compatible": "OpenAI compatible",
"standalone": "────────",
"plan": "Plan",
"local": "Self-hosted",
"custom": "Custom"
}
}