diff --git a/crates/services/src/services/config/versions/v6.rs b/crates/services/src/services/config/versions/v6.rs index e5bfdd6d..472a1ed7 100644 --- a/crates/services/src/services/config/versions/v6.rs +++ b/crates/services/src/services/config/versions/v6.rs @@ -20,6 +20,7 @@ pub enum UiLanguage { Es, // Force Spanish Ko, // Force Korean ZhHans, // Force Simplified Chinese + ZhHant, // Force Traditional Chinese } #[derive(Clone, Debug, Serialize, Deserialize, TS)] diff --git a/frontend/src/i18n/config.ts b/frontend/src/i18n/config.ts index 298ff918..9a61bb6b 100644 --- a/frontend/src/i18n/config.ts +++ b/frontend/src/i18n/config.ts @@ -29,6 +29,11 @@ import zhHansSettings from './locales/zh-Hans/settings.json'; import zhHansProjects from './locales/zh-Hans/projects.json'; import zhHansTasks from './locales/zh-Hans/tasks.json'; import zhHansOrganization from './locales/zh-Hans/organization.json'; +import zhHantCommon from './locales/zh-Hant/common.json'; +import zhHantSettings from './locales/zh-Hant/settings.json'; +import zhHantProjects from './locales/zh-Hant/projects.json'; +import zhHantTasks from './locales/zh-Hant/tasks.json'; +import zhHantOrganization from './locales/zh-Hant/organization.json'; const resources = { en: { @@ -66,6 +71,13 @@ const resources = { tasks: zhHansTasks, organization: zhHansOrganization, }, + 'zh-Hant': { + common: zhHantCommon, + settings: zhHantSettings, + projects: zhHantProjects, + tasks: zhHantTasks, + organization: zhHantOrganization, + }, }; i18n @@ -74,12 +86,16 @@ i18n .init({ resources, fallbackLng: { + 'zh-TW': ['zh-Hant'], + 'zh-HK': ['zh-Hant'], + 'zh-MO': ['zh-Hant'], zh: ['zh-Hans'], // Map generic Chinese to Simplified Chinese default: ['en'], }, defaultNS: 'common', debug: import.meta.env.DEV, - supportedLngs: [...SUPPORTED_I18N_CODES, 'zh'], // Include 'zh' for browser detection + // Include 'zh' + Traditional Chinese locales for browser detection + supportedLngs: [...SUPPORTED_I18N_CODES, 'zh', 'zh-TW', 'zh-HK', 'zh-MO'], nonExplicitSupportedLngs: true, // Accept zh -> zh-Hans mapping load: 'currentOnly', // Load exact language code diff --git a/frontend/src/i18n/languages.ts b/frontend/src/i18n/languages.ts index 300210a4..eb77c1e8 100644 --- a/frontend/src/i18n/languages.ts +++ b/frontend/src/i18n/languages.ts @@ -12,6 +12,7 @@ export const UI_TO_I18N = { ES: 'es', KO: 'ko', ZH_HANS: 'zh-Hans', + ZH_HANT: 'zh-Hant', } as const; const SUPPORTED_UI_LANGUAGES = [ @@ -21,6 +22,7 @@ const SUPPORTED_UI_LANGUAGES = [ 'ES', 'KO', 'ZH_HANS', + 'ZH_HANT', ] as const; export const SUPPORTED_I18N_CODES = Object.values(UI_TO_I18N); @@ -30,6 +32,7 @@ const FALLBACK_ENDONYMS = { es: 'Español', ko: '한국어', 'zh-Hans': '简体中文', + 'zh-Hant': '繁體中文', } as const; /** diff --git a/frontend/src/i18n/locales/zh-Hant/common.json b/frontend/src/i18n/locales/zh-Hant/common.json new file mode 100644 index 00000000..321c1854 --- /dev/null +++ b/frontend/src/i18n/locales/zh-Hant/common.json @@ -0,0 +1,97 @@ +{ + "buttons": { + "save": "儲存", + "cancel": "取消", + "send": "傳送", + "delete": "刪除", + "edit": "編輯", + "create": "建立", + "continue": "繼續", + "reset": "重設", + "manage": "管理", + "connect": "連線", + "disconnect": "中斷連線", + "close": "關閉", + "replay": "重播" + }, + "states": { + "loading": "載入中...", + "saving": "儲存中...", + "error": "錯誤", + "success": "成功", + "reconnecting": "重新連線中" + }, + "language": { + "browserDefault": "瀏覽器預設" + }, + "conversation": { + "plan": "計畫", + "planToggle": { + "show": "顯示計畫", + "hide": "隱藏計畫" + }, + "toolDetailsToggle": { + "show": "顯示詳細資訊", + "hide": "隱藏詳細資訊" + }, + "args": "參數", + "output": "輸出", + "result": "結果", + "deniedByUser": "使用者拒絕了 {{toolName}}" + }, + "folderPicker": { + "legend": "點擊資料夾名稱進行導覽 • 使用操作按鈕進行選擇", + "manualPathLabel": "手動輸入路徑:", + "go": "前往", + "searchLabel": "搜尋目前目錄:", + "selectCurrent": "選取目前", + "gitRepo": "Git 儲存庫", + "selectPath": "選取路徑" + }, + "branchSelector": { + "placeholder": "選擇分支", + "searchPlaceholder": "搜尋分支...", + "empty": "找不到分支", + "badges": { + "current": "目前", + "remote": "遠端" + }, + "currentDisabled": "無法選擇目前分支" + }, + "breadcrumb": { + "more": "更多" + }, + "orgMembers": { + "moreCount": "還有 {{count}} 位" + }, + "orgSwitcher": { + "title": "切換組織", + "description": "選擇要切換到的組織。", + "loadError": "載入組織失敗。請重試。", + "noOrganizations": "您不是任何組織的成員。", + "menuItem": "組織", + "loadingPlaceholder": "載入組織中...", + "selectPlaceholder": "選擇組織", + "currentBadge": "(目前)" + }, + "signOut": "登出", + "devMode": { + "banner": "開發模式 - 這是開發版本" + }, + "oauth": { + "title": "登入 Vibe Kanban", + "description": "登入以加入組織並與團隊共享任務", + "continueWithGitHub": "使用 GitHub 繼續", + "continueWithGoogle": "使用 Google 繼續", + "waitingTitle": "完成身分驗證", + "waitingDescription": "已開啟彈出視窗進行驗證", + "waitingForAuth": "等待身分驗證...", + "popupInstructions": "如果彈出視窗未開啟,請檢查您的彈出視窗攔截器設定。", + "back": "返回", + "successTitle": "身分驗證成功!", + "welcomeBack": "歡迎回來,{{name}}", + "errorTitle": "身分驗證失敗", + "errorDescription": "驗證您的帳號時發生問題", + "tryAgain": "重試" + } +} diff --git a/frontend/src/i18n/locales/zh-Hant/organization.json b/frontend/src/i18n/locales/zh-Hant/organization.json new file mode 100644 index 00000000..0f3b0c78 --- /dev/null +++ b/frontend/src/i18n/locales/zh-Hant/organization.json @@ -0,0 +1,78 @@ +{ + "createDialog": { + "title": "建立新組織", + "description": "建立新組織以與團隊協作。", + "nameLabel": "組織名稱", + "namePlaceholder": "例如:Acme 公司", + "slugLabel": "短標識", + "slugPlaceholder": "例如:acme-corporation", + "slugHelper": "用於 URL。僅限小寫字母、數字與連字號。", + "creating": "建立中...", + "createButton": "建立組織" + }, + "inviteDialog": { + "title": "邀請成員", + "description": "發送邀請加入您的組織。", + "emailLabel": "電子郵件地址", + "emailPlaceholder": "colleague@example.com", + "roleLabel": "角色", + "rolePlaceholder": "選擇角色", + "roleHelper": "管理員可以管理成員與組織設定。", + "sending": "發送中...", + "sendButton": "發送邀請" + }, + "roles": { + "member": "成員", + "admin": "管理員" + }, + "memberList": { + "title": "成員", + "description": "管理 {{orgName}} 中的成員與角色", + "inviteButton": "邀請成員", + "loading": "載入成員中...", + "none": "找不到成員", + "you": "您" + }, + "invitationList": { + "title": "待處理邀請", + "description": "查看 {{orgName}} 的待處理邀請", + "loading": "載入邀請中...", + "none": "沒有待處理的邀請", + "invited": "邀請於 {{date}}", + "pending": "待處理" + }, + "settings": { + "title": "組織設定", + "description": "管理組織成員與權限", + "selectLabel": "選擇組織", + "selectPlaceholder": "選擇組織", + "selectHelper": "選擇要查看與管理成員的組織", + "noOrganizations": "沒有可用的組織", + "loadingOrganizations": "載入組織中...", + "loadError": "載入組織失敗", + "dangerZone": "危險區域", + "dangerZoneDescription": "不可逆且具破壞性的操作", + "deleteOrganization": "刪除組織", + "deleteOrganizationDescription": "永久刪除此組織及其所有資料", + "confirmDelete": "您確定要刪除 {{orgName}} 嗎?此操作無法復原。", + "deleteSuccess": "組織刪除成功", + "deleteError": "刪除組織失敗" + }, + "loginRequired": { + "title": "需要登入", + "description": "您需要登入才能管理組織設定。", + "action": "登入" + }, + "confirmRemoveMember": "您確定要從組織中移除此成員嗎?", + "sharedProjects": { + "title": "共享專案", + "description": "{{orgName}} 中的遠端專案及其與本地專案的連結", + "loading": "載入專案中...", + "noProjects": "此組織中找不到共享專案", + "notLinked": "未連結", + "linkedTo": "連結到:{{projectName}}", + "linked": "已連結", + "linkProject": "連結專案...", + "noAvailableProjects": "沒有可用的專案" + } +} diff --git a/frontend/src/i18n/locales/zh-Hant/projects.json b/frontend/src/i18n/locales/zh-Hant/projects.json new file mode 100644 index 00000000..f63f388f --- /dev/null +++ b/frontend/src/i18n/locales/zh-Hant/projects.json @@ -0,0 +1,53 @@ +{ + "title": "專案", + "subtitle": "管理您的專案並追蹤進度", + "createProject": "建立專案", + "linkToOrganization": "連結到遠端專案", + "loading": "載入專案中...", + "errors": { + "fetchFailed": "取得專案失敗", + "deleteFailed": "刪除專案失敗" + }, + "empty": { + "title": "還沒有專案", + "description": "先建立您的第一個專案。", + "createFirst": "建立您的第一個專案" + }, + "linkDialog": { + "title": "將專案連結到遠端專案", + "description": "將此本地專案連結到遠端專案以協作與同步。", + "projectLabel": "專案", + "organizationLabel": "組織", + "loadingOrganizations": "載入組織中...", + "noOrganizations": "沒有可用的組織。請先建立組織。", + "selectOrganization": "選擇組織", + "loginRequired": { + "title": "需要登入", + "description": "您需要登入才能連結專案。", + "action": "登入" + }, + "linkModeLabel": "連結模式", + "linkToExisting": "連結到既有", + "createNew": "新建", + "remoteProjectLabel": "遠端專案", + "loadingRemoteProjects": "載入遠端專案中...", + "noRemoteProjects": "在此組織中找不到遠端專案。請嘗試建立新專案。", + "selectRemoteProject": "選擇遠端專案", + "newProjectNameLabel": "新遠端專案名稱", + "newProjectNamePlaceholder": "輸入專案名稱", + "linking": "連結中...", + "linkButton": "連結專案", + "errors": { + "selectOrganization": "請選擇組織", + "selectRemoteProject": "請選擇遠端專案", + "enterProjectName": "請輸入專案名稱", + "linkFailed": "連結專案失敗" + } + }, + "unlinkFromOrganization": "取消連結遠端專案", + "projectNotFound": "您要查找的專案不存在或已被刪除。", + "viewProject": "查看專案", + "openInIDE": "在 IDE 中開啟", + "createdDate": "建立於 {{date}}", + "copyFilesPlaceholderWithSearch": "檔案路徑或 glob 模式(例如:.env、config/*.json)" +} diff --git a/frontend/src/i18n/locales/zh-Hant/settings.json b/frontend/src/i18n/locales/zh-Hant/settings.json new file mode 100644 index 00000000..1e98644c --- /dev/null +++ b/frontend/src/i18n/locales/zh-Hant/settings.json @@ -0,0 +1,411 @@ +{ + "settings": { + "layout": { + "nav": { + "title": "設定", + "general": "一般", + "generalDesc": "主題、通知與偏好設定", + "projects": "專案", + "projectsDesc": "專案腳本與設定", + "agents": "代理", + "agentsDesc": "編碼代理設定", + "mcp": "MCP 伺服器", + "mcpDesc": "模型上下文協議伺服器", + "organizations": "組織設定", + "organizationsDesc": "管理組織成員與權限" + } + }, + "general": { + "loading": "載入設定中...", + "loadError": "載入設定失敗。", + "save": { + "button": "儲存設定", + "success": "✓ 設定儲存成功!", + "error": "儲存設定失敗", + "unsavedChanges": "• 您有未儲存的變更", + "discard": "放棄" + }, + "appearance": { + "title": "外觀", + "description": "自訂應用程式的外觀與風格。", + "theme": { + "label": "主題", + "placeholder": "選擇主題", + "helper": "選擇您喜歡的配色方案。" + }, + "language": { + "label": "語言", + "placeholder": "選擇語言", + "helper": "選擇您偏好的語言。瀏覽器預設將跟隨系統語言。" + } + }, + "taskExecution": { + "title": "預設編碼代理", + "description": "選擇任務的預設編碼代理。", + "executor": { + "label": "預設代理設定檔", + "placeholder": "選擇設定檔", + "helper": "選擇建立任務嘗試時要使用的預設代理設定檔。" + }, + "variant": "預設", + "defaultLabel": "預設" + }, + "editor": { + "title": "編輯器", + "description": "設定您的程式碼編輯體驗。", + "type": { + "label": "編輯器類型", + "placeholder": "選擇編輯器", + "helper": "選擇您偏好的程式碼編輯器介面。" + }, + "customCommand": { + "label": "自訂編輯器指令", + "placeholder": "例如:code、subl、vim", + "helper": "輸入啟動自訂編輯器的指令,用於開啟檔案。" + }, + "remoteSsh": { + "host": { + "label": "遠端 SSH 主機(選填)", + "placeholder": "例如:主機名稱或 IP 位址", + "helper": "若 Vibe Kanban 在遠端伺服器上執行,請設定此項。設定後,點擊在編輯器中開啟將產生 URL 以透過 SSH 開啟編輯器,而非執行本機指令。" + }, + "user": { + "label": "遠端 SSH 使用者(選填)", + "placeholder": "例如:使用者名稱", + "helper": "遠端連線的 SSH 使用者名稱。若未設定,VS Code 將使用您的 SSH 設定或提示輸入。" + } + }, + "availability": { + "checking": "檢查可用性...", + "available": "可用", + "notFound": "在 PATH 中找不到" + } + }, + "github": { + "title": "GitHub 整合", + "cliSetup": { + "title": "GitHub CLI 設定", + "description": "需要 GitHub CLI 驗證才能建立 PR 並與 GitHub 儲存庫互動。", + "setupWillTitle": "此設定將:", + "steps": { + "checkInstalled": "檢查是否已安裝 GitHub CLI (gh)", + "installHomebrew": "如有需要,透過 Homebrew 安裝(macOS)", + "authenticate": "使用 OAuth 進行 GitHub 驗證" + }, + "setupNote": "設定會在聊天視窗中執行。您需要在瀏覽器中完成驗證。", + "runSetup": "執行設定", + "running": "執行中...", + "errors": { + "brewMissing": "未安裝 Homebrew。請安裝以啟用自動設定。", + "notSupported": "此平台不支援自動設定。請手動安裝 GitHub CLI。", + "setupFailed": "執行 GitHub CLI 設定失敗。" + }, + "help": { + "homebrew": { + "description": "自動安裝需要 Homebrew。請至", + "brewSh": "brew.sh", + "manualInstall": "安裝 Homebrew,然後重新執行設定。或使用以下指令手動安裝 GitHub CLI:", + "afterInstall": "安裝後,使用以下指令進行驗證:" + }, + "manual": { + "description": "從", + "officialDocs": "官方文件", + "andAuthenticate": "安裝 GitHub CLI,並使用您的 GitHub 帳號進行驗證。" + } + } + } + }, + "git": { + "title": "Git", + "description": "設定 Git 分支命名偏好", + "branchPrefix": { + "label": "分支前綴", + "placeholder": "vk", + "helper": "自動產生的分支名稱前綴。留空表示不使用前綴。", + "preview": "預覽:", + "previewWithPrefix": "{{prefix}}/1a2b-task-name", + "previewNoPrefix": "1a2b-task-name", + "errors": { + "slash": "前綴不能包含 '/'。", + "startsWithDot": "前綴不能以 '.' 開頭。", + "endsWithDot": "前綴不能以 '.' 或 '.lock' 結尾。", + "invalidSequence": "包含無效序列(..、@{)。", + "invalidChars": "包含無效字元。", + "controlChars": "包含控制字元。" + } + } + }, + "pullRequests": { + "title": "PR", + "description": "設定 PR 建立行為", + "autoDescription": { + "label": "預設自動產生 PR 描述", + "helper": "啟用後,AI 代理會在建立 PR 後自動更新標題與描述。" + }, + "customPrompt": { + "useCustom": "使用自訂提示", + "helper": "產生 PR 描述時 AI 代理使用的自訂提示。使用 {pr_number} 與 {pr_url} 作為佔位符。" + } + }, + "notifications": { + "title": "通知", + "description": "控制何時與如何接收通知。", + "sound": { + "label": "音效通知", + "helper": "任務嘗試完成執行時播放音效。", + "fileLabel": "音效", + "filePlaceholder": "選擇音效", + "fileHelper": "選擇任務完成時播放的音效。點擊音量按鈕可預覽。" + }, + "push": { + "label": "推播通知", + "helper": "任務嘗試完成執行時顯示系統通知。" + } + }, + "privacy": { + "title": "隱私", + "description": "透過分享匿名使用資料來協助改善 Vibe Kanban。", + "telemetry": { + "label": "啟用遙測", + "helper": "啟用匿名使用事件追蹤以協助改善應用程式。不會收集提示或專案資訊。" + } + }, + "taskTemplates": { + "title": "標籤", + "description": "建立可用 @tag_name 插入任務描述的可重用文字片段。" + }, + "tags": { + "manager": { + "title": "任務標籤", + "addTag": "新增標籤", + "noTags": "尚無標籤。為常見任務描述建立可重用文字片段。在任何任務中使用 @tag_name。", + "table": { + "tagName": "標籤名稱", + "content": "內容", + "actions": "操作" + }, + "actions": { + "editTag": "編輯標籤", + "deleteTag": "刪除標籤" + }, + "deleteConfirm": "您確定要刪除標籤 {{tagName}} 嗎?" + }, + "dialog": { + "createTitle": "建立標籤", + "editTitle": "編輯標籤", + "tagName": { + "label": "標籤名稱", + "required": "*", + "hint": "在任務描述中使用 @ 加上此名稱:@{{tagName}}", + "placeholder": "例如:bug_fix、test_plan、api_docs", + "error": "標籤名稱不能包含空白。請使用底線(例如:my_tag)" + }, + "content": { + "label": "內容", + "required": "*", + "hint": "在任務描述中使用 @{{tagName}} 時會插入的文字", + "placeholder": "輸入使用此標籤時要插入的文字" + }, + "errors": { + "nameRequired": "標籤名稱為必填", + "saveFailed": "儲存標籤失敗" + }, + "buttons": { + "cancel": "取消", + "create": "建立", + "update": "更新" + } + } + }, + "safety": { + "title": "安全與免責聲明", + "description": "重設安全警告與入門流程確認。", + "disclaimer": { + "title": "免責聲明確認", + "description": "重設安全免責聲明。", + "button": "重設" + }, + "onboarding": { + "title": "入門流程", + "description": "重設入門流程。", + "button": "重設" + } + } + }, + "agents": { + "title": "編碼代理設定", + "description": "使用不同設定自訂編碼代理的行為。", + "loading": "載入代理設定中...", + "save": { + "button": "儲存代理設定", + "success": "✓ 執行器設定儲存成功!" + }, + "availability": { + "checking": "檢查中...", + "loginDetected": "偵測到最近使用", + "loginDetectedTooltip": "找到此代理的最近驗證憑證", + "installationFound": "偵測到曾使用", + "installationFoundTooltip": "找到代理設定。您可能需要登入才能使用。", + "notFound": "未找到", + "notFoundTooltip": "未偵測到曾使用。代理可能需要安裝和/或登入。" + }, + "editor": { + "formLabel": "編輯 JSON", + "agentLabel": "代理", + "agentPlaceholder": "選擇執行器類型", + "configLabel": "設定", + "configPlaceholder": "選擇設定", + "createNew": "新建...", + "deleteTitle": "無法刪除最後一個設定", + "deleteButton": "刪除 {{name}}", + "deleteText": "刪除", + "jsonLabel": "代理設定(JSON)", + "jsonPlaceholder": "載入設定檔中...", + "jsonLoading": "載入中...", + "pathLabel": "設定檔位置:" + }, + "errors": { + "deleteFailed": "刪除設定失敗。請重試。", + "saveFailed": "儲存代理設定失敗。請重試。", + "saveConfigFailed": "儲存設定失敗。請重試。" + } + }, + "mcp": { + "title": "MCP 伺服器設定", + "description": "設定模型上下文協議伺服器,使用自訂工具與資源擴充編碼代理功能。", + "loading": "載入 MCP 設定中...", + "applying": "套用設定中...", + "labels": { + "agent": "代理", + "agentPlaceholder": "選擇執行器", + "agentHelper": "選擇要設定 MCP 伺服器的代理。", + "serverConfig": "伺服器設定(JSON)", + "popularServers": "熱門伺服器", + "serverHelper": "點擊卡片將該 MCP 伺服器插入到上方 JSON 中。", + "saveLocation": "變更將儲存到:" + }, + "loadingStates": { + "jsonEditor": "載入中...", + "configuration": "載入目前 MCP 伺服器設定..." + }, + "errors": { + "loadFailed": "載入設定失敗。", + "invalidJson": "JSON 格式無效", + "validationError": "驗證錯誤", + "saveFailed": "儲存 MCP 伺服器失敗", + "applyFailed": "套用 MCP 伺服器設定失敗", + "addServerFailed": "新增預設伺服器失敗", + "mcpError": "MCP 設定錯誤:{{error}}", + "notSupported": "不支援 MCP", + "supportMessage": "要使用 MCP 伺服器,請在上方選擇支援 MCP 的其他執行器(Claude、Amp、Gemini、Codex 或 Opencode)。" + }, + "save": { + "button": "儲存 MCP 設定", + "success": "設定已儲存!", + "successMessage": "✓ MCP 設定儲存成功!", + "loading": "載入目前 MCP 伺服器設定..." + } + }, + "projects": { + "title": "專案設定", + "description": "設定專案專屬的腳本與選項。", + "loading": "載入專案中...", + "loadError": "載入專案失敗。", + "selector": { + "label": "選擇專案", + "placeholder": "選擇要設定的專案", + "helper": "選擇專案以查看與編輯其設定。", + "noProjects": "沒有可用的專案" + }, + "general": { + "title": "一般設定", + "description": "設定基本專案資訊。", + "name": { + "label": "專案名稱", + "placeholder": "輸入專案名稱", + "helper": "此專案的顯示名稱。" + }, + "repoPath": { + "label": "Git 儲存庫路徑", + "placeholder": "/path/to/your/existing/repo", + "helper": "磁碟上的 Git 儲存庫絕對路徑。" + } + }, + "scripts": { + "title": "腳本與設定", + "description": "為此專案設定設定腳本、清理腳本與要複製的檔案。", + "setup": { + "label": "設定腳本", + "helper": "此腳本在工作樹內執行,於建立後、編碼代理啟動前執行。用於安裝相依套件或準備環境等設定工作。", + "parallelLabel": "與編碼代理平行執行設定腳本", + "parallelHelper": "啟用後,設定腳本將與編碼代理同時執行,而不是等待設定完成後再啟動。" + }, + "dev": { + "label": "開發伺服器腳本", + "helper": "從任務嘗試中啟動開發伺服器。腳本會從工作區目錄(每個儲存庫工作樹的上一層)執行,除非在下方指定工作目錄。" + }, + "devWorkingDir": { + "label": "開發伺服器工作目錄", + "placeholder": "例如:my-repo", + "helper": "執行開發伺服器腳本的目錄,相對於工作區根目錄。留空則從工作區根目錄執行。" + }, + "agentWorkingDir": { + "label": "代理工作目錄", + "placeholder": "例如:my-repo", + "helper": "新工作區執行編碼代理的預設目錄,相對於工作區根目錄。此值在建立工作區時保存,不會影響現有工作區。單一儲存庫專案預設為儲存庫名稱。留空則從工作區根目錄執行。" + }, + "cleanup": { + "label": "清理腳本", + "helper": "此腳本在工作樹內執行,於編碼代理執行後(僅在有變更時)執行。用於品質保證工作,如執行 linter、格式化工具、測試或其他驗證步驟。若無變更將略過此腳本。" + }, + "copyFiles": { + "label": "複製檔案", + "helper": "要從原始專案目錄複製到工作樹的檔案清單(以逗號分隔)。這些檔案會在建立工作樹後但在執行設定腳本前複製。適合用於 .env、設定檔與本機設定等環境特定檔案。請確保這些檔案已加入 gitignore,否則可能會被提交!" + } + }, + "save": { + "button": "儲存專案設定", + "success": "✓ 專案設定儲存成功!", + "error": "儲存專案設定失敗", + "unsavedChanges": "• 您有未儲存的變更", + "discard": "放棄", + "confirmSwitch": "您有未儲存的變更。確定要切換專案嗎?您的變更將會遺失。" + } + } + }, + "integrations": { + "github": { + "cliSetup": { + "title": "GitHub CLI 設定", + "description": "需要 GitHub CLI 驗證才能建立 PR 並與 GitHub 儲存庫互動。", + "setupWillTitle": "此設定將:", + "steps": { + "checkInstalled": "檢查是否已安裝 GitHub CLI (gh)", + "installHomebrew": "如有需要,透過 Homebrew 安裝(macOS)", + "authenticate": "使用 OAuth 進行 GitHub 驗證" + }, + "setupNote": "設定會在聊天視窗中執行。您需要在瀏覽器中完成驗證。", + "runSetup": "執行設定", + "running": "執行中...", + "errors": { + "brewMissing": "未安裝 Homebrew。請安裝以啟用自動設定。", + "notSupported": "此平台不支援自動設定。請手動安裝 GitHub CLI。", + "setupFailed": "執行 GitHub CLI 設定失敗。" + }, + "help": { + "homebrew": { + "description": "自動安裝需要 Homebrew。請至", + "brewSh": "brew.sh", + "manualInstall": "安裝 Homebrew,然後重新執行設定。或使用以下指令手動安裝 GitHub CLI:", + "afterInstall": "安裝後,使用以下指令進行驗證:" + }, + "manual": { + "description": "從", + "officialDocs": "官方文件", + "andAuthenticate": "安裝 GitHub CLI,並使用您的 GitHub 帳號進行驗證。" + } + } + } + } + } +} diff --git a/frontend/src/i18n/locales/zh-Hant/tasks.json b/frontend/src/i18n/locales/zh-Hant/tasks.json new file mode 100644 index 00000000..ae8f20c5 --- /dev/null +++ b/frontend/src/i18n/locales/zh-Hant/tasks.json @@ -0,0 +1,518 @@ +{ + "loading": "載入任務中...", + "empty": { + "noTasks": "找不到此專案的任務。", + "createFirst": "建立第一個任務", + "noSearchResults": "沒有任務符合您的搜尋。" + }, + "actions": { + "addTask": "新增任務" + }, + "filters": { + "sharedToggleAria": "切換共享任務", + "sharedToggleTooltip": "顯示/隱藏共享內容" + }, + "rebase": { + "common": { + "action": "重基底", + "inProgress": "重基底中...", + "withTarget": "重基底到 {{branch}}" + }, + "dialog": { + "title": "重基底任務嘗試", + "description": "選擇新的基底分支以將此任務嘗試重基底到該分支上。", + "upstreamLabel": "上游分支", + "upstreamPlaceholder": "選擇上游分支", + "targetLabel": "目標分支", + "targetPlaceholder": "選擇目標分支", + "advanced": "進階" + }, + "status": { + "inProgress": "重基底進行中{{counts}}", + "needed": "需要重基底{{dirty}}{{counts}}", + "dirtyMarker": "(髒)" + } + }, + "branches": { + "changeTarget": { + "dialog": { + "title": "變更目標分支", + "description": "為任務嘗試選擇新的目標分支。", + "placeholder": "選擇目標分支", + "action": "變更分支", + "inProgress": "變更中..." + } + } + }, + "repos": { + "changeRepo": { + "dialog": { + "title": "變更儲存庫", + "description": "選擇用於 Git 操作的儲存庫。", + "label": "儲存庫", + "placeholder": "選擇儲存庫", + "action": "變更儲存庫" + } + }, + "selector": { + "placeholder": "選擇儲存庫", + "empty": "沒有可用的儲存庫" + } + }, + "repoBranchSelector": { + "label": "基底分支" + }, + "attemptRepoSelector": { + "label": "儲存庫", + "addButton": "新增", + "empty": "尚未選擇儲存庫。請至少新增一個儲存庫。", + "selectBranch": "選擇分支", + "addRepo": { + "title": "選擇 Git 儲存庫", + "description": "選擇要新增到此嘗試的 Git 儲存庫" + } + }, + "preview": { + "title": "預覽", + "selectAttempt": "選擇嘗試以查看預覽", + "troubleAlert": { + "title": "我們在預覽您的應用程式時遇到問題:", + "item1": "開發伺服器是否成功啟動?可能有錯誤需要處理,或需要安裝相依套件。", + "item2": "您的開發伺服器是否以格式將 URL 與連接埠輸出到終端機", + "item2Suffix": "?(這是我們判斷它是否在執行的方式)", + "item3": "您是否安裝了 Web Companion(點擊編輯所需)?如果沒有,請", + "item3Link": "依照此處的安裝說明操作" + }, + "noServer": { + "title": "沒有執行中的開發伺服器", + "startPrompt": "請啟動開發伺服器以查看預覽", + "setupPrompt": "要使用即時預覽與點擊編輯,請為此專案新增開發伺服器腳本。", + "companionPrompt": "要使用點擊編輯功能,請將瀏覽器 Companion 加到您的專案。", + "companionLink": "查看安裝指南", + "startButton": "啟動開發伺服器", + "editButton": "編輯開發腳本", + "stopAndEditButton": "停止開發伺服器並解決問題" + }, + "devScript": { + "saveAndStart": "儲存並啟動", + "saveOnly": "僅儲存", + "saveChanges": "儲存變更", + "cancel": "取消", + "errors": { + "notLoaded": "專案未載入", + "empty": "開發腳本不得為空" + } + }, + "logs": { + "title": "開發伺服器日誌", + "hide": "隱藏", + "show": "顯示" + }, + "iframe": { + "title": "開發伺服器預覽" + }, + "toolbar": { + "refresh": "重新整理預覽", + "copyUrl": "複製 URL", + "openInTab": "在新分頁開啟", + "stopDevServer": "停止開發伺服器" + } + }, + "diff": { + "viewModes": { + "inline": "行內檢視", + "split": "分割檢視" + }, + "ignoreWhitespace": "忽略空白變更", + "errorLoadingDiff": "載入差異失敗:{{error}}", + "expandAll": "展開所有差異", + "collapseAll": "收合所有差異", + "filesChanged_one": "{{count}} 個檔案已變更", + "filesChanged_other": "{{count}} 個檔案已變更", + "noChanges": "尚未進行任何變更" + }, + "taskPanel": { + "noTaskSelected": "未選擇任務", + "loadingAttempts": "載入嘗試中...", + "errorLoadingAttempts": "載入嘗試失敗", + "attemptsCount": "嘗試({{count}})", + "noAttempts": "尚無嘗試" + }, + "processes": { + "selectAttempt": "選擇嘗試以查看執行程序。", + "errorLoadingUpdates": "載入程序的即時更新失敗。", + "reconnecting": "重新連線中...", + "loading": "載入執行程序中...", + "noProcesses": "找不到此嘗試的執行程序。", + "processId": "程序 ID:{{id}}", + "deleted": "已刪除", + "deletedTooltip": "因復原而刪除:時間軸已回復到檢查點,後續執行已移除", + "agent": "代理:", + "exit": "退出:{{code}}", + "started": "開始:{{date}}", + "completed": "完成:{{date}}", + "detailsTitle": "程序詳情", + "backToList": "返回列表", + "loadingDetails": "載入程序詳情中...", + "errorLoadingDetails": "載入程序詳情失敗。請重試。", + "copyLogs": "複製日誌", + "logsCopied": "已複製!" + }, + "taskHeader": { + "editTask": "編輯任務", + "deleteTask": "刪除任務", + "closePanel": "關閉面板" + }, + "navigateToParent": "導航到父任務嘗試", + "toolbar": { + "actions": "操作", + "noAttempts": "尚無嘗試", + "startFirstAttempt": "開始第一次嘗試以開始處理此任務", + "startAttempt": "開始嘗試" + }, + "followUp": { + "stop": "停止", + "clearReviewComments": "清除審查評論", + "resolveConflicts": "解決衝突", + "send": "傳送", + "unqueuing": "取消佇列中...", + "edit": "編輯", + "queuing": "佇列中...", + "queueForNextTurn": "排入下一輪", + "queue": "佇列", + "cancelQueue": "取消佇列", + "queuedMessage": "訊息已加入佇列 - 會在目前執行完成後處理", + "runSetupScript": "執行設定腳本", + "runCleanupScript": "執行清理腳本", + "noSetupScript": "未為此專案設定設定腳本", + "noCleanupScript": "未為此專案設定清理腳本", + "scriptsDisabledWhileRunning": "程序執行時無法執行腳本" + }, + "todos": { + "title_one": "待辦事項({{count}})", + "title_other": "待辦事項({{count}})" + }, + "attempt": { + "actions": { + "openInIde": "在 IDE 中開啟", + "openMenu": "開啟選單", + "startDevServer": "啟動開發伺服器", + "stopDevServer": "停止開發伺服器" + }, + "labels": { + "attempt": "嘗試", + "agent": "代理", + "branch": "分支", + "diffs": "差異", + "summaryAndActions": "摘要與操作" + }, + "agent": "代理", + "path": "路徑", + "openInEditor": "在 {{editor}} 中查看變更", + "copied": "已複製!", + "clickToCopy": "複製工作樹路徑", + "stopDev": "停止開發", + "pauseDev": "暫停開發", + "startDev": "啟動開發", + "viewDevLogs": "查看開發伺服器日誌", + "stopping": "停止中...", + "stopAttempt": "停止嘗試", + "newAttempt": "新嘗試", + "viewHistory": "查看嘗試歷史", + "createSubtask": "建立子任務", + "preview": "預覽", + "diffs": "差異", + "gitActions": "Git 操作", + "tryAgain": "重試", + "runSetup": "執行設定", + "setupHelpText": "{{agent}} 未正確設定。點擊執行設定以安裝並登入。", + "devScriptMissingTooltip": "要啟動開發伺服器,請為此專案新增開發腳本" + }, + "git": { + "labels": { + "taskBranch": "任務分支" + }, + "branch": { + "current": "目前" + }, + "forcePushDialog": { + "title": "需要強制推送", + "description": "遠端分支{{branchLabel}}已與本機分支分岔。一般推送被拒絕。", + "warning": "強制推送將以本機變更覆寫遠端變更。此操作無法復原。", + "note": "僅在您確定要取代遠端分支歷史時才繼續。", + "error": "強制推送失敗" + }, + "status": { + "commits_one": "提交", + "commits_other": "提交", + "conflicts": "衝突", + "upToDate": "最新", + "ahead": "領先", + "behind": "落後" + }, + "states": { + "merged": "已合併!", + "merging": "合併中...", + "merge": "合併", + "rebasing": "重基底中...", + "rebase": "重基底", + "pushed": "已推送!", + "pushing": "推送中...", + "push": "推送", + "forcePush": "強制推送", + "forcePushing": "強制推送中...", + "creating": "建立中...", + "createPr": "建立 PR" + }, + "errors": { + "changeTargetBranch": "變更目標分支失敗", + "pushChanges": "推送變更失敗", + "mergeChanges": "合併變更失敗", + "rebaseBranch": "重基底分支失敗" + }, + "pr": { + "open": "開啟 PR #{{number}}", + "number": "PR #{{number}}" + }, + "actions": { + "title": "Git 操作", + "prMerged": "PR #{{number}} 已合併", + "loginRequired": { + "title": "登入以管理 Git 操作", + "description": "登入 Vibe Kanban,才能推送分支、合併變更或為此任務建立 PR。", + "action": "登入" + } + } + }, + "createAttemptDialog": { + "title": "建立嘗試", + "description": "使用編碼代理開始新的嘗試。將建立 Git 工作樹與任務分支。", + "baseBranch": "基底分支", + "loadingBranches": "載入分支中...", + "selectBranch": "選擇分支", + "error": "建立嘗試失敗。請重試。", + "creating": "建立中...", + "start": "開始" + }, + "viewProcessesDialog": { + "title": "執行程序" + }, + "viewRelatedTasksDialog": { + "title": "相關任務", + "empty": "此嘗試沒有相關任務", + "error": "載入相關任務失敗", + "tasksCount": "任務({{count}})", + "columns": { + "title": "標題", + "description": "描述", + "status": "狀態" + } + }, + "attemptHeaderActions": { + "preview": "預覽", + "diffs": "差異", + "relatedTasks": "相關任務" + }, + "actionsMenu": { + "attempt": "嘗試", + "openInIde": "在 IDE 中開啟嘗試", + "viewProcesses": "查看程序", + "viewRelatedTasks": "查看相關任務", + "createNewAttempt": "建立新嘗試", + "createSubtask": "建立子任務", + "gitActions": "Git 操作", + "editBranchName": "編輯分支名稱", + "task": "任務", + "share": "分享", + "reassign": "重新指派", + "stopShare": "停止分享", + "duplicate": "複製" + }, + "editBranchName": { + "dialog": { + "title": "編輯分支名稱", + "description": "輸入分支的新名稱。如果有未關閉的 PR,則無法重新命名。", + "branchNameLabel": "分支名稱", + "placeholder": "例如:feature/my-branch", + "renaming": "重新命名中...", + "action": "重新命名分支" + } + }, + "stopShareDialog": { + "title": "停止分享任務", + "description": "停止與您的組織分享 {{title}}?", + "warning": "停止與組織分享任務,但保留本地任務。", + "confirm": "停止分享任務", + "inProgress": "停止分享中...", + "genericError": "停止分享任務失敗。請重試。" + }, + "shareDialog": { + "title": "分享任務", + "description": "與您的組織分享 {{title}}?", + "success": "任務分享成功。", + "genericError": "分享任務失敗。請重試。", + "loadingSystem": "載入帳戶狀態中...", + "loginRequired": { + "title": "需要登入", + "description": "您需要登入才能分享任務。我們會將您導向登入頁面。", + "action": "前往登入" + }, + "githubRequired": { + "title": "連結 GitHub", + "description": "連結您的 GitHub 帳號以分享任務。此專案必須在 GitHub 上有遠端儲存庫。", + "action": "連結 GitHub" + }, + "linkProjectRequired": { + "description": "分享任務前,請先將此專案連結到組織。", + "action": "連結專案" + }, + "confirmationTitle": "確認分享", + "confirmationBody": "分享會將此任務發佈到您的共享工作區。", + "cancel": "取消", + "confirm": "分享任務", + "inProgress": "分享中...", + "closeButton": "關閉" + }, + "createPrDialog": { + "title": "建立 GitHub PR", + "description": "在 GitHub 上為此任務嘗試建立 PR。", + "titleLabel": "標題", + "titlePlaceholder": "輸入 PR 標題", + "descriptionLabel": "描述(選填)", + "descriptionPlaceholder": "輸入 PR 描述", + "baseBranchLabel": "基底分支", + "loadingBranches": "載入分支中...", + "selectBaseBranch": "選擇基底分支", + "draftLabel": "建立為草稿", + "autoGenerateLabel": "請求 AI 代理產生更好的 PR 描述", + "creating": "建立中...", + "createButton": "建立 PR", + "errors": { + "insufficientPermissions": "權限不足。請確認 GitHub CLI 具有必要權限。", + "repoNotFoundOrNoAccess": "找不到儲存庫或沒有存取權。請檢查儲存庫權限並確保已完成驗證。", + "failedToCreate": "建立 GitHub PR 失敗", + "gitCliNotLoggedIn": "Git 尚未驗證。請執行 gh auth login(或設定 Git 憑證)後重試。", + "gitCliNotInstalled": "未安裝 Git CLI。請安裝 Git 以建立 PR。", + "targetBranchNotFound": "遠端不存在目標分支 {{branch}}。建立 PR 前請確認該分支存在。" + }, + "loginRequired": { + "title": "登入以建立 PR", + "description": "您需要登入才能為此任務建立 PR。我們會將您導向登入頁面。", + "action": "登入" + } + }, + "showcases": { + "taskPanel": { + "companion": { + "title": "Vibe Kanban Companion 點選功能", + "description": "點擊預覽視窗中的任何 UI 元件以精準選取它。編碼代理將收到確切的 DOM 選擇器與元件層級結構,減少模糊回饋。" + }, + "installation": { + "title": "開發伺服器與 Companion 安裝", + "description": "為預覽設定開發伺服器命令,設定腳本可在設定中配置。使用編碼代理自動安裝 Vibe Kanban Web Companion。" + }, + "codeReview": { + "title": "內建程式碼審查", + "description": "使用加號圖示直接在差異檢視中新增特定行的評論。所有回饋會彙整並作為完整審查送給編碼代理。" + }, + "pullRequest": { + "title": "從任務建立 PR", + "description": "直接從任務嘗試合併變更或建立 PR。PR 對話框會從任務詳情預填標題與描述,簡化流程。" + }, + "tags": { + "title": "自訂提示標籤", + "description": "將自訂提示儲存為標籤,並可嵌入新任務或後續訊息。重用常見指示以維持一致流程。" + } + }, + "buttons": { + "previous": "上一個", + "next": "下一個", + "finish": "完成" + } + }, + "githubComments": { + "dialog": { + "title": "選擇 GitHub 評論", + "noComments": "此 PR 沒有評論", + "selectAll": "全選", + "deselectAll": "取消全選", + "add": "新增", + "selectedCount": "已選擇 {{selected}} / {{total}}" + }, + "card": { + "review": "審查", + "tooltip": "點擊在 GitHub 上查看,雙擊編輯" + } + }, + "taskFormDialog": { + "createTitle": "建立新任務", + "editTitle": "編輯任務", + "titlePlaceholder": "任務標題", + "descriptionPlaceholder": "新增更多細節(選填)。輸入 @ 搜尋檔案。", + "statusLabel": "狀態", + "statusOptions": { + "todo": "待辦", + "inprogress": "進行中", + "inreview": "審查中", + "done": "完成", + "cancelled": "已取消" + }, + "startLabel": "開始", + "attachImage": "附加圖片", + "dropImagesHere": "將圖片放在這裡", + "updating": "更新中...", + "updateTask": "更新任務", + "starting": "開始中...", + "creating": "建立中...", + "create": "建立", + "discardDialog": { + "title": "放棄未儲存的變更?", + "description": "您有未儲存的變更。確定要放棄嗎?", + "continueEditing": "繼續編輯", + "discardChanges": "放棄變更" + } + }, + "restoreLogsDialog": { + "title": "確認重試", + "historyChange": { + "title": "歷史紀錄變更", + "willDelete": "將刪除此程序", + "andLaterProcesses_one": "及後續 {{count}} 個程序", + "andLaterProcesses_other": "及後續 {{count}} 個程序", + "fromHistory": "從歷史紀錄中刪除。", + "codingAgentRuns_one": "{{count}} 次編碼代理執行", + "codingAgentRuns_other": "{{count}} 次編碼代理執行", + "scriptProcesses_one": "{{count}} 個腳本程序", + "scriptProcesses_other": "{{count}} 個腳本程序", + "setupCleanupBreakdown": "({{setup}} 個設定,{{cleanup}} 個清理)", + "permanentWarning": "此操作會永久變更歷史紀錄,無法復原。" + }, + "uncommittedChanges": { + "title": "偵測到未提交的變更", + "description_one": "您有 {{count}} 個未提交的變更", + "description_other": "您有 {{count}} 個未提交的變更", + "andUntracked_one": "與 {{count}} 個未追蹤的檔案", + "andUntracked_other": "與 {{count}} 個未追蹤的檔案", + "acknowledgeLabel": "我了解這些變更可能會受到影響" + }, + "resetWorktree": { + "title": "重設工作樹", + "enabled": "已啟用", + "disabled": "已停用", + "disabledUncommitted": "已停用(偵測到未提交的變更)", + "restoreDescription": "您的工作樹將還原到此提交。", + "rollbackCommits_one": "從目前 HEAD 回滾 {{count}} 個提交。", + "rollbackCommits_other": "從目前 HEAD 回滾 {{count}} 個提交。", + "discardChanges_one": "捨棄 {{count}} 個未提交的變更。", + "discardChanges_other": "捨棄 {{count}} 個未提交的變更。", + "untrackedPresent_one": "存在 {{count}} 個未追蹤的檔案(不受重設影響)。", + "untrackedPresent_other": "存在 {{count}} 個未追蹤的檔案(不受重設影響)。", + "forceReset": "強制重設(捨棄未提交的變更)", + "uncommittedWillDiscard": "未提交的變更將被捨棄。", + "uncommittedPresentHint": "存在未提交的變更。請啟用強制重設或先提交/暫存後再繼續。" + }, + "buttons": { + "retry": "重試" + } + } +} diff --git a/shared/types.ts b/shared/types.ts index 27dd98a3..ea8c4c0b 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -320,7 +320,7 @@ export type GitHubConfig = { pat: string | null, oauth_token: string | null, use export enum SoundFile { ABSTRACT_SOUND1 = "ABSTRACT_SOUND1", ABSTRACT_SOUND2 = "ABSTRACT_SOUND2", ABSTRACT_SOUND3 = "ABSTRACT_SOUND3", ABSTRACT_SOUND4 = "ABSTRACT_SOUND4", COW_MOOING = "COW_MOOING", PHONE_VIBRATION = "PHONE_VIBRATION", ROOSTER = "ROOSTER" } -export type UiLanguage = "BROWSER" | "EN" | "JA" | "ES" | "KO" | "ZH_HANS"; +export type UiLanguage = "BROWSER" | "EN" | "JA" | "ES" | "KO" | "ZH_HANS" | "ZH_HANT"; export type ShowcaseState = { seen_features: Array, };