diff --git a/apps/desktop/src/lib/i18n.ts b/apps/desktop/src/lib/i18n.ts index 3193bd29..60faadd5 100644 --- a/apps/desktop/src/lib/i18n.ts +++ b/apps/desktop/src/lib/i18n.ts @@ -10,9 +10,19 @@ /** * Returns the locale-appropriate string set based on `navigator.language`. * Falls back to English for any non-Chinese locale. + * When `zh-TW` or `zh-HK` is detected and a `"zh-TW"` key exists, it is + * preferred; otherwise falls back to `zh`. * * `en` and `zh` must share the same structural shape — string values may differ. */ -export function resolveLocale(strings: { en: T; zh: T }): T { - return navigator.language.startsWith("zh") ? strings.zh : strings.en; +export function resolveLocale(strings: { + en: T; + zh: T; + "zh-TW"?: T; +}): T { + const lang = navigator.language; + if (lang === "zh-TW" || lang === "zh-HK") { + return strings["zh-TW"] ?? strings.zh; + } + return lang.startsWith("zh") ? strings.zh : strings.en; } diff --git a/apps/web/src/components/language-switcher.tsx b/apps/web/src/components/language-switcher.tsx index 7da81363..56f437c7 100644 --- a/apps/web/src/components/language-switcher.tsx +++ b/apps/web/src/components/language-switcher.tsx @@ -38,7 +38,8 @@ export function LanguageSwitcher({ variant = "light", size = "sm" }: Props) { const options: Array<{ value: Locale; label: string }> = [ { value: "en", label: "English" }, - { value: "zh", label: "中文" }, + { value: "zh", label: "简体中文" }, + { value: "zh-TW", label: "繁體中文" }, ]; const currentLabel = diff --git a/apps/web/src/hooks/use-locale.tsx b/apps/web/src/hooks/use-locale.tsx index 0376a4bb..2ba5fd6e 100644 --- a/apps/web/src/hooks/use-locale.tsx +++ b/apps/web/src/hooks/use-locale.tsx @@ -13,7 +13,7 @@ import { patchApiInternalDesktopPreferences, } from "../../lib/api/sdk.gen"; -export type Locale = "en" | "zh"; +export type Locale = "en" | "zh" | "zh-TW"; interface LocaleCtx { locale: Locale; @@ -26,12 +26,15 @@ const STORAGE_KEY = "nexu_locale"; function detectDefault(): Locale { try { const stored = localStorage.getItem(STORAGE_KEY); - if (stored === "en" || stored === "zh") return stored; + if (stored === "en" || stored === "zh" || stored === "zh-TW") + return stored; } catch { /* ignore */ } const lang = navigator.language || ""; - return lang.startsWith("zh") ? "zh" : "en"; + if (lang === "zh-TW" || lang === "zh-HK") return "zh-TW"; + if (lang.startsWith("zh")) return "zh"; + return "en"; } const LocaleContext = createContext({ @@ -49,7 +52,12 @@ export function LocaleProvider({ children }: { children: ReactNode }) { const userInteractedRef = useRef(false); useEffect(() => { - document.documentElement.lang = locale === "zh" ? "zh-CN" : "en"; + const langMap: Record = { + en: "en", + zh: "zh-CN", + "zh-TW": "zh-TW", + }; + document.documentElement.lang = langMap[locale]; }, [locale]); useEffect(() => { @@ -92,9 +100,14 @@ export function useLocale() { } async function syncDesktopLocale(locale: Locale): Promise { + const apiLocaleMap: Record = { + en: "en", + zh: "zh-CN", + "zh-TW": "zh-TW", + }; await patchApiInternalDesktopPreferences({ body: { - locale: locale === "zh" ? "zh-CN" : "en", + locale: apiLocaleMap[locale], }, }).catch(() => { // Best-effort sync only; local UI language should still work offline. @@ -118,8 +131,17 @@ async function bootstrapLocale( return; } - if (storedLocale === "en" || storedLocale === "zh-CN") { - const nextLocale = storedLocale === "zh-CN" ? "zh" : "en"; + if ( + storedLocale === "en" || + storedLocale === "zh-CN" || + storedLocale === "zh-TW" + ) { + const nextLocale: Locale = + storedLocale === "zh-CN" + ? "zh" + : storedLocale === "zh-TW" + ? "zh-TW" + : "en"; await i18n.changeLanguage(nextLocale); setLocaleState(nextLocale); try { diff --git a/apps/web/src/i18n/index.ts b/apps/web/src/i18n/index.ts index 4364ba28..438df678 100644 --- a/apps/web/src/i18n/index.ts +++ b/apps/web/src/i18n/index.ts @@ -2,24 +2,28 @@ import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import en from "./locales/en"; import zhCN from "./locales/zh-CN"; +import zhTW from "./locales/zh-TW"; const STORAGE_KEY = "nexu_locale"; function detectLocale(): string { try { const stored = localStorage.getItem(STORAGE_KEY); - if (stored === "en" || stored === "zh") return stored; + if (stored === "en" || stored === "zh" || stored === "zh-TW") return stored; } catch { /* ignore */ } const lang = navigator.language || ""; - return lang.startsWith("zh") ? "zh" : "en"; + if (lang === "zh-TW" || lang === "zh-HK") return "zh-TW"; + if (lang.startsWith("zh")) return "zh"; + return "en"; } i18n.use(initReactI18next).init({ resources: { en: { translation: en }, zh: { translation: zhCN }, + "zh-TW": { translation: zhTW }, }, lng: detectLocale(), fallbackLng: "en", diff --git a/apps/web/src/i18n/locales/zh-TW.ts b/apps/web/src/i18n/locales/zh-TW.ts new file mode 100644 index 00000000..2052f6b3 --- /dev/null +++ b/apps/web/src/i18n/locales/zh-TW.ts @@ -0,0 +1,1210 @@ +const zhTW = { + // ── Brand Rail ── + "brand.title.line1": "OpenClaw,", + "brand.title.line2": "開箱即用", + "brand.body": + "nexu 讓 OpenClaw 變成一個安裝即可使用的完整產品。飛書文件、日曆、審批等工具能力開箱可用,同時接入 Claude、GPT 等頂級模型,所有工作都在一個工作臺裡完成。", + "brand.bullet.openclaw": "安裝即用,無需額外配置 OpenClaw", + "brand.bullet.feishu": "飛書文件、日曆、審批等工具能力開箱可用", + "brand.bullet.models": "接入 Claude、GPT 等頂級模型", + "brand.github": "在 GitHub 上 Star nexu", + + // ── Welcome ── + "welcome.pageTitle": "歡迎來到 nexu", + "welcome.mobileLabel": "客戶端", + "welcome.title": "一步連線 nexu", + "welcome.subtitle": + "使用 nexu 賬號登入後,可以在本地工作區裡直接使用託管高階模型,並透過獎勵中心繼續獲得額外用量。", + "welcome.option.login.title": "使用 nexu 賬號", + "welcome.option.login.badge": "推薦", + "welcome.option.login.description": + "透過瀏覽器授權登入後,直接啟用 nexu 託管高階模型、獎勵中心和完整工作區體驗,無需手動配置模型。", + "welcome.option.login.meta.1": "Google / GitHub / 郵箱", + "welcome.option.login.meta.2": "Browser OAuth", + "welcome.option.login.meta.3": "適合大多數使用者", + "welcome.option.login.highlight.unlimited": "無限量使用", + "welcome.option.byok.title": "使用你自己的模型", + "welcome.option.byok.badge": "BYOK", + "welcome.option.byok.description": + "不登入也可以開始,直接連線你自己的 API Key,本地優先,完全可控。", + "welcome.option.byok.meta.1": "無需註冊", + "welcome.option.byok.meta.2": "本地配置", + "welcome.option.byok.meta.3": "適合高階使用者", + "welcome.byokLink": "想用 BYOK?直接開啟服務商設定", + "welcome.rewardsHint": + "獎勵中心會在登入後出現在工作區裡:共 11 個任務位,覆蓋每日打卡、開源支援和社交分享。", + "welcome.back": "返回選擇", + "welcome.byok.title": "連線你的模型", + "welcome.byok.subtitle": + "不需要賬號,選擇服務商並輸入你的 API Key。所有配置都由你自己掌控。", + "welcome.byok.note": + "你的 API Key 只用於當前客戶端配置,不會要求你先建立 nexu 賬號。", + "welcome.byok.verify.loading": "驗證中...", + "welcome.byok.verify.idle": "驗證連線", + "welcome.byok.success": "連線成功,進入 nexu", + "welcome.waitingLogin": "等待瀏覽器登入完成…", + "welcome.waitingLoginHint": "請在瀏覽器中完成登入,此頁面會自動跳轉", + "welcome.cancel": "取消", + "welcome.connectFailed": "連線失敗,請稍後重試", + "welcome.cloudConnectError": "無法連線到 nexu 雲端服務", + "welcome.cloudConnectInProgress": + "瀏覽器登入已在進行中,請到瀏覽器完成授權。", + "welcome.browserOpened": "已開啟瀏覽器登入,請在瀏覽器中完成授權。", + "welcome.connectCancelled": "已取消瀏覽器登入。", + + // ── Auth ── + "auth.terms": "服務條款", + "auth.privacy": "隱私政策", + "auth.copyright": "© 2026 nexu by Refly", + "auth.desktopConnectPrompt": "登入以連線 nexu 桌面端", + "auth.welcomeBack": "歡迎回來", + "auth.createAccount": "建立你的賬號", + "auth.loginSubtitle": "登入你的數字分身", + "auth.signupSubtitle": "註冊獲取你的 nexu 數字分身", + "auth.continueGoogle": "使用 Google 賬號繼續", + "auth.chooseMethod": "選擇你的登入方式", + "auth.loginToContinue": "登入以繼續使用", + "auth.emailRegister": "使用郵箱註冊", + "auth.emailLogin": "使用郵箱登入", + "auth.otherMethods": "其他登入方式", + "auth.or": "或", + "auth.nameLabel": "姓名", + "auth.namePlaceholder": "你的姓名", + "auth.emailLabel": "郵箱", + "auth.emailPlaceholder": "you@example.com", + "auth.passwordLabel": "密碼", + "auth.passwordPlaceholder": "最少 8 個字元", + "auth.loginButton": "登入", + "auth.createAccountButton": "建立賬號", + "auth.noAccount": "還沒有賬號?", + "auth.hasAccount": "已有賬號?", + "auth.signUp": "註冊", + "auth.logIn": "登入", + "auth.checkEmail": "檢查你的郵箱", + "auth.otpSentTo": "我們向以下郵箱傳送了 6 位驗證碼", + "auth.verify": "驗證", + "auth.didntReceive": "沒有收到驗證碼?", + "auth.resendIn": "{{seconds}} 秒後重新傳送", + "auth.resendCode": "重新傳送", + "auth.backToSignup": "返回註冊", + "auth.connected": "已連線!", + "auth.desktopConnected": + "你的 nexu 桌面端已連線到雲端賬號。你可以關閉此標籤頁,返回桌面端應用。", + "auth.autoCloseIn": "{{seconds}} 秒後自動關閉", + "auth.connectingDesktop": "正在連線桌面端...", + "auth.heroTitle.line1": "你的數字", + "auth.heroTitle.line2": "同事,", + "auth.heroTitle.line3": "全天線上。", + "auth.heroBody": + "AI 分身入駐 Slack —— 不只是聊天,而是交付真正的成果。開發應用、分析資料、撰寫內容、執行自動化。", + "auth.capability.code": "編碼 & 部署", + "auth.capability.data": "資料分析", + "auth.capability.content": "內容創作", + "auth.capability.research": "資訊研究", + "auth.capability.automation": "自動化", + + // ── Document Titles ── + "title.signIn": "登入 · nexu", + "title.claim": "認領 · nexu", + "title.home": "首頁 · nexu", + "title.integrations": "整合 · nexu", + "title.rewards": "獎勵 · nexu", + "title.skills": "技能 · nexu", + "title.settings": "設定 · nexu", + "title.linkFeishu": "繫結飛書 · nexu", + "title.connecting": "連線中 · nexu", + "title.default": "nexu", + + // ── Workspace Layout ── + "layout.brand": "你的數字同事", + "layout.nav.home": "首頁", + "layout.nav.rewards": "獎勵", + "layout.nav.deployments": "部署", + "layout.nav.skills": "技能", + "layout.nav.settings": "設定", + "layout.conversations": "對話", + "layout.signOut": "退出登入", + "layout.help.title": "幫助", + "layout.help.docs": "文件", + "layout.help.contact": "聯絡我們", + "layout.help.changelog": "更新日誌", + "layout.expandSidebar": "展開側邊欄", + "layout.collapseSidebar": "收起側邊欄", + "layout.update.available": "{{version}} 可用", + "layout.update.downloading": "正在下載更新...", + "layout.update.installing": "正在準備安裝並重啟...", + "layout.update.readyToInstall": "更新已就緒", + "layout.update.download": "下載", + "layout.update.install": "重啟並安裝", + "layout.update.later": "稍後", + "layout.update.badge": "更新", + "layout.mobile.home": "首頁", + "layout.mobile.homeSubtitle": "歡迎來到 nexu", + "layout.mobile.rewards": "獎勵", + "layout.mobile.rewardsSubtitle": "獲取額外用量", + "layout.mobile.deployments": "部署", + "layout.mobile.deploymentsSubtitle": "所有部署記錄", + "layout.mobile.skills": "技能", + "layout.mobile.skillsSubtitle": "瀏覽 AI 能力", + "layout.mobile.settings": "設定", + "layout.mobile.settingsSubtitle": "管理 AI 模型服務商", + "layout.mobile.conversations": "對話", + "layout.sidebar.loginTitle": "登入 nexu 賬號", + "layout.sidebar.loginSubtitle": "使用官方額度", + "layout.sidebar.loginPending": "等待瀏覽器完成登入", + "layout.sidebar.rewardsTitle": "分享 nexu,獲取額外積分", + "layout.sidebar.rewardsSubtitle": "每日、開源與社媒任務", + "layout.sidebar.progressLabel": "已領取任務", + "layout.sidebar.balanceLabel": "積分餘額", + "layout.sidebar.balanceUnit": "積分", + "layout.sidebar.balancePlaceholder": "積分同步中…", + "layout.sidebar.rewardsCta": "檢視", + "layout.sidebar.balancePopup.total": "剩餘積分總量", + "layout.sidebar.balancePopup.recharged": "套餐積分", + "layout.sidebar.balancePopup.rechargedTooltip": + "當前來自訂閱套餐的積分餘額。", + "layout.sidebar.balancePopup.earned": "贈送積分", + "layout.sidebar.balancePopup.earnedTooltip": + "當前來自注冊獎勵、任務獎勵等活動的積分餘額。", + "layout.sidebar.balancePopup.consumed": "累計消耗", + "layout.sidebar.balancePopup.viewDetail": "檢視使用情況", + "layout.empty.title": "暫無對話", + "layout.empty.description": + "請先配置平臺 Bot,然後在 Slack / Discord / WhatsApp 中 @nexu 或直接私信小龍蝦 🦞 —— 對話會自動出現在這裡。", + "layout.empty.setupBot": "配置 Bot", + "layout.empty.step1": "連線平臺", + "layout.empty.step2": "提及 @nexu", + "layout.empty.step3": "對話出現", + "layout.loginCta": "登入", + "layout.credits.label": "積分", + "layout.credits.earned": "已獲取", + + // ── Home Page ── + "home.running": "執行中", + "home.status.starting": "正在啟動", + "home.status.degraded": "部分可用", + "home.status.offline": "已離線", + "home.status.idle": "待命中", + "home.status.ready": "準備就緒", + "home.status.subtitle.starting": "正在準備中...", + "home.status.subtitle.idle": "連線渠道後即可開始使用", + "home.status.subtitle.ready": "等待渠道連線", + "home.status.subtitle.offline": "服務正在重啟...", + "home.status.subtitle.degraded": "部分功能可能響應較慢", + "home.todayMessages": "今日 {{count}} 條訊息", + "home.noActivity": "暫無活動", + "home.justActive": "剛剛活躍", + "home.minutesAgo": "{{count}} 分鐘前活躍", + "home.hoursAgo": "{{count}} 小時前活躍", + "home.daysAgo": "{{count}} 天前活躍", + "home.chat": "對話", + "home.feishu": "飛書", + "home.channel.feishu": "飛書 / Feishu", + "home.channel.slack": "Slack", + "home.channel.discord": "Discord", + "home.channel.wechat": "微信", + "home.channel.telegram": "Telegram", + "home.channel.whatsapp": "WhatsApp", + "home.channel.dingtalk": "釘釘", + "home.channel.qqbot": "QQ", + "home.channel.wecom": "企微", + "home.channel.addBot": "新增 nexu Bot", + "home.tab.channels": "渠道", + "home.tab.models": "模型 & Key", + "home.loading": "載入中...", + "home.connected": "已連線", + "home.notConnected": "未連線", + "home.checking": "檢查中...", + "home.channelConnecting": "連線中...", + "home.active": "當前", + "home.setActive": "設為當前", + "home.disconnect": "斷開連線", + "home.disconnecting": "正在斷開...", + "home.disconnected": "已斷開連線", + "home.disconnectFailed": "斷開連線失敗", + "home.channel.syncing": "正在同步配置...", + "home.channel.gatewayStarting": "閘道器啟動中...", + "home.channel.connecting": "機器人連線中...", + "home.channel.ready": "渠道已就緒,機器人可正常回復", + "home.channel.readinessTimeout": "連線超時,請稍後檢查渠道狀態", + "home.channel.phase.connecting": "正在建立連線...", + "home.channel.phase.configuring": "正在配置技能...", + "home.channel.phase.almostReady": "nexu 即將就緒...", + "home.channel.phase.done": "一切就緒!nexu 可以開始對話了", + "home.channel.restarting": "重啟中...", + "home.channel.error": "錯誤", + "home.channel.errorDetail.not configured": "請重新連線", + "home.channel.errorDetail.session expired": "請重新連線", + "home.channel.errorDetail.disabled": "已停用", + "home.channel.disconnected": "已斷開", + "home.agent.alive": "Agent 執行中", + "home.agent.starting": "Agent 啟動中...", + "home.connect": "連線", + "home.connectChannel": "連線渠道", + "home.changeConfig": "更改配置", + "home.notSelected": "未選擇", + "home.searchModels": "搜尋模型...", + "home.noMatchingModels": "無匹配模型", + "home.configureProviders": "配置 AI 服務商", + "home.viewConversations": "檢視對話", + "home.viewConversationsDesc": "訊息執行緒和頻道活動", + "home.manageSkills": "管理技能", + "home.manageSkillsDesc": "工具和能力", + "home.rewardsTeaser.eyebrow": "獎勵", + "home.rewardsTeaser.title": "把每次傳播變成額外用量", + "home.rewardsTeaser.description": + "每日打卡、開源支援和社交分享現在都彙總進工作區獎勵中心,領取邏輯也統一了。", + "home.rewardsTeaser.summaryLabel": "任務位", + "home.rewardsTeaser.summaryValue": "已獲得 +{{earned}}", + "home.rewardsTeaser.footer": + "Facebook 和 WhatsApp 已併入新的“社交與即時通訊”分組。", + "home.rewardsTeaser.cta": "檢視獎勵", + "home.starGithub": "Star on GitHub", + "home.starNexu": "在 GitHub 上 Star Nexu", + "home.starCta": "幫助我們壯大開源社群 — 你的 Star 很重要", + "home.seedance.promo.title": "Seedance 2.0 體驗 Key", + "home.seedance.promo.badge": "限時體驗", + "home.seedance.promo.subtitle": + "nexu 已支援 Seedance 2.0。Star 後加入飛書群並填寫問卷,我們會聯絡併傳送 Key。", + "home.seedance.promo.dismiss": "關閉活動橫幅", + "home.seedance.modal.title": "領取 Seedance 2.0 體驗 Key", + "home.seedance.modal.lead": "兩步就能完成:先點 Star,再走飛書群申請流程。", + "home.seedance.modal.step1.title": "第一步:GitHub Star 並截圖", + "home.seedance.modal.step1.copy": + "在 GitHub 為 nexu star;並將點完後的倉庫頁面進行截圖。", + "home.seedance.modal.step1.cta": "去 GitHub Star", + "home.seedance.modal.step1.done": "已點 Star", + "home.seedance.modal.step1.nextCta": "我已經截圖,去進群填問卷", + "home.seedance.modal.step2.title": "第二步:加入飛書群並填寫問卷", + "home.seedance.modal.step2.copy": + "加入飛書群並填寫問卷後,我們會聯絡併傳送 Key。拿到 Key 後,將其輸入到 nexu Bot 即可開始體驗。", + "home.seedance.modal.step2.cta": "點選連結加入飛書群", + "home.seedance.modal.step2.tutorial": + "檢視教程:如何在 nexu Bot 中體驗 Seedance 2.0", + "home.seedance.modal.step2.done": "好的,已瞭解", + "home.recentActivity": "最近活動", + "home.noRecentActivity": "暫無最近對話", + + // ── Rewards ── + "rewards.badge": "獎勵中心", + "rewards.title": "分享 nexu,獲取額外積分", + "rewards.desc": "把 nexu 分享給你的社群,完成任務獲取額外積分。", + "rewards.refresh": "重新整理", + "rewards.progressLabel": "已完成", + "rewards.earnedLabel": "已獲得", + "rewards.totalCredits": "獎勵額度 {{n}}", + "rewards.taskProgress": "每週任務 {{a}} / {{b}}", + "rewards.group.daily": "每日", + "rewards.group.opensource": "開源社群", + "rewards.group.social": "社交與即時通訊", + "rewards.tab.web": "Web 版", + "rewards.tab.mobile": "移動端", + "rewards.mobileQrHint": "使用相機掃描以從手機邀請", + "rewards.mobileQrDesc": + "使用手機相機掃描二維碼,從手機發起邀請並完成任務即可領取積分", + "rewards.cloudBalance": "雲端餘額", + "rewards.totalEarned": "累計獲得", + "rewards.totalUsed": "累計消耗", + "rewards.loginTitle": "登入後可使用託管模型與獎勵領取", + "rewards.loginBody": + "獎勵任務可以先瀏覽,但官方託管模型體驗和獎勵領取會圍繞你的 nexu Cloud 登入狀態展開。", + "rewards.loginCta": "使用 nexu 登入", + "rewards.modelHintTitle": "切回 nexu 官方模型後即可使用獎勵額度", + "rewards.modelHintBody": + "你的領取記錄會保留,但獎勵額度主要用於官方託管模型體驗。你可以隨時在模型設定中切換。", + "rewards.modelHintCta": "開啟模型設定", + "rewards.claimSuccess": "獎勵領取成功", + "rewards.claimAlreadyDone": "當前週期內已領取過該獎勵", + "rewards.claimFailed": "獎勵領取失敗", + "rewards.loginRequired": "請先登入 nexu 賬號", + "rewards.githubUnavailable": "暫不可用", + "rewards.downloadFailed": "分享卡下載失敗", + "rewards.githubSessionFailed": "啟動 GitHub Star 監測失敗,請稍後重試", + "rewards.githubVerifying": "正在驗證 GitHub Star,預計需要幾秒鐘...", + "rewards.proofUrlLabel": "回填分享連結", + "rewards.proofUrlPlaceholder": "貼上你在對應平臺釋出後的公開連結", + "rewards.proofUrlHint": "只有符合對應平臺格式的公開連結才能領取積分。", + "rewards.proofUrlInvalid": "連結格式不符合當前平臺要求,請檢查後重試。", + "rewards.proofUrlReopen": "重新開啟分享頁", + "rewards.proofUrlLoginGuidance": + "如果瀏覽器停留在平臺首頁,請先登入,然後點選上方「重新開啟分享頁」跳轉到預填好內容的發帖頁。", + "rewards.progress": "已完成 {{earned}} / {{total}}", + "rewards.card.cycle": "每週週期內可領取,不含每日重複打卡", + "rewards.card.weekly": "一次性任務與每週分享", + "rewards.card.localState": "控制器狀態", + "rewards.card.localStateHint": + "獎勵領取現在來自桌面控制器路由,並且在重啟後仍保持冪等。", + "budget.viral.title": "分享 nexu,獲取額外積分", + "budget.viral.loginFirst": "登入 Cloud 賬號,免費使用模型", + "budget.viral.desc": "幫助傳播 nexu,獲得獎勵。", + "budget.viral.rules": "檢視獎勵規則 →", + "budget.viral.summary": "{{claimed}}/{{total}} 已完成 · 已獲 {{earned}} 積分", + "budget.viral.viewAll": "檢視全部獎勵 →", + "budget.cta.go": "前往領取", + "budget.cta.share": "前往分享", + "budget.cta.download": "儲存圖片", + "budget.cta.checkin": "立即打卡", + "budget.cta.done": "+${n} 積分 已完成", + "budget.confirm.title": "確認:{channel}", + "budget.confirm.desc": "完成操作後,回來確認即可領取 +${n} 積分。", + "budget.confirm.screenshotDesc": + "請先在目標平臺完成分享,然後回來確認即可領取 +${n} 積分。", + "budget.confirm.imageDesc": "完成掃碼分享後,回來確認即可領取 +${n} 積分。", + "budget.confirm.downloadImage": "下載分享卡", + "budget.confirm.done": "我已完成", + "budget.confirm.cancel": "稍後再說", + "budget.confirm.checkinDesc": + "確認今日打卡後,+${n} 積分會加入你的獎勵額度。每天可領取一次。", + "budget.confirm.checkingTitle": "正在檢查任務完成情況", + "budget.confirm.checkingDesc": "請稍候,我們正在為你確認任務狀態。", + "budget.confirm.checkingImageDesc": "請稍候,我們正在確認分享卡提交流程。", + "budget.confirm.checkingCheckinDesc": "請稍候,我們正在確認今日打卡狀態。", + "budget.confirm.checking": "檢查中...", + "budget.confirm.claimingTitle": "正在領取獎勵", + "budget.confirm.claimingDesc": "請稍候,獎勵額度正在同步到你的賬戶。", + "budget.confirm.claiming": "領取中...", + "budget.banner.warningTitle": "雲端額度即將耗盡", + "budget.banner.depletedTitle": "雲端額度已用盡", + "budget.banner.warningHeadline": + "可用積分即將耗盡,可採取以下方式避免任務中斷", + "budget.banner.depletedHeadline": + "可用積分已用盡(明天重置),可採取以下方式繼續使用", + "budget.banner.description": + "完成任務賺取更多積分,或使用自帶 API Key (BYOK) 繼續使用。", + "budget.banner.warningDescription": + "雲端額度即將耗盡,去做任務賺積分或切換到自帶 API Key 可避免任務中斷。", + "budget.banner.depletedDescription": + "雲端額度已用盡(明天重置),去做任務賺積分或切換到自帶 API Key 可繼續使用。", + "budget.banner.actionsLabel": "選擇操作", + "budget.banner.apiKey": "自帶 API Key", + "budget.banner.upgrade": "升級套餐", + "budget.banner.earnCredits": "做任務賺積分", + "budget.banner.byok": "自帶 API Key", + "budget.autoFallback.toast": + "雲端額度已用盡,已自動切換到你的 API Key 繼續執行。", + "budget.autoFallback.failed": + "雲端額度已用盡,自動切換到 BYOK 失敗。請配置 API Key 或先去賺取積分後繼續使用。", + "rewards.action.claimed": "已領取", + "rewards.action.checkIn": "打卡", + "rewards.action.download": "下載", + "rewards.action.share": "分享", + "rewards.action.open": "開啟", + "reward.daily_checkin.name": "每日打卡", + "reward.daily_checkin.desc": "每天可領一次", + "reward.daily_checkin.autoGrantedDesc": "每日獎勵自動發放,無需手動領取", + "reward.github_star.name": "Star us", + "reward.github_star.desc": "僅限一次", + "reward.x_share.name": "分享到 X", + "reward.x_share.desc": "每週可領一次", + "reward.reddit.name": "發帖到 Reddit", + "reward.reddit.desc": "每週可領一次", + "reward.mobile_share.name": "從手機邀請", + "reward.mobile_share.desc": + "使用手機相機掃描二維碼,從手機發起邀請即可領取積分", + "reward.lingying.name": "發帖到領英", + "reward.lingying.desc": "每週可領一次", + "reward.facebook.name": "分享到 Facebook", + "reward.facebook.desc": "每週可領一次", + "reward.whatsapp.name": "分享到 WhatsApp", + "reward.whatsapp.desc": "每週可領一次", + + // ── Models Page ── + "models.pageTitle": "設定", + "models.pageSubtitle": "管理 AI 模型服務商", + "settings.pageSubtitle": "管理資料、語言偏好與 AI 模型服務商", + "settings.tabGeneral": "通用", + "settings.tabProviders": "AI 模型服務商", + "settings.general.account": "賬戶", + "settings.general.avatar": "頭像", + "settings.general.avatarHint": "支援 JPG、PNG、WEBP、GIF,最大 1MB", + "settings.general.fullName": "全名", + "settings.general.fullNameHint": "顯示在工作區側邊欄和賬號區域", + "settings.general.email": "郵箱", + "settings.general.emailHint": "設定已同步。可使用 Nexu 賬戶下的高階模型。", + "settings.general.loggedOut": "未登入", + "settings.general.loggedOutHint": "登入後可同步設定並使用高階模型", + "settings.general.goLogin": "去登入", + "settings.general.logoutConfirmTitle": "確認退出當前 nexu 賬號?", + "settings.general.logoutConfirmDescription": + "退出後,當前桌面工作區將斷開與你的 nexu 賬號連線。", + "settings.general.preferences": "偏好", + "settings.general.language": "語言", + "settings.general.languageHint": "選擇介面顯示語言", + "settings.section.desktop": "應用行為", + "settings.section.data": "資料與隱私", + "settings.desktop.launchAtLogin": "開機時啟動應用", + "settings.desktop.launchAtLoginHint": "當您的電腦開機啟動時自動開啟 Nexu", + "settings.desktop.showInDock": "在 Dock 中顯示應用", + "settings.desktop.showInDockHint": + "在您的 Mac Dock 中顯示 nexu,以便快速訪問。", + "settings.desktop.showInTaskbar": "在工作列中顯示", + "settings.desktop.showInTaskbarHint": + "顯示在工作列中;關閉後僅保留系統托盤入口", + "settings.desktop.updateFailed": "更新桌面設定失敗", + "settings.data.analytics": "使用分析", + "settings.data.analyticsHint": "傳送匿名使用資料以幫助改進 nexu", + "settings.data.crashReports": "崩潰報告", + "settings.data.crashReportsHint": "自動傳送崩潰報告以幫助修復問題", + "settings.general.saveTitle": "儲存修改", + "settings.general.saveHint": "儲存後立即應用資料變更", + "settings.general.save": "儲存", + "settings.general.saved": "資料已更新", + "settings.general.saveFailed": "資料更新失敗", + "settings.general.nameRequired": "請輸入全名", + "settings.general.avatarTooLarge": "頭像檔案不能超過 1MB", + "settings.general.avatarReadFailed": "讀取頭像檔案失敗", + "settings.general.githubTitle": "Star on GitHub", + "settings.general.githubBody": "關注版本釋出並公開支援這個專案。", + "settings.general.githubBadge": "GitHub", + "settings.general.githubStarred": "感謝你 Star nexu", + "settings.general.githubStarredBody": "你正在幫助塑造桌面端和工作區體驗。", + "settings.general.githubStarredBadge": "已 Star", + "settings.section.profile": "資料", + "settings.section.updates": "更新", + "settings.section.about": "關於", + "settings.updates.version": "版本", + "settings.updates.checkNow": "立即檢查", + "settings.updates.checking": "檢查中...", + "settings.updates.retry": "重新檢查", + "settings.updates.idleHint": "檢查更新並安裝最新桌面版本。", + "settings.updates.checkingHint": "正在查詢新版本...", + "settings.updates.downloading": "下載中 {{percent}}%", + "settings.updates.downloadingHint": "正在下載更新:{{percent}}%", + "settings.updates.error": "暫時無法檢查更新。", + "settings.updates.versionUnknown": "暫時無法獲取當前版本。", + "settings.about.docs": "文件", + "settings.about.github": "GitHub 倉庫", + "settings.about.changelog": "更新日誌", + "settings.about.feedback": "傳送反饋", + "settings.providers.botModelTitle": "nexu Bot 模型", + "settings.providers.botModelDesc": "選擇桌面工作區預設使用的模型。", + "settings.providers.workspace": "工作區", + "models.loading": "正在載入模型...", + "models.retry": "重試", + "models.loadFailed": "載入模型失敗", + "models.loadFailedHint": "請確認你已登入且 API 服務正在執行。", + "models.selectProvider": "選擇一個服務商", + "models.configured": "已配置", + "models.notConfigured": "未配置", + "models.currentModel": "當前模型", + "models.noModelConfigured": "未配置模型", + "models.configureProviderHint": "請先在下方配置服務商", + "models.searchModels": "搜尋模型...", + "models.modelSwitched": "模型已切換", + "models.modelSwitchedAndSynced": "模型已切換,已同步到機器人", + "models.modelSwitchedSyncFailed": "模型已切換(同步到機器人待確認)", + "models.modelSwitchFailed": "模型切換失敗", + "models.autoSwitched": "已自動切換為 {{model}}", + "models.switchingModel": "正在切換模型…", + "models.provider.nexu.name": "nexu Official", + "models.provider.nexu.description": + "登入後使用 nexu 官方高階模型,無需單獨配置 API Key", + "models.provider.anthropic.description": "Claude 系列 AI 模型", + "models.provider.openai.description": "GPT 系列 AI 模型", + "models.provider.google.description": "Gemini 系列 AI 模型", + "models.provider.ollama.description": "使用你機器上本地執行的 Ollama 模型", + "models.provider.qwen.name": "千問", + "models.provider.volcengine.name": "火山引擎", + "models.provider.qianfan.name": "百度千帆", + "models.provider.xiaomi.name": "小米 MiMo", + "models.provider.glm.name": "智譜", + "models.provider.siliconflow.name": "矽基流動", + "models.provider.siliconflow.description": + "矽基流動透過相容 OpenAI 的介面提供託管基礎模型服務。", + "models.provider.ppio.description": + "PPIO 提供託管的 OpenAI 相容介面,可接入熱門模型。", + "models.provider.qwen.description": + "阿里雲百鍊透過相容介面提供千問等模型服務。", + "models.provider.volcengine.description": + "火山引擎方舟可接入豆包、DeepSeek 等託管模型。", + "models.provider.qianfan.description": + "百度智慧雲千帆透過相容介面提供文心等託管模型。", + "models.provider.xiaomi.description": + "小米 MiMo 透過相容介面提供 Flash、Pro 和 Omni 模型。", + "models.provider.minimax.description": + "MiniMax 透過託管 API 平臺提供對話與推理模型。", + "models.provider.kimi.description": + "月之暗面透過 OpenAI 相容介面提供 Kimi 模型。", + "models.provider.glm.description": + "智譜透過 BigModel 相容介面提供 GLM 模型。", + "models.provider.nvidia.description": + "NVIDIA NIM 透過相容 OpenAI 的介面提供託管模型服務。", + "models.provider.stepfun.description": + "StepFun 透過相容 OpenAI 的介面提供託管模型服務。", + "models.provider.amazonBedrock.description": + "AWS Bedrock 使用你的 AWS 憑證鏈與區域配置進行鑑權。", + "models.provider.deepseek.description": + "DeepSeek 透過相容 OpenAI 的介面提供託管模型服務。", + "models.provider.openaiCompatible.description": + "相容 OpenAI 協議的模型服務商", + "models.managed.connected": "退出登入", + "models.managed.notConnected": "未連線", + "models.managed.cloudConnectAria": "連線 nexu 雲端", + "models.managed.cloudDisconnectAria": "斷開 nexu 雲端", + "models.managed.loginRequired": "登入後可用", + "models.managed.cloudConnected": "已連線 nexu 雲端", + "models.managed.cloudModelsAvailable": "雲端模型已可用,可在下方檢視和管理。", + "models.managed.refresh": "重新整理", + "models.managed.refreshModelList": "重新整理模型列表", + "models.managed.disconnect": "斷開", + "models.managed.loginPrompt": "登入以使用 nexu 官方模型", + "models.managed.loginDescription": + "登入 nexu 賬號後,即可無限使用 Claude Opus 4.6、GPT-5.4 等高階模型,無需 API Key。", + "models.managed.waitingLogin": "等待瀏覽器登入...", + "models.managed.loginButton": "登入 nexu 賬號", + "models.managed.logoutConfirmTitle": "確認退出 nexu Official?", + "models.managed.logoutConfirmDescription": + "退出後,此裝置上的 nexu Official 將斷開當前 nexu 賬號連線。", + "models.managed.availableModels": "可用模型", + "models.managed.refreshSucceeded": "模型已重新整理", + "models.managed.refreshFailed": "重新整理模型失敗", + "models.managed.totalCount": "共 {{count}} 個", + "models.byok.getApiKey": "獲取 API Key", + "models.byok.apiKey": "API Key", + "models.byok.apiKeySaved": "API Key 已儲存", + "models.byok.apiKeySavedHint": + "出於安全原因,不會回顯已儲存的金鑰。只有在你想替換時才需要重新輸入。", + "models.byok.changeApiKey": "更換金鑰", + "models.byok.verify": "檢查", + "models.byok.keyValid": "金鑰有效 — 檢測到 {{count}} 個模型", + "models.byok.keyInvalid": "金鑰無效: {{error}}", + "models.byok.keyInvalidUnknown": "未知錯誤", + "models.byok.proxyUrl": "API 代理地址", + "models.byok.modelList": "模型列表", + "models.byok.modelsTotalCount": "共 {{count}} 個模型", + "models.byok.enabledSection": "已啟用模型", + "models.byok.enabledHint": "這些模型會出現在模型選擇器中", + "models.byok.disabledSection": "未啟用模型", + "models.byok.none": "暫無", + "models.byok.refreshModels": "重新整理", + "models.byok.fetchingModels": "正在獲取模型列表...", + "models.byok.refreshSuccess": "模型列表已重新整理,共 {{count}} 個模型", + "models.byok.refreshFailed": "重新整理模型列表失敗,請重試", + "models.byok.updateConfig": "更新配置", + "models.byok.saveAndEnable": "儲存", + "models.byok.remove": "移除", + "models.byok.confirmRemove": "確定要移除此服務商配置嗎?", + "models.byok.saveSuccess": "儲存成功", + "models.byok.saveFailed": "儲存失敗,請重試", + "models.byok.oauthLoginChatGPT": "使用 ChatGPT 登入", + "models.byok.oauthConnected": "已透過 ChatGPT 連線", + "models.byok.oauthDisconnect": "斷開連線", + "models.byok.oauthPending": "等待 ChatGPT 登入...", + "models.byok.oauthSuccess": "ChatGPT 連線成功", + "models.byok.oauthFailed": "ChatGPT 登入失敗", + "models.byok.oauthOrApiKey": "或手動輸入 API Key", + "models.byok.oauthDescription": "使用你的 ChatGPT Plus/Pro 訂閱", + "models.byok.awsSdkAuth": "鑑權方式:AWS 憑證鏈", + "models.byok.awsSdkAuthHint": + "這裡無需填寫 API Key。請在執行環境中配置 AWS 憑證與區域。", + "models.byok.minimax.authModeOauth": "OAuth 登入", + "models.byok.minimax.authModeApiKey": "API Key", + "models.byok.minimax.oauthTitle": "MiniMax Coding Plan OAuth", + "models.byok.minimax.oauthDescription": + "使用 MiniMax OAuth 連線 Coding Plan,無需手動貼上 API Key。", + "models.byok.minimax.regionGlobal": "Global", + "models.byok.minimax.regionCn": "CN", + "models.byok.minimax.endpoint": "端點:{{endpoint}}", + "models.byok.minimax.connected": "已透過 OAuth 連線", + "models.byok.minimax.dismissError": "關閉錯誤提示", + "models.byok.minimax.waitingLogin": "等待 MiniMax 登入", + "models.byok.minimax.cancel": "取消", + "models.byok.minimax.reconnect": "重新連線", + "models.byok.minimax.login": "使用 MiniMax 登入", + "models.byok.zaiCodingPlan": "智譜 Coding Plan", + "models.byok.zaiCodingPlanDesc": "使用你的智譜 Coding Plan 訂閱(免費模型)", + "models.byok.zaiOrGeneralApi": "或使用通用 API Key", + "models.customProvider.addButton": "新增自定義服務商", + "models.customProvider.title": "新建自定義服務商", + "models.customProvider.newProvider": "新的自定義服務商", + "models.customProvider.compatibility": "相容協議", + "models.customProvider.compatibilityOpenai": "相容 OpenAI", + "models.customProvider.compatibilityAnthropic": "相容 Anthropic", + "models.customProvider.instanceId": "例項 ID", + "models.customProvider.instanceIdPlaceholder": "例如:team-gateway", + "models.customProvider.displayName": "顯示名稱", + "models.customProvider.displayNamePlaceholder": "自定義服務商", + "models.customProvider.baseUrl": "Base URL", + "models.customProvider.baseUrlPlaceholder": "https://api.example.com/v1", + "models.customProvider.create": "建立服務商", + "models.customProvider.creating": "建立中...", + "models.customProvider.createFailed": "建立自定義服務商失敗", + "models.customProvider.removeDraft": "移除草稿", + + // ── Channels Page ── + "channels.pageTitle": "渠道", + "channels.pageSubtitle": "連線你的訊息平臺,讓 nexu 🦞 加入你的工作區", + "channels.comingSoon": "Microsoft Teams、Line 等更多平臺即將支援", + "channels.backToConfig": "返回配置", + "channels.statusConnected": "{{platform}} Bot 已連線", + "channels.statusConnecting": "連線中...", + "channels.statusError": "連線異常", + "channels.configuredDate": "配置於 {{date}}", + "channels.connectionActive": "連線正常", + "channels.setupGuide": "配置指南", + "channels.addToServer": "新增到伺服器", + "channels.addToServerDesc": "使用以下連結將 Bot 邀請到你的 Discord 伺服器。", + "channels.addBotToServer": "新增 Bot 到伺服器", + "channels.openInSlack": "在 Slack 中開啟", + "channels.openSlackDM": "在 Slack 中開啟與 Bot 的私信。", + "channels.openSlackWorkspace": "開啟你的 Slack 工作區。", + "channels.messageBotSlack": "在 Slack 中傳送訊息", + "channels.openWorkspace": "開啟工作區", + "channels.openInFeishu": "在飛書中開啟", + "channels.openFeishuDM": "在飛書中開啟與 Bot 的私信。", + "channels.messageBotFeishu": "在飛書中傳送訊息", + "channels.openInTelegram": "在 Telegram 中開啟", + "channels.openTelegramDesc": + "開啟你的 Bot 主頁,發起私聊,或將它加入群組。群內只有在 @ 提及時才會回覆。", + "channels.openTelegramBot": "開啟 Bot", + "channels.open": "開啟", + "channels.openInDiscord": "在 Discord 中開啟", + "channels.openInWhatsApp": "在 WhatsApp 中開啟", + "channels.openInDingTalk": "在釘釘中開啟", + "channels.openInWeCom": "在企微中開啟", + "channels.openInQQ": "在 QQ 中開啟", + "channels.openInWeChat": "在微信中開啟", + "channels.webhookUrl": "Webhook URL", + "channels.credentials": "憑證", + "channels.accountId": "賬號 ID", + "channels.serverName": "伺服器名稱", + "channels.teamName": "團隊名稱", + "channels.resetConfig": "重置配置", + "channels.resetConfigDesc": + "這將移除當前的 {{platform}} Bot 配置。你需要重新完成配置流程。", + "channels.resetReconfigure": "重置並重新配置", + "channels.confirmReset": "確認重置", + "channels.confirmResetDesc": "{{platform}} 將被斷開連線。", + "channels.confirmResetBody": + "這將移除你當前的 {{platform}} Bot 配置。在重新配置之前,nexu 將無法接收來自此平臺的訊息。", + "channels.cancel": "取消", + "channels.quotaTitle": "當前需求量較大", + "channels.quotaBody": "新的 Bot 配置將在 {{countdown}} 後可用。請稍後重試。", + + // ── Channel Connect Modal ── + "modal.connect": "連線 {{name}}", + "modal.configureCredentials": "配置 Bot 憑證", + "modal.close": "關閉", + "modal.viewDocs": "檢視 {{name}} 接入教程", + "modal.cancel": "取消", + "modal.connectButton": "連線", + "modal.connecting": "連線中...", + "modal.channelConnected": "渠道已連線,正在重新整理...", + "modal.connectFailed": "連線失敗", + "modal.connectSuccess": "{{name}} 連線成功", + "modal.connectRetryFailed": "連線失敗,請重試", + "modal.feishu.name": "飛書 / Feishu", + "modal.feishu.appIdHelp": "從飛書開放平臺 > 應用憑證頁面獲取", + "modal.feishu.appSecretHelp": "從飛書開放平臺 > 應用憑證頁面獲取", + "modal.slack.botTokenHelp": "從 Slack App 的 OAuth & Permissions 頁面獲取", + "modal.slack.signingSecretHelp": "從 Slack App 的 Basic Information 頁面獲取", + "modal.discord.botTokenHelp": "從 Discord Developer Portal > Bot 頁面獲取", + "modal.discord.appIdHelp": + "從 Discord Developer Portal > General Information 獲取", + + // ── Skills Page ── + "skills.pageTitle": "技能", + "skills.pageSubtitle": "管理 AI 能力", + "skills.skillsCount": "{{count}} 個技能", + "skills.searchPlaceholder": "搜尋", + "skills.official": "官方", + "skills.all": "全部", + "skills.explore": "ClawHub", + "skills.yours": "我的", + "skills.clawhubDisclaimer": + "Skill 來自 ClawHub,網路或服務偶有不穩定;若遇到問題,歡迎在", + "skills.clawhubDisclaimerAfterLink": "反饋。", + "skills.builtin": "內建", + "skills.custom": "自定義", + "skills.installQueued": "技能已加入安裝佇列", + "skills.skillNotFound": + '"{{slug}}" 在 ClawHub 上不可用,可能已被移除或重命名。', + "skills.skillNotAvailable": + "該技能在 ClawHub 上不可用,可能已被移除或重新命名。", + "skills.installRateLimited": "ClawHub 正在限流,請稍後重試。", + "skills.installFailedGeneric": "安裝失敗,請稍後重試。", + "skills.retryInstall": "重試", + "skills.cancelInstall": "取消", + "skills.cancelling": "取消中…", + "skills.cancelFailed": "取消失敗:{{error}}", + "skills.installNpmMissing": + "安裝該技能需要 npm。請先從 https://nodejs.org/ 安裝 Node.js 並重啟 Nexu。", + "skills.installDepsFailed": + '"{{slug}}" 的依赖安装失败,请查看控制器日志了解详情。', + "skills.installFailed": '"{{slug}}" 安装失败:{{error}}', + "skills.installRequestFailed": "無法啟動安裝:{{error}}", + "skills.uninstallRequestFailed": "無法解除安裝該技能:{{error}}", + "skills.import": "匯入", + "skills.importSkill": "匯入技能", + "skills.importSkillDesc": "從 zip 檔案或 GitHub 倉庫新增自定義技能", + "skills.uploadZip": "上傳 Zip", + "skills.githubLink": "GitHub 連結", + "skills.importSuccess": "技能匯入成功", + "skills.importFailed": "匯入失敗", + "skills.dropZipHere": "將 .zip 技能檔案拖放到此處", + "skills.orClickBrowse": "或點選瀏覽", + "skills.clickToChange": "點選更換檔案", + "skills.zipHint": "zip 檔案中應包含 SKILL.md 清單及相關的提示詞或配置檔案。", + "skills.githubUrlLabel": "GitHub 倉庫地址", + "skills.githubComingSoon": + "GitHub 匯入即將推出,請先使用「上傳 Zip」標籤頁。", + "skills.importing": "匯入中...", + "skills.cancel": "取消", + "skills.loadingCatalog": "正在下載技能目錄...", + "skills.catalogUnavailable": "目錄不可用", + "skills.retrying": "重試中...", + "skills.tryAgain": "重試", + "skills.noInstalledSkills": "還沒有安裝任何技能。點選「+ 匯入」新增一個。", + "skills.noMatchingSkills": "沒有匹配的技能", + "skills.noAuth": "無需授權", + "skills.copied": "已複製", + "skills.try": "試用", + "skills.noMatchSearch": "沒有匹配的技能", + "skills.noAvailable": "暫無可用技能", + "skills.downloadingCatalog": "正在下載技能目錄...", + "skills.searchCommunity": "搜尋社群技能...", + "skills.sortDownloads": "下載量", + "skills.sortStars": "收藏", + "skills.sortNewest": "最新", + "skills.refreshCatalog": "重新整理目錄", + "skills.lastUpdated": "上次更新:{{time}} · {{count}} 個技能", + "skills.tagAll": "全部", + "skills.noCommunitySkills": "暫無社群技能", + "skills.noInstalled": "暫無已安裝技能", + "skills.tabCommunity": "社群", + "skills.tabInstalled": "已安裝", + "skills.sourceRecommended": "推薦", + "skills.sourceRecommendedDesc": "nexu 推薦的預裝技能", + "skills.sourceInstalled": "已安裝", + "skills.sourceInstalledDesc": "你安裝的社群技能", + "skills.justNow": "剛剛", + "skills.hoursAgo": "{{count}}小時前", + "skills.daysAgo": "{{count}}天前", + "skills.installAction": "安裝", + "skills.uninstallAction": "解除安裝", + "skills.installingAction": "安裝中…", + "skills.uninstallingAction": "解除安裝中…", + "skills.agentSkills": "代理技能", + + // ── Skill Detail Page ── + "skillDetail.backToSkills": "返回技能列表", + "skillDetail.notFound": "技能未找到", + "skillDetail.notFoundDesc": "該技能不存在或已被移除。", + "skillDetail.quickInfo": "基本資訊", + "skillDetail.category": "分類", + "skillDetail.auth": "認證", + "skillDetail.noAuthNeeded": "無需授權", + "skillDetail.providers": "服務商", + "skillDetail.platforms": "平臺", + "skillDetail.connect": "連線", + "skillDetail.toolAuth": "工具授權", + "skillDetail.toolAuthDesc": + "我們管理 OAuth、令牌重新整理和許可權範圍 —— 你只需對話。", + "skillDetail.examples": "示例", + "skillDetail.tryPrompts": "試試這些提示詞", + "skillDetail.tryPromptsDesc": + "複製一條提示詞傳送給你的 nexu Bot 來試用這個技能。", + "skillDetail.copy": "複製", + "skillDetail.explore": "探索", + "skillDetail.relatedSkills": "相關技能", + "skillDetail.viewAll": "檢視所有技能", + "skillDetail.connected": "已連線", + "skillDetail.disconnect": "斷開連線", + "skillDetail.connecting": "連線中...", + "skillDetail.disconnectTitle": "斷開 {{name}}?", + "skillDetail.disconnectDesc": "這將移除連線和所有已儲存的憑證。", + "skillDetail.downloads": "次下載", + "skillDetail.stars": "次收藏", + "skillDetail.homepage": "主頁", + "skillDetail.files": "檔案", + "skillDetail.install": "安裝", + "skillDetail.installing": "安裝中...", + "skillDetail.uninstall": "解除安裝", + "skillDetail.removing": "解除安裝中...", + + // ── Sessions Page ── + "sessions.selectSession": "選擇一個會話", + "sessions.selectSessionDesc": + "從側邊欄選擇一個會話檢視詳情,或透過已連線的渠道發起對話。", + "sessions.loading": "載入中...", + "sessions.messages": "{{count}} 條訊息", + "sessions.deployments": "部署", + "sessions.noDeployments": "暫無部署", + "sessions.preview": "預覽", + "sessions.justNow": "剛剛", + "sessions.minutesAgo": "{{count}}分鐘前", + "sessions.hoursAgo": "{{count}}小時前", + "sessions.daysAgo": "{{count}}天前", + "sessions.chat.messages": "{{count}} 條訊息", + "sessions.chat.lastActive": "最後活躍於 {{time}}", + "sessions.chat.empty": "暫無訊息", + "sessions.chat.emptyDesc": "對話開始後訊息將在此顯示。", + "sessions.chat.unavailable": "執行時不可用", + "sessions.chat.unavailableDesc": "無法連線到聊天執行時。", + "sessions.chat.loading": "載入訊息中...", + "sessions.chat.replyLabel": "回覆", + "sessions.chat.toolActivity": "工具", + "sessions.chat.toolCompleted": "已完成", + "sessions.openFolder": "開啟資料夾", + + // ── Integrations Page ── + "integrations.pageTitle": "整合", + "integrations.tools": "{{count}} 個工具", + "integrations.connected": "{{count}} 個已連線", + "integrations.searchPlaceholder": "搜尋整合...", + "integrations.all": "全部", + "integrations.connectedFilter": "已連線", + "integrations.available": "可用", + "integrations.provided": "已提供", + "integrations.update": "更新", + "integrations.configure": "配置", + "integrations.updateCredentials": "更新憑證", + "integrations.saveConnect": "儲存並連線", + "integrations.noMatchSearch": "沒有匹配的整合", + "integrations.noAvailable": "暫無可用整合", + "integrations.statusConnected": "已連線", + "integrations.statusConnecting": "連線中...", + "integrations.statusAvailable": "可用", + "integrations.statusFailed": "失敗", + "integrations.statusExpired": "已過期", + "integrations.statusDisconnected": "已斷開", + "integrations.statusUnknown": "未知", + "integrations.disconnect": "斷開連線", + "integrations.disconnectTitle": "斷開 {{name}}?", + "integrations.disconnectDesc": "這將移除連線和所有已儲存的憑證。", + + // ── OAuth Callback Page ── + "oauth.connectTitle": "連線 {{name}}", + "oauth.requestingAccess": "nexu 正在請求訪問你的 {{name}} 賬號", + "oauth.connectingAccount": "正在連線你的賬號...", + "oauth.waitingForAuth": "請稍候,我們正在建立連線。", + "oauth.permissionsRequested": "請求的許可權", + "oauth.waitingAuth": "等待授權...", + "oauth.securityNote": + "nexu 使用 OAuth 2.0。你的憑證不會被儲存。你可以隨時撤銷訪問。", + "oauth.authSuccess": "授權成功", + "oauth.connectedTo": "{{name}} 已連線到 nexu", + "oauth.returnSlack": "返回 Slack", + "oauth.returnDiscord": "返回 Discord", + "oauth.goToIntegrations": "前往整合", + "oauth.manageHint": "在工作區設定中管理已連線的服務", + "oauth.connectionFailed": "連線失敗", + + // ── Slack OAuth Callback ── + "slackOAuth.connected": "Slack 已連線", + "slackOAuth.connectedDesc": '工作区"{{teamName}}"已成功连接到你的 Bot。', + "slackOAuth.redirecting": "正在跳轉...", + + // ── Slack Claim Page ── + "claim.invalidLink": "無效的認領連結", + "claim.invalidLinkDesc": + "該連結無效。請檢查你在 {{platform}} 中收到的訊息以獲取正確連結。", + "claim.linkExpired": "連結已過期", + "claim.linkExpiredDesc": + "該認領連結已過期。在 {{platform}} 中給 nexu Bot 發訊息以獲取新連結。", + "claim.linkUsed": "連結已被使用", + "claim.linkUsedDesc": + "該認領連結已被使用。如果是你使用的,你的賬號已配置完成。", + "claim.open": "開啟 {{platform}}", + "claim.goToSignIn": "前往登入", + "claim.getStarted": "開始使用 nexu", + "claim.joinTeam": "加入你的團隊", + "claim.joinTeamDesc": + "登入以連線你的 {{platform}} 身份並開始與團隊一起使用 nexu。", + "claim.createAccountDesc": + "建立賬號以認領你的 {{platform}} 訪問許可權並解鎖 AI 驅動的工作流。", + "claim.teammatesAlready": "{{count}} 位同事已在使用 nexu —— 無需額外配置", + "claim.createAccount": "建立賬號", + "claim.alreadyHaveAccount": "已有賬號?", + "claim.teamUsesnexu.line1": "你的團隊", + "claim.teamUsesnexu.line2": "已在使用", + "claim.teamUsesnexu.line3": "nexu", + "claim.teammatesHere": "{{count}} 位同事已加入", + "claim.noConfigNeeded": + "你的團隊已連線 nexu —— 無需額外配置。只需登入即可開始。", + "claim.claimAccess": "認領你的 {{platform}} 訪問許可權", + "claim.claimAccessDescExisting": + "將你的 {{platform}} 身份連線到 nexu 賬號並加入 {{team}}。", + "claim.claimAccessDescNew": + "將你的 {{platform}} 身份關聯到 nexu 賬號以解鎖 AI 驅動的工作流。", + "claim.signedInAs": "已登入為", + "claim.claimButton": "認領你的 {{platform}} 訪問許可權", + "claim.useDifferentAccount": "使用其他賬號", + "claim.claiming": "正在認領你的 {{platform}} 訪問許可權...", + "claim.claimingDesc": "正在將你的 {{platform}} 身份關聯到 nexu 賬號。", + "claim.allSet": "全部完成!", + "claim.allSetDesc": "你的 {{platform}} 賬號已關聯到 nexu。", + "claim.nowPartOf": "你現在已加入", + "claim.backTo": "返回 {{platform}}", + "claim.explorenexu": "探索 nexu", + + // ── Feishu Bind Page ── + "feishuBind.linked": "飛書賬號已繫結!", + "feishuBind.linkedDesc": + "你的飛書身份已關聯到 nexu 賬號。你現在可以正常使用 Bot。", + "feishuBind.backToFeishu": "返回飛書", + "feishuBind.explorenexu": "探索 nexu", + "feishuBind.bindFailed": "繫結失敗", + "feishuBind.tryAgain": "重試", + "feishuBind.linkTitle.line1": "繫結你的", + "feishuBind.linkTitle.line2": "飛書", + "feishuBind.linkTitle.line3": "身份", + "feishuBind.linkDesc": + "將你的飛書賬號連線到 nexu,在聊天中直接解鎖 AI 驅動的工作流。", + "feishuBind.linkAccount": "繫結你的飛書賬號", + "feishuBind.signInFirst": "請先登入 nexu,然後繫結你的飛書身份。", + "feishuBind.authorizeDesc": "透過飛書授權將你的身份關聯到 nexu 賬號。", + "feishuBind.signedInAs": "已登入為", + "feishuBind.bindButton": "繫結飛書賬號", + "feishuBind.redirecting": "正在跳轉到飛書...", + + // ── Feishu Setup ── + "feishuSetup.stepCreateApp": "建立應用", + "feishuSetup.stepPermissions": "許可權配置", + "feishuSetup.stepCredentials": "憑證", + "feishuSetup.step": "步驟 {{number}}", + "feishuSetup.createTitle": "建立飛書應用", + "feishuSetup.createDesc": "前往飛書開放平臺,建立一個新的自建應用。", + "feishuSetup.createStep1": "開啟飛書開放平臺開發者控制檯", + "feishuSetup.createStep2": "點選「建立自建應用」", + "feishuSetup.createStep3": "輸入應用名稱和描述", + "feishuSetup.createStep4": "在「應用能力」中啟用「機器人」", + "feishuSetup.openConsole": "開啟開發者控制檯", + "feishuSetup.permissionsTitle": "配置許可權併發布", + "feishuSetup.permissionsDesc": "匯入以下許可權 JSON,然後建立版本併發布應用。", + "feishuSetup.permissionsJson": "許可權 JSON", + "feishuSetup.copied": "已複製", + "feishuSetup.copy": "複製", + "feishuSetup.permStep1": "前往「許可權管理」→ 點選「批次開通」", + "feishuSetup.permStep2": "貼上上方 JSON 並確認", + "feishuSetup.permStep3": "前往「版本管理」→「建立版本」", + "feishuSetup.permStep4": "提交稽核併發布", + "feishuSetup.credentialsTitle": "輸入憑證", + "feishuSetup.credentialsDesc": + "在飛書應用的「憑證與基本資訊」頁面找到 App ID 和 App Secret。", + "feishuSetup.appIdLabel": "App ID", + "feishuSetup.appIdHint": "— 以 cli_ 開頭", + "feishuSetup.appIdPlaceholder": "例如 cli_a1b2c3d4e5f6g7h8", + "feishuSetup.appSecretLabel": "App Secret", + "feishuSetup.appSecretPlaceholder": "你的 App Secret", + "feishuSetup.verifyConnect": "驗證並連線", + "feishuSetup.previous": "上一步", + "feishuSetup.next": "下一步", + "feishuSetup.helpText": "需要幫助?閱讀", + "feishuSetup.helpLinkText": "飛書自建應用開發指南", + "feishuSetup.helpSuffix": "獲取詳細說明。", + "feishuSetup.connectSuccess": "飛書 Bot 已連線!", + "feishuSetup.connectFailed": "連線飛書失敗", + + // ── WeChat Setup ── + "wechatSetup.title": "連線微信", + "wechatSetup.desc": "用手機微信掃碼即可連線。", + "wechatSetup.scanQr": "掃碼連線", + "wechatSetup.scanning": "等待掃碼...", + "wechatSetup.scanHint": "開啟手機微信,掃描上方二維碼以關聯賬號。", + "wechatSetup.connectSuccess": "微信已連線!", + "wechatSetup.connectFailed": "連線微信失敗", + "wechatSetup.timeout": "二維碼已過期,請重試。", + "wechatSetup.retry": "重試", + "wechatSetup.gatewayError": "Gateway 未連線,請先啟動執行時。", + "wechatSetup.waitingGateway": "等待閘道器啟動中...", + "wechatSetup.waitingGatewayHint": "第 {{attempt}}/{{total}} 次嘗試", + "wechatSetup.loadingQr": "正在獲取二維碼...", + + // ── Telegram Setup ── + "telegramSetup.title": "連線 Telegram", + "telegramSetup.desc": + "在 BotFather 中建立 Bot,把 token 貼上到這裡,然後將 Bot 新增到你希望它回覆的群組。Nexu 僅會在群內被提及時回覆。", + "telegramSetup.quickSetup": "快速配置", + "telegramSetup.step1": "開啟 Telegram,並與 BotFather 對話。", + "telegramSetup.step2": "使用 `/newbot` 建立一個 Bot。", + "telegramSetup.step3": "複製 HTTP API token 並貼上到下方。", + "telegramSetup.step4": "如果你希望群聊回覆,請把 Bot 加入群組。", + "telegramSetup.botTokenLabel": "Bot Token", + "telegramSetup.botTokenPlaceholder": "1234567890:AA...", + "telegramSetup.connect": "連線 Telegram", + "telegramSetup.tokenRequired": "請輸入 Telegram Bot token", + "telegramSetup.connectFailed": "連線 Telegram 失敗", + "telegramSetup.connectSuccess": "Telegram 已連線", + + // ── WhatsApp Setup ── + "whatsappSetup.title": "連線 WhatsApp", + "whatsappSetup.personalTitle": "連線個人 WhatsApp", + "whatsappSetup.desc": + "用手機掃描一次即可繫結 WhatsApp Web。私聊會保持開啟;在群聊中提到該賬號時,也會預設啟用回覆。", + "whatsappSetup.qrAlt": "WhatsApp 二維碼", + "whatsappSetup.waitingForScan": "等待掃描 WhatsApp 二維碼", + "whatsappSetup.scanHint": + "在手機上開啟 WhatsApp,進入“關聯裝置”後掃描此二維碼。", + "whatsappSetup.preparingQr": "正在準備 WhatsApp 二維碼", + "whatsappSetup.finishingConnection": "正在完成 WhatsApp 連線", + "whatsappSetup.retry": "重試", + "whatsappSetup.scanQr": "掃描 WhatsApp 二維碼", + "whatsappSetup.connectSuccess": "WhatsApp 已連線", + "whatsappSetup.connectFailed": "WhatsApp 連線失敗", + "whatsappSetup.startFailed": "啟動 WhatsApp 登入失敗", + "whatsappSetup.loadQrFailed": "載入 WhatsApp 二維碼失敗", + "whatsappSetup.waitFailed": "WhatsApp 登入超時", + + // ── QQ Setup ── + "qqbotSetup.title": "連線 QQ", + "qqbotSetup.desc": + "建立 QQ 機器人應用後,將 App ID 和 App Secret 貼上到這裡,Nexu 會透過內建 OpenClaw 外掛進行回覆。", + "qqbotSetup.quickSetup": "快速配置", + "qqbotSetup.step1": "開啟 QQ 機器人平臺", + "qqbotSetup.step2": "建立或開啟你的機器人應用。", + "qqbotSetup.step3": "複製 App ID 和 App Secret。", + "qqbotSetup.step4": "將憑證貼上到下方並驗證連線。", + "qqbotSetup.appIdLabel": "App ID", + "qqbotSetup.appIdPlaceholder": "例如 1024", + "qqbotSetup.appSecretLabel": "App Secret", + "qqbotSetup.appSecretPlaceholder": "你的應用金鑰", + "qqbotSetup.credentialsRequired": "請輸入 QQ App ID 和 App Secret", + "qqbotSetup.testSuccess": "QQ 憑證有效", + "qqbotSetup.testFailed": "驗證 QQ 憑證失敗", + "qqbotSetup.connect": "連線 QQ", + "qqbotSetup.connectSuccess": "QQ 已連線", + "qqbotSetup.connectFailed": "連線 QQ 失敗", + + // ── DingTalk Setup ── + "dingtalkSetup.title": "連線釘釘", + "dingtalkSetup.desc": + "在釘釘開放平臺建立應用後,將 Client ID 和 Client Secret 貼上到這裡。", + "dingtalkSetup.quickSetup": "快速配置", + "dingtalkSetup.step1": "開啟釘釘開放平臺", + "dingtalkSetup.step2": "建立或開啟啟用了機器人能力的應用。", + "dingtalkSetup.step3": "從應用憑證中複製 Client ID 和 Client Secret。", + "dingtalkSetup.step4": "將憑證貼上到下方並驗證連線。", + "dingtalkSetup.clientIdLabel": "Client ID", + "dingtalkSetup.clientIdPlaceholder": "例如 dingxxxxxxxxxxxxxxxx", + "dingtalkSetup.clientSecretLabel": "Client Secret", + "dingtalkSetup.clientSecretPlaceholder": "你的客戶端金鑰", + "dingtalkSetup.credentialsRequired": "請輸入釘釘 Client ID 和 Client Secret", + "dingtalkSetup.testSuccess": "釘釘憑證有效", + "dingtalkSetup.testFailed": "驗證釘釘憑證失敗", + "dingtalkSetup.connect": "連線釘釘", + "dingtalkSetup.connectSuccess": "釘釘已連線", + "dingtalkSetup.connectFailed": "連線釘釘失敗", + + // ── WeCom Setup ── + "wecomSetup.title": "連線企微", + "wecomSetup.desc": + "輸入企微 Bot 憑證後,Nexu 會透過內建 OpenClaw 外掛完成接入。", + "wecomSetup.quickSetup": "快速配置", + "wecomSetup.step1LinkLabel": "開啟企業微信開發者中心", + "wecomSetup.step1Suffix": "。", + "wecomSetup.step2": "建立或開啟你的機器人應用。", + "wecomSetup.step3": "複製 Bot ID 和 Secret。", + "wecomSetup.step4": "將憑證貼上到下方並驗證連線。", + "wecomSetup.botIdLabel": "Bot ID", + "wecomSetup.botIdPlaceholder": "例如 ww1234567890abcdef", + "wecomSetup.secretLabel": "Secret", + "wecomSetup.secretPlaceholder": "你的機器人金鑰", + "wecomSetup.credentialsRequired": "請輸入企微 Bot ID 和 Secret", + "wecomSetup.testSuccess": "企微憑證有效", + "wecomSetup.testFailed": "驗證企微憑證失敗", + "wecomSetup.connect": "連線企微", + "wecomSetup.connectSuccess": "企微已連線", + "wecomSetup.connectFailed": "連線企微失敗", + + // ── Common UI ── + "common.closeDialog": "關閉對話方塊", + + // ── Slack Setup ── + "slackSetup.stepCreateApp": "建立 Slack App", + "slackSetup.stepSigningSecret": "Signing Secret", + "slackSetup.stepBotToken": "Bot Token", + "slackSetup.stepEnableDMs": "啟用私信", + "slackSetup.step": "步驟 {{number}}", + "slackSetup.addnexuTitle": "將 nexu 新增到 Slack", + "slackSetup.addnexuDesc": + "一鍵安裝 — 透過 OAuth 授權 nexu Bot 到你的 Slack 工作區", + "slackSetup.addToSlack": "新增到 Slack", + "slackSetup.orConnectManually": "或手動連線", + "slackSetup.authorizing": "授權中...", + "slackSetup.connectingWorkspace": "正在連線你的 Slack 工作區", + "slackSetup.oauthFailed": "OAuth 授權失敗", + "slackSetup.manualConnection": "手動連線", + "slackSetup.oauthNotCompleted": "Slack 自動授權未完成。", + "slackSetup.manualDesc": "在下方輸入你現有的 Slack App 憑證以手動連線。", + "slackSetup.tryOauthSuffix": "你可以重試 OAuth 或使用以下手動流程。", + "slackSetup.tryOauthAgain": "重試 OAuth", + "slackSetup.createAppTitle": "建立 Slack App", + "slackSetup.createAppDesc": + "點選下方按鈕建立預配置的 Slack App,包含所有必需的許可權範圍、事件和 Bot 設定。建立後,點選「下一步」輸入憑證。", + "slackSetup.createSlackApp": "建立 Slack App", + "slackSetup.signingSecretTitle": "複製 Signing Secret", + "slackSetup.signingSecretDesc": "從你的 Slack App 中複製 Signing Secret。", + "slackSetup.signingSecretLabel": "Signing Secret", + "slackSetup.botTokenTitle": "安裝應用並複製 Bot Token", + "slackSetup.botTokenDesc": "安裝你的 Slack App 並複製 Bot Token。", + "slackSetup.botTokenLabel": "Bot User OAuth Token", + "slackSetup.enableDMsTitle": "啟用私信", + "slackSetup.enableDMsDesc": "允許使用者透過 Slack 私信與你的 Bot 聊天。", + "slackSetup.dmWarning": + "如果不啟用此設定,使用者將無法在「訊息」標籤頁中給你的 Bot 傳送訊息。", + "slackSetup.connect": "連線", + "slackSetup.back": "返回", + "slackSetup.previous": "上一步", + "slackSetup.next": "下一步", + "slackSetup.helpText": "需要幫助?閱讀", + "slackSetup.helpLinkText": "Slack 認證指南", + "slackSetup.helpSuffix": "獲取詳細說明。", + "slackSetup.authNotCompleted": "授權未完成", + "slackSetup.connectFailed": "連線 Slack 失敗", + "slackSetup.connectSuccess": "Slack 工作區「{{teamName}}」已連線!", + "slackSetup.startFailed": "啟動 Slack 連線失敗", + "slackSetup.oauthUrlFailed": "獲取 Slack OAuth URL 失敗", + + // ── Discord Setup ── + "discordSetup.stepCreateApp": "建立應用", + "discordSetup.stepConfigureBot": "配置 Bot", + "discordSetup.stepPermissions": "許可權", + "discordSetup.stepCredentials": "憑證", + "discordSetup.step": "步驟 {{number}}", + "discordSetup.createTitle": "建立 Discord 應用", + "discordSetup.createDesc": "前往 Discord 開發者門戶,建立一個新應用。", + "discordSetup.createStep1": "開啟 Discord 開發者門戶", + "discordSetup.createStep2": "點選「New Application」", + "discordSetup.createStep3": "輸入應用名稱", + "discordSetup.createStep4": "點選「Create」確認", + "discordSetup.openPortal": "開啟開發者門戶", + "discordSetup.configureBotTitle": "配置 Bot", + "discordSetup.configureBotDesc": + "進入應用設定中的 Bot 頁面。點選「Reset Token」生成 Bot Token(請妥善儲存)。", + "discordSetup.botStep1": "前往 Application → Bot 頁面", + "discordSetup.botStep2": "點選「Reset Token」並複製 Bot Token", + "discordSetup.botStep3": "啟用 Privileged Gateway Intents(見下方)", + "discordSetup.requiredIntents": "所需特權意圖", + "discordSetup.permissionsTitle": "設定安裝和許可權", + "discordSetup.permissionsDesc": + "前往 Installation 頁面。在「Guild Install」下,新增所需的範圍和許可權。", + "discordSetup.oauthScopes": "OAuth2 許可權範圍", + "discordSetup.botPermissions": "Bot 許可權", + "discordSetup.installLinkHint": + "配置完成後,複製生成的安裝連結並在瀏覽器中開啟,將 Bot 新增到你的伺服器。", + "discordSetup.credentialsTitle": "輸入憑證", + "discordSetup.credentialsDesc": + "在下方貼上你的 Discord 應用憑證。可在 General Information 和 Bot 頁面找到。", + "discordSetup.appIdLabel": "Application ID", + "discordSetup.appIdHint": "— 在 General Information 中找到", + "discordSetup.botTokenLabel": "Bot Token", + "discordSetup.botTokenHint": "— 在 Bot → Reset Token 中找到(僅顯示一次)", + "discordSetup.verifyConnect": "驗證並連線", + "discordSetup.previous": "上一步", + "discordSetup.next": "下一步", + "discordSetup.helpText": "需要幫助?閱讀", + "discordSetup.helpLinkText": "Discord 入門指南", + "discordSetup.helpSuffix": "獲取詳細說明。", + "discordSetup.connectSuccess": "Discord 伺服器「{{teamName}}」已連線!", + "discordSetup.connectFailed": "連線 Discord 失敗", + + // ── Common ── + "common.cancel": "取消", + "common.confirm": "確認", + "common.loading": "載入中...", + "common.connect": "連線", + "common.disconnect": "斷開連線", +} as const; + +export default zhTW; diff --git a/apps/web/src/pages/models.tsx b/apps/web/src/pages/models.tsx index 27c7fa76..7b77de0b 100644 --- a/apps/web/src/pages/models.tsx +++ b/apps/web/src/pages/models.tsx @@ -985,11 +985,17 @@ function _GeneralSettings() {