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

+87
View File
@@ -0,0 +1,87 @@
{
"panel": {
"title": "에이전트 CLI",
"modelConfigured": "{{provider}} · {{model}}",
"modelNotConfigured": "구성된 모델 없음",
"sshReady": "SSH · {{target}}",
"sshNotConnected": "연결된 원격 SSH 없음",
"defaultTarget": "현재 SSH 세션",
"emptyHint": "운영 작업을 설명하고 전송하세요. 같은 스레드에서 후속 질문을 하거나, +를 눌러 새 주제를 시작하세요.",
"newTopic": "새 주제",
"close": "닫기",
"thinking": "생각하는 중…",
"conclusion": "결론",
"copy": "복사",
"copied": "복사됨",
"stop": "중지",
"send": "전송",
"placeholder": "작업 또는 후속 질문… (Enter로 전송, Shift+Enter로 줄 바꿈)",
"hintFollowUp": "후속 질문은 이 스레드의 컨텍스트를 포함합니다",
"hintSelection": "선택한 {{lines}}줄을 포함합니다",
"hintSteps": "최대 {{max}}단계 · 저장되지 않음",
"footerNote": "고위험은 확인 필요 · 치명적 작업은 차단됨 · 세션 저장 안 함"
},
"safety": {
"aria": "에이전트 안전 모드",
"strict": {
"label": "엄격",
"short": "중간 위험부터 확인",
"description": "파일 변경, 권한 편집 및 더 높은 위험의 명령은 확인이 필요합니다. 프로덕션이나 익숙하지 않은 호스트에 가장 적합합니다."
},
"relaxed": {
"label": "완화",
"short": "고위험만 확인",
"description": "읽기 전용 및 일상적인 편집은 자동으로 실행됩니다; 삭제, 재시작, 설치 등은 확인이 필요합니다."
}
},
"risk": {
"safe": "안전",
"low": "낮은 위험",
"medium": "중간 위험",
"high": "높은 위험",
"critical": "차단됨"
},
"step": {
"round": "{{round}}단계",
"awaiting": "승인 대기 중",
"running": "실행 중",
"done": "완료",
"confirmTitle": "{{round}}단계 · {{risk}}",
"confirmMessage": "SSH · {{target}}\n{{mode}}\n\n$ {{command}}",
"rejected": "{{round}}단계 명령이 거부되었습니다.",
"terminated": "종료됨",
"stoppedMessage": "중지됨. 실행 중인 원격 명령에 대해 인터럽트가 요청되었습니다."
},
"confirm": {
"reject": "거부",
"once": "1회",
"always": "항상",
"hint": "Enter · 1회 Esc · 거부 항상 · 이 세션에서 유사한 확인 건너뛰기"
},
"error": {
"noProvider": "먼저 설정 → AI에서 AI 제공자를 구성하세요",
"noApiKey": "\"{{provider}}\"에 대해 저장된 API 키가 없습니다",
"emptyTask": "작업 또는 후속 질문을 입력하세요",
"sshRequired": "연결된 원격 SSH 세션이 필요합니다",
"modelEmpty": "모델이 콘텐츠를 반환하지 않았습니다",
"protocolFailed": "모델이 도구 프로토콜을 두 번 실패했습니다; 중지됨",
"noConclusion": "모델이 사용 가능한 결론을 반환하지 않았습니다",
"multipleCommands": "모델이 여러 명령을 반환했습니다; 실행이 거부되었습니다",
"invalidCommand": "모델이 단일 한 줄 명령을 반환하지 않았습니다; 실행이 거부되었습니다",
"repeatLoop": "반복된 명령 루프가 감지되었습니다; 중지됨: {{command}}",
"criticalBlocked": "명령이 파괴적인 하드 차단에 걸렸습니다; 재정의 불가: {{command}}",
"execFailed": "ssh-exec 실패: {{error}}",
"execUnknown": "알 수 없는 오류",
"execNoOutput": "명령이 출력 없이 완료됨",
"maxSteps": "{{max}}단계 한도에 도달했습니다; 범위를 좁히고 재시도하세요"
},
"output": {
"empty": "(빈 출력)",
"truncatedMiddle": "... [{{count}}줄 생략됨] ...",
"totalLines": "전체 줄 수: {{count}}{{truncatedSuffix}}",
"truncatedSuffix": " (처음/끝 보존됨)",
"errorLines": "가능한 오류/경고 줄 ({{count}}):\n{{lines}}",
"noErrorKeywords": "명백한 오류 키워드가 발견되지 않았습니다",
"snippetLabel": "출력 스니펫:\n{{snippet}}"
}
}
+335
View File
@@ -0,0 +1,335 @@
{
"action": {
"confirm": "확인",
"cancel": "취소",
"close": "닫기",
"delete": "삭제",
"save": "저장",
"create": "생성",
"copy": "복사",
"copied": "복사됨",
"refresh": "새로고침",
"gotIt": "확인",
"edit": "편집",
"open": "열기",
"clone": "복제",
"reconnect": "재연결",
"disconnect": "연결 끊기",
"submit": "확인"
},
"status": {
"loading": "불러오는 중...",
"processing": "처리 중...",
"connecting": "연결 중...",
"connected": "연결됨",
"disconnected": "연결 끊김",
"background": "백그라운드",
"suspended": "일시 중단",
"reconnecting": "재연결 중",
"error": "연결 오류",
"reading": "불러오는 중...",
"saving": "저장 중..."
},
"error": {
"title": "문제가 발생했습니다",
"body": "앱에서 예기치 않은 문제가 발생했습니다",
"recoverable": "이 오류는 복구 가능합니다. 페이지를 새로고침해 보세요.",
"refreshPage": "페이지 새로고침",
"restartApp": "앱 재시작",
"supportHint": "문제가 지속되면 로그를 확인하거나 지원팀에 문의하세요"
},
"toast": {
"closeAria": "알림 닫기"
},
"metrics": {
"timezone": "시간대 {{value}}",
"memory": "메모리 {{percent}}%{{detail}}",
"sessionTransfer": "세션 트래픽 {{value}}"
},
"palette": {
"title": "명령 팔레트",
"aria": "명령 팔레트",
"placeholder": "명령, 세션 또는 스니펫 검색...",
"empty": "일치하는 결과가 없습니다",
"emptyHint": "다른 키워드를 시도해 보세요",
"resultCount": "{{count}}개 결과",
"badge": {
"command": "명령",
"session": "세션",
"snippet": "스니펫"
},
"hint": {
"nav": "탐색",
"run": "실행",
"close": "닫기"
},
"cmd": {
"newSession": "새 세션",
"newSessionDesc": "새 SSH 세션 프로필 생성",
"quickConnect": "빠른 연결",
"quickConnectDesc": "호스트 정보로 직접 연결",
"localTerminal": "로컬 터미널",
"localTerminalDesc": "로컬 셸 열기",
"settings": "설정 열기",
"settingsDesc": "앱 환경설정",
"toggleSidebar": "사이드바 전환",
"toggleSidebarDesc": "터미널에 집중하도록 사이드바 숨기기",
"newTab": "새 탭",
"closeTab": "현재 탭 닫기",
"closeAllTabs": "모든 탭 닫기",
"portForward": "새 포트 포워딩",
"upgradePro": "OpsXShell Pro 업그레이드",
"editSession": "세션 편집: {{name}}"
}
},
"tab": {
"welcome": "환영합니다",
"new": "새 탭",
"settings": "설정",
"portForward": "포트 포워딩",
"terminal": "터미널",
"batch": "일괄 실행",
"newTerminal": "새 터미널",
"kind": {
"terminal": "터미널",
"sftp": "SFTP",
"portforward": "포워딩",
"serial": "시리얼",
"rdp": "RDP",
"vnc": "VNC",
"batch": "일괄",
"settings": "설정"
},
"menu": {
"closeOthers": "다른 탭 닫기",
"closeRight": "오른쪽 탭 닫기",
"closeLeft": "왼쪽 탭 닫기",
"closeAll": "모두 닫기",
"clone": "탭 복제"
}
},
"sidebar": {
"brandSub": "SSH / SFTP 터미널",
"collapse": "사이드바 접기 (Ctrl/Cmd+B)",
"collapseAria": "사이드바 접기",
"expand": "사이드바 펼치기",
"expandAria": "사이드바 펼치기",
"toggle": "사이드바 전환",
"searchPlaceholder": "검색...",
"localShell": {
"openDefault": "기본 로컬 셸 열기",
"choose": "셸 선택",
"title": "로컬 셸",
"subtitle": "이 컴퓨터에서 터미널 열기",
"default": "기본"
}
},
"connectionPanel": {
"title": "연결",
"empty": "연결 없음",
"emptyDesc": "활성 연결이 없습니다. 서버에 연결하면 여기에 표시됩니다.",
"stat": {
"total": "전체",
"active": "활성",
"background": "백그라운드",
"error": "연결 끊김/오류"
},
"status": {
"connected": "연결됨",
"connecting": "연결 중",
"background": "백그라운드",
"suspended": "일시 중단",
"error": "오류",
"disconnected": "연결 끊김",
"reconnecting": "재연결 중"
},
"refCount": "참조 {{count}}개",
"reconnect": "재연결",
"reconnecting": "재연결 중...",
"disconnect": "연결 끊기"
},
"pro": {
"upgrade": "Pro 업그레이드",
"feature": "Pro 기능",
"unlock": "{{feature}} 잠금 해제",
"comingSoon": "출시 예정",
"activateSuccess": "활성화됨",
"activateFailed": "활성화 실패",
"licenseActivated": "Pro 라이선스가 활성화되었습니다",
"paymentPending": "결제 후 라이선스를 여기에 붙여넣거나 나중에 다시 활성화해 보세요",
"invalidLicense": "활성화 실패: 잘못된 라이선스",
"goUpgrade": "업그레이드",
"haveLicense": "라이선스가 있나요? 활성화",
"title": "OpsXShell Pro · Pro 운영 기능 잠금 해제",
"subtitleComingSoon": "{{feature}} 출시 예정 · 조기 액세스는 Pro 업그레이드",
"subtitleUnlock": "잠금 해제 중: {{feature}}",
"subtitleDefault": "포워딩, 프록시, 시리얼, AI, 일괄 실행, 브로드캐스트",
"activated": "Pro 활성화됨",
"expiresAt": " · {{date}}까지 유효",
"lifetime": " · 평생 라이선스",
"oneTimeFee": "1회 구매 · 이 기기에서 평생 사용 · 구독 없음",
"pasteLicense": "라이선스 붙여넣기",
"activateButton": "활성화",
"clearLicense": "로컬 라이선스 삭제",
"paymentNote": "결제는 Waffo가 처리합니다. 이 앱은 카드 정보를 수집하지 않습니다.",
"testDeviceId": "테스트 환경 · 기기 ID: {{deviceId}}",
"later": "나중에 하기",
"viewPro": "Pro 보기",
"wallComingSoonSuffix": " · 출시 예정",
"wallUnlock": "{{feature}} 잠금 해제",
"wallMessageComingSoon": "이 Pro 기능은 아직 개발 중입니다. 조기 액세스를 위해 업그레이드하세요.",
"wallMessageDefault": "이 기능은 OpsXShell Pro가 필요합니다. 이 기기에서 사용하려면 업그레이드하세요.",
"checkoutUnavailable": "결제를 사용할 수 없습니다 ({{status}})",
"freeTier": "무료",
"proTier": "Pro",
"freeItems": {
"ssh": "SSH 터미널",
"sftp": "SFTP 파일 관리자",
"local": "로컬 터미널",
"crud": "세션 CRUD",
"import": "단일 / ssh_config 가져오기"
},
"proItems": {
"forward": "포트 포워딩",
"proxy": "세션 프록시 / SOCKS",
"serial": "시리얼 터미널",
"ai": "터미널 AI 어시스턴트",
"batch": "일괄 실행 / 브로드캐스트 동기화",
"broadcast": "브로드캐스트 입력 동기화",
"importExport": "호스트 일괄 가져오기/내보내기",
"desktop": "RDP / VNC 원격 데스크톱"
}
},
"launcher": {
"title": "빠른 실행",
"description": "세션, 로컬 셸 및 기기 콘솔",
"cards": {
"quickConnect": {
"title": "빠른 연결",
"desc": "user@host:port"
},
"saveSession": {
"title": "세션 저장",
"desc": "자격 증명, 그룹, 프록시"
},
"serial": {
"title": "시리얼 터미널",
"desc": "보레이트 및 포트 설정"
}
},
"sectionLocalShell": "로컬 셸",
"sectionSavedSessions": "저장된 세션",
"systemDefault": "시스템 기본값"
},
"statusBar": {
"socksLabel": "포워딩",
"socksIdle": "포트 포워딩 열기 · 우클릭으로 SOCKS 복사",
"socksRunning": "SOCKS5 실행 중 · 클릭하여 관리 · 우클릭으로 복사",
"forwardOpenIdle": "포트 포워딩 열기 · 우클릭으로 socks5://127.0.0.1:{{port}} 복사",
"forwardOpenRunning": "SOCKS5 실행 중 (:{{port}}) · 클릭하여 관리 · 우클릭으로 복사",
"forwardStarted": "포워딩 시작됨",
"forwardStartedDynamic": "SOCKS5 시작됨: socks5://127.0.0.1:{{port}}",
"socksStartFailed": "시작 실패: {{message}}",
"socksStopFailed": "중지 실패: {{message}}",
"socksCopied": "socks5://127.0.0.1:{{port}} 복사됨"
},
"portForward": {
"title": "포트 포워딩",
"connectedAs": "연결됨: {{target}}",
"notConnected": "연결되지 않음 — 먼저 SSH를 연결하세요",
"socksDefaultHint": "로컬 SOCKS5: 127.0.0.1:1080",
"socksRunning": "SOCKS5 실행 중",
"socksStart": "SOCKS5 시작",
"addRule": "추가",
"emptyTitle": "포트 포워딩 없음",
"emptyDesc": "SOCKS5를 시작하거나 로컬/원격 규칙을 추가하세요",
"emptyAction": "127.0.0.1:1080 시작",
"typeLocal": "로컬",
"typeRemote": "원격",
"typeDynamic": "동적",
"running": "실행 중",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "원격 {{remote}} → 로컬 {{local}}",
"stats": "{{connections}}개 연결 · ↑{{up}} · ↓{{down}}",
"copyProxy": "프록시 복사",
"copyRule": "규칙 복제",
"editRule": "편집",
"stopListener": "중지",
"start": "시작",
"delete": "삭제",
"editTitle": "포워딩 편집",
"addTitle": "포워딩 추가",
"typeLocalDesc": "로컬 → 원격",
"typeRemoteDesc": "원격 → 로컬",
"typeDynamicDesc": "SOCKS5",
"selectType": "유형",
"drawerSubtitle": "현재 SSH 세션을 통한 터널",
"ruleFields": "세부 정보",
"dynamicHint": "127.0.0.1:1080의 로컬 SOCKS5. 트래픽은 이 SSH 서버의 공인 IP를 통해 나갑니다.",
"dynamicSingleHint": "SSH 호스트당 하나의 동적 규칙, 고정 포트 1080.",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"ruleList": "규칙",
"ruleListEmpty": "아직 로컬/원격 규칙이 없습니다",
"addSection": "새로 추가",
"errorDynamicExists": "동적 규칙이 이미 존재합니다 (1080). 대신 시작하거나 중지하세요.",
"diagram": {
"title": "작동 방식",
"localApp": "로컬 앱",
"sshHost": "SSH 호스트",
"remoteService": "원격 서비스",
"remoteClient": "원격 클라이언트",
"localService": "로컬 서비스",
"localClient": "로컬",
"browser": "로컬 클라이언트",
"socksProxy": "로컬 SOCKS",
"anyTarget": "모든 대상",
"localSide": "로컬",
"remoteSide": "원격",
"firewall": "방화벽",
"viaApp": "OpsXShell 경유",
"viaSsh": "SSH 경유",
"toTarget": "대상으로",
"toListen": "수신",
"targetDb": "DB",
"targetWeb": "웹",
"targetApi": "API",
"remotePeerA": "원격 A",
"remotePeerB": "원격 B",
"remotePeerC": "원격 C",
"cloudA": "클라우드 A",
"cloudB": "클라우드 B",
"internet": "인터넷",
"localCaption": "로컬: 원격 포트를 로컬 포트인 것처럼 접근합니다.",
"remoteCaption": "원격: 원격 접근을 로컬 서비스로 포워딩합니다.",
"dynamicCaption": "동적: 이 컴퓨터가 현재 SSH 서버의 공인 IP를 통해 나가는 SOCKS5 프록시가 됩니다."
},
"ruleName": "이름",
"ruleNamePlaceholder": "예: MySQL",
"localListenPort": "로컬 수신 포트",
"localTargetPort": "로컬 대상 포트",
"remoteTargetPort": "원격 대상 포트",
"remoteListenPort": "원격 수신 포트",
"portPlaceholder": "예: 3306",
"remoteHost": "원격 호스트",
"remoteHostPlaceholder": "localhost 또는 IP",
"socksRuleName": "SOCKS5 프록시",
"defaultLocalName": "로컬 포워딩",
"defaultRemoteName": "원격 포워딩",
"sessionRestoredTitle": "세션 복원됨",
"sessionRestoredDesc": "마지막 세션의 포트 포워딩 탭이 복원되었습니다.\n다시 사용하려면 SSH를 재연결하세요.",
"stopEditTitle": "편집 전 중지",
"stopEditMessage": "이 포워딩이 실행 중입니다. 편집하기 전에 중지하시겠습니까?",
"stopEditConfirm": "중지하고 편집",
"deleteTitle": "규칙 삭제",
"deleteRunning": "실행 중인 포워딩이 먼저 중지됩니다.",
"deleteConfirm": "이 규칙을 삭제하시겠습니까?",
"errorNamePort": "이름과 유효한 포트(1–65535)를 입력하세요",
"errorTargetPort": "유효한 대상 포트(1–65535)를 입력하세요",
"errorRemoteHost": "원격 호스트를 입력하세요",
"errorNotConnected": "연결되지 않음",
"errorStartFailed": "시작 실패",
"errorStopFailed": "중지 실패",
"errorSocksRunning": "SOCKS5가 이미 실행 중입니다",
"copySuffix": "복사"
}
}
+44
View File
@@ -0,0 +1,44 @@
{
"connect": {
"rdpTitle": "RDP 연결",
"vncTitle": "VNC 연결",
"rdpDesc": "Windows 원격 데스크톱 · 네이티브 IronRDP 엔진",
"vncDesc": "VNC / RFB 원격 데스크톱 · 네이티브 엔진",
"confirm": "연결",
"host": "호스트",
"hostPlaceholderRdp": "windows.example.com",
"hostPlaceholderVnc": "192.168.1.10",
"port": "포트",
"username": "사용자 이름",
"domain": "도메인 (선택 사항)",
"password": "비밀번호",
"passwordOptional": "비밀번호 (선택 사항)",
"width": "너비",
"height": "높이",
"rdpFootnote": "네이티브 IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS; 45초 핸드셰이크 시간 초과. 개발 중 인증서 확인은 완화됩니다.",
"vncFootnote": "네이티브 vnc-rs RFB(Tight JPEG 디코딩); 클립보드는 UTF-8로 전송됩니다(매우 오래된 서버는 텍스트가 깨질 수 있음).",
"errorHostRequired": "호스트 주소를 입력하세요",
"errorUsernameRequired": "사용자 이름을 입력하세요"
},
"toolbar": {
"pasteClipboard": "로컬 클립보드를 원격에 붙여넣기",
"pasteAria": "원격에 붙여넣기",
"shareDrive": "공유 드라이브에 로컬 파일 복사 (OpsXShell에서 로컬 다운로드 = 원격 다운로드)",
"shareDriveAria": "공유 드라이브에 추가",
"openShareDir": "공유 폴더를 로컬에서 열기 (다운로드)",
"openShareDirAria": "공유 폴더 열기",
"disconnect": "연결 끊기",
"disconnectAria": "연결 끊기"
},
"status": {
"connecting": "연결 중…",
"connected": "연결됨",
"disconnected": "연결 끊김",
"connectFailed": "연결 실패",
"clipboardSynced": "원격 클립보드 동기화됨",
"savedToDownloads": "로컬 다운로드에 저장됨: {{name}}",
"pastedToRemote": "원격에 붙여넣음",
"fileTooLarge": "단일 파일 한도는 50MB입니다",
"fileShared": "공유 다운로드에 추가됨: {{name}} (원격 이 PC에서 볼 수 있음)"
}
}
+161
View File
@@ -0,0 +1,161 @@
{
"code": {
"1000": "연결 실패. 네트워크 또는 호스트 주소를 확인하세요.",
"1001": "연결 시간 초과. 네트워크를 확인하거나 나중에 다시 시도하세요.",
"1002": "인증 실패. 사용자 이름과 비밀번호를 확인하세요.",
"1003": "호스트에 연결할 수 없습니다. 네트워크 설정을 확인하세요.",
"1004": "연결이 닫혔습니다",
"1100": "터미널 생성 실패",
"1101": "명령 실행 실패",
"1102": "포트 포워딩 설정 실패",
"1200": "SFTP 연결 실패",
"1201": "파일을 찾을 수 없음",
"1202": "이 파일 또는 디렉터리에 대한 권한이 없습니다",
"1203": "파일 전송 실패",
"1204": "디렉터리 내용을 읽을 수 없습니다",
"1300": "세션을 찾을 수 없음",
"1301": "세션 저장 실패",
"1302": "세션 로드 실패",
"1400": "잘못된 호스트 주소 형식",
"1401": "포트는 1에서 65535 사이여야 합니다",
"1402": "잘못된 자격 증명 형식",
"9000": "알 수 없는 오류가 발생했습니다",
"9001": "내부 통신 오류",
"9002": "파일 시스템 오류",
"9003": "네트워크 오류"
},
"action": {
"retry": "재시도",
"reconnect": "재연결",
"ignore": "무시",
"exit": "종료",
"none": "없음"
},
"connection": {
"failed": "연결 실패. 네트워크 또는 호스트 주소를 확인하세요.",
"timeout": "연결 시간 초과. 네트워크를 확인하거나 나중에 다시 시도하세요.",
"authFailed": "인증 실패. 사용자 이름과 비밀번호를 확인하세요.",
"hostUnreachable": "호스트에 연결할 수 없습니다. 네트워크 설정을 확인하세요.",
"closed": "연결이 닫혔습니다",
"dnsFailed": "호스트를 확인할 수 없습니다",
"refused": "연결이 거부되었습니다",
"disconnected": "연결 끊김"
},
"auth": {
"failed": "인증 실패. 사용자 이름과 비밀번호를 확인하세요.",
"invalidCredentials": "잘못된 자격 증명 형식",
"keyLoadFailed": "개인 키 로드 실패",
"passphraseRequired": "개인 키에 암호가 필요합니다",
"passphraseWrong": "잘못된 개인 키 암호"
},
"shell": {
"createFailed": "터미널 생성 실패",
"execFailed": "명령 실행 실패",
"localCreateFailed": "로컬 셸 생성 실패",
"remoteCreateFailed": "원격 셸 생성 실패"
},
"proxy": {
"connectFailed": "프록시 연결 실패",
"authFailed": "프록시 인증 실패",
"tunnelFailed": "프록시 터널 설정 실패",
"unsupported": "지원되지 않는 프록시 유형",
"jumpFailed": "점프 호스트 연결 실패",
"hostRequired": "프록시 호스트가 필요합니다",
"hostNoSpaces": "프록시 호스트에는 공백이 포함될 수 없습니다",
"portRequired": "프록시 포트는 0보다 커야 합니다",
"portTooHigh": "프록시 포트는 65535를 초과할 수 없습니다"
},
"forward": {
"failed": "포트 포워딩 설정 실패",
"bindFailed": "포트 바인딩 실패",
"alreadyInUse": "포트가 이미 사용 중입니다"
},
"sftp": {
"connectFailed": "SFTP 연결 실패",
"fileNotFound": "파일을 찾을 수 없음",
"permissionDenied": "이 파일 또는 디렉터리에 대한 권한이 없습니다",
"transferFailed": "파일 전송 실패",
"listFailed": "디렉터리 내용을 읽을 수 없습니다",
"readFailed": "읽기 실패",
"writeFailed": "저장 실패",
"renameFailed": "이름 변경 실패",
"chmodFailed": "권한 업데이트 실패",
"apiUnavailable": "SFTP API를 사용할 수 없음"
},
"session": {
"notFound": "세션을 찾을 수 없음",
"saveFailed": "세션 저장 실패",
"loadFailed": "세션 로드 실패",
"readConfigFailed": "세션 설정을 읽을 수 없습니다",
"exportWriteFailed": "내보내기 파일 쓰기 실패",
"exportFailed": "세션 내보내기 실패",
"importReadFailed": "파일 읽기 실패",
"importFailed": "세션 가져오기 실패",
"importEmpty": "가져올 수 있는 세션을 찾지 못했습니다"
},
"validation": {
"invalidHost": "잘못된 호스트 주소 형식",
"invalidPort": "포트는 1에서 65535 사이여야 합니다",
"invalidCredentials": "잘못된 자격 증명 형식",
"hostRequired": "호스트 주소를 입력하세요",
"usernameRequired": "사용자 이름을 입력하세요",
"targetRequired": "호스트를 입력하세요, 예: root@192.168.1.10 또는 opsbase.cn:5555",
"serialPathRequired": "시리얼 장치 경로를 입력하세요",
"taskRequired": "작업 또는 후속 질문을 입력하세요"
},
"filesystem": {
"error": "파일 시스템 오류",
"readFailed": "파일 읽기 실패",
"writeFailed": "파일 쓰기 실패"
},
"clipboard": {
"readFailed": "클립보드 읽기 실패",
"writeFailed": "클립보드 쓰기 실패",
"copyPathFailed": "경로 복사 실패",
"unsupportedRead": "이 환경에서는 클립보드 읽기가 지원되지 않습니다",
"unsupportedWrite": "이 환경에서는 클립보드 쓰기가 지원되지 않습니다"
},
"ipc": {
"error": "내부 통신 오류",
"nativeApiUnavailable": "네이티브 API를 사용할 수 없음"
},
"network": {
"error": "네트워크 오류"
},
"pool": {
"limitReached": "연결 한도에 도달했습니다 ({{max}}). 일부 연결을 먼저 닫으세요."
},
"desktop": {
"connectFailed": "연결 실패",
"fileTooLarge": "단일 파일 한도는 50MB입니다",
"nativeOnly": "원격 연결은 OpsXShell Tauri 데스크톱 앱에서만 사용할 수 있습니다",
"rdpNativeOnly": "RDP는 OpsXShell Tauri 데스크톱 앱에서만 사용할 수 있습니다",
"vncNativeOnly": "VNC는 OpsXShell Tauri 데스크톱 앱에서만 사용할 수 있습니다"
},
"serial": {
"openFailed": "시리얼 포트 열기 실패",
"writeFailed": "시리얼 쓰기 실패",
"nativeOnly": "시리얼 포트는 Tauri 데스크톱 앱에서만 사용할 수 있습니다"
},
"ai": {
"noProvider": "먼저 설정 → AI에서 AI 제공자를 구성하세요",
"noApiKey": "\"{{provider}}\"에 대해 저장된 API 키가 없습니다",
"modelEmpty": "모델이 콘텐츠를 반환하지 않았습니다",
"protocolFailed": "모델이 도구 프로토콜을 두 번 실패했습니다; 중지됨",
"noConclusion": "모델이 사용 가능한 결론을 반환하지 않았습니다",
"multipleCommands": "모델이 여러 명령을 반환했습니다; 실행이 거부되었습니다",
"invalidCommand": "모델이 단일 한 줄 명령을 반환하지 않았습니다; 실행이 거부되었습니다",
"repeatLoop": "반복된 명령 루프가 감지되었습니다; 중지됨: {{command}}",
"criticalBlocked": "명령이 파괴적인 하드 차단에 걸렸습니다; 재정의 불가: {{command}}",
"execFailed": "ssh-exec 실패: {{error}}",
"maxSteps": "{{max}}단계 한도에 도달했습니다; 범위를 좁히고 재시도하세요",
"sshRequired": "연결된 원격 SSH 세션이 필요합니다"
},
"zmodem": {
"readFailed": "읽기 실패: {{name}}",
"writeFailed": "쓰기 실패: {{name}}"
},
"unknown": {
"error": "알 수 없는 오류가 발생했습니다"
}
}
+44
View File
@@ -0,0 +1,44 @@
{
"connect": {
"title": "시리얼 포트 연결",
"description": "네이티브 시리얼 터미널 · 라우터, 스위치, 보드 및 디버그 콘솔",
"confirm": "포트 열기",
"device": "장치",
"refresh": "새로고침",
"devicePlaceholder": "{{path}}",
"noDevicesHint": "나열된 장치가 없으면 경로를 수동으로 입력하세요, 예: {{examples}}.",
"examplesWindows": "{{default}}, COM3",
"examplesLinux": "{{default}}, /dev/ttyACM0",
"examplesMac": "{{default}}, /dev/tty.usbserial-*",
"baudRate": "보레이트",
"dataBits": "데이터 비트",
"stopBits": "스톱 비트",
"parity": "패리티",
"parityNone": "없음",
"parityOdd": "홀수",
"parityEven": "짝수",
"flowControl": "플로 제어",
"flowNone": "없음",
"flowSoftware": "소프트웨어 XON/XOFF",
"flowHardware": "하드웨어 RTS/CTS",
"lineEnding": "줄 끝",
"lineEndingLf": "LF (\\n)",
"lineEndingCr": "CR (\\r)",
"lineEndingCrlf": "CRLF (\\r\\n)",
"localEcho": "로컬 에코",
"localEchoHint": "(반이중 디버깅)",
"errorPathRequired": "시리얼 장치 경로를 입력하세요"
},
"terminal": {
"title": "시리얼",
"connected": "연결됨",
"disconnected": "연결 끊김",
"connecting": "연결 중…",
"error": "시리얼 오류",
"configSummary": "{{path}} · {{baud}} · {{dataBits}}-{{parity}}-{{stopBits}}",
"opening": "{{path}} @ {{baud}} 여는 중...",
"openFailed": "시리얼 포트 열기 실패: {{message}}",
"connectedBanner": "연결됨 {{path}} · {{baud}} {{frame}} · {{lineEnding}}{{echo}}",
"localEchoSuffix": " · 로컬 에코"
}
}
+237
View File
@@ -0,0 +1,237 @@
{
"sidebar": {
"quickConnect": "빠른 연결",
"quickConnectShort": "연결",
"newSession": "새 세션",
"newSessionShort": "새로",
"searchPlaceholder": "세션 검색...",
"batchMode": "일괄 작업",
"exitBatchMode": "일괄 모드 종료",
"batchSelected": "{{count}}개 SSH 선택됨",
"batchExcludedDesktop": " · RDP/VNC 제외됨",
"selectAllVisible": "보이는 항목 모두 선택",
"deselectAllVisible": "보이는 항목 선택 해제",
"batchExec": "일괄 실행",
"settings": "설정",
"resizeHint": "드래그하여 크기 조정; 더블클릭하여 접기"
},
"tree": {
"selectSession": "세션 선택",
"noMatchTitle": "일치하는 세션 없음",
"noMatchDesc": "다른 키워드를 시도해 보세요",
"emptyTitle": "아직 세션이 없습니다",
"emptyDesc": "빠른 연결 또는 세션 생성; 더블클릭하여 터미널 열기",
"emptyAction": "새 세션"
},
"contextMenu": {
"blank": {
"newGroup": "새 그룹",
"newSession": "새 세션"
},
"group": {
"newSessionHere": "여기에 새 세션",
"newGroup": "새 그룹",
"renameGroup": "그룹 이름 변경",
"deleteEmptyGroup": "빈 그룹 삭제"
},
"session": {
"open": "열기",
"edit": "편집",
"duplicate": "복제",
"delete": "삭제"
}
},
"groups": {
"default": "기본",
"new": {
"title": "새 그룹",
"message": "그룹 이름 입력",
"placeholder": "예: 프로덕션",
"confirm": "생성"
},
"rename": {
"title": "그룹 이름 변경",
"message": "\"{{name}}\"을(를) 다음으로 변경",
"placeholder": "그룹 이름",
"confirm": "저장"
},
"deleteBlocked": {
"title": "삭제할 수 없음",
"message": "그룹 \"{{name}}\"에 아직 세션이 있습니다. 먼저 이동하거나 삭제하세요.",
"confirm": "확인"
},
"newOption": "새 그룹…",
"hint": "다른 것을 선택하거나 생성하지 않으면 기본 그룹이 사용됩니다"
},
"deleteSession": {
"title": "세션 삭제",
"message": "세션 \"{{name}}\"을(를) 삭제하시겠습니까?",
"confirm": "삭제"
},
"welcome": {
"tagline": "원격 터미널 · SFTP · 포트 포워딩",
"sectionStart": "시작하기",
"sectionDesktop": "원격 데스크톱",
"sectionRecent": "최근 세션",
"quickConnect": {
"title": "빠른 연결",
"desc": "1회성 SSH; 라이브러리에 저장되지 않음"
},
"newSession": {
"title": "새 세션",
"desc": "호스트 저장; 사이드바에서 더블클릭하여 연결"
},
"localShell": {
"title": "로컬 셸",
"selectShell": "셸 선택",
"default": "기본"
},
"rdp": {
"title": "RDP 원격 데스크톱",
"desc": "Windows · NLA / CredSSP"
},
"vnc": {
"title": "VNC 원격 데스크톱",
"desc": "RFB · 크로스 플랫폼 그래픽 세션"
},
"recentEmpty": {
"title": "저장된 세션 없음",
"desc": "빠른 연결을 시도하거나, 나중에 재사용할 세션을 생성하세요"
}
},
"launcher": {
"searchPlaceholder": "호스트, 그룹 또는 탭 검색"
},
"quickConnect": {
"title": "빠른 연결",
"target": "대상",
"targetPlaceholder": "root@192.168.1.10:22",
"targetHint": "호스트, user@host, user@host:port 지원",
"password": "비밀번호",
"passwordOptional": "선택 사항 · 키 사용 시 비워두세요",
"connect": "연결",
"errorInvalidTarget": "호스트를 입력하세요, 예: root@192.168.1.10 또는 opsbase.cn:5555",
"errorConnectFailed": "연결 실패"
},
"dialog": {
"create": "새 세션",
"edit": "세션 편집",
"subtitle": "1줄 대상 · 고급 옵션 접힘",
"saving": "저장 중…",
"save": "저장",
"createAndSave": "생성 및 저장",
"basic": "기본",
"login": "로그인",
"advanced": "고급",
"advancedCollapsed": "프록시 · 점프 호스트 · 태그",
"collapse": "접기",
"protocol": "프로토콜",
"displayName": "표시 이름 (선택 사항)",
"displayNamePlaceholder": "기본값은 user@host 또는 vnc:host",
"host": "호스트",
"hostPlaceholder": "192.168.1.10",
"hostHint": "IP 또는 호스트명; host:port도 허용됨",
"port": "포트",
"username": "사용자 이름",
"usernamePlaceholderRdp": "Administrator",
"usernamePlaceholderSsh": "root",
"width": "너비",
"height": "높이",
"group": "그룹",
"authPassword": "비밀번호",
"authKey": "키",
"password": "비밀번호",
"domain": "도메인 (선택 사항)",
"domainPlaceholder": "도메인 계정을 사용하지 않으면 거의 필요하지 않음",
"keySource": "키 소스",
"keyFile": "파일",
"keyText": "텍스트",
"privateKeyPath": "개인 키 경로",
"privateKeyText": "개인 키 텍스트",
"privateKeyTextHint": "붙여넣은 키는 비밀번호처럼 디스크에 암호화됩니다",
"pickKeyFile": "찾아보기…",
"pickKeyDialogTitle": "개인 키 파일 선택",
"allFilesFilter": "모든 파일",
"passphrase": "키 암호 (선택 사항)",
"passphrasePlaceholder": "선택 사항",
"tags": "태그",
"tagsPlaceholder": "prod, web",
"startupCommand": "시작 명령 (선택 사항)",
"startupCommandPlaceholder": "연결 후 실행, 예: cd /var/log",
"proxy": "프록시",
"proxyNone": "없음",
"proxyHostPlaceholder": "프록시 호스트",
"proxyPortPlaceholder": "포트",
"proxyUserPlaceholder": "사용자 이름 (선택 사항)",
"proxyPasswordPlaceholder": "비밀번호 (선택 사항)",
"jumpHost": "점프 호스트 (선택 사항)",
"jumpNone": "점프 호스트 없음",
"jumpNoneAlt": "점프 호스트 없음",
"jumpHint": "저장된 세션 하나를 점프 호스트로 사용할 수 있습니다"
},
"batch": {
"title": "일괄 실행",
"subtitle": "{{selected}}개 선택됨 · 동시성 {{concurrency}} · 탭 닫기 시 결과 폐기",
"dialogTitle": "일괄 명령",
"dialogDesc": "{{selected}}/{{total}}개 호스트 선택됨 · 최대 동시성 {{concurrency}}",
"targetCount": "{{count}}개 대상",
"runningProgress": "실행 중 {{completed}}/{{total}}",
"execute": "{{count}}개 호스트에서 실행",
"executeAgain": "다시 실행",
"success": "{{count}}개 성공",
"failed": "{{count}}개 실패",
"command": "원격 명령",
"commandPlaceholder": "예: uptime",
"targets": "대상 호스트",
"filterPlaceholder": "이름, IP, 그룹 또는 태그",
"filterAria": "호스트 필터",
"noMatchHosts": "일치하는 호스트 없음",
"resultMatrix": "결과 매트릭스",
"resultMatrixHint": "호스트 × 상태 × 출력",
"emptySelection": "왼쪽에서 대상을 선택하거나, 사이드바 일괄 모드에서 선택한 상태로 여세요",
"noOutput": "(출력 없음)",
"errorReadConfig": "세션 설정을 읽을 수 없음",
"errorConnectFailed": "연결 실패",
"errorExecFailed": "명령 실행 실패",
"results": "결과",
"resultsHint": "출력은 이 대화상자에만 보관됩니다",
"ctrlEnterHint": "Ctrl/⌘ + Enter로 실행",
"executeTo": "{{count}}개 호스트에서 실행",
"selectFromLeft": "왼쪽에서 대상 선택"
},
"importExport": {
"exportTitle": "세션 내보내기",
"exportDefaultPath": "opsxshell-sessions.bak",
"exportFilterBak": "OpsXShell 백업",
"exportFilterJson": "JSON",
"exportSuccess": "{{count}}개 세션을 다음으로 내보냄:\n{{path}}",
"exportWriteFailed": "내보내기 파일 쓰기 실패",
"exportFailed": "세션 내보내기 실패",
"exportFailedDetail": "세션 내보내기 실패: {{message}}",
"exportPasswordTitle": "백업 비밀번호 설정",
"exportPasswordMessage": "내보내기 파일은 호스트 그룹, 개인 키, 비밀번호 및 기타 비밀을 암호화합니다. 백업 비밀번호를 선택하세요.",
"exportPasswordPlaceholder": "백업 비밀번호 입력",
"exportPasswordConfirmTitle": "백업 비밀번호 확인",
"exportPasswordConfirmMessage": "확인을 위해 백업 비밀번호를 다시 입력하세요.",
"exportPasswordConfirmPlaceholder": "백업 비밀번호 재입력",
"exportPasswordMismatch": "비밀번호가 일치하지 않습니다",
"exportPasswordRequired": "내보내기에는 백업 비밀번호가 필요합니다",
"importTitle": "세션 가져오기",
"importFilterBak": "OpsXShell 백업",
"importFilterJson": "JSON",
"importFilterSshConfig": "SSH Config",
"importFilterAll": "모든 파일",
"readFileFailed": "파일 읽기 실패",
"readFileFailedDetail": "파일 읽기 실패: {{message}}",
"importPasswordTitle": "백업 비밀번호 입력",
"importPasswordMessage": "이 파일은 암호화되어 있습니다. 호스트 그룹과 자격 증명을 가져오려면 내보낼 때 설정한 비밀번호를 입력하세요.",
"importPasswordPlaceholder": "백업 비밀번호 입력",
"importPasswordRequired": "암호화된 백업을 가져오려면 비밀번호가 필요합니다",
"importPasswordInvalid": "잘못된 백업 비밀번호이거나 파일이 손상되었습니다",
"noSessionsFound": "가져올 수 있는 세션을 찾지 못했습니다",
"noValidSessions": "파일에 유효한 세션 항목이 없습니다",
"importSuccess": "{{created}}/{{total}}개 세션을 가져왔습니다",
"importFailed": "세션 가져오기 실패",
"importFailedDetail": "세션 가져오기 실패: {{message}}"
}
}
+174
View File
@@ -0,0 +1,174 @@
{
"nav": {
"general": "워크스페이스",
"generalDesc": "레이아웃 및 리소스",
"appearance": "외관",
"appearanceDesc": "테마 및 언어",
"terminal": "터미널",
"terminalDesc": "글꼴 및 색상",
"shortcuts": "단축키",
"shortcutsDesc": "키 바인딩",
"ssh": "SSH",
"sshDesc": "연결 및 풀",
"security": "보안",
"securityDesc": "자격 증명 및 호스트 키",
"ai": "AI 모델",
"aiDesc": "AI 제공자",
"about": "정보",
"aboutDesc": "버전 및 데이터"
},
"title": "설정",
"search": {
"placeholder": "설정 검색..."
},
"language": {
"label": "언어",
"description": "즉시 적용",
"zhCN": "简体中文",
"zhTW": "繁體中文",
"en": "English",
"ja": "日本語",
"ko": "한국어",
"vi": "Tiếng Việt",
"ru": "Русский"
},
"general": {
"layout": "워크스페이스 레이아웃",
"sidebarWidth": "사이드바 너비",
"sidebarWidthDesc": "세션 사이드바의 기본 너비",
"collapseSidebar": "사이드바 접기",
"collapseSidebarDesc": "터미널에 집중하도록 세션 트리 숨기기; Ctrl/Cmd+B로 전환"
},
"appearance": {
"themeGroup": "테마",
"theme": "테마",
"themeDesc": "앱 UI 색상(터미널 색상과 별개)",
"dark": "다크",
"light": "라이트",
"system": "시스템"
},
"terminal": {
"fontGroup": "글꼴 및 크기",
"fontFamily": "글꼴",
"fontFamilyDesc": "Zsh 프롬프트 아이콘을 위해 Nerd Font를 사용하세요",
"fontSize": "크기",
"fontSizeDesc": "터미널 텍스트 크기",
"scrollback": "스크롤백",
"scrollbackDesc": "터미널당 보관되는 히스토리 줄 수",
"keywordHighlight": "키워드 강조",
"keywordHighlightDesc": "오류, 경고 및 성공 상태 강조",
"colorTheme": "색상 테마"
},
"shortcuts": {
"resetAll": "모두 기본값으로 재설정",
"custom": "사용자 지정",
"pressKeys": "키를 누르세요...",
"resetDefault": "기본값으로 재설정",
"conflict": "\"{{label}}\"와 충돌",
"setTo": "{{keys}}로 설정",
"hint": "단축키를 클릭하여 재지정 · Esc로 취소",
"category": {
"tabs": "탭",
"view": "보기",
"session": "세션",
"tools": "도구"
},
"actions": {
"tabNext": "다음 탭",
"tabPrev": "이전 탭",
"tabGotoN": "탭 N으로 이동",
"tabClose": "현재 탭 닫기",
"tabNew": "새 탭",
"viewFullscreen": "전체 화면 전환",
"viewToggleSidebar": "사이드바 전환",
"sessionNew": "새 세션",
"sessionQuickConnect": "빠른 연결",
"toolsCommandPalette": "명령 팔레트"
}
},
"ssh": {
"connection": "연결",
"keepAlive": "연결 유지",
"keepAliveDesc": "연결 끊김을 줄이기 위해 유휴 시 keep-alive 전송",
"autoReconnect": "자동 재연결",
"autoReconnectDesc": "예기치 않은 연결 끊김 후 자동으로 재시도",
"timeout": "연결 시간 초과",
"timeoutDesc": "SSH 설정 시 최대 대기 시간(초)",
"maxReconnect": "재연결 시도",
"maxReconnectDesc": "예기치 않은 연결 끊김 후 최대 재시도 횟수",
"pool": "연결 풀",
"maxConnections": "최대 연결",
"maxConnectionsDesc": "SSH, SFTP 및 일괄 연결에 공유되는 상한",
"maxBackground": "백그라운드 연결 제한",
"maxBackgroundDesc": "제한 초과 시 가장 오래전 사용한 연결 제거",
"suspend": "백그라운드 일시 중단",
"suspendDesc": "탭이 백그라운드에 있을 때 활성 채널을 해제하기까지의 시간(분)"
},
"security": {
"credentials": "자격 증명 보호",
"sessionPassword": "세션 비밀번호 및 키 암호",
"sessionPasswordDesc": "저장 전 Rust에서 AES-256-GCM으로 암호화됨; 비활성화할 수 없음",
"enabled": "활성화됨",
"masterKey": "로컬 마스터 키",
"masterKeyDesc": "현재 시스템 사용자만 읽을 수 있음; 경로 ~/.opsxshell/master.key (레거시 ~/.opsxshsell은 자동 마이그레이션됨)",
"knownHosts": "알려진 호스트",
"knownHostsHint": "첫 연결 시 호스트 핑거프린트를 확인합니다. 재설치나 복제로 키가 변경된 경우, 프롬프트에서 \"신뢰하고 업데이트\"를 선택하여 기존 기록을 교체하세요. 여기서 항목을 개별 제거하거나 모두 지울 수 있습니다.",
"clearAll": "모두 지우기",
"removeHost": "이 호스트 기록 제거",
"empty": "기록 없음",
"clearConfirm": "모든 알려진 호스트 키를 지우시겠습니까? 다음 연결 시 다시 확인 메시지가 표시됩니다."
},
"about": {
"tagline": "가벼운 네이티브 SSH / SFTP 운영 터미널",
"appVersion": "앱 v{{version}}",
"copyVersion": "버전 정보 복사",
"runtime": "런타임",
"system": "시스템",
"localData": "로컬 데이터",
"sessionsSettings": "세션 및 설정",
"masterKeyPath": "마스터 키",
"privacyNote": "비밀번호와 키 암호는 Rust에서 AES-256-GCM으로 암호화됩니다. OpsXShell은 터미널 명령 히스토리를 저장하지 않습니다.",
"license": "MIT 라이선스 · Rust · XTerm.js"
},
"ai": {
"presets": "제공자 프리셋",
"add": "추가",
"configured": "구성됨",
"configuredHint": "제공자를 선택하고 추가를 클릭하세요",
"emptyHint": "시작하려면 제공자를 추가하세요",
"noModel": "선택된 모델 없음",
"name": "이름",
"model": "모델",
"protocol": "프로토콜",
"auth": "인증",
"authNone": "없음",
"test": "테스트",
"testing": "테스트 중",
"testingMessage": "테스트 중...",
"saved": "저장됨",
"retest": "다시 테스트해 주세요",
"testFailed": "연결 테스트 실패",
"available": "정상 · {{latency}} ms",
"savedKeepBlank": "저장됨 — 유지하려면 비워두세요",
"notRequired": "필요하지 않음",
"otherModels": "다른 모델…",
"customModel": "사용자 지정 모델",
"backToList": "목록으로",
"apiKeyOptional": "API 키 (필요하지 않음)",
"advanced": "고급",
"allowHttp": "HTTP 허용 (localhost/LAN)",
"setActive": "활성으로 설정",
"deleteTitle": "삭제",
"apiKeySaveFailed": "API 키 저장 실패",
"providerNotFound": "제공자를 찾을 수 없음",
"modelCatalogReadFailed": "모델 카탈로그 읽기 실패",
"catalogUnavailable": "models.dev를 사용할 수 없습니다"
},
"family": {
"openai_compatible": "OpenAI 호환",
"standalone": "────────",
"plan": "플랜",
"local": "셀프 호스팅",
"custom": "사용자 지정"
}
}
+186
View File
@@ -0,0 +1,186 @@
{
"panel": {
"local": "로컬",
"remote": "원격",
"notConnectedTitle": "원격 서버에 연결되지 않음",
"notConnectedDesc": "SFTP를 사용하려면 먼저 SSH 세션을 연결하세요",
"ariaLabel": "{{title}} 파일 패널"
},
"connection": {
"selectServer": "서버 선택",
"noSessions": "저장된 세션 없음",
"createSessionHint": "먼저 사이드바에서 세션을 생성하세요",
"reconnect": "재연결",
"notConnected": "연결되지 않음",
"connecting": "연결 중..."
},
"errors": {
"notConnected": "SFTP가 연결되지 않았습니다",
"noUploadFiles": "업로드할 파일이 없습니다",
"localStatFailed": "로컬 파일 정보를 읽을 수 없습니다",
"loadRemoteFailed": "원격 디렉터리 로드 실패: {{message}}",
"noFolderDownload": "폴더 다운로드 실패",
"selectDownloadFiles": "먼저 다운로드할 파일을 선택하세요",
"uploadFailed": "업로드 실패",
"downloadFailed": "다운로드 실패",
"fileError": "{{fileName}}: {{message}}"
},
"toolbar": {
"upload": "업로드",
"uploadAria": "업로드",
"download": "다운로드",
"downloadAria": "다운로드",
"downloadNeedSelection": "먼저 원격 파일을 선택하세요",
"downloadHint": "선택한 원격 파일 다운로드",
"refresh": "새로고침",
"refreshAria": "새로고침",
"newFolder": "새 폴더",
"newFolderAria": "새 폴더"
},
"sort": {
"name": "이름",
"modified": "수정일",
"size": "크기",
"type": "유형"
},
"nav": {
"home": "홈",
"back": "뒤로",
"forward": "앞으로",
"up": "위로",
"searchPlaceholder": "파일 이름 검색",
"clearSearch": "검색 지우기",
"clearSearchAria": "검색 지우기",
"showHidden": "숨김 파일 표시",
"hideHidden": "도트파일 숨기기 (.xxx)",
"showHiddenAria": "숨김 파일 표시",
"hideHiddenAria": "도트파일 숨기기",
"searchAria": "{{title}}에서 검색"
},
"status": {
"loading": "불러오는 중...",
"selected": "{{count}}개 선택됨",
"filtered": "{{shown}} / {{total}} 표시 중",
"hiddenCount": "전체 {{total}}개 항목 ({{hidden}}개 숨김)",
"total": "{{count}}개 항목",
"filterHint": "필터: {{query}}"
},
"empty": {
"dirTitle": "빈 디렉터리",
"dirDescLocal": "이 디렉터리에 파일이 없습니다",
"dirDescRemote": "위로 이동하거나 새로고침해 보세요",
"goUp": "위로 이동",
"hiddenOnlyTitle": "숨김 파일만",
"hiddenOnlyDesc": "헤더의 눈 아이콘을 클릭하여 도트파일 표시",
"showHiddenAction": "숨김 파일 표시",
"noMatchTitle": "일치하는 파일 없음",
"noMatchDesc": "\"{{query}}\"와 일치하는 파일이 없습니다"
},
"fileType": {
"folder": "폴더",
"symlink": "링크",
"symlinkLong": "심볼릭 링크",
"file": "파일",
"text": "텍스트",
"log": "로그",
"database": "데이터베이스",
"imageIso": "디스크 이미지",
"executable": "실행 파일",
"library": "라이브러리"
},
"relativeDate": {
"today": "오늘",
"yesterday": "어제",
"daysAgo": "{{count}}일 전"
},
"contextMenu": {
"open": "열기",
"upload": "업로드",
"download": "다운로드",
"edit": "편집",
"rename": "이름 변경",
"copyPath": "경로 복사",
"properties": "속성",
"permissions": "권한",
"delete": "삭제"
},
"dialog": {
"renameTitle": "이름 변경",
"renameMessage": "새 이름 입력:",
"renamePlaceholder": "새 이름",
"newFolderTitle": "새 폴더",
"newFolderMessage": "폴더 이름 입력:",
"newFolderPlaceholder": "폴더 이름",
"propertiesTitle": "파일 속성",
"propertiesClose": "닫기",
"chmodTitle": "권한 편집",
"chmodApply": "적용",
"pickUploadTitle": "업로드할 파일 또는 폴더 선택",
"pickUploadRzTitle": "업로드할 파일 선택 (rz)"
},
"properties": {
"name": "이름",
"path": "경로",
"size": "크기",
"permissions": "권한",
"modified": "수정일",
"accessed": "액세스일",
"symlink": "심볼릭 링크",
"loadingDetails": "세부 정보 로드 중..."
},
"chmod": {
"read": "읽기",
"write": "쓰기",
"execute": "실행",
"owner": "소유자",
"group": "그룹",
"other": "기타",
"current": "현재 모드:",
"readR": "읽기 (r)",
"writeW": "쓰기 (w)",
"executeX": "실행 (x)"
},
"transfer": {
"queue": "전송 대기열",
"active": "{{count}}개 활성",
"completed": "{{count}}개 완료",
"taskCount": "{{count}}개 작업",
"empty": "전송 작업 없음",
"cancel": "취소",
"remove": "제거",
"statusWaiting": "대기 중",
"statusDone": "완료",
"statusFailed": "실패",
"statusCancelled": "취소됨",
"dropUpload": "{{path}}에 업로드",
"dropDownload": "{{path}}에 다운로드"
},
"editor": {
"readFailed": "읽기 실패",
"saveFailed": "저장 실패",
"unsavedClose": "저장되지 않은 변경 사항이 있습니다. 그래도 닫으시겠습니까?",
"saving": "저장 중...",
"save": "저장",
"saved": "파일 저장됨",
"loadingEditor": "에디터 로드 중...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S 저장 · 최대 ~2MB",
"charCount": "{{count}}자",
"unsavedMark": " · 저장 안 됨",
"savedMark": " · 저장됨"
},
"toast": {
"renamed": "{{name}}(으)로 이름 변경됨",
"renameFailed": "이름 변경 실패",
"pathCopied": "경로가 클립보드에 복사됨",
"pathCopyFailed": "경로 복사 실패",
"chmodUpdated": "권한이 {{mode}}(으)로 업데이트됨",
"chmodFailed": "권한 업데이트 실패",
"uploadPartial": "{{action}} 완료 {{completed}}, 실패 {{failed}}: {{detail}}",
"uploadSuccess": "{{completed}}개 항목에 대해 {{action}} 완료",
"uploadAction": "업로드",
"downloadAction": "다운로드",
"noFolderUpload": "폴더 업로드 실패",
"noDragPath": "드래그 앤 드롭 경로를 사용할 수 없습니다; 업로드를 사용하세요",
"noFolderRecursive": "재귀 폴더 전송 실패; 재시도하거나 업로드를 사용하세요"
}
}
+32
View File
@@ -0,0 +1,32 @@
{
"panel": {
"title": "명령 스니펫"
},
"search": {
"placeholder": "스니펫 검색..."
},
"form": {
"name": "이름",
"command": "명령",
"tags": "태그",
"tagsHint": "(쉼표로 구분)",
"namePlaceholder": "예: Nginx 재시작",
"commandPlaceholder": "sudo systemctl restart nginx\n# {{host}} {{username}} {{date}} 지원",
"variables": "변수:"
},
"dialog": {
"createTitle": "새 스니펫",
"editTitle": "스니펫 편집"
},
"empty": {
"noMatch": "일치하는 스니펫 없음",
"noMatchDesc": "다른 키워드를 시도해 보세요",
"noSnippets": "아직 스니펫이 없습니다",
"noSnippetsDesc": "자주 쓰는 명령을 저장하고 터미널에 삽입하세요"
},
"action": {
"create": "새 스니펫",
"insert": "터미널에 삽입",
"noTerminal": "활성 터미널 없음"
}
}
+119
View File
@@ -0,0 +1,119 @@
{
"toolbar": {
"splitHorizontal": "좌/우 분할",
"splitVertical": "상/하 분할",
"addPane": "창 추가",
"closePane": "현재 창 닫기",
"maximizePane": "현재 창 최대화",
"restoreLayout": "분할 레이아웃 복원",
"broadcast": "브로드캐스트",
"broadcastAria": "입력 브로드캐스트",
"broadcastOn": "브로드캐스트 켜짐: 입력이 범위 내 {{count}}개 터미널에 동기화됨",
"broadcastOffPro": "입력 브로드캐스트 (Pro) · 범위 내 {{count}}개 터미널",
"broadcastNeedPanesTab": "이 탭은 브로드캐스트하려면 최소 2개의 준비된 창이 필요합니다 (먼저 분할하세요)",
"broadcastNeedPanesAll": "모든 터미널 탭은 브로드캐스트하려면 최소 2개의 준비된 터미널이 필요합니다",
"broadcastScopeAria": "브로드캐스트 범위",
"broadcastScopeTab": "현재 탭 창",
"broadcastScopeAll": "모든 터미널 탭",
"broadcastActive": "브로드캐스트 중 · {{count}}",
"aiAssistant": "AI 어시스턴트",
"aiOpen": "터미널 AI 어시스턴트 열기",
"aiClose": "터미널 AI 어시스턴트 닫기",
"aiTitle": "터미널 AI 어시스턴트 (Pro)",
"paneCount": "{{current}}/{{max}}",
"labelLocal": "로컬 터미널",
"labelSsh": "SSH 터미널",
"closePaneLabel": "현재 창 닫기",
"closeTabLabel": "현재 터미널 탭 닫기",
"targetSshSession": "현재 SSH 세션"
},
"overlay": {
"shellClosedIdle": "유휴 시간 초과; 셸이 종료됨",
"shellClosed": "셸이 종료됨",
"shellClosedHint": "SSH 연결은 유지됩니다; 다른 창, SFTP 및 터널은 영향을 받지 않습니다",
"reopenShell": "셸 다시 열기",
"reopening": "여는 중…",
"disconnected": "연결 끊김",
"disconnectedHint": "SSH 세션이 종료되었거나 네트워크가 끊겼습니다. 아래를 클릭하여 재연결하세요.",
"reconnect": "재연결",
"suspended": "연결 일시 중단됨",
"suspendedHint": "오랫동안 활동이 없어 리소스 절약을 위해 연결이 일시 중단되었습니다",
"resume": "연결 재개",
"connectFailed": "연결 실패",
"connectFailedHint": "호스트, 포트, 사용자 이름 및 인증을 확인하세요",
"retryConnect": "연결 재시도",
"connecting": "연결 중…",
"reconnecting": "자동 재연결 중{{attempt}}…",
"reconnectingAttempt": " ({{count}})",
"localShellExited": "로컬 셸이 종료됨"
},
"hostKey": {
"titleNew": "호스트 키 확인",
"titleChanged": "호스트 키가 변경됨",
"descNew": "이 호스트에 처음 연결합니다. 신뢰하기 전에 핑거프린트를 확인하세요.",
"descChanged": "이 호스트의 SSH 키가 로컬 기록과 더 이상 일치하지 않습니다. MITM 위험 가능성.",
"host": "호스트",
"type": "유형",
"fingerprint": "SHA256 핑거프린트",
"previousFingerprint": "이전 핑거프린트",
"reject": "거부",
"acceptOnce": "한 번 신뢰",
"acceptAlways": "항상 신뢰",
"acceptAlwaysChanged": "그래도 신뢰하고 업데이트"
},
"contextMenu": {
"aria": "터미널 작업",
"copy": "복사",
"paste": "붙여넣기",
"selectAll": "모두 선택",
"clear": "화면 지우기",
"splitRight": "오른쪽으로 분할",
"splitDown": "아래로 분할",
"maximizePane": "현재 창 최대화",
"restoreLayout": "분할 레이아웃 복원"
},
"search": {
"placeholder": "검색...",
"previous": "이전 (Shift+Enter)",
"next": "다음 (Enter)",
"close": "닫기 (Escape)"
},
"zmodem": {
"uploadTransferring": "rz 업로드: {{detail}}",
"downloadTransferring": "sz 다운로드: {{detail}}",
"selectLocalFile": "로컬 파일 선택",
"pickUploadTitle": "업로드할 파일 선택 (rz)",
"uploadedCount": "{{count}}개 파일 업로드됨",
"downloadedSingle": "{{path}}",
"downloadedCount": "{{count}}개 파일 다운로드됨 → {{dir}}",
"transferDone": "전송 완료",
"transferFailed": "전송 실패 {{message}}",
"uploadSuccessTerminal": "✓ {{count}}개 파일을 원격 작업 디렉터리에 업로드함",
"downloadSuccessTerminal": "✓ {{path}} 다운로드됨",
"savedDownloadsSingle": "✓ 다운로드에 저장됨",
"savedDownloadsMultiple": "✓ {{count}}개 파일을 다운로드에 저장함",
"nativeApiUnavailable": "네이티브 API를 사용할 수 없음",
"readFailed": "읽기 실패: {{name}}",
"writeFailed": "쓰기 실패: {{name}}",
"createLocalShellFailed": "로컬 셸 생성 실패",
"createRemoteShellFailed": "원격 셸 생성 실패",
"createShellFailed": "셸 생성 실패: {{error}}"
},
"clipboard": {
"readFailed": "클립보드 읽기 실패",
"writeFailed": "클립보드 쓰기 실패"
},
"input": {
"failed": "터미널 입력 실패"
},
"connection": {
"errorPrefix": "오류: {{message}}",
"autoReconnecting": "자동 재연결 중 ({{attempt}})...",
"autoReconnectLimit": "자동 재연결 한도 도달 ({{max}}){{reasonSuffix}}",
"autoReconnectLimitReason": " — {{reason}}",
"disconnectedRetry": "연결 끊김, {{seconds}}초 후 {{attempt}}/{{max}} 재시도...",
"autoReconnectBanner": "[자동 재연결] {{seconds}}초 후 {{attempt}}/{{max}} 재시도 중",
"disconnectedBanner": "[연결 끊김] {{reason}}",
"noConfig": "사용 가능한 연결 정보가 없음"
}
}