diff --git a/apps/desktop/src/app/settings/config-settings.tsx b/apps/desktop/src/app/settings/config-settings.tsx index 571a3812b89bc..6a6d75f93a4bf 100644 --- a/apps/desktop/src/app/settings/config-settings.tsx +++ b/apps/desktop/src/app/settings/config-settings.tsx @@ -476,7 +476,13 @@ export function ConfigSettings({ : enumOptionsFor(key, getNested(config, key), config) } onChange={value => updateConfig(setNested(config, key, value))} - optionLabels={key === 'tts.elevenlabs.voice_id' ? elevenLabsVoiceLabels : undefined} + optionLabels={ + key === 'tts.elevenlabs.voice_id' + ? elevenLabsVoiceLabels + : key === 'display.personality' + ? t.settings.config.personalityLabels + : undefined + } schema={field} schemaKey={key} value={getNested(config, key)} diff --git a/apps/desktop/src/app/settings/helpers.test.ts b/apps/desktop/src/app/settings/helpers.test.ts index 616876a2f268e..0f0cee7e00389 100644 --- a/apps/desktop/src/app/settings/helpers.test.ts +++ b/apps/desktop/src/app/settings/helpers.test.ts @@ -1,7 +1,9 @@ import { describe, expect, it } from 'vitest' +import { TRANSLATIONS } from '@/i18n/catalog' import type { HermesConfigRecord } from '@/types/hermes' +import { BUILTIN_PERSONALITIES } from './constants' import { defineFieldCopy, fieldCopyForSchemaKey, schemaKeyToFieldCopyKey } from './field-copy' import { enumOptionsFor, @@ -42,6 +44,26 @@ describe('settings helpers', () => { }) }) + describe('personalityLabels', () => { + it('covers every built-in personality in every locale', () => { + for (const [locale, catalog] of Object.entries(TRANSLATIONS)) { + for (const id of BUILTIN_PERSONALITIES) { + expect(catalog.settings.config.personalityLabels[id], `${locale}: ${id}`).toBeTruthy() + } + } + }) + + it('actually translates labels in non-English locales (not just the English fallback)', () => { + const english = TRANSLATIONS.en.settings.config.personalityLabels + + for (const locale of ['zh', 'zh-hant', 'ja'] as const) { + const labels = TRANSLATIONS[locale].settings.config.personalityLabels + expect(labels.pirate, `${locale}: pirate should differ from English`).not.toBe(english.pirate) + expect(labels.teacher, `${locale}: teacher should differ from English`).not.toBe(english.teacher) + } + }) + }) + describe('defineFieldCopy', () => { it('flattens nested field copy paths', () => { const copy = defineFieldCopy({ diff --git a/apps/desktop/src/i18n/en.ts b/apps/desktop/src/i18n/en.ts index 00a8f13445a2a..7d99b8bc6829d 100644 --- a/apps/desktop/src/i18n/en.ts +++ b/apps/desktop/src/i18n/en.ts @@ -522,7 +522,25 @@ export const en: Translations = { failedLoad: 'Settings failed to load', autosaveFailed: 'Autosave failed', imported: 'Config imported', - invalidJson: 'Invalid config JSON' + invalidJson: 'Invalid config JSON', + // Display names for the built-in personalities (config IDs stay English). + // Custom personalities fall back to prettyName(id) in the picker. + personalityLabels: { + helpful: 'Helpful', + concise: 'Concise', + technical: 'Technical', + creative: 'Creative', + teacher: 'Teacher', + kawaii: 'Kawaii', + catgirl: 'Catgirl', + pirate: 'Pirate', + shakespeare: 'Shakespeare', + surfer: 'Surfer', + noir: 'Noir', + uwu: 'uwu', + philosopher: 'Philosopher', + hype: 'Hype' + } }, credentials: { pasteKey: 'Paste key', diff --git a/apps/desktop/src/i18n/ja.ts b/apps/desktop/src/i18n/ja.ts index d24e33ecff044..018a3fd73db22 100644 --- a/apps/desktop/src/i18n/ja.ts +++ b/apps/desktop/src/i18n/ja.ts @@ -620,7 +620,23 @@ export const ja = defineLocale({ failedLoad: '設定の読み込みに失敗しました', autosaveFailed: '自動保存に失敗しました', imported: '設定をインポートしました', - invalidJson: '設定 JSON が無効です' + invalidJson: '設定 JSON が無効です', + personalityLabels: { + helpful: '親切', + concise: '簡潔', + technical: 'テクニカル', + creative: 'クリエイティブ', + teacher: '先生', + kawaii: 'カワイイ', + catgirl: 'ネコガール', + pirate: '海賊', + shakespeare: 'シェイクスピア', + surfer: 'サーファー', + noir: 'ノワール', + uwu: 'uwu', + philosopher: '哲学者', + hype: 'ハイテンション' + } }, credentials: { pasteKey: 'キーを貼り付け', diff --git a/apps/desktop/src/i18n/types.ts b/apps/desktop/src/i18n/types.ts index e48c37d6e382b..1986834fa0566 100644 --- a/apps/desktop/src/i18n/types.ts +++ b/apps/desktop/src/i18n/types.ts @@ -434,6 +434,7 @@ export interface Translations { autosaveFailed: string imported: string invalidJson: string + personalityLabels: Record } credentials: { pasteKey: string diff --git a/apps/desktop/src/i18n/zh-hant.ts b/apps/desktop/src/i18n/zh-hant.ts index 4439465ad84a5..e9acf9d5dc9bb 100644 --- a/apps/desktop/src/i18n/zh-hant.ts +++ b/apps/desktop/src/i18n/zh-hant.ts @@ -184,7 +184,107 @@ export const zhHant = defineLocale({ muteHaptics: '靜音觸感回饋', unmuteHaptics: '開啟觸感回饋', openSettings: '開啟設定', - openStarmap: '開啟記憶圖譜' + openStarmap: '開啟記憶圖譜', + openKeybinds: '鍵盤快捷鍵', + layoutEditor: '版面配置編輯器', + layoutEditorTitle: '版面配置編輯器 — ⌘+點擊可重設版面配置' + }, + + keybinds: { + title: '鍵盤快捷鍵', + subtitle: open => `點擊快捷鍵即可重新綁定 · ${open} 可重新開啟此面板。`, + search: '搜尋快捷鍵…', + rebind: '重新綁定', + reset: '重設為預設值', + resetAll: '全部重設', + pressKey: '請按下按鍵…', + set: '設定', + conflictWith: label => `也綁定到「${label}」`, + categories: { + composer: '輸入框', + profiles: '設定檔', + session: '工作階段', + navigation: '導覽', + view: '檢視' + }, + actions: { + 'keybinds.openPanel': '開啟鍵盤快捷鍵', + 'nav.commandPalette': '開啟命令面板', + 'nav.commandCenter': '開啟命令中心', + 'nav.settings': '開啟設定', + 'nav.profiles': '開啟設定檔', + 'nav.skills': '開啟技能', + 'nav.messaging': '開啟訊息', + 'nav.artifacts': '開啟成品', + 'nav.cron': '開啟排程工作', + 'nav.agents': '開啟代理', + 'session.new': '新增工作階段', + 'session.newTab': '新增工作階段分頁', + 'session.newWindow': '在新視窗開啟工作階段', + 'session.next': '下一個工作階段', + 'session.prev': '上一個工作階段', + 'session.slot.1': '切換到最近的工作階段 1', + 'session.slot.2': '切換到最近的工作階段 2', + 'session.slot.3': '切換到最近的工作階段 3', + 'session.slot.4': '切換到最近的工作階段 4', + 'session.slot.5': '切換到最近的工作階段 5', + 'session.slot.6': '切換到最近的工作階段 6', + 'session.slot.7': '切換到最近的工作階段 7', + 'session.slot.8': '切換到最近的工作階段 8', + 'session.slot.9': '切換到最近的工作階段 9', + 'session.focusSearch': '搜尋工作階段', + 'session.togglePin': '釘選/取消釘選目前的工作階段', + 'workspace.newWorktree': '新增工作樹', + 'composer.focus': '聚焦輸入框', + 'composer.modelPicker': '開啟模型選擇器', + 'composer.voice': '開始/停止語音對話', + 'view.toggleSidebar': '切換工作階段側邊欄', + 'view.toggleRightSidebar': '切換檔案瀏覽器', + 'view.toggleReview': '切換審查窗格', + 'view.showFiles': '顯示檔案瀏覽器', + 'view.showTerminal': '切換終端機', + 'view.newTerminal': '新增終端機', + 'view.nextTerminal': '下一個終端機', + 'view.prevTerminal': '上一個終端機', + 'view.closeTerminal': '關閉終端機', + 'view.terminalSelection': '將終端機選取內容傳送到輸入框', + 'view.closeTab': '關閉分頁', + 'view.reopenTab': '重新開啟已關閉的分頁', + 'view.flipPanes': '交換側邊欄位置', + 'appearance.toggleMode': '切換淺色/深色', + 'profile.default': '切換到預設設定檔', + 'profile.switch.1': '切換到設定檔 1', + 'profile.switch.2': '切換到設定檔 2', + 'profile.switch.3': '切換到設定檔 3', + 'profile.switch.4': '切換到設定檔 4', + 'profile.switch.5': '切換到設定檔 5', + 'profile.switch.6': '切換到設定檔 6', + 'profile.switch.7': '切換到設定檔 7', + 'profile.switch.8': '切換到設定檔 8', + 'profile.switch.9': '切換到設定檔 9', + 'profile.switch.10': '切換到設定檔 10', + 'profile.switch.11': '切換到設定檔 11', + 'profile.switch.12': '切換到設定檔 12', + 'profile.switch.13': '切換到設定檔 13', + 'profile.switch.14': '切換到設定檔 14', + 'profile.switch.15': '切換到設定檔 15', + 'profile.switch.16': '切換到設定檔 16', + 'profile.switch.17': '切換到設定檔 17', + 'profile.switch.18': '切換到設定檔 18', + 'profile.next': '下一個設定檔', + 'profile.prev': '上一個設定檔', + 'profile.toggleAll': '切換全部設定檔檢視', + 'profile.create': '建立設定檔', + 'composer.send': '傳送訊息', + 'composer.newline': '插入換行', + 'composer.steer': '引導執行中的回合', + 'composer.sendQueued': '傳送下一個排隊的回合', + 'composer.mention': '參照檔案、資料夾、URL', + 'composer.slash': '斜線指令面板', + 'composer.help': '快速說明', + 'composer.history': '切換彈出視窗/歷史', + 'composer.cancel': '關閉彈出視窗 · 取消執行' + } }, language: { @@ -218,7 +318,22 @@ export const zhHant = defineLocale({ archivedChats: '已封存聊天', about: '關於', billing: '帳單', - notifications: '通知' + notifications: '通知', + plugins: '外掛' + }, + plugins: { + title: '桌面外掛', + blurb: + '載入到此應用程式的 UI 擴充功能——隨組建內建,或放入 desktop-plugins 資料夾(包括 Hermes 自己寫入的)。停用會即時卸載外掛,且重新啟動後仍維持停用。', + count: n => `已安裝 ${n} 個`, + openFolder: '開啟外掛資料夾', + rescan: '重新掃描', + reveal: '在檔案管理員中顯示', + enable: '啟用', + disable: '停用', + failed: '失敗', + empty: '尚未安裝任何桌面外掛。', + kinds: { bundled: '內建', disk: '磁碟上', runtime: '執行階段' } }, notifications: { title: '通知', @@ -608,7 +723,23 @@ export const zhHant = defineLocale({ failedLoad: '設定載入失敗', autosaveFailed: '自動儲存失敗', imported: '設定已匯入', - invalidJson: '設定 JSON 無效' + invalidJson: '設定 JSON 無效', + personalityLabels: { + helpful: '樂於助人', + concise: '簡潔扼要', + technical: '技術專家', + creative: '創意發想', + teacher: '循循善誘', + kawaii: '卡哇伊', + catgirl: '貓娘', + pirate: '海盜船長', + shakespeare: '莎士比亞', + surfer: '衝浪客', + noir: '黑色偵探', + uwu: 'uwu', + philosopher: '哲學家', + hype: '熱血滿點' + } }, credentials: { pasteKey: '貼上金鑰', @@ -644,11 +775,43 @@ export const zhHant = defineLocale({ profileConnection: profile => `僅當「${profile}」為作用中設定檔時使用此連線。設為本機可繼承預設連線。`, envOverrideTitle: '環境變數正在控制此桌面工作階段。', envOverrideDesc: '取消設定 HERMES_DESKTOP_REMOTE_URL 和 HERMES_DESKTOP_REMOTE_TOKEN 後才會使用下方儲存的設定。', + modeTitle: '連線模式', localTitle: '本機閘道', localDesc: '在 localhost 啟動私有 Hermes 後端。這是預設方式,可離線使用。', remoteTitle: '遠端閘道', - remoteDesc: - '將此桌面殼層連線至遠端 Hermes 後端。託管閘道使用 OAuth 或帳號密碼;自託管閘道也可使用工作階段 Token。', + remoteDesc: '將此桌面殼層連線至遠端 Hermes 後端。', + remoteAuthHint: '託管閘道使用 OAuth 或帳號密碼;自託管閘道也可使用工作階段 Token。', + cloudTitle: 'Hermes Cloud', + cloudDesc: '登入一次 Hermes Cloud,即可從您帳號中的代理挑選——不需要貼任何 URL。', + cloudSignInTitle: 'Hermes Cloud', + cloudSignIn: '登入 Hermes Cloud', + cloudSignedIn: '已登入 Hermes Cloud', + cloudNeedsSignIn: '登入 Hermes Cloud 以探索您帳號中的代理。', + cloudSignedInDesc: '您已登入。請在下方挑選代理;工作階段會自動重新整理。', + cloudAgentsTitle: '您的代理', + cloudOrgPickerTitle: '選擇組織', + cloudOrgSelect: '選取', + cloudOrgChange: '變更組織', + cloudOrgRole: role => `角色:${role}`, + cloudLoadingAgents: '正在載入您的代理…', + cloudNoAgents: { + before: '此帳號找不到任何代理。請在 ', + linkText: 'Nous 入口網站', + after: ' 建立一個,然後重新整理。' + }, + cloudRefresh: '重新整理', + cloudConnect: '連線', + cloudConnecting: '連線中…', + cloudDiscoverFailed: '無法載入您的 Hermes Cloud 代理', + cloudConnectFailed: '無法連線至該代理', + cloudSignInFailed: 'Hermes Cloud 登入失敗', + cloudSignedOutTitle: '已登出 Hermes Cloud', + cloudSignedOutMessage: '已清除 Hermes Cloud 工作階段。', + cloudConnectedTitle: '已連線', + cloudConnectedPill: '已連線', + cloudConnectedTo: name => `已連線至 ${name}。`, + cloudAgentProvisioning: '佈建中…', + cloudStatusLabel: status => `狀態:${status}`, remoteUrlTitle: '遠端 URL', remoteUrlDesc: '遠端儀表板後端的基礎 URL。支援路徑前綴,例如 /hermes。', probing: '正在檢查此閘道的驗證方式…', @@ -740,7 +903,30 @@ export const zhHant = defineLocale({ unsavedConnect: '未儲存 — 儲存 mcp.json 以連線。', enableTool: tool => `啟用 ${tool}`, disableTool: tool => `停用 ${tool}`, - noOutput: '尚無輸出。' + noOutput: '尚無輸出。', + test: '測試連線', + testing: '測試中...', + testOk: count => `已連線 — ${count} 個工具可用`, + testFailed: '連線失敗', + enableServer: name => `啟用 ${name}`, + disableServer: name => `停用 ${name}`, + serverEnabled: name => `已啟用 ${name} — 套用至新工作階段。`, + serverDisabled: name => `已停用 ${name} — 套用至新工作階段。`, + toggleFailed: name => `無法切換 ${name}`, + tabServers: '伺服器', + tabCatalog: '目錄', + catalogLoading: '正在載入 MCP 目錄...', + catalogLoadFailed: 'MCP 目錄載入失敗', + catalogEmpty: '沒有可用的目錄項目。', + catalogInstalled: '已安裝', + catalogEnabled: '已啟用', + catalogNeedsInstall: '需要建置', + catalogInstall: '安裝', + catalogInstalling: '安裝中...', + catalogInstallStarted: name => `正在安裝 ${name}... 完成後套用至新工作階段。`, + catalogInstallFailed: name => `安裝 ${name} 失敗`, + catalogEnvPrompt: name => `${name} 需要憑證`, + catalogEnvRequired: '安裝前請填寫必要的值。' }, model: { loading: '正在載入模型設定...', @@ -755,6 +941,13 @@ export const zhHant = defineLocale({ change: '變更', autoUseMain: '自動 · 使用主要模型', providerDefault: '(提供方預設)', + defaultsLabel: '預設值', + reasoning: '推理', + reasoningOff: '關閉', + defaultsFailed: '無法儲存模型預設值', + fallbackAdd: '新增備援', + fallbackEmpty: '沒有備援模型——除非預設模型失敗,否則一律使用預設模型。', + notInCatalog: '不在此提供方的模型清單中——呼叫可能會退回備援模型。', tasks: { vision: { label: '視覺', hint: '圖片分析' }, web_extract: { label: '網頁擷取', hint: '頁面摘要' }, @@ -776,6 +969,11 @@ export const zhHant = defineLocale({ otherProviders: '其他提供方', removeConfirm: provider => `移除 ${provider}?`, removeKeyManaged: provider => `${provider} 由 API 金鑰設定。請從 API Keys 中移除。`, + disconnect: '解除連結', + disconnectInTerminal: '解除連結(在終端機執行移除指令)', + removeExternalGeneric: provider => `${provider} 由其自身的 CLI 管理——請在該處移除。`, + removeTerminalConfirm: (provider, command) => `解除連結 ${provider}?將在終端機執行「${command}」以清除憑證。`, + removeTerminalRunning: provider => `正在終端機執行 ${provider} 解除連結…`, removedTitle: '帳號已移除', removedMessage: provider => `${provider} 已移除。`, failedRemove: provider => `無法移除 ${provider}`, @@ -857,7 +1055,16 @@ export const zhHant = defineLocale({ selectedMessage: backend => `終端命令現在透過 ${backend} 執行。將套用於新工作階段。`, failedSelect: backend => `選擇 ${backend} 失敗`, needsSetupHint: '現在即可選擇此後端——但在完成設定前命令將會失敗。' - } + }, + loadingModels: '正在載入模型清單...', + modelSectionTitle: '模型', + modelCount: count => `${count} 個模型`, + modelInUse: '使用中', + modelDefault: '預設', + modelInactiveHint: '請先選擇此後端,再變更其模型。', + modelSelectedTitle: '已選擇模型', + modelSelectedMessage: model => `${model} 將套用至新工作階段。`, + failedSelectModel: model => `選擇 ${model} 失敗` } }, @@ -865,6 +1072,7 @@ export const zhHant = defineLocale({ tabSkills: '技能', tabToolsets: '工具集', tabMcp: 'MCP', + tabHub: '瀏覽技能中心', all: '全部', searchSkills: '搜尋技能...', searchToolsets: '搜尋工具集...', @@ -912,7 +1120,50 @@ export const zhHant = defineLocale({ edit: '編輯', archive: '封存', skillArchivedTitle: '技能已封存', - skillArchivedMessage: '可透過 hermes curator restore 還原。' + skillArchivedMessage: '可透過 hermes curator restore 還原。', + hub: { + searchPlaceholder: '搜尋技能中心', + search: '搜尋', + searching: '搜尋中...', + connectingHubs: '正在連線技能中心...', + connectedHubs: '已連線的中心:', + featured: '精選技能', + landingHint: '搜尋技能中心,瀏覽來自官方索引、GitHub 與社群來源的可安裝技能。', + noResults: '技能中心裡找不到符合的技能。', + resultCount: (count, ms) => `${count} 個結果${ms !== null ? `,耗時 ${ms}ms` : ''}`, + timedOut: sources => `逾時:${sources}`, + installed: '已安裝', + install: '安裝', + installing: '安裝中...', + uninstall: '解除安裝', + uninstalling: '解除安裝中...', + updateAll: '更新已安裝項目', + updating: '更新中...', + preview: '預覽', + scan: '掃描', + scanning: '掃描中...', + close: '關閉', + files: '檔案', + noReadme: '此技能沒有 SKILL.md 預覽。', + trust: { builtin: '內建', trusted: '可信', community: '社群' }, + verdictSafe: '安全', + verdictCaution: '注意', + verdictDangerous: '危險', + policyAllow: '允許安裝', + policyAsk: '安裝前請審查', + policyBlock: '安裝已被原則封鎖', + findings: count => `${count} 項發現`, + noFindings: '沒有安全性發現。', + installStarted: name => `正在安裝 ${name}...`, + uninstallStarted: name => `正在解除安裝 ${name}...`, + updateStarted: '正在更新已安裝的技能...', + actionFailed: '技能操作失敗', + actionLog: '操作記錄', + loadFailed: '技能中心載入失敗', + previewFailed: '技能預覽失敗', + scanFailed: '安全性掃描失敗', + searchFailed: '技能中心搜尋失敗' + } }, starmap: { @@ -928,7 +1179,19 @@ export const zhHant = defineLocale({ loadFailed: '無法載入記憶圖譜', loading: '載入中…', emptyTitle: '尚無學習內容', - emptyDesc: '當 Hermes 為你的工作建立技能與記憶時,會顯示在這裡。' + emptyDesc: '當 Hermes 為你的工作建立技能與記憶時,會顯示在這裡。', + share: '分享圖譜', + shareHint: '複製代碼以分享此圖譜,或貼上代碼以載入。僅包含版面配置,不含您的記憶或技能內容。', + shareTitle: '匯入/匯出圖譜', + sharePlaceholder: '貼上圖譜代碼…', + copy: '複製圖譜代碼', + copied: '已複製!', + importMap: '匯入圖譜', + importBtn: '載入', + importEmpty: '貼上圖譜代碼以載入。', + importSuccess: nodes => `已載入含 ${nodes} 個節點的圖譜。`, + importedBadge: '匯入的圖譜', + resetToMine: '回到我的圖譜' }, agents: { close: '關閉代理', @@ -968,6 +1231,7 @@ export const zhHant = defineLocale({ goTo: '前往', goToSession: '前往工作階段', branches: '分支', + commands: '命令', startInBranch: branch => `在 ${branch} 中開始新對話`, commandCenter: '命令中心', appearance: '外觀', @@ -1033,8 +1297,9 @@ export const zhHant = defineLocale({ settingsFields: '設定欄位', mcpServers: 'MCP 伺服器', archivedChats: '已封存聊天', - sections: { sessions: '工作階段', system: '系統', usage: '使用量' }, + sections: { maintenance: '維護', sessions: '工作階段', system: '系統', usage: '使用量' }, sectionDescriptions: { + maintenance: '診斷、備份、策展器與記憶資料', sessions: '搜尋和管理工作階段', system: '狀態、記錄和系統動作', usage: '一段時間內的詞元、費用和技能活動' @@ -1074,6 +1339,53 @@ export const zhHant = defineLocale({ loadingStatus: '正在載入狀態…', recentLogs: '最近記錄', noLogs: '尚未載入記錄。', + logFile: '記錄檔', + logLevel: '層級', + logSearchPlaceholder: '篩選記錄行...', + maintenance: { + runOps: '診斷', + doctor: '執行 doctor', + doctorDesc: '健康檢查安裝、設定與提供方', + securityAudit: '安全性稽核', + securityAuditDesc: '掃描設定與技能中的風險設定', + backup: '建立備份', + backupDesc: '將設定、記憶、技能與工作階段壓縮為 zip', + debugShare: '除錯分享', + debugShareDesc: '上傳去識別化的報告與記錄,取得可分享連結(6 小時後自動刪除)', + debugShareRunning: '正在上傳除錯報告...', + debugShareLinks: '分享連結', + debugShareFailed: '除錯分享失敗', + copyLink: '複製連結', + linkCopied: '連結已複製', + curator: '技能策展器', + curatorDesc: '在背景審查並封存過時的代理自建技能', + curatorPaused: '已暫停', + curatorActive: '作用中', + curatorDisabled: '已停用', + curatorLastRun: when => `上次執行 ${when}`, + curatorNeverRan: '從未執行', + pause: '暫停', + resume: '繼續', + runNow: '立即執行', + memoryData: '記憶資料', + memoryDataDesc: '注入每個工作階段的內建記憶檔案', + memoryProvider: name => `作用中提供方:${name}`, + builtinMemory: '內建', + memoryFile: '代理記憶(MEMORY.md)', + userFile: '使用者檔案(USER.md)', + bytes: size => size, + empty: '空', + resetMemory: '重設記憶', + resetUser: '重設使用者檔案', + resetAll: '兩者皆重設', + resetConfirm: target => `刪除 ${target}?此操作無法復原。`, + resetDone: files => `已刪除 ${files}。`, + resetFailed: '記憶重設失敗', + actionStarted: name => `${name} 已開始——正在追蹤記錄...`, + actionFailed: name => `${name} 啟動失敗`, + running: '執行中...', + viewLog: '操作記錄' + }, days: count => `${count} 天`, statSessions: '工作階段', statApiCalls: 'API 呼叫', @@ -1474,6 +1786,9 @@ export const zhHant = defineLocale({ noSessions: '尚無工作階段', projects: { sectionLabel: '專案', + reorder: label => `重新排列 ${label}`, + toggle: label => `切換 ${label} 的工作階段`, + back: '全部專案', newButton: '新增專案', createTitle: '新增專案', createDesc: '為工作區命名並新增一個或多個資料夾。', @@ -1544,6 +1859,9 @@ export const zhHant = defineLocale({ rename: '重新命名', archive: '封存', newWindow: '新視窗', + hideTabBar: '隱藏分頁列', + openInNewTab: '在新分頁開啟', + openInSplit: '在分割視窗開啟', copyIdFailed: '無法複製工作階段 ID', actionsFor: title => `${title} 的動作`, sessionActions: '工作階段動作', @@ -1593,6 +1911,7 @@ export const zhHant = defineLocale({ ], startVoice: '開始語音對話', queueMessage: '排隊訊息', + steer: '引導目前的執行', stop: '停止', send: '傳送', speaking: '說話中', @@ -1878,6 +2197,7 @@ export const zhHant = defineLocale({ getKey: '取得金鑰', replaceCurrent: '取代目前值', pasteApiKey: '貼上 API 金鑰', + localApiKeyPlaceholder: 'API 金鑰(選填——僅在您的端點需要時填寫)', couldNotSave: '無法儲存憑證。', connecting: '連線中', update: '更新', @@ -2195,6 +2515,10 @@ export const zhHant = defineLocale({ hideHeader: '隱藏標題列', minimize: '最小化', restore: '還原', + closeRunningTitle: '關閉執行中的分頁?', + closeRunningBody: + '此聊天仍在工作(或正在等待您的輸入)。關閉分頁只會隱藏它——工作階段會保留進度,可從側邊欄重新開啟。', + closeRunningConfirm: '關閉分頁', closeOthers: '關閉其他', closeToRight: '關閉右側', closeAll: '全部關閉', @@ -2244,6 +2568,8 @@ export const zhHant = defineLocale({ yesterday: time => `昨天,${time}`, copy: '複製', refresh: '重新整理', + expandMessage: '展開訊息', + scrollToBottom: '捲動至底部', moreActions: '更多動作', branchNewChat: '在新聊天中分支', dismissError: '关闭错误', diff --git a/apps/desktop/src/i18n/zh.ts b/apps/desktop/src/i18n/zh.ts index c682cdae57a7d..c07303ca4d714 100644 --- a/apps/desktop/src/i18n/zh.ts +++ b/apps/desktop/src/i18n/zh.ts @@ -719,7 +719,23 @@ export const zh: Translations = { failedLoad: '设置加载失败', autosaveFailed: '自动保存失败', imported: '配置已导入', - invalidJson: '配置 JSON 无效' + invalidJson: '配置 JSON 无效', + personalityLabels: { + helpful: '乐于助人', + concise: '简明扼要', + technical: '技术专家', + creative: '创意发想', + teacher: '耐心教师', + kawaii: '可爱系', + catgirl: '猫娘', + pirate: '海盗船长', + shakespeare: '莎士比亚', + surfer: '冲浪客', + noir: '黑色侦探', + uwu: 'uwu', + philosopher: '哲学家', + hype: '热血满格' + } }, credentials: { pasteKey: '粘贴密钥',