From 0ffb8705a323a693abafcf3aa0ce0fbada8e2318 Mon Sep 17 00:00:00 2001 From: moduvoice Date: Sat, 11 Jul 2026 22:21:29 +0700 Subject: [PATCH] feat(i18n): add Korean (ko) translation Adds a complete Korean locale (web/src/i18n/locales/ko.json) mirroring the full key structure of en.json (1340 leaf keys, 0 missing/extra), with interpolation placeholders and inline tags verified to match exactly. Registers ko in the i18next resource map (i18n/config.ts) and the language switcher dropdown (LanguageSwitcher). Verified with: - python key-set diff (en vs ko): 0 missing, 0 extra - python placeholder/tag diff ({{var}}, <1>...): 0 mismatches - pnpm vitest run (full suite): 180 files / 609 tests passed - tsc --noEmit: no errors - eslint on changed files: no issues --- web/src/i18n/config.ts | 2 + web/src/i18n/locales/ko.json | 1552 +++++++++++++++++ .../shared/components/language-switcher.tsx | 1 + 3 files changed, 1555 insertions(+) create mode 100644 web/src/i18n/locales/ko.json diff --git a/web/src/i18n/config.ts b/web/src/i18n/config.ts index 9973671f..f866308e 100644 --- a/web/src/i18n/config.ts +++ b/web/src/i18n/config.ts @@ -3,6 +3,7 @@ import { initReactI18next } from 'react-i18next' import LanguageDetector from 'i18next-browser-languagedetector' import en from './locales/en.json' import zh from './locales/zh.json' +import ko from './locales/ko.json' /** * Initializes i18next for the browser app. Language preference is restored from @@ -16,6 +17,7 @@ i18n resources: { en: { translation: en }, zh: { translation: zh }, + ko: { translation: ko }, }, fallbackLng: 'en', interpolation: { diff --git a/web/src/i18n/locales/ko.json b/web/src/i18n/locales/ko.json new file mode 100644 index 00000000..33d4169f --- /dev/null +++ b/web/src/i18n/locales/ko.json @@ -0,0 +1,1552 @@ +{ + "nav": { + "landing": "홈", + "home": "스킬 센터", + "search": "검색", + "skillDetail": "스킬 상세", + "explore": "스킬 탐색", + "dashboard": "대시보드", + "mySkills": "내 스킬", + "publish": "게시", + "login": "로그인" + }, + "landing": { + "hero": { + "title": "AI 스킬을 발견하고 공유하세요", + "subtitle": "커뮤니티가 만든 스킬로 강력한 AI 에이전트를 만들어 보세요", + "searchPlaceholder": "스킬 검색...", + "exploreSkills": "스킬 탐색", + "publishSkill": "스킬 게시" + }, + "features": { + "secure": { + "title": "보안 및 프라이버시", + "description": "AI 워크플로우를 위한 엔터프라이즈급 보안" + }, + "community": { + "title": "커뮤니티 기반", + "description": "전 세계 개발자들과 스킬을 공유하고 발견하세요" + }, + "integration": { + "title": "손쉬운 연동", + "description": "기존에 사용하던 도구와 매끄럽게 통합됩니다" + }, + "versionControl": { + "title": "버전 관리", + "description": "스킬 패키지를 추적 가능하고 안정적으로 유지하는 체계적인 버전 관리 및 릴리스 워크플로우" + }, + "cli": { + "title": "CLI 도구", + "description": "스킬 패키지를 게시, 설치, 관리할 수 있는 강력한 커맨드라인 워크플로우" + }, + "governance": { + "title": "리뷰 거버넌스", + "description": "엔터프라이즈 스킬 품질을 유지하는 내장 리뷰 절차와 권한 제어" + } + }, + "stats": { + "skills": "카탈로그", + "downloads": "다운로드", + "teams": "팀" + }, + "whySkillHub": { + "title": "SkillHub를 선택해야 하는 이유", + "subtitle": "엔터프라이즈 팀을 위해 설계된 프라이빗 에이전트 스킬 플랫폼" + }, + "badge": "엔터프라이즈 스킬 레지스트리", + "tagline": "게시, 발견, 관리", + "taglineHighlight": " 에이전트 스킬", + "description": "팀을 위한 안전하고 효율적인 스킬 공유와 협업을 제공하는 셀프 호스팅 프라이빗 스킬 레지스트리", + "publishSkill": "스킬 게시", + "statsSkills": "스킬", + "statsDownloads": "다운로드", + "statsTeams": "팀", + "whyTitle": "선택해야 하는 이유", + "whyDescription": "완전한 게시, 발견, 거버넌스 기능을 갖춘 엔터프라이즈급 스킬 관리 플랫폼", + "featuresList": { + "privateDeploy": { + "title": "프라이빗 배포", + "description": "데이터 주권을 보장하는 완전한 셀프 호스팅. 한 번의 클릭으로 인프라에 배포하여 방화벽 뒤에서 안전하게 운영하세요." + }, + "versionControl": { + "title": "버전 관리", + "description": "시맨틱 버전 관리, 커스텀 태그(beta, stable), 최신 버전 자동 추적" + }, + "smartSearch": { + "title": "스마트 검색", + "description": "네임스페이스, 다운로드 수, 평점, 시간 등 다차원 필터링을 지원하는 전문(全文) 검색" + }, + "teamwork": { + "title": "팀 협업", + "description": "네임스페이스 관리, 역할 기반 접근 제어(Owner/Admin/Member), 게시 정책 설정" + }, + "governance": { + "title": "리뷰 및 거버넌스", + "description": "팀 단위 리뷰, 플랫폼 단위 승인, 전체 감사 추적으로 컴플라이언스 요구사항을 충족합니다" + }, + "cliFirst": { + "title": "CLI 퍼스트", + "description": "네이티브 REST API로 기존 ClawHub CLI 도구와 호환되며, 클라이언트 측 변경이 필요 없습니다" + } + }, + "ctaTitle": "지금 바로 시작해 보세요", + "ctaDescription": "명령어 하나로 로컬 개발 환경을 실행하고 전체 스킬 관리 워크플로우를 체험해 보세요", + "ctaButton": "지금 시작하기", + "footerLicense": "© 2026 SkillHub. Apache License 2.0.", + "footerDocs": "문서", + "footerGithub": "GitHub", + "footerCommunity": "커뮤니티", + "quickStart": { + "title": "빠른 시작", + "subtitle": "Quick Start", + "description": "원하는 작업 방식을 선택한 뒤 설정 안내를 복사해서 계속 진행하세요", + "tip": "💡 팁: 스킬 상세 페이지에서 환경 변수가 포함된 원클릭 설치 명령을 확인할 수 있습니다", + "tabs": { + "agent": "저는 에이전트입니다", + "human": "저는 사람입니다", + "cli": "CLI" + }, + "cli": { + "description": "SkillHub CLI를 로컬에 설치하고 skillhub install 명령으로 스킬을 설치하세요.", + "command": "npm i -g @astron-team/skillhub" + }, + "agent": { + "description": "에이전트에게 프롬프트를 전달해 SkillHub 레지스트리를 설정하세요", + "command": "https://www.example.com/registry/skill.md 문서를 읽고 안내에 따라 SkillHub Skills Registry를 설정하세요", + "commandTemplate": "{{url}}을(를) 읽고 안내에 따라 SkillHub Skills Registry를 설정하세요" + }, + "human": { + "description": "CLI 도구로 스킬을 설치하세요", + "command": "npx clawhub search " + }, + "steps": { + "configureEnv": { + "title": "1. 환경 변수 설정", + "description": "ClawHub CLI가 SkillHub에 연결되도록 설정합니다" + }, + "installSkills": { + "title": "2. 스킬 설치", + "description": "필요한 스킬을 검색하고 설치하세요", + "code": "# 스킬 검색\nclawhub search \n\n# 스킬 설치\nclawhub install " + }, + "publishSkills": { + "title": "3. 스킬 게시", + "description": "만든 스킬을 팀과 공유하세요", + "code": "# 스킬 게시\nclawhub publish\n\n# 또는 웹 화면에서\n# \"스킬 게시\" 클릭" + } + } + } + }, + "home": { + "subtitle": "스킬 레지스트리", + "description": "개발자를 위한 효율적인 스킬 관리, 배포, 협업 플랫폼", + "browseSkills": "스킬 둘러보기", + "publishSkill": "스킬 게시", + "popularTitle": "인기 다운로드", + "popularDescription": "커뮤니티에서 가장 인기 있는 스킬", + "latestTitle": "최신 릴리스", + "latestDescription": "새로 게시된 스킬", + "viewAll": "전체 보기 →", + "quickStart": { + "title": "빠른 시작", + "subtitle": "Quick Start", + "description": "몇 가지 간단한 단계만으로 SkillHub를 시작할 수 있습니다", + "tip": "💡 팁: 스킬 상세 페이지에서 환경 변수가 포함된 원클릭 설치 명령을 확인할 수 있습니다", + "steps": { + "configureEnv": { + "title": "1. 환경 변수 설정", + "description": "ClawHub CLI가 SkillHub에 연결되도록 설정합니다" + }, + "installSkills": { + "title": "2. 스킬 설치", + "description": "필요한 스킬을 검색하고 설치하세요", + "code": "# 스킬 검색\nclawhub search \n\n# 스킬 설치\nclawhub install " + }, + "publishSkills": { + "title": "3. 스킬 게시", + "description": "만든 스킬을 팀과 공유하세요", + "code": "# 스킬 게시\nclawhub publish\n\n# 또는 웹 화면에서\n# \"스킬 게시\" 클릭" + } + } + } + }, + "search": { + "title": "스킬 검색", + "placeholder": "스킬 검색...", + "filters": { + "label": "필터:" + }, + "sort": { + "label": "정렬:", + "relevance": "관련도", + "downloads": "다운로드", + "stars": "평점", + "newest": "최신순" + }, + "noResults": "검색 결과가 없습니다", + "noResultsFor": "\"{{q}}\"에 대한 검색 결과가 없습니다", + "filterStarred": "즐겨찾기만 보기", + "noStarredResults": "즐겨찾기한 스킬이 없습니다", + "noStarredResultsFor": "즐겨찾기한 스킬 중 \"{{q}}\"와(과) 일치하는 항목이 없습니다", + "noStarredSkills": "아직 즐겨찾기한 스킬이 없습니다", + "namespaceFilter": "@{{namespace}}", + "enterKeyword": "검색어를 입력해 주세요", + "results": "스킬 {{count}}개를 찾았습니다", + "resultCount": "총 <1>{{count}}개의 결과", + "loadingMore": "검색 결과를 갱신하는 중..." + }, + "searchBar": { + "placeholder": "스킬 검색...", + "button": "검색", + "clear": "검색어 지우기" + }, + "login": { + "title": "SkillHub 로그인", + "subtitle": "계속하려면 로그인 방법을 선택하세요", + "tabPassword": "비밀번호", + "tabOAuth": "OAuth", + "username": "아이디", + "password": "비밀번호", + "usernamePlaceholder": "아이디를 입력하세요", + "passwordPlaceholder": "비밀번호를 입력하세요", + "usernameRequired": "아이디를 입력해 주세요", + "passwordRequired": "비밀번호를 입력해 주세요", + "showPassword": "비밀번호 표시", + "hidePassword": "비밀번호 숨기기", + "submitting": "로그인 중...", + "submit": "로그인", + "forgotPassword": "비밀번호를 잊으셨나요?", + "noAccount": "계정이 없으신가요?", + "register": "지금 가입하기", + "oauthHint": "OAuth 인증이 끝나면 이 사이트로 자동으로 돌아옵니다.", + "passwordCompatHint": "이 배포 환경은 비밀번호 호환 계층이 활성화되어 있습니다. 폼이 고정된 로컬 계정 엔드포인트 대신 {{name}}(으)로 전달됩니다.", + "enterpriseSsoTitle": "기업용 SSO", + "enterpriseSsoHint": "이 배포 환경은 호환 계층이 활성화되어 있습니다. 브라우저에 이미 {{name}} 세션이 있다면 바로 SkillHub 세션을 만들어 볼 수 있습니다.", + "enterpriseSsoAutoHint": "이 배포 환경은 {{name}} 자동 감지가 활성화되어 있습니다. 성공하지 않으면 다른 일반 로그인 방법을 계속 사용할 수 있습니다.", + "enterpriseSsoAction": "{{name}}(으)로 시도", + "enterpriseSsoSubmitting": "{{name}}(으)로 시도 중...", + "agreementPrefix": "로그인하면 다음에 동의하는 것으로 간주됩니다:", + "terms": "이용약관", + "and": "및", + "privacy": "개인정보처리방침" + }, + "register": { + "title": "계정 만들기", + "subtitle": "로컬 계정으로 가입하거나 OAuth로 바로 로그인할 수 있습니다.", + "tabLocal": "로컬 계정", + "tabOAuth": "OAuth", + "username": "아이디", + "email": "이메일", + "password": "비밀번호", + "usernamePlaceholder": "3~64자: 영문, 숫자, 밑줄(_) 사용 가능", + "emailPlaceholder": "이메일을 입력하세요", + "emailRequired": "이메일을 입력해 주세요", + "passwordPlaceholder": "8자 이상, 문자 유형 3종류 이상 조합", + "submitting": "가입 중...", + "submit": "가입하고 로그인", + "hasAccount": "이미 계정이 있으신가요?", + "login": "로그인으로 돌아가기", + "oauthHint": "기존 OAuth 계정으로 바로 로그인할 수 있습니다. 로컬 비밀번호가 필요하지 않습니다.", + "usernameRequired": "아이디를 입력해 주세요", + "usernameInvalid": "영문, 숫자, 밑줄(_)만 사용할 수 있습니다 (3~64자)", + "usernameExists": "이미 사용 중인 아이디입니다", + "passwordRequired": "비밀번호를 입력해 주세요", + "passwordTooShort": "비밀번호는 8자 이상이어야 합니다", + "passwordTooWeak": "비밀번호는 대문자, 소문자, 숫자, 특수문자 중 최소 3종류를 포함해야 합니다", + "emailInvalid": "올바르지 않은 이메일 형식입니다", + "emailExists": "이미 사용 중인 이메일입니다" + }, + "resetPassword": { + "title": "비밀번호 재설정", + "subtitle": "이메일, 인증 코드, 새 비밀번호를 입력하세요.", + "email": "이메일", + "emailPlaceholder": "이메일을 입력하세요", + "emailRequired": "이메일을 입력해 주세요", + "emailInvalid": "올바른 이메일 주소를 입력해 주세요", + "code": "인증 코드", + "codePlaceholder": "6자리 인증 코드를 입력하세요", + "sendCode": "인증 코드 보내기", + "sendingCode": "보내는 중...", + "codeSentMessage": "해당 계정이 확인되면 인증 코드가 전송됩니다.", + "codeRequired": "인증 코드를 입력해 주세요", + "newPassword": "새 비밀번호", + "newPasswordPlaceholder": "새 비밀번호를 입력하세요", + "newPasswordRequired": "새 비밀번호를 입력해 주세요", + "confirmPassword": "비밀번호 확인", + "confirmPasswordPlaceholder": "새 비밀번호를 다시 입력하세요", + "passwordMismatch": "두 비밀번호가 일치하지 않습니다", + "submit": "비밀번호 재설정", + "submitting": "재설정 중...", + "successMessage": "비밀번호가 재설정되었습니다. 새 비밀번호로 로그인해 주세요.", + "genericError": "비밀번호 재설정에 실패했습니다", + "backToLogin": "로그인으로 돌아가기" + }, + "device": { + "title": "기기 인증", + "subtitle": "기기에 표시된 8자리 사용자 코드를 입력하세요", + "codeLabel": "사용자 코드", + "codeHint": "형식: XXXX-XXXX (붙여넣기 지원)", + "incompleteCode": "8자리 사용자 코드를 모두 입력해 주세요", + "success": "기기 인증에 성공했습니다!", + "defaultError": "인증에 실패했습니다. 사용자 코드를 확인해 주세요", + "submitting": "인증 중...", + "submit": "기기 인증", + "notice": "인증이 완료되면 해당 기기가 계정에 접근할 수 있게 됩니다" + }, + "cliAuth": { + "validating": "확인 중...", + "pleaseWait": "잠시만 기다려 주세요", + "creatingToken": "토큰 생성 중...", + "almostThere": "거의 다 되었습니다", + "success": "인증에 성공했습니다", + "redirecting": "CLI로 이동하는 중...", + "fallbackInstructions": "브라우저가 자동으로 이동하지 않으면 아래 토큰을 복사해 주세요:", + "error": "인증에 실패했습니다", + "notAuthenticated": "로그인되어 있지 않습니다", + "invalidRedirectUri": "유효하지 않은 리디렉션 URI입니다", + "missingState": "보안 파라미터가 누락되었습니다", + "windowsUrlBug": "알려진 Windows 이슈: 브라우저가 불완전한 URL을 열었습니다. CLI 출력에서 'Opening browser:'로 시작하는 줄의 전체 URL을 복사해 브라우저 주소창에 붙여넣어 주세요.", + "tokenCreationFailed": "토큰 생성에 실패했습니다", + "loginRequired": "CLI 접근을 인증하려면 먼저 로그인해 주세요", + "goToLogin": "로그인하러 가기" + }, + "dashboard": { + "title": "대시보드", + "subtitle": "계정 정보, 스킬, 접근 자격 증명을 한곳에서 확인하세요", + "backToDashboard": "대시보드로 돌아가기", + "userInfo": "계정 정보", + "userInfoDesc": "기본 계정 정보와 플랫폼 역할", + "loginVia": "{{provider}}(으)로 로그인함", + "platformRoles": "플랫폼 역할", + "starsAndRatings": "즐겨찾기 및 평점", + "viewStars": "내 즐겨찾기 보기", + "subscriptions": "구독", + "viewSubscriptions": "내 구독 보기", + "mySkillsTitle": "내 스킬", + "openMySkills": "내 스킬 보기", + "mySkillsPreviewDescription": "최근에 게시한 스킬 5개를 표시합니다. 스킬을 열거나 내 스킬 페이지에서 전체 목록을 확인하세요.", + "mySkillsPreviewEmpty": "아직 게시한 스킬이 없습니다", + "credentials": "자격 증명", + "openTokens": "API 토큰 보기", + "governanceTitle": "리뷰 및 거버넌스", + "viewGovernance": "거버넌스 센터 열기", + "viewPromotions": "승격 목록 보기", + "reportsTitle": "신고 관리", + "viewReports": "스킬 신고 보기", + "previewMore": "...", + "previewMoreLabel": "전체 보기", + "userId": "사용자 ID" + }, + "mySkills": { + "title": "내 스킬", + "subtitle": "게시한 스킬을 관리하세요", + "searchPlaceholder": "이름, 슬러그, 설명으로 검색", + "namespaceFilterLabel": "네임스페이스로 필터링", + "namespaceFilterAll": "모든 네임스페이스", + "clearSearch": "필터 지우기", + "emptySearchTitle": "일치하는 스킬이 없습니다", + "emptySearchDescription": "검색어를 조정하거나 네임스페이스를 변경해 보세요.", + "filters": { + "ALL": "전체", + "PENDING_REVIEW": "리뷰 대기 중", + "PUBLISHED": "게시됨", + "REJECTED": "거부됨", + "ARCHIVED": "보관됨", + "HIDDEN": "숨김" + }, + "publishNew": "새 스킬 게시", + "update": "업데이트", + "archive": "보관", + "unarchive": "복원", + "statusArchived": "보관됨", + "statusPendingReview": "리뷰 대기 중", + "statusPublished": "게시됨", + "statusRejected": "거부됨", + "statusHidden": "숨김", + "statusScanning": "검사 중", + "statusScanFailed": "검사 실패", + "archiveConfirmTitle": "스킬 보관", + "archiveConfirmDescription": "보관하면 일반 사용자는 더 이상 \"{{skill}}\"을(를) 보거나 다운로드할 수 없습니다. 계속하시겠습니까?", + "unarchiveConfirmTitle": "스킬 복원", + "unarchiveConfirmDescription": "복원하면 \"{{skill}}\"이(가) 다시 표시되며 새 버전을 게시할 수 있습니다.", + "archiveSuccessTitle": "스킬이 보관되었습니다", + "archiveSuccessDescription": "\"{{skill}}\"이(가) 보관되었습니다.", + "archiveErrorTitle": "스킬 보관에 실패했습니다", + "unarchiveSuccessTitle": "스킬이 복원되었습니다", + "unarchiveSuccessDescription": "\"{{skill}}\"이(가) 복원되어 다시 새 버전을 게시할 수 있습니다.", + "unarchiveErrorTitle": "스킬 복원에 실패했습니다", + "withdrawReview": "리뷰 철회", + "withdrawConfirmTitle": "업로드 철회", + "withdrawConfirmDescription": "철회하면 \"{{skill}}\"은(는) 더 이상 리뷰되지 않으며 대기 중인 버전이 삭제됩니다.", + "withdrawSuccessTitle": "업로드가 철회되었습니다", + "withdrawSuccessDescription": "\"{{skill}}\"의 대기 중이던 버전이 철회되었습니다.", + "withdrawErrorTitle": "업로드 철회에 실패했습니다", + "promoteToGlobal": "글로벌로 승격", + "promotionConfirmTitle": "승격 요청 제출", + "promotionConfirmDescription": "\"{{skill}}\"의 v{{version}}을(를) 글로벌 네임스페이스로 승격하도록 제출하시겠습니까?", + "promotionSuccessTitle": "승격 요청이 제출되었습니다", + "promotionSuccessDescription": "\"{{skill}}\"의 v{{version}}이(가) 글로벌 승격 리뷰 대기열에 등록되었습니다.", + "promotionDuplicateTitle": "이미 대기 중인 승격 요청이 있습니다", + "promotionDuplicateDescription": "이 버전은 이미 승격 요청이 대기 중입니다.", + "promotionAlreadyPromotedTitle": "이미 승격된 스킬입니다", + "promotionAlreadyPromotedDescription": "이 스킬은 이미 글로벌 네임스페이스로 승격되었습니다.", + "promotionErrorTitle": "승격 요청 제출에 실패했습니다", + "emptyTitle": "아직 스킬이 없습니다", + "emptyDescription": "첫 스킬을 게시해 보세요", + "emptyFilteredTitle": "이 필터와 일치하는 스킬이 없습니다", + "emptyFilteredDescription": { + "PENDING_REVIEW": "현재 리뷰를 기다리는 스킬이 없습니다.", + "PUBLISHED": "현재 게시된 스킬이 없습니다.", + "REJECTED": "현재 거부된 스킬이 없습니다.", + "ARCHIVED": "현재 보관된 스킬이 없습니다.", + "HIDDEN": "현재 숨겨진 스킬이 없습니다." + }, + "publishSkill": "스킬 게시" + }, + "myNamespaces": { + "title": "내 네임스페이스", + "subtitle": "네임스페이스와 팀을 관리하세요", + "create": "네임스페이스 만들기", + "creating": "만드는 중...", + "createSubmit": "지금 만들기", + "createDialogTitle": "팀 네임스페이스 만들기", + "createDialogDescription": "생성 후에는 소유자(OWNER)가 되며, 이어서 멤버, 리뷰, 스킬 게시를 관리할 수 있습니다.", + "createSlugLabel": "네임스페이스 슬러그", + "createSlugPlaceholder": "예: team-ml", + "createSlugHint": "2~64자의 영문 소문자, 숫자, 하이픈(-)만 사용하고, 시작과 끝에 하이픈을 넣지 마세요.", + "createSlugRequired": "네임스페이스 슬러그를 입력해 주세요", + "createSlugLength": "네임스페이스 슬러그는 {{min}}~{{max}}자여야 합니다", + "createSlugPattern": "네임스페이스 슬러그는 영문 소문자, 숫자, 하이픈(-)만 사용할 수 있습니다", + "createSlugDoubleHyphen": "네임스페이스 슬러그에는 하이픈을 연속으로 사용할 수 없습니다", + "createSlugReserved": "\"{{slug}}\"은(는) 예약된 이름입니다. 다른 슬러그를 선택해 주세요.", + "createDisplayNameLabel": "표시 이름", + "createDisplayNamePlaceholder": "예: Machine Learning Team", + "createDisplayNameRequired": "표시 이름을 입력해 주세요", + "createDisplayNameLength": "표시 이름은 최대 {{max}}자까지 가능합니다", + "createDescriptionLabel": "설명", + "createDescriptionPlaceholder": "이 네임스페이스의 용도, 사용자, 운영 방식을 간단히 설명해 주세요", + "createDescriptionHint": "선택 사항이며 최대 512자까지 입력할 수 있습니다.", + "createDescriptionLength": "설명은 최대 {{max}}자까지 가능합니다", + "createSuccessTitle": "네임스페이스가 생성되었습니다", + "createSuccessDescription": "\"{{name}}\"이(가) 준비되었습니다. 이제 멤버를 관리하거나 스킬을 게시할 수 있습니다.", + "createErrorTitle": "네임스페이스 생성에 실패했습니다", + "typeGlobal": "글로벌", + "typeTeam": "팀", + "roleLabel": "현재 역할", + "roleUnknown": "알 수 없음", + "manageMembers": "멤버 관리", + "reviewTasks": "리뷰 작업", + "freeze": "동결", + "unfreeze": "동결 해제", + "archive": "보관", + "restore": "복원", + "delete": "삭제", + "activeHint": "이 네임스페이스는 완전히 활성화되어 있으며 멤버, 리뷰, 스킬 게시를 계속 관리할 수 있습니다.", + "frozenHint": "이 네임스페이스는 동결되어 있습니다. 멤버는 여전히 볼 수 있지만 읽기 전용이며 게시나 멤버 변경은 할 수 없습니다.", + "archivedHint": "이 네임스페이스는 보관되어 있습니다. 공개 진입점에서는 숨겨지지만 대시보드에서 계속 보고 복원할 수 있습니다.", + "immutableHint": "이 네임스페이스는 시스템 기본 네임스페이스이며 항상 읽기 전용으로 유지됩니다.", + "freezeConfirmTitle": "네임스페이스 동결", + "freezeConfirmDescription": "동결하면 \"{{name}}\"은(는) 읽기 전용이 됩니다. 계속하시겠습니까?", + "unfreezeConfirmTitle": "네임스페이스 동결 해제", + "unfreezeConfirmDescription": "동결 해제하면 \"{{name}}\"이(가) 일반 관리 및 게시 기능을 다시 사용할 수 있게 됩니다.", + "archiveConfirmTitle": "네임스페이스 보관", + "archiveConfirmDescription": "\"{{name}}\"은(는) 공개 진입점에서 숨겨지며 대시보드에서만 복원할 수 있습니다.", + "restoreConfirmTitle": "네임스페이스 복원", + "restoreConfirmDescription": "\"{{name}}\"이(가) 다시 활성 상태로 돌아갑니다.", + "deleteConfirmTitle": "네임스페이스 삭제", + "deleteConfirmDescription": "\"{{name}}\"이(가) 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", + "freezeSuccessTitle": "네임스페이스가 동결되었습니다", + "freezeSuccessDescription": "\"{{name}}\"이(가) 이제 읽기 전용입니다.", + "freezeErrorTitle": "네임스페이스 동결에 실패했습니다", + "unfreezeSuccessTitle": "네임스페이스 동결이 해제되었습니다", + "unfreezeSuccessDescription": "\"{{name}}\"이(가) 다시 활성화되었습니다.", + "unfreezeErrorTitle": "네임스페이스 동결 해제에 실패했습니다", + "archiveSuccessTitle": "네임스페이스가 보관되었습니다", + "archiveSuccessDescription": "\"{{name}}\"이(가) 이제 공개 진입점에서 숨겨집니다.", + "archiveErrorTitle": "네임스페이스 보관에 실패했습니다", + "restoreSuccessTitle": "네임스페이스가 복원되었습니다", + "restoreSuccessDescription": "\"{{name}}\"이(가) 다시 정상적으로 운영될 수 있습니다.", + "restoreErrorTitle": "네임스페이스 복원에 실패했습니다", + "deleteSuccessTitle": "네임스페이스가 삭제되었습니다", + "deleteSuccessDescription": "\"{{name}}\"이(가) 영구적으로 삭제되었습니다.", + "deleteErrorTitle": "네임스페이스 삭제에 실패했습니다", + "emptyTitle": "아직 네임스페이스가 없습니다", + "emptyDescription": "네임스페이스를 만들어 스킬을 정리해 보세요" + }, + "tokens": { + "pageTitle": "토큰 관리", + "pageSubtitle": "CLI 및 API 접근 자격 증명을 관리하세요" + }, + "reviews": { + "title": "리뷰 센터", + "subtitle": "플랫폼 리뷰 작업을 관리하세요", + "typeSkill": "스킬 리뷰", + "typeProfile": "프로필 리뷰", + "tabPending": "대기 중", + "tabApproved": "승인됨", + "tabRejected": "거부됨", + "empty": "리뷰 작업이 없습니다", + "colSkill": "스킬", + "colVersion": "버전", + "colSubmitter": "제출자", + "colSubmitTime": "제출 시각", + "colReviewer": "리뷰어", + "colReviewTime": "리뷰 시각", + "sortLabel": "시간순 정렬", + "sortNewest": "최신순", + "sortOldest": "오래된순", + "pageSummary": "총 {{total}}건, {{page}}페이지", + "prevPage": "이전", + "nextPage": "다음" + }, + "profileReview": { + "queueTitle": "프로필 리뷰 대기열", + "queueSubtitle": "상태 필터, 페이지네이션, 리뷰 작업을 통해 표시 이름 변경 요청을 처리하세요.", + "empty": "프로필 리뷰 작업이 없습니다", + "colUser": "사용자", + "colCurrentName": "현재 이름", + "colRequestedName": "요청한 이름", + "colSubmittedAt": "제출 시각", + "colMachineResult": "자동 검사 결과", + "colActions": "작업", + "colReviewInfo": "리뷰 정보", + "approve": "승인", + "reject": "거부", + "approveSuccess": "프로필 변경이 승인되었습니다", + "approveFailed": "승인에 실패했습니다", + "rejectSuccess": "프로필 변경이 거부되었습니다", + "rejectFailed": "거부 처리에 실패했습니다", + "confirmApproveTitle": "승인 확인", + "confirmApproveDesc": "\"{{from}}\"을(를) \"{{to}}\"(으)로 변경하는 것을 승인하시겠습니까?", + "confirmRejectTitle": "변경 거부", + "confirmRejectDesc": "거부 사유를 입력해 주세요.", + "rejectPlaceholder": "거부 사유...", + "userId": "사용자 ID", + "reviewer": "리뷰어", + "comment": "코멘트", + "totalItems": "총 {{total}}건의 프로필 리뷰 기록", + "sortLabel": "시간순 정렬", + "sortNewest": "최신순", + "sortOldest": "오래된순", + "pageSummary": "총 {{total}}건, {{page}}페이지", + "prevPage": "이전", + "nextPage": "다음", + "tabPending": "대기 중", + "tabApproved": "승인됨", + "tabRejected": "거부됨" + }, + "stars": { + "title": "내 즐겨찾기", + "subtitle": "즐겨찾기한 스킬을 확인하세요", + "empty": "아직 즐겨찾기한 스킬이 없습니다" + }, + "subscriptions": { + "title": "내 구독", + "subtitle": "업데이트 소식을 구독 중인 스킬", + "empty": "아직 구독한 스킬이 없습니다." + }, + "promotions": { + "title": "승격 리뷰", + "subtitle": "팀 스킬의 글로벌 네임스페이스 승격 요청을 리뷰하세요", + "tabPending": "대기 중", + "tabApproved": "승인됨", + "tabRejected": "거부됨", + "commentPlaceholder": "리뷰 코멘트(선택 사항)", + "approve": "승인", + "reject": "거부", + "empty": "승격 요청이 없습니다", + "historyTableLabel": "승격 이력", + "colSkill": "스킬", + "colVersion": "버전", + "colSubmitter": "제출자", + "colReviewer": "리뷰어", + "colReviewedAt": "리뷰 시각", + "colReviewComment": "리뷰 코멘트", + "sortReviewedTimeAsc": "리뷰 시각 오름차순 정렬", + "sortReviewedTimeDesc": "리뷰 시각 내림차순 정렬", + "emptyValue": "-", + "versionTag": "v{{version}}", + "submitterTag": "제출자 {{user}}", + "fileCountTag": "파일 {{count}}개", + "packageSizeTag": "{{size}}", + "downloadCountTag": "다운로드 {{value}}회", + "starCountTag": "즐겨찾기 {{value}}개" + }, + "adminUsers": { + "title": "사용자 관리", + "subtitle": "플랫폼 사용자와 권한을 관리하세요", + "searchLabel": "사용자 검색", + "searchPlaceholder": "아이디 또는 이메일로 검색...", + "searchHint": "아이디 또는 이메일을 입력한 뒤 Enter를 누르거나 검색을 클릭하세요.", + "searchAction": "검색", + "clearSearch": "지우기", + "filterLabel": "상태 필터", + "filterAll": "전체", + "filterActive": "활성", + "filterPending": "대기 중", + "filterDisabled": "비활성화됨", + "empty": "사용자 데이터가 없습니다", + "colUsername": "아이디", + "colUserId": "사용자 ID", + "copyUserId": "{{username}}의 사용자 ID 복사", + "colEmail": "이메일", + "colStatus": "상태", + "colRole": "역할", + "colCreatedAt": "생성 시각", + "colActions": "작업", + "statusActive": "활성", + "statusPending": "대기 중", + "statusDisabled": "비활성화됨", + "changeRole": "역할 변경", + "approveUser": "승인", + "disable": "비활성화", + "enable": "활성화", + "resetPassword": "비밀번호 재설정", + "totalRecords": "총 {{total}}건, {{page}}페이지", + "prevPage": "이전", + "nextPage": "다음", + "changeRoleTitle": "사용자 역할 변경", + "changeRoleDesc": "{{username}} 사용자에게 새 역할을 부여합니다", + "roleLabel": "역할", + "selectRole": "역할 선택", + "roleUser": "일반 사용자", + "roleReviewer": "리뷰어", + "roleUserAdmin": "사용자 관리자", + "roleAuditor": "감사자", + "roleSuperAdmin": "슈퍼 관리자", + "confirmAction": "작업 확인", + "confirmDisable": "{{username}} 사용자를 비활성화하시겠습니까?", + "confirmEnable": "{{username}} 사용자를 활성화하시겠습니까?", + "confirmResetPassword": "{{username}} 사용자에게 비밀번호 재설정 인증 코드를 전송하시겠습니까?" + }, + "adminLabels": { + "title": "라벨 관리", + "subtitle": "라벨 정의, 노출 여부, 번역, 필터 정렬 순서를 관리하세요.", + "createAction": "라벨 만들기", + "editAction": "수정", + "deleteAction": "삭제", + "saveAction": "변경 사항 저장", + "cancelAction": "취소", + "moveUp": "위로 이동", + "moveDown": "아래로 이동", + "empty": "아직 정의된 라벨이 없습니다.", + "summaryDefinitionsTitle": "정의", + "summaryVisibleTitle": "노출 필터", + "summaryPrivilegedTitle": "권한 라벨", + "colLabel": "라벨", + "colType": "유형", + "colVisibility": "노출 여부", + "colSortOrder": "정렬 순서", + "colTranslations": "번역", + "colCreatedAt": "생성 시각", + "colActions": "작업", + "typeRecommended": "추천", + "typePrivileged": "권한", + "visibilityVisible": "필터에 노출", + "visibilityHidden": "필터에서 숨김", + "createDialogTitle": "라벨 만들기", + "createDialogDescription": "검색 및 상세 화면에 표시할 새 라벨과 번역을 정의하세요.", + "editDialogTitle": "라벨 수정", + "editDialogDescription": "이 라벨 정의의 노출 규칙과 번역을 업데이트하세요.", + "deleteDialogTitle": "라벨 삭제", + "deleteDialogDescription": "\"{{slug}}\" 라벨을 삭제하고 연결된 모든 스킬에서 제거합니다.", + "formSlug": "슬러그", + "formType": "유형", + "formVisibility": "노출 여부", + "formSortOrder": "정렬 순서", + "formTranslations": "번역", + "formTranslationsHint": "로케일과 표시 이름 쌍을 최소 하나 이상 입력하세요.", + "translationLocalePlaceholder": "로케일, 예: en 또는 zh-CN", + "translationDisplayNamePlaceholder": "표시 이름", + "addTranslation": "번역 추가", + "removeTranslation": "제거", + "validationSlugTitle": "슬러그가 필요합니다", + "validationSlugDescription": "저장하기 전에 고정된 슬러그를 입력하세요.", + "validationSlugPatternDescription": "영문 소문자, 숫자, 단일 하이픈만 사용하세요. 슬러그는 문자 또는 숫자로 시작하고 끝나야 합니다.", + "validationTranslationsTitle": "번역이 필요합니다", + "validationTranslationsDescription": "로케일과 표시 이름이 모두 채워진 항목이 최소 하나 이상 필요합니다.", + "validationDuplicateLocaleDescription": "각 번역 로케일은 한 번만 사용할 수 있습니다.", + "createSuccessTitle": "라벨이 생성되었습니다", + "createSuccessDescription": "라벨 정의를 이제 사용할 수 있습니다.", + "createErrorTitle": "라벨 생성에 실패했습니다", + "updateSuccessTitle": "라벨이 업데이트되었습니다", + "updateSuccessDescription": "라벨 정의가 업데이트되었습니다.", + "updateErrorTitle": "라벨 업데이트에 실패했습니다", + "deleteSuccessTitle": "라벨이 삭제되었습니다", + "deleteSuccessDescription": "라벨 정의가 제거되었습니다.", + "deleteErrorTitle": "라벨 삭제에 실패했습니다", + "sortSuccessTitle": "정렬 순서가 업데이트되었습니다", + "sortSuccessDescription": "라벨 정렬 순서가 저장되었습니다.", + "sortErrorTitle": "정렬 순서 업데이트에 실패했습니다", + "fallbackErrorDescription": "라벨 작업을 완료할 수 없습니다." + }, + "auditLog": { + "title": "감사 로그", + "subtitle": "시스템 운영 기록을 확인하세요", + "filterAll": "전체", + "filterCliPublish": "CLI 게시", + "filterCompatPublish": "호환 게시", + "filterReviewSubmit": "리뷰 제출됨", + "filterReviewApprove": "리뷰 승인됨", + "filterReviewReject": "리뷰 거부됨", + "filterPromotionSubmit": "승격 요청 제출됨", + "filterPromotionApprove": "승격 승인됨", + "filterPromotionReject": "승격 거부됨", + "filterReportSkill": "스킬 신고됨", + "filterResolveSkillReport": "신고 처리됨", + "filterDismissSkillReport": "신고 반려됨", + "filterHideSkill": "스킬 숨김", + "filterArchiveSkill": "스킬 보관됨", + "filterUnhideSkill": "스킬 숨김 해제됨", + "filterUnarchiveSkill": "스킬 복원됨", + "filterYankVersion": "버전 회수됨", + "filterRebuildSearchIndex": "검색 색인 재구축됨", + "quickFilterSearchRebuild": "검색 색인 재구축만 보기", + "clearFilters": "필터 지우기", + "userIdPlaceholder": "사용자 ID...", + "requestIdPlaceholder": "요청 ID...", + "ipPlaceholder": "IP 주소...", + "resourceTypePlaceholder": "리소스 유형...", + "resourceIdPlaceholder": "리소스 ID...", + "empty": "감사 로그가 없습니다", + "colTime": "시각", + "colAction": "작업", + "colUserId": "사용자 ID", + "colUsername": "아이디", + "colIp": "IP 주소", + "colDetail": "상세 정보", + "totalRecords": "총 {{total}}건, {{page}}페이지", + "prevPage": "이전", + "nextPage": "다음" + }, + "profile": { + "title": "프로필 설정", + "subtitle": "표시 이름과 개인 정보를 관리하세요.", + "displayName": "표시 이름", + "email": "이메일", + "resetPassword": "비밀번호 재설정", + "edit": "수정", + "save": "저장", + "saving": "저장 중...", + "cancel": "취소", + "successTitle": "프로필이 업데이트되었습니다", + "successDescription": "표시 이름이 업데이트되었습니다.", + "pendingReviewTitle": "리뷰 제출됨", + "pendingReviewDescription": "표시 이름 변경이 리뷰 대기 중이며 승인되면 적용됩니다.", + "defaultError": "프로필 업데이트에 실패했습니다. 다시 시도해 주세요.", + "validation": { + "length": "표시 이름은 2~32자여야 합니다.", + "pattern": "표시 이름에는 중국어, 영어, 숫자, 공백, 밑줄(_), 하이픈(-)만 사용할 수 있습니다." + }, + "pendingReview": "\"{{name}}\"(으)로의 표시 이름 변경이 리뷰 대기 중입니다.", + "rejected": "표시 이름 변경이 거부되었습니다.", + "rejectedReason": "사유: {{reason}}", + "reviewHint": "일부 변경 사항은 적용 전에 관리자 리뷰가 필요합니다.", + "partiallyAppliedTitle": "일부만 적용됨", + "partiallyAppliedDescription": "일부 변경 사항은 즉시 적용되었고, 나머지는 관리자 리뷰를 기다리고 있습니다.", + "noChanges": "저장할 변경 사항이 없습니다.", + "userId": "사용자 ID" + }, + "security": { + "title": "보안 설정", + "subtitle": "로컬 계정 로그인이 활성화된 경우 비밀번호를 변경하세요.", + "currentPassword": "현재 비밀번호", + "newPassword": "새 비밀번호", + "currentPasswordRequired": "현재 비밀번호를 입력해 주세요", + "newPasswordRequired": "새 비밀번호를 입력해 주세요", + "invalidCurrentPassword": "현재 비밀번호가 올바르지 않습니다", + "success": "비밀번호가 변경되었습니다", + "successTitle": "비밀번호가 변경되었습니다", + "successDescription": "새 비밀번호로 다시 로그인해 주세요.", + "defaultError": "비밀번호 변경에 실패했습니다", + "unavailableTitle": "이 계정에서는 비밀번호 변경을 사용할 수 없습니다.", + "unavailableDescription": "이 계정은 외부 신원 제공자를 통해 로그인하거나 로컬 비밀번호 자격 증명이 없습니다.", + "submitting": "제출 중...", + "submit": "비밀번호 업데이트" + }, + "accounts": { + "initiateTitle": "계정 병합 시작", + "initiateDesc": "보조 계정 식별자를 입력하세요. 로컬 아이디 또는 `provider:subject` 형식의 외부 신원을 지원합니다.", + "secondaryLabel": "보조 식별자", + "secondaryPlaceholder": "예: other_user 또는 github:123456", + "initiating": "시작하는 중...", + "initiate": "병합 시작", + "initiateSuccess": "병합 요청이 생성되었습니다. secondary={{secondaryUserId}}", + "initiateError": "병합 시작에 실패했습니다", + "verifyTitle": "확인 및 병합 완료", + "verifyDesc": "먼저 토큰 확인을 완료한 뒤 데이터 마이그레이션 실행을 확정하세요.", + "mergeRequestId": "병합 요청 ID", + "verificationToken": "확인 토큰", + "verifying": "확인 중...", + "verify": "병합 완료", + "verifySuccess": "확인이 완료되었습니다. 병합 실행을 확정하세요", + "verifyError": "병합 확인에 실패했습니다", + "confirming": "확정하는 중...", + "confirm": "확정 및 병합 완료", + "confirmSuccess": "계정 병합이 완료되었습니다", + "confirmError": "병합 확정에 실패했습니다" + }, + "namespace": { + "notFound": "네임스페이스를 찾을 수 없습니다", + "skillList": "스킬", + "emptyTitle": "스킬이 없습니다", + "emptyDescription": "이 네임스페이스에는 아직 게시된 스킬이 없습니다" + }, + "skillDetail": { + "back": "뒤로", + "notFound": "스킬을 찾을 수 없습니다", + "notFoundDesc": "이 스킬은 삭제되었거나 존재하지 않을 수 있습니다", + "loginRequired": "로그인이 필요합니다", + "loginRequiredDesc": "이 스킬은 비공개입니다. 상세 내용을 보려면 로그인해 주세요.", + "accessDenied": "접근이 거부되었습니다", + "accessDeniedDesc": "이 스킬을 볼 권한이 없습니다", + "tabReadme": "README", + "tabOverview": "개요", + "tabFiles": "파일", + "tabVersions": "버전", + "noReadme": "README가 없습니다", + "readmeUnavailable": "README를 일시적으로 사용할 수 없습니다. 나중에 다시 시도하거나 이 스킬 버전을 다시 업로드해 주세요.", + "documentationSource": "출처: {{path}}", + "documentationUnavailableTitle": "문서를 사용할 수 없습니다", + "documentationUnavailable": "문서 파일을 불러올 수 없습니다. 파일 목록에서 패키지 내용을 확인할 수 있습니다.", + "packageLinkMissingTitle": "파일을 찾을 수 없습니다", + "packageLinkMissingDescription": "이 링크는 현재 스킬 버전에 포함되지 않은 파일을 가리키고 있습니다.", + "authorLabel": "작성자: {{name}}", + "expandOverview": "전체 개요 펼치기", + "collapseOverview": "내용 접기", + "noDocumentationTitle": "패키지 문서가 없습니다", + "noDocumentationDescription": "이 스킬 버전에는 읽을 수 있는 개요 파일이 포함되어 있지 않습니다.", + "noDocumentationHint": "일부 스킬은 실행 파일만 제공합니다. 아래의 파일 목록과 버전 정보를 계속 확인해 보세요.", + "summaryLabel": "요약", + "noFiles": "파일이 없습니다", + "noVersions": "버전이 없습니다", + "fileCount": "파일 {{count}}개", + "version": "버전", + "downloads": "다운로드", + "rating": "평점", + "ratingNone": "없음", + "namespaceLabel": "네임스페이스", + "loginToRate": "즐겨찾기 및 평점을 남기려면 로그인하세요", + "install": "설치", + "installMethodClawhub": "ClawHub CLI", + "installMethodSkillhub": "SkillHub CLI", + "download": "다운로드", + "labelsSectionTitle": "라벨", + "labelsSectionDescription": "사용자가 이 스킬을 쉽게 찾을 수 있도록 추천 라벨을 추가하거나 제거하세요.", + "labelsSectionDescriptionSuperAdmin": "공개 필터에서는 숨겨지는 권한 라벨을 포함해 이 스킬의 모든 라벨을 관리하세요.", + "currentLabelsTitle": "현재 라벨", + "availableLabelsTitle": "사용 가능한 라벨", + "noLabelsAssigned": "이 스킬에 아직 연결된 라벨이 없습니다.", + "loadingAvailableLabels": "사용 가능한 라벨을 불러오는 중...", + "noAvailableLabels": "지금은 더 추가할 수 있는 라벨이 없습니다.", + "addLabel": "{{label}} 추가", + "removeLabel": "제거", + "labelRestrictedHint": "슈퍼 관리자만 가능", + "labelAttachSuccessTitle": "라벨이 추가되었습니다", + "labelAttachSuccessDescription": "스킬 라벨이 업데이트되었습니다.", + "labelAttachErrorTitle": "라벨 추가에 실패했습니다", + "labelDetachSuccessTitle": "라벨이 제거되었습니다", + "labelDetachSuccessDescription": "스킬 라벨이 업데이트되었습니다.", + "labelDetachErrorTitle": "라벨 제거에 실패했습니다", + "labelActionFallbackError": "라벨 작업을 완료할 수 없습니다.", + "lifecycle": "라이프사이클", + "lifecycleHint": "이 스킬을 보관할 수 있습니다. 보관된 스킬은 일반 사용자에게 숨겨지며 다운로드할 수 없습니다.", + "archivedPublishHint": "이 스킬은 보관되어 있습니다. 새 버전을 게시하려면 먼저 복원하세요.", + "archivedInstallHint": "이 스킬은 보관되어 있어 공개 다운로드를 사용할 수 없습니다.", + "statusActive": "활성", + "statusArchived": "보관됨", + "statusHidden": "숨김", + "versionStatusDraft": "초안", + "versionStatusScanning": "검사 중", + "versionStatusScanFailed": "검사 실패", + "versionStatusUploaded": "업로드됨", + "versionStatusPendingReview": "리뷰 대기 중", + "versionStatusPublished": "게시됨", + "versionStatusRejected": "거부됨", + "versionStatusYanked": "회수됨", + "pendingPreviewBadge": "대기 중 미리보기", + "rejectedBadge": "리뷰 거부됨", + "pendingPreviewTitle": "리뷰 대기 중인 버전을 미리 보고 있습니다", + "pendingPreviewDescription": "이 버전은 본인에게만 표시됩니다. 리뷰 승인 전까지는 README, 파일, 버전 정보를 확인할 수 있지만 즐겨찾기, 평점, 신고, 다운로드는 할 수 없습니다.", + "pendingPreviewInteractionHint": "이 버전이 리뷰 대기 중인 동안에는 즐겨찾기, 평점, 신고를 사용할 수 없습니다.", + "rejectedPreviewDescription": "이 버전은 거부되었으며 현재 본인에게만 표시됩니다. 아래 피드백을 참고해 수정한 뒤 다시 게시하세요.", + "rejectedPreviewInteractionHint": "거부된 미리보기 버전은 즐겨찾기, 평점, 신고를 사용할 수 없습니다.", + "rejectedFeedbackTitle": "리뷰 거부됨", + "rejectedFeedbackLabel": "리뷰어 피드백", + "rejectedFeedbackFallback": "제공된 거부 피드백이 없습니다.", + "governance": "거버넌스", + "processing": "처리 중...", + "archiveSkill": "스킬 보관", + "unarchiveSkill": "스킬 복원", + "deleteSkill": "스킬 삭제", + "deleteSkillContinue": "계속", + "deleteSkillFinal": "영구 삭제", + "withdrawReview": "리뷰 철회", + "hideSkill": "스킬 숨기기", + "unhideSkill": "스킬 숨김 해제", + "archiveConfirmTitle": "스킬 보관", + "archiveConfirmDescription": "보관하면 일반 사용자는 더 이상 \"{{skill}}\"을(를) 보거나 다운로드할 수 없습니다. 계속하시겠습니까?", + "unarchiveConfirmTitle": "스킬 복원", + "unarchiveConfirmDescription": "복원하면 \"{{skill}}\"이(가) 다시 표시되며 새 버전을 게시할 수 있습니다.", + "deleteSkillConfirmTitle": "스킬 영구 삭제", + "deleteSkillConfirmDescription": "\"{{skill}}\"의 모든 버전, 파일, 다운로드 번들이 제거되며 이 작업은 되돌릴 수 없습니다.", + "deleteSkillInputTitle": "확인을 위해 스킬 슬러그를 입력하세요", + "deleteSkillInputDescription": "계속하려면 스킬 슬러그 \"{{slug}}\"을(를) 입력하세요.", + "deleteSkillInputPlaceholder": "스킬 슬러그 입력", + "deleteSkillWarning": "이 작업은 물리적 완전 삭제입니다. 이력 버전과 번들이 영구적으로 제거됩니다.", + "archiveSuccessTitle": "스킬이 보관되었습니다", + "archiveSuccessDescription": "\"{{skill}}\"이(가) 보관되었습니다.", + "archiveErrorTitle": "스킬 보관에 실패했습니다", + "unarchiveSuccessTitle": "스킬이 복원되었습니다", + "unarchiveSuccessDescription": "\"{{skill}}\"이(가) 복원되었습니다.", + "unarchiveErrorTitle": "스킬 복원에 실패했습니다", + "deleteSkillSuccessTitle": "스킬이 삭제되었습니다", + "deleteSkillSuccessDescription": "\"{{skill}}\"이(가) 영구적으로 삭제되었습니다.", + "deleteSkillErrorTitle": "스킬 삭제에 실패했습니다", + "withdrawReviewConfirmTitle": "리뷰 철회", + "withdrawReviewConfirmDescription": "철회하면 버전 {{version}}이(가) 리뷰 대기열에서 빠져 초안으로 돌아가며 나중에 다시 제출할 수 있습니다.", + "withdrawReviewSuccessTitle": "리뷰가 철회되었습니다", + "withdrawReviewSuccessDescription": "버전 {{version}}이(가) 리뷰에서 철회되었습니다.", + "withdrawReviewErrorTitle": "리뷰 철회에 실패했습니다", + "confirmPublish": "게시 확정", + "confirmPublishDialogTitle": "게시 확정", + "confirmPublishDialogDescription": "버전 {{version}}을(를) 비공개 스킬로 게시하시겠습니까? 본인은 다운로드하고 설치할 수 있지만 마켓플레이스에는 노출되지 않습니다.", + "confirmPublishSuccessTitle": "버전이 게시되었습니다", + "confirmPublishSuccessDescription": "버전 {{version}}이(가) 비공개 스킬로 게시되었습니다.", + "confirmPublishErrorTitle": "게시 확정에 실패했습니다", + "submitReview": "리뷰 제출", + "submitReviewDialogTitle": "리뷰 제출", + "submitReviewDialogDescription": "버전 {{version}}을(를) 공개 리뷰에 제출하시겠습니까? 승인되면 마켓플레이스에 노출됩니다.", + "submitReviewSuccessTitle": "리뷰가 제출되었습니다", + "submitReviewSuccessDescription": "버전 {{version}}이(가) 리뷰에 제출되었습니다.", + "submitReviewErrorTitle": "리뷰 제출에 실패했습니다", + "deleteVersion": "버전 삭제", + "deleteVersionConfirmTitle": "버전 삭제", + "deleteVersionConfirmDescription": "버전 {{version}}은(는) 삭제 후 복구할 수 없습니다. 계속하시겠습니까?", + "deleteVersionSuccessTitle": "버전이 삭제되었습니다", + "deleteVersionSuccessDescription": "버전 {{version}}이(가) 삭제되었습니다.", + "deleteVersionErrorTitle": "버전 삭제에 실패했습니다", + "currentVersion": "현재", + "currentPublicVersion": "현재 공개 버전", + "pendingReviewSectionTitle": "리뷰 대기 중인 버전", + "pendingReviewSectionDescription": "v{{pendingVersion}}이(가) 현재 리뷰 중입니다. 공개되어 설치 가능한 버전은 여전히 v{{publishedVersion}}입니다.", + "pendingReviewVersionLabel": "대기 중인 버전", + "pendingReviewStatusLabel": "리뷰 상태", + "pendingReviewStatusValue": "리뷰 중", + "lifecyclePublicVersionLabel": "현재 공개 버전", + "lifecycleNoPublishedVersion": "게시된 버전이 없습니다", + "lifecyclePendingVersionLabel": "리뷰 대기 중인 버전", + "lifecyclePendingVersionValue": "v{{version}}이(가) 리뷰 중입니다", + "lifecycleNoPendingVersion": "리뷰 대기 중인 버전이 없습니다", + "lifecycleContainerStateLabel": "스킬 컨테이너 상태", + "compareVersions": "비교", + "compareDialogTitle": "버전 비교", + "compareDialogDescription": "v{{source}}와(과) v{{target}}을(를) 비교합니다.", + "compareSourceLabel": "선택한 버전", + "compareTargetLabel": "비교 대상", + "versionCompareUnavailableTitle": "비교할 버전이 충분하지 않습니다", + "versionCompareUnavailableDescription": "버전 비교를 사용하려면 최소 두 개 이상의 버전을 게시해야 합니다.", + "metadataChanges": "메타데이터 변경 사항", + "noMetadataChanges": "메타데이터 변경 사항이 없습니다", + "readmeChange": "README 변경", + "readmeChanged": "README 내용이 변경되었습니다", + "readmeUnchanged": "README 내용이 변경되지 않았습니다", + "fileChanges": "파일 변경 사항", + "filesAdded": "추가됨", + "filesRemoved": "제거됨", + "filesChanged": "변경됨", + "expandDiff": "차이점 보기", + "collapseDiff": "차이점 숨기기", + "binaryFileNotice": "바이너리 파일 — 차이점을 표시할 수 없습니다", + "largeFileWarning": "이 파일은 용량이 커서 렌더링이 느릴 수 있습니다.", + "diffLoadError": "파일 내용을 불러오지 못했습니다", + "diffRetry": "재시도", + "diffViewUnified": "통합 보기", + "diffViewSplit": "분할 보기", + "rereleaseVersion": "재배포", + "rereleaseDialogTitle": "버전에서 재배포", + "rereleaseDialogDescription": "v{{version}}을(를) 기반으로 새 게시 버전을 만듭니다.", + "rereleaseSourceVersion": "원본 버전", + "rereleaseTargetVersion": "새 버전", + "rereleaseSuccessTitle": "버전이 재배포되었습니다", + "rereleaseSuccessDescription": "v{{source}}에서 v{{target}}을(를) 생성했습니다.", + "rereleaseErrorTitle": "버전 재배포에 실패했습니다", + "rereleaseWarningTitle": "게시 전 경고", + "rereleaseWarningDescription": "다음과 같은 위험 알림이 발견되었습니다. 내용을 이해했고 계속 진행하려면 재배포를 계속할 수 있습니다.", + "rereleaseWarningConfirm": "재배포 계속하기", + "yankVersion": "현재 버전 회수", + "promoteToGlobal": "글로벌로 승격", + "promotionSectionTitle": "글로벌로 승격", + "promotionSectionDescription": "현재 게시된 버전 v{{version}}을(를) 글로벌 네임스페이스 리뷰에 제출합니다.", + "promotionConfirmTitle": "승격 요청 제출", + "promotionConfirmDescription": "\"{{skill}}\"의 v{{version}}을(를) 글로벌 네임스페이스로 승격하도록 제출하시겠습니까?", + "promotionSuccessTitle": "승격 요청이 제출되었습니다", + "promotionSuccessDescription": "\"{{skill}}\"의 v{{version}}이(가) 글로벌 승격 리뷰 대기열에 등록되었습니다.", + "promotionDuplicateTitle": "이미 대기 중인 승격 요청이 있습니다", + "promotionDuplicateDescription": "이 버전은 이미 승격 요청이 대기 중입니다.", + "promotionAlreadyPromotedTitle": "이미 승격된 스킬입니다", + "promotionAlreadyPromotedDescription": "이 스킬은 이미 글로벌 네임스페이스로 승격되었습니다.", + "promotionErrorTitle": "승격 요청 제출에 실패했습니다", + "reportSkill": "스킬 신고", + "reportedSkill": "신고됨", + "reportDialogTitle": "스킬 신고", + "reportDialogDescription": "관리자가 신속히 확인하고 조치할 수 있도록 사유를 입력해 주세요.", + "reportReasonPlaceholder": "사유 예시: 정책 위반, 오해의 소지가 있는 내용, 저작권 침해 등", + "reportDetailsPlaceholder": "추가 상세 내용(선택 사항)", + "submitReport": "신고 제출", + "reportReasonRequired": "신고 사유를 입력해 주세요", + "reportSuccessTitle": "신고가 접수되었습니다", + "reportSuccessDescription": "관리자가 곧 이 신고를 검토할 예정입니다.", + "downloadErrorTitle": "다운로드에 실패했습니다", + "reportErrorTitle": "신고 접수에 실패했습니다", + "share": { + "button": "공유", + "copied": "복사됨", + "defaultDescription": "유용한 스킬입니다" + } + }, + "skillCompare": { + "pageTitle": "버전 비교", + "filesChanged": "파일 {{count}}개 변경됨", + "searchFiles": "파일 검색", + "errorLoadingCompare": "버전 비교를 불러오지 못했습니다", + "loadDiff": "차이점 불러오기", + "loading": "불러오는 중...", + "totalFiles": "파일", + "addedLines": "추가된 줄", + "removedLines": "삭제된 줄", + "baseVersion": "기준 버전", + "headVersion": "대상 버전", + "fileList": "파일 목록", + "binaryFile": "바이너리 파일 — 차이점을 표시할 수 없습니다", + "truncatedFile": "차이점 출력이 잘렸습니다", + "notEnoughPublishedVersions": "비교하려면 최소 두 개 이상의 버전을 게시해야 합니다.", + "noFilesFound": "일치하는 파일이 없습니다.", + "changeTypeAdded": "추가됨", + "changeTypeModified": "수정됨", + "changeTypeRemoved": "삭제됨" + }, + "reports": { + "title": "스킬 신고", + "subtitle": "사용자가 제출한 스킬 신고를 처리하세요", + "tabPending": "대기 중", + "tabResolved": "처리됨", + "tabDismissed": "반려됨", + "empty": "신고 내역이 없습니다", + "reporter": "신고자", + "handledBy": "처리자", + "resolve": "처리", + "resolveAndHide": "처리 및 숨기기", + "resolveAndArchive": "처리 및 보관", + "dismiss": "반려", + "resolveConfirmTitle": "신고 처리", + "resolveConfirmDescription": "\"{{skill}}\"에 대한 신고를 처리 완료로 표시하시겠습니까?", + "resolveAndHideConfirmDescription": "\"{{skill}}\"에 대한 신고를 처리하고 이 스킬을 공개에서 숨기시겠습니까?", + "resolveAndArchiveConfirmDescription": "\"{{skill}}\"에 대한 신고를 처리하고 이 스킬을 보관하시겠습니까?", + "dismissConfirmTitle": "신고 반려", + "dismissConfirmDescription": "\"{{skill}}\"에 대한 신고를 반려하시겠습니까?", + "resolveSuccessTitle": "신고가 처리되었습니다", + "resolveSuccessDescription": "\"{{skill}}\"에 대한 신고가 처리 완료로 표시되었습니다.", + "resolveAndHideSuccessTitle": "신고가 처리되고 스킬이 숨겨졌습니다", + "resolveAndHideSuccessDescription": "신고 처리 후 \"{{skill}}\"이(가) 숨겨졌습니다.", + "resolveAndArchiveSuccessTitle": "신고가 처리되고 스킬이 보관되었습니다", + "resolveAndArchiveSuccessDescription": "신고 처리 후 \"{{skill}}\"이(가) 보관되었습니다.", + "dismissSuccessTitle": "신고가 반려되었습니다", + "dismissSuccessDescription": "\"{{skill}}\"에 대한 신고가 반려되었습니다.", + "resolveErrorTitle": "신고 처리에 실패했습니다", + "resolveAndHideErrorTitle": "신고 처리 및 스킬 숨기기에 실패했습니다", + "resolveAndArchiveErrorTitle": "신고 처리 및 스킬 보관에 실패했습니다", + "dismissErrorTitle": "신고 반려에 실패했습니다" + }, + "governance": { + "title": "거버넌스 센터", + "subtitle": "리뷰, 승격, 신고, 감사 활동을 한곳에서 확인하세요.", + "pendingReviews": "대기 중인 리뷰", + "pendingPromotions": "대기 중인 승격", + "pendingReports": "대기 중인 신고", + "unreadNotifications": "읽지 않은 알림", + "inboxTitle": "거버넌스 수신함", + "inboxSubtitle": "아직 처리가 필요한 운영 작업을 모아 보는 통합 대기열입니다.", + "tabAll": "전체", + "tabReview": "리뷰", + "tabPromotion": "승격", + "tabReport": "신고", + "emptyInbox": "지금은 거버넌스 작업 항목이 없습니다.", + "openItem": "열기", + "notificationsTitle": "알림", + "notificationsSubtitle": "주의가 필요한 최근 거버넌스 업데이트입니다.", + "emptyNotifications": "아직 알림이 없습니다.", + "markRead": "읽음으로 표시", + "activityTitle": "거버넌스 활동", + "activitySubtitle": "리뷰, 승격, 신고, 라이프사이클 작업에 대한 최근 감사 이벤트입니다.", + "emptyActivity": "최근 거버넌스 활동이 없습니다.", + "unknownActor": "알 수 없는 사용자", + "searchMaintenanceTitle": "검색 색인 유지 보수", + "searchMaintenanceDescription": "전체 스킬 검색 색인을 재구축합니다. 이 작업은 슈퍼 관리자만 사용할 수 있으며, 검색 규칙 변경 후 전체 백필이 필요할 때 사용합니다.", + "searchMaintenanceHint": "시간이 다소 걸릴 수 있습니다. 반복해서 실행하지 마세요.", + "searchRebuildAction": "전체 검색 색인 재구축", + "searchRebuildRunning": "재구축 중...", + "searchRebuildConfirmTitle": "전체 검색 색인을 재구축할까요?", + "searchRebuildConfirmDescription": "시스템이 현재 색인 규칙을 사용해 모든 스킬의 검색 문서를 재구축합니다. 이 작업은 시간이 걸릴 수 있습니다.", + "searchRebuildSuccessTitle": "검색 색인 재구축이 시작되었습니다", + "searchRebuildSuccessDescription": "시스템이 현재 규칙을 사용해 전체 검색 색인을 재구축하고 있습니다.", + "searchRebuildErrorTitle": "검색 색인 재구축에 실패했습니다" + }, + "members": { + "title": "멤버 관리", + "addMember": "멤버 추가", + "addingMember": "추가하는 중...", + "addDialogTitle": "네임스페이스 멤버 추가", + "addDialogDescription": "플랫폼 사용자를 검색하거나 사용자 ID를 직접 입력하세요. 추가된 사용자는 즉시 이 네임스페이스에서 협업할 수 있습니다.", + "searchLabel": "사용자 검색", + "searchPlaceholder": "아이디, 이메일, 사용자 ID로 검색", + "searchHint": "최소 2자 이상 입력해 검색하세요. 결과에는 바로 추가할 수 있는 사용자 ID가 포함됩니다.", + "searchAction": "검색", + "searchTooShort": "검색어는 최소 2자 이상이어야 합니다", + "searchResultsTitle": "후보 사용자", + "searchEmpty": "추가할 수 있는 활성 사용자가 없습니다", + "selectCandidate": "이 사용자 선택", + "manualUserIdLabel": "사용자 ID 직접 입력", + "manualUserIdPlaceholder": "예: user-123 또는 usr_abcd", + "manualUserIdHint": "사용자 ID를 이미 알고 있다면 여기에 직접 입력해 추가할 수 있습니다.", + "userIdRequired": "사용자 ID를 입력해 주세요", + "roleLabel": "멤버 역할", + "roleOwner": "OWNER", + "roleAdmin": "ADMIN", + "roleMember": "MEMBER", + "saveRole": "역할 저장", + "savingRole": "저장 중...", + "changeRole": "역할 변경", + "colUserId": "사용자 ID", + "colUsername": "아이디", + "colEmail": "이메일", + "colRole": "역할", + "colJoinedAt": "참여 시각", + "colActions": "작업", + "remove": "제거", + "empty": "멤버가 없습니다", + "namespaceNotFound": "네임스페이스를 찾을 수 없습니다", + "globalReadOnly": "이 네임스페이스는 시스템 기본 네임스페이스입니다. 멤버십은 조회만 가능하며 변경할 수 없습니다.", + "frozenReadOnly": "이 네임스페이스는 동결되어 있습니다. 멤버는 계속 볼 수 있지만 추가, 제거, 역할 변경은 할 수 없습니다.", + "archivedReadOnly": "이 네임스페이스는 보관되어 있습니다. 멤버는 계속 볼 수 있지만 복원되기 전까지 멤버십을 변경할 수 없습니다.", + "memberReadOnly": "이 네임스페이스에서 일반 멤버입니다. 멤버 목록은 볼 수 있지만 변경은 OWNER 또는 ADMIN만 할 수 있습니다.", + "addSuccessTitle": "멤버가 추가되었습니다", + "addSuccessDescription": "사용자 {{userId}}이(가) 이 네임스페이스에 추가되었습니다.", + "addErrorTitle": "멤버 추가에 실패했습니다", + "updateRoleSuccessTitle": "멤버 역할이 업데이트되었습니다", + "updateRoleSuccessDescription": "사용자 {{userId}}의 역할이 이제 {{role}}입니다.", + "updateRoleErrorTitle": "멤버 역할 업데이트에 실패했습니다", + "removeConfirmTitle": "멤버 제거", + "removeConfirmDescription": "제거하면 사용자 {{userId}}은(는) 이 네임스페이스에 대한 접근 권한을 잃습니다.", + "removeSuccessTitle": "멤버가 제거되었습니다", + "removeSuccessDescription": "사용자 {{userId}}이(가) 이 네임스페이스에서 제거되었습니다.", + "removeErrorTitle": "멤버 제거에 실패했습니다", + "searchEmptyMemberHint": "사용자가 이미 이 네임스페이스에 속해 있다면 여기에는 표시되지 않습니다 — 멤버 목록에서 확인해 주세요.", + "transferOwnership": "소유권 이전", + "transferDialogTitle": "네임스페이스 소유권 이전", + "transferDialogDescription": "다른 멤버에게 소유권을 이전합니다. 본인은 ADMIN이 됩니다.", + "transferWarning": "이 작업은 되돌릴 수 없습니다. 이전 후에는 더 이상 소유자가 아닙니다.", + "transferNewOwnerLabel": "새 소유자", + "transferSelectPlaceholder": "멤버 선택", + "transferNoCandidates": "소유권을 이전할 수 있는 다른 멤버가 없습니다.", + "transferConfirmSlugPrompt": "확인을 위해 네임스페이스 슬러그를 입력하세요", + "transferConfirmSlugHint": "확인하려면 {{slug}}을(를) 입력하세요", + "transferConfirmAction": "소유권 이전", + "transferring": "이전하는 중...", + "transferSuccessTitle": "소유권이 이전되었습니다", + "transferSuccessDescription": "{{userId}}이(가) 이제 이 네임스페이스의 소유자입니다.", + "transferErrorTitle": "소유권 이전에 실패했습니다", + "batchImport": "일괄 가져오기", + "batchDialogTitle": "멤버 일괄 가져오기", + "batchDialogDescription": "CSV 파일을 업로드해 여러 멤버를 한 번에 추가하세요. 각 행에는 사용자 ID와 역할이 포함되어야 합니다.", + "batchStepUpload": "CSV 업로드", + "batchStepPreview": "미리 보기", + "batchStepResults": "결과", + "batchDownloadTemplate": "CSV 템플릿 다운로드", + "batchDropHint": "CSV 파일을 여기에 끌어다 놓거나 클릭해서 선택하세요", + "batchFormatHint": ".csv 형식만 지원합니다", + "batchParseError": "CSV 파일을 분석하지 못했습니다", + "batchEmptyFile": "CSV 파일이 비어 있거나 유효한 행이 없습니다", + "batchPreviewTitle": "미리 보기 ({{count}}행)", + "batchColUserId": "사용자 ID", + "batchColRole": "역할", + "batchColStatus": "상태", + "batchValidationMissingUserId": "사용자 ID가 없습니다", + "batchValidationInvalidRole": "유효하지 않은 역할입니다(MEMBER 또는 ADMIN이어야 함)", + "batchValidationDuplicate": "중복된 사용자 ID입니다", + "batchValidationValid": "준비됨", + "batchValidRows": "유효 {{valid}}건, 무효 {{invalid}}건", + "batchSubmitting": "가져오는 중...", + "batchSubmit": "멤버 {{count}}명 가져오기", + "batchResultTitle": "가져오기 결과", + "batchResultSummary": "총 {{total}}건 중 성공 {{success}}건, 실패 {{failure}}건", + "batchResultSuccess": "추가됨", + "batchResultAlreadyMember": "이미 멤버입니다", + "batchResultUserNotFound": "사용자를 찾을 수 없습니다", + "batchResultInvalidRole": "유효하지 않은 역할입니다", + "batchResultUnknownError": "알 수 없는 오류입니다", + "batchDone": "완료", + "batchBack": "뒤로" + }, + "namespaceEdit": { + "editButton": "수정", + "dialogTitle": "네임스페이스 수정", + "displayNameLabel": "표시 이름", + "displayNameRequired": "표시 이름을 입력해 주세요", + "descriptionLabel": "설명", + "saveAction": "저장", + "saving": "저장 중...", + "saveSuccess": "네임스페이스가 성공적으로 업데이트되었습니다", + "saveErrorTitle": "네임스페이스 업데이트에 실패했습니다" + }, + "upload": { + "dropHint": "놓으면 업로드됩니다...", + "dragHint": "ZIP 파일을 여기에 끌어다 놓거나 클릭해서 선택하세요", + "formatHint": ".zip 형식만 지원합니다" + }, + "layout": { + "footerDescription": "개발자를 위한 효율적인 스킬 관리 및 배포를 지원하는 스킬 레지스트리입니다." + }, + "nsReviews": { + "title": "네임스페이스 리뷰", + "loadingNamespace": "네임스페이스 정보 불러오는 중", + "reviewsFor": "{{name}}의 리뷰 작업", + "empty": "리뷰 기록이 없습니다", + "version": "버전 {{version}}", + "tabPending": "대기 중", + "tabApproved": "승인됨", + "tabRejected": "거부됨", + "sortLabel": "시간순 정렬", + "sortNewest": "최신순", + "sortOldest": "오래된순", + "openReview": "리뷰 열기", + "pageSummary": "총 {{total}}건, {{page}}페이지", + "prevPage": "이전", + "nextPage": "다음", + "globalReadOnly": "이 네임스페이스는 시스템 기본 네임스페이스입니다. 리뷰 기록은 볼 수 있지만 새로운 리뷰 작업은 할 수 없습니다.", + "frozenReadOnly": "이 네임스페이스는 동결되어 있습니다. 리뷰 기록은 볼 수 있지만 리뷰 작업을 계속 처리할 수는 없습니다.", + "archivedReadOnly": "이 네임스페이스는 보관되어 있습니다. 리뷰 기록은 볼 수 있지만 복원되기 전까지 리뷰 작업을 계속 처리할 수는 없습니다." + }, + "namespaceStatus": { + "active": "활성", + "frozen": "동결됨", + "archived": "보관됨", + "frozenHint": "이 네임스페이스는 현재 읽기 전용이며 게시, 리뷰, 멤버 변경을 할 수 없습니다.", + "archivedHint": "이 네임스페이스는 공개 진입점에서 숨겨져 있으며 대시보드 멤버에게만 보입니다.", + "immutableHint": "이 네임스페이스는 시스템 기본 네임스페이스이며 거버넌스나 멤버십 변경이 허용되지 않습니다." + }, + "fileTree": { + "title": "파일" + }, + "filePreview": { + "loadError": "파일을 불러오지 못했습니다", + "tooLarge": "파일이 너무 커서 미리 볼 수 없습니다", + "binaryFile": "바이너리 파일은 미리 볼 수 없습니다", + "unsupported": "이 파일 형식은 미리 보기를 지원하지 않습니다", + "downloadFile": "파일 다운로드", + "downloadHint": "{{name}} 다운로드", + "copy": "내용 복사", + "copySuccess": "클립보드에 복사되었습니다", + "close": "닫기" + }, + "loginButton": { + "loading": "불러오는 중...", + "loginWith": "{{name}}(으)로 로그인" + }, + "ratingInput": { + "yourRating": "내 평점: {{score}}점" + }, + "createToken": { + "title": "API 토큰 생성", + "description": "CLI 또는 API 접근을 위한 새 API 토큰을 생성하세요", + "nameLabel": "토큰 이름", + "namePlaceholder": "예: my-cli-token", + "nameRequired": "토큰 이름을 입력해 주세요", + "nameTooLong": "토큰 이름은 최대 {{max}}자까지 가능합니다", + "nameDuplicate": "이미 같은 이름의 토큰이 있습니다", + "creating": "생성 중...", + "create": "생성", + "successTitle": "토큰이 생성되었습니다", + "successDescription": "지금 이 토큰을 복사해 저장해 두세요. 생성 시점에만 표시되고 복사할 수 있습니다. 나중에 다시 필요하면 새 토큰을 생성해야 합니다.", + "tokenLabel": "토큰", + "nameDisplay": "이름", + "expirationLabel": "만료", + "expirationHint": "기본적으로 토큰은 만료되지 않습니다. 자동 만료 시간을 선택할 수도 있습니다.", + "expirationNever": "만료되지 않음", + "expiration7d": "7일 후 만료", + "expiration30d": "30일 후 만료", + "expiration90d": "90일 후 만료", + "expirationCustom": "날짜 및 시간 직접 지정", + "expiresAtRequired": "만료 시간을 직접 선택해 주세요", + "expiresAtDisplay": "만료 시각", + "copyToken": "토큰 복사", + "copySuccess": "토큰이 클립보드에 복사되었습니다", + "copyFailed": "토큰 복사에 실패했습니다. 다시 시도해 주세요." + }, + "starButton": { + "starred": "즐겨찾기됨", + "star": "즐겨찾기" + }, + "subscribeButton": { + "subscribed": "구독 중", + "subscribe": "구독" + }, + "skillCard": { + "starred": "즐겨찾기됨", + "starredAction": "클릭하면 즐겨찾기가 해제됩니다", + "unstarTitle": "즐겨찾기에서 제거", + "unstarDescription": "\"{{name}}\"을(를) 즐겨찾기에서 제거하시겠습니까?", + "unstarConfirm": "제거" + }, + "copyButton": { + "copied": "복사됨", + "copy": "복사" + }, + "pagination": { + "prev": "이전", + "next": "다음", + "pagePrefix": "페이지", + "pageSuffix": "", + "goToPage": "{{page}}페이지로 이동" + }, + "user": { + "menu": { + "dashboard": "대시보드", + "mySkills": "내 스킬", + "myNamespaces": "내 네임스페이스", + "governance": "거버넌스 센터", + "stars": "즐겨찾기", + "subscriptions": "내 구독", + "reviews": "리뷰 관리", + "promotions": "승격 관리", + "reports": "신고 관리", + "users": "사용자 관리", + "labels": "라벨 관리", + "auditLog": "감사 로그", + "security": "보안 설정", + "profile": "프로필 설정", + "notifications": "알림 설정", + "accounts": "계정 병합", + "logout": "로그아웃" + } + }, + "footer": { + "resources": "리소스", + "docs": "문서", + "api": "API", + "community": "커뮤니티", + "privacy": "개인정보처리방침", + "terms": "이용약관", + "copyright": "© 2026 SkillHub. All rights reserved." + }, + "publish": { + "title": "스킬 게시", + "subtitle": "스킬 패키지를 SkillHub에 업로드하세요", + "reviewNotice": { + "title": "리뷰 안내", + "description": "제출한 스킬 패키지는 게시 전에 관리자 리뷰가 필요합니다." + }, + "namespace": "네임스페이스", + "selectNamespace": "네임스페이스 선택", + "visibility": "공개 범위", + "visibilityOptions": { + "public": "공개", + "namespaceOnly": "네임스페이스 전용", + "loggedInUsersOnly": "로그인한 사용자만", + "private": "비공개" + }, + "file": "스킬 패키지 파일", + "removeSelectedFile": "선택한 파일 제거", + "publishing": "게시하는 중...", + "confirm": "게시 확정", + "success": "게시 완료", + "successDescription": "{{skill}}이(가) 리뷰에 제출되었으며 관리자 승인 후 사용할 수 있습니다", + "publishedTitle": "게시 완료", + "publishedDescription": "{{skill}}이(가) 이제 공개되어 다운로드할 수 있습니다", + "pendingReviewTitle": "리뷰 제출됨", + "pendingReviewDescription": "{{skill}}이(가) 리뷰에 제출되었으며 관리자 승인 후 사용할 수 있습니다", + "error": "게시 실패", + "timeoutTitle": "게시 시간이 초과되었습니다", + "timeoutDescription": "게시 요청 처리 시간이 너무 오래 걸렸습니다. 잠시 후 스킬 목록을 확인하거나 다시 시도해 주세요.", + "versionExistsTitle": "이미 존재하는 버전입니다", + "versionExistsDescription": "이 스킬 버전은 이미 게시되었습니다. SKILL.md의 버전을 갱신하고 패키지를 다시 빌드한 뒤 다시 업로드해 주세요.", + "precheckFailedTitle": "게시 전 점검에 실패했습니다", + "precheckFailedDescription": "패키지에 비밀 값, 토큰, 또는 비밀번호가 포함된 것으로 보입니다. 실제 자격 증명을 대체 값으로 바꾼 뒤 다시 시도해 주세요.", + "warningConfirmTitle": "게시 전 경고", + "warningConfirmDescription": "다음과 같은 위험 알림이 발견되었습니다. 내용을 이해했고 계속 진행하려면 게시를 계속할 수 있습니다.", + "warningConfirmContinue": "게시 계속하기", + "warningConfirmCancel": "돌아가서 수정하기", + "frontmatterFailedTitle": "SKILL.md 형식이 올바르지 않습니다", + "frontmatterFailedDescription": "SKILL.md 상단의 YAML 프런트매터를 확인해 주세요. 값에 콜론(:)이 포함된 경우 따옴표로 감싸 주세요.", + "selectRequired": "네임스페이스와 파일을 선택해 주세요" + }, + "toast": { + "success": "성공", + "error": "오류", + "warning": "경고", + "info": "안내" + }, + "dialog": { + "confirm": "확인", + "cancel": "취소", + "delete": "삭제", + "close": "닫기" + }, + "review": { + "detail": "리뷰 상세", + "id": "리뷰 ID", + "backToList": "목록으로 돌아가기", + "namespace": "네임스페이스 / 슬러그", + "version": "버전", + "status": "상태", + "statusPending": "대기 중", + "statusApproved": "승인됨", + "statusRejected": "거부됨", + "submitter": "제출자", + "submitTime": "제출 시각", + "reviewer": "리뷰어", + "reviewTime": "리뷰 시각", + "reviewComment": "리뷰 코멘트", + "actions": "리뷰 작업", + "commentLabel": "코멘트(선택 사항)", + "commentPlaceholder": "리뷰 코멘트를 입력하세요...", + "approve": "승인", + "reject": "거부", + "confirmReject": "거부 확정", + "cancelReject": "취소", + "rejectReasonRequired": "거부하려면 사유를 입력해야 합니다", + "approveTitle": "리뷰 승인", + "approveDescription": "이 리뷰를 승인하시겠습니까?", + "approveConfirm": "승인", + "rejectTitle": "리뷰 거부", + "rejectDescription": "이 리뷰를 거부하시겠습니까?", + "rejectConfirm": "거부", + "approveSuccess": "리뷰가 승인되었습니다", + "approveFailed": "승인에 실패했습니다", + "rejectSuccess": "리뷰가 거부되었습니다", + "rejectFailed": "거부 처리에 실패했습니다", + "approveDisabledScanning": "보안 검사가 진행 중입니다. 검사가 끝나야 승인할 수 있습니다.", + "notFound": "리뷰 작업을 찾을 수 없습니다", + "skillDetailTitle": "스킬 상세", + "skillDetailDescription": "아래 섹션은 이 리뷰 작업에 연결된 대기 중인 버전으로 고정되어 있습니다: {{skill}}", + "skillDetailError": "이 리뷰의 스킬 상세 정보를 불러오지 못했습니다.", + "activeReviewVersion": "리뷰 버전", + "downloadSkillZip": "스킬 ZIP 다운로드", + "noDocumentation": "이 리뷰 버전에는 읽을 수 있는 문서 파일이 포함되어 있지 않습니다." + }, + "token": { + "title": "API 토큰", + "createNew": "토큰 생성", + "copyHint": "보안을 위해 토큰 원문은 생성 시 단 한 번만 복사할 수 있습니다. 이후에는 다시 보거나 복사할 수 없습니다. 여전히 필요하다면 새 토큰을 생성해 주세요.", + "empty": "아직 생성된 토큰이 없습니다", + "emptyHint": "위 버튼을 클릭해 첫 토큰을 생성하세요", + "name": "이름", + "prefix": "토큰 접두사", + "createdAt": "생성 시각", + "lastUsed": "마지막 사용", + "expiresAt": "만료 시각", + "neverExpires": "만료되지 않음", + "actions": "작업", + "copy": "복사", + "copySuccess": "토큰이 클립보드에 복사되었습니다", + "copyFailed": "토큰 복사에 실패했습니다. 다시 시도해 주세요.", + "copyUnavailableTitle": "이전 토큰 원문은 다시 복사할 수 없습니다", + "copyUnavailableDescription": "토큰 원문은 생성 직후 한 번만 표시됩니다. 더 이상 가지고 있지 않다면 새 토큰을 생성해 주세요.", + "editExpiration": "만료 시간 수정", + "editExpirationTitle": "토큰 만료 시간 수정", + "editExpirationDescription": "\"{{name}}\" 토큰의 새 만료 시간을 설정하세요.", + "saveExpiration": "만료 시간 저장", + "updatingExpiration": "저장 중...", + "updateExpirationSuccess": "토큰 만료 시간이 업데이트되었습니다", + "updateExpirationFailed": "토큰 만료 시간 업데이트에 실패했습니다", + "delete": "삭제", + "deleteTitle": "토큰 삭제", + "deleteDescription": "\"{{name}}\" 토큰을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "deleteSuccess": "토큰이 삭제되었습니다", + "deleteFailed": "삭제에 실패했습니다", + "loading": "불러오는 중..." + }, + "apiError": { + "unauthorized": "세션이 만료되었습니다. 다시 로그인해 주세요", + "forbidden": "이 작업에 대한 권한이 없습니다", + "notFound": "요청한 리소스를 찾을 수 없습니다", + "serverError": "서버 오류입니다. 잠시 후 다시 시도해 주세요", + "networkError": "네트워크 연결에 실패했습니다. 네트워크 상태를 확인해 주세요", + "unknown": "작업에 실패했습니다" + }, + "routeGuard": { + "forbiddenTitle": "이 페이지를 볼 권한이 없습니다", + "forbiddenDescription": "계정 권한이 변경되었습니다. 이전 페이지로 돌아갑니다." + }, + "securityAudit": { + "title": "보안 감사", + "dialogDescription": "이 버전에 대한 상세 보안 검사 결과입니다.", + "findings": "발견 사항", + "findingsCount": "발견 사항 {{count}}건", + "totalFindings": "총 발견 사항 {{count}}건", + "scanDuration": "{{seconds}}초", + "statusScanning": "검사 중", + "statusScanFailed": "검사 실패", + "remediation": "조치 방법", + "viewDetails": "상세 보기", + "verdict": { + "SAFE": "안전", + "SUSPICIOUS": "의심스러움", + "DANGEROUS": "위험", + "BLOCKED": "고위험" + }, + "severity": { + "CRITICAL": "심각", + "HIGH": "높음", + "MEDIUM": "보통", + "LOW": "낮음", + "INFO": "정보" + } + }, + "error": { + "auth": { + "local": { + "invalidCredentials": "아이디 또는 비밀번호가 올바르지 않습니다", + "accountDisabled": "이 계정은 비활성화되었습니다", + "accountPending": "이 계정은 활성화 대기 중입니다", + "accountMerged": "이 계정은 병합되어 더 이상 로그인에 사용할 수 없습니다", + "locked": "로그인 시도가 너무 많이 실패했습니다. 잠시 후 다시 시도해 주세요" + }, + "direct": { + "disabled": "직접 인증 호환 기능이 비활성화되어 있습니다", + "providerUnsupported": "지원되지 않는 로그인 방식입니다" + }, + "sessionBootstrap": { + "disabled": "세션 부트스트랩이 비활성화되어 있습니다", + "providerUnsupported": "지원되지 않는 SSO 부트스트랩 방식입니다", + "notAuthenticated": "인증된 외부 세션을 찾을 수 없습니다" + } + } + }, + "notification": { + "title": "알림", + "empty": "알림이 없습니다", + "markAllRead": "모두 읽음으로 표시", + "deleteRead": "읽은 알림 삭제", + "viewAll": "모든 알림 보기", + "unread": "읽지 않음", + "all": "전체", + "publish": "게시", + "review": "리뷰", + "promotion": "승격", + "report": "신고", + "timeAgo": "{{time}} 전", + "preferences": { + "title": "알림 설정", + "description": "알림 설정을 관리하세요", + "publish": "게시 알림", + "publishDesc": "스킬이 게시되면 알림을 받습니다", + "review": "리뷰 알림", + "reviewDesc": "리뷰 제출, 승인, 거부 시 알림을 받습니다", + "promotion": "승격 알림", + "promotionDesc": "승격 요청, 승인, 거부 시 알림을 받습니다", + "report": "신고 알림", + "reportDesc": "신고 제출 또는 처리 시 알림을 받습니다" + } + } +} diff --git a/web/src/shared/components/language-switcher.tsx b/web/src/shared/components/language-switcher.tsx index 6a7d1e39..7d42c061 100644 --- a/web/src/shared/components/language-switcher.tsx +++ b/web/src/shared/components/language-switcher.tsx @@ -19,6 +19,7 @@ export function LanguageSwitcher({ className }: LanguageSwitcherProps) { const languages = [ { code: 'zh', name: '中文' }, { code: 'en', name: 'English' }, + { code: 'ko', name: '한국어' }, ] // 获取当前语言的主要代码(去掉地区代码)