mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
i18n: one word per locale for the agent
Five locales each called the agent two different things, and one of them was a mistranslation rather than a style difference: Arabic used the word for customer, including on the agent picker's own label. Traditional Chinese turned out to be wider than it looked. The word we were treating as a synonym also means proxy in seven strings and agency in two — so the settings page was using one word for three different things, with the network-proxy hint and the agent picker reading identically. Those nine stay as they are; the other thirty-two join the rest. Bare English stays wherever it already is: it clusters on developer-facing surfaces while native words carry the user-facing ones, and that division reads deliberate. Turkish is written per key rather than replaced, because the word takes case suffixes — and because the same string is the word for tool in eight places and means "by way of" in five more. A blind replacement would have ruined thirteen unrelated lines. The Persian call is the weakest here and is marked as such: both forms are correct, and the choice rests on which one already holds the interface. The guard compares the set of keys containing each word against an explicit allow-list with the English source quoted per entry, so a new offender is reported by name rather than as a count, and the traditional-Chinese case also fails on a simplified character. The glossary gains the row it always said should be added when someone hit a real terminology choice, including why "agent" must not be translated back to the proxy word and which Turkish strings look like matches but are not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YLzsEWJ1UAjk9WjXEozQiW
This commit is contained in:
co-authored by
Claude Opus 5
parent
93a2d97d7b
commit
457f6c34e3
@@ -441,6 +441,7 @@ These mappings needed human judgment in #194 — OpenCC won't catch them and the
|
||||
|
||||
| English / context | zh-CN | zh-TW |
|
||||
| ------------------------ | --------- | --------- |
|
||||
| agent (the AI agent) | 智能体 | 智能體 |
|
||||
| fallback / safety net | 兜底 | 備援 |
|
||||
| bundle / package up | 捆绑 | 納入 |
|
||||
| live, dynamic | 活的 | 動態的 |
|
||||
@@ -451,6 +452,47 @@ These mappings needed human judgment in #194 — OpenCC won't catch them and the
|
||||
| crash, screw up (slang) | 翻车 | 出包 |
|
||||
| go viral (slang) | 出圈 | 爆紅 |
|
||||
|
||||
**Do not use 代理 for the agent.** 代理 is already the Chinese word for a network
|
||||
proxy (`settings.cliEnvTitle`, `settings.baseUrlDefaultHint`), and 代理商 is a
|
||||
marketing agency (`settings.onboardingRoleAgency`) — the Settings dialog was
|
||||
using the same word for all three. 智慧體, 智慧代理, and 代理人 were also in use
|
||||
and are retired.
|
||||
|
||||
### One word per locale for "agent"
|
||||
|
||||
`agent` drifted further than any other term in this repo: run-error cards were
|
||||
added in batches over several months, and each batch picked its own wording
|
||||
without checking the rest of the dictionary. Before this was cleaned up, zh-TW
|
||||
alone named one product concept five different ways, and `chat.runError.*` had
|
||||
become a dialect of its own in more than one language.
|
||||
|
||||
The rule is now **one word per locale**, pinned by
|
||||
`apps/web/tests/i18n/agent-term-consistency.test.ts`:
|
||||
|
||||
| Locale | Use | Retired |
|
||||
| ------ | ------ | -------------------------------- |
|
||||
| zh-CN | 智能体 | 代理 |
|
||||
| zh-TW | 智能體 | 智慧體, 智慧代理, 代理, 代理人 |
|
||||
| ar | وكيل | عميل (that word means "client") |
|
||||
| fa | عامل | ایجنت (transliteration) |
|
||||
| tr | ajan | aracı (that word means "broker") |
|
||||
|
||||
Two deliberate exceptions, both encoded in that test:
|
||||
|
||||
- **Bare English `Agent` is allowed.** Every locale keeps the English proper
|
||||
noun on developer-facing surfaces (MCP setup, integrations, `useEverywhere`)
|
||||
and translates it on end-user surfaces. That split is intentional; don't
|
||||
"fix" it.
|
||||
- **Homographs stay.** A word that merely looks like the agent term but means
|
||||
something else — a network proxy, a marketing agency, a generic tool, an MCP
|
||||
client — is allowlisted by dictionary key in the test, with the English
|
||||
source quoted alongside. Turkish is the trap worth naming: `araç` means
|
||||
"tool" and inflects to `aracı`, and `aracılığıyla` means "by way of", so a
|
||||
blind find-and-replace of `aracı` corrupts eight unrelated strings.
|
||||
|
||||
When you add a locale, add its row. When you add a run-error card, reuse the
|
||||
row rather than inventing a sixth spelling.
|
||||
|
||||
### Portuguese: pt-BR vs pt-PT
|
||||
|
||||
**Brazilian Portuguese (`pt-BR`)** differs significantly from European Portuguese:
|
||||
|
||||
@@ -742,7 +742,7 @@ export const ar: Dict = {
|
||||
'settings.mcpCodexUninstallSuccess': 'تمت الإزالة من Codex.',
|
||||
'settings.mcpCodexBusy': 'جارٍ العمل…',
|
||||
'settings.mcpCodexInstallError': 'فشلت العملية: {error}',
|
||||
'settings.mcpRestartNote': 'أعد تشغيل عميلك لالتقاط الخادم الجديد.',
|
||||
'settings.mcpRestartNote': 'أعد تشغيل وكيلك لالتقاط الخادم الجديد.',
|
||||
'settings.mcpRestartDetail': 'معظم المحررات تُحمّل خوادم MCP عند بدء التشغيل فقط. في Cursor / VS Code / Antigravity / Windsurf يمكنك تشغيل `Developer: Reload Window` من Command Palette بدلًا من إعادة التشغيل الكاملة. أما Zed و Claude Code فيحتاجان إلى الإغلاق وإعادة الفتح.',
|
||||
'settings.mcpCapabilitiesTitle': 'ما يستطيع Agent القيام به',
|
||||
'settings.mcpCapabilityRead': 'قراءة أي ملف في المشروع أو البحث فيه (HTML، JSX، CSS، JSON، SVG، Markdown).',
|
||||
@@ -2052,9 +2052,9 @@ export const ar: Dict = {
|
||||
'inlineSwitcher.chipCli': 'CLI محلي',
|
||||
'inlineSwitcher.chipByok': 'BYOK',
|
||||
'inlineSwitcher.modelDefault': 'افتراضي',
|
||||
'inlineSwitcher.noAgent': 'لا يوجد عميل',
|
||||
'inlineSwitcher.noAgent': 'لا يوجد وكيل',
|
||||
'inlineSwitcher.modeLabel': 'الوضع',
|
||||
'inlineSwitcher.agentLabel': 'عميل',
|
||||
'inlineSwitcher.agentLabel': 'وكيل',
|
||||
'inlineSwitcher.providerLabel': 'المزود',
|
||||
'inlineSwitcher.modelLabel': 'النموذج',
|
||||
'inlineSwitcher.useCli': 'استخدام CLI محلي',
|
||||
|
||||
@@ -76,13 +76,13 @@ export const fa: Dict = {
|
||||
'chat.amrBalanceGate.message': 'اعتبار کافی نیست (باقیمانده {balance}). پس از ارتقای طرح یا شارژ، وظیفه بلافاصله شروع میشود.',
|
||||
'chat.amrBalanceGate.benefitsTitle': 'آنچه OpenDesign Cloud به شما میدهد',
|
||||
'chat.amrBalanceGate.benefit1': 'بدون کلید API، مدلهای فراوان در دسترس',
|
||||
'chat.amrBalanceGate.benefit2': 'ایجنت طراحی SOTA داخلی، بدون پیکربندی',
|
||||
'chat.amrBalanceGate.benefit2': 'عامل طراحی SOTA داخلی، بدون پیکربندی',
|
||||
'chat.amrBalanceGate.benefit3': 'سرویس رسمی و قابل اعتماد',
|
||||
'chat.amrBalanceGate.benefit4': 'بهروزرسانی مداوم: انتشار تککلیکی، چندوجهی، نسخه تیمی و موارد دیگر',
|
||||
'chat.amrBalanceGate.laterCta': 'حالا نه',
|
||||
'chat.amrBalanceGate.plansCta': 'ارتقای طرح',
|
||||
'chat.amrBalanceGate.signedOutTitle': 'برای شروع خلق وارد شوید',
|
||||
'chat.amrBalanceGate.signedOutMessage': 'شما از ایجنت OpenDesign Cloud استفاده میکنید — وارد شوید تا این وظیفه بلافاصله شروع شود.',
|
||||
'chat.amrBalanceGate.signedOutMessage': 'شما از عامل OpenDesign Cloud استفاده میکنید — وارد شوید تا این وظیفه بلافاصله شروع شود.',
|
||||
'chat.amrBalanceGate.signInCta': 'ورود',
|
||||
'chat.amrBalanceGate.watchingWallet': 'بهمحض بهروزرسانی موجودی، بهطور خودکار ادامه میدهیم.',
|
||||
'chat.amrLowBalance.title': 'اعتبار رو به اتمام است',
|
||||
@@ -1880,8 +1880,8 @@ export const fa: Dict = {
|
||||
'newproj.promptTemplateSearch': 'جستوجوی قالبها…',
|
||||
'newproj.promptTemplateEmpty': 'هنوز قالبی برای این نوع نصب نشده است.',
|
||||
'newproj.promptTemplateBodyLabel': 'پرامپت (قابل ویرایش)',
|
||||
'newproj.promptTemplateOptimizeHint': 'هر چیزی را میتوانید ویرایش کنید — تغییرات شما به بریف ایجنت اضافه میشود.',
|
||||
'newproj.promptTemplateBodyEmpty': 'متن خالی است — ایجنت هیچ مرجع قالبی دریافت نمیکند.',
|
||||
'newproj.promptTemplateOptimizeHint': 'هر چیزی را میتوانید ویرایش کنید — تغییرات شما به بریف عامل اضافه میشود.',
|
||||
'newproj.promptTemplateBodyEmpty': 'متن خالی است — عامل هیچ مرجع قالبی دریافت نمیکند.',
|
||||
'newproj.deleteTemplateTitle': 'حذف قالب',
|
||||
'newproj.deleteTemplateConfirm': 'آیا «{name}» حذف شود؟ این عمل قابل بازگشت نیست.',
|
||||
'newproj.deleteTemplateConfirmCta': 'حذف قالب',
|
||||
@@ -3658,7 +3658,7 @@ export const fa: Dict = {
|
||||
'critiqueTheater.belowThresholdBadge': 'زیر آستانه',
|
||||
'critiqueTheater.timedOutBadge': 'زمان به پایان رسید',
|
||||
'critiqueTheater.failedHeading': 'اجرا ناموفق بود',
|
||||
'critiqueTheater.failedReasonCliExit': 'CLI ایجنت پیش از پایان کار پنل با کد غیرصفر خارج شد.',
|
||||
'critiqueTheater.failedReasonCliExit': 'CLI عامل پیش از پایان کار پنل با کد غیرصفر خارج شد.',
|
||||
'critiqueTheater.failedReasonPerRoundTimeout': 'یک دور از بودجه زمانی خود فراتر رفت.',
|
||||
'critiqueTheater.failedReasonTotalTimeout': 'کل اجرا از بودجه زمانی کل خود فراتر رفت.',
|
||||
'critiqueTheater.failedReasonOrchestrator': 'خطای داخلی هماهنگکننده.',
|
||||
@@ -3671,8 +3671,8 @@ export const fa: Dict = {
|
||||
'critiqueTheater.replaySpeedFast': 'سریع',
|
||||
'critiqueTheater.settingsNav': 'هیئت داوران طراحی',
|
||||
'critiqueTheater.settingsNavHint': 'بررسی طراحی پنجپنلی برای اجراهای شما',
|
||||
'critiqueTheater.settingsEnabledLabel': 'نمایش هیئت داوران طراحی در حین اجرای ایجنت',
|
||||
'critiqueTheater.settingsEnabledDescription': 'وقتی فعال باشد، یک بررسی پنجپنلی در کنار تولیدات ایجنت ظاهر میشود و پیش از انتشار به خروجی امتیاز میدهد. میتوانید هر زمان آن را متوقف کنید.',
|
||||
'critiqueTheater.settingsEnabledLabel': 'نمایش هیئت داوران طراحی در حین اجرای عامل',
|
||||
'critiqueTheater.settingsEnabledDescription': 'وقتی فعال باشد، یک بررسی پنجپنلی در کنار تولیدات عامل ظاهر میشود و پیش از انتشار به خروجی امتیاز میدهد. میتوانید هر زمان آن را متوقف کنید.',
|
||||
'critiqueTheater.settingsEnabledProjectHint': 'برای این پروژه ذخیره شد. اجراهای جدید در این پروژه از سمت سرور از طریق هیئت داوران طراحی هدایت میشوند.',
|
||||
'critiqueTheater.settingsEnabledNoProjectHint': 'برای ماندگار کردن این تنظیم در سمت سرور، یک پروژه باز کنید. تا آن زمان، این فقط ترجیح درونمرورگر را تغییر میدهد.',
|
||||
'pet.title': 'حیوان خانگی',
|
||||
@@ -3710,11 +3710,11 @@ export const fa: Dict = {
|
||||
'pet.overlayAria': 'همراه حیوان خانگی',
|
||||
'pet.spriteAria': '{name} — برای جابجایی بکشید، برای گفتوگو کلیک کنید',
|
||||
'pet.spriteTitle': 'سلام از طرف {name}! برای گفتوگو کلیک کنید.',
|
||||
'pet.taskSummarySingle': '{count} وظیفه ایجنت در حال اجراست.',
|
||||
'pet.taskSummaryMultiple': '{count} وظیفه ایجنت در {projects} پروژه در حال اجراست.',
|
||||
'pet.taskSummaryRecentSingle': '{count} وظیفه ایجنت اخیراً تکمیل شد.',
|
||||
'pet.taskSummaryRecentMultiple': '{count} وظیفه ایجنت اخیراً تکمیل شدند.',
|
||||
'pet.taskListAria': 'وظایف فعال ایجنت',
|
||||
'pet.taskSummarySingle': '{count} وظیفه عامل در حال اجراست.',
|
||||
'pet.taskSummaryMultiple': '{count} وظیفه عامل در {projects} پروژه در حال اجراست.',
|
||||
'pet.taskSummaryRecentSingle': '{count} وظیفه عامل اخیراً تکمیل شد.',
|
||||
'pet.taskSummaryRecentMultiple': '{count} وظیفه عامل اخیراً تکمیل شدند.',
|
||||
'pet.taskListAria': 'وظایف فعال عامل',
|
||||
'pet.taskOpenProject': 'باز کردن {project}',
|
||||
'pet.taskGroup.running': 'در حال اجرا',
|
||||
'pet.taskGroup.queued': 'در انتظار',
|
||||
|
||||
@@ -116,17 +116,17 @@ export const tr: Dict = {
|
||||
'chat.runError.title.membershipConcurrencyLimit': 'Eşzamanlı görev sınırına ulaşıldı',
|
||||
'chat.runError.title.strategyTaskHalted': "Görev kalite kapısı tarafından durduruldu",
|
||||
'chat.runError.title.agentReplyIncomplete': "Yanıt geldi ama kaydedilemedi",
|
||||
'chat.runError.title.clarificationRepeated': "Aracı bir soru daha sordu",
|
||||
'chat.runError.title.clarificationRepeated': "Ajan bir soru daha sordu",
|
||||
'chat.runError.title.clientEnvironment': 'Ağ ortamı sorunu',
|
||||
'chat.runError.title.generic': 'Görev başarısız',
|
||||
'chat.runError.title.artifactMissing': 'Teslim edilebilir çıktı oluşturulmadı',
|
||||
'chat.runError.signInMessage.amr': 'OpenDesign Cloud aracısı henüz oturum açmadı — kullanmaya başlamak için oturum açın.',
|
||||
'chat.runError.signInMessage.other': '{agent} oturum açmadı. Oturum durumunu yerel olarak kontrol edin. Daha kararlı ve hesaplı OpenDesign Cloud aracısını öneririz.',
|
||||
'chat.runError.agentFallback': 'aracı',
|
||||
'chat.runError.signInMessage.amr': 'OpenDesign Cloud ajanı henüz oturum açmadı — kullanmaya başlamak için oturum açın.',
|
||||
'chat.runError.signInMessage.other': '{agent} oturum açmadı. Oturum durumunu yerel olarak kontrol edin. Daha kararlı ve hesaplı OpenDesign Cloud ajanını öneririz.',
|
||||
'chat.runError.agentFallback': 'ajan',
|
||||
'chat.runError.sourceLabel': 'Hata ayrıntıları',
|
||||
'chat.runError.sourceExpandAria': 'Hata kaynağını genişlet',
|
||||
'chat.runError.sourceCollapseAria': 'Hata kaynağını daralt',
|
||||
'chat.runError.title.cliMissing': 'Aracı yüklü değil',
|
||||
'chat.runError.title.cliMissing': 'Ajan yüklü değil',
|
||||
'chat.runError.title.promptTooLarge': 'Giriş çok uzun',
|
||||
'chat.runError.title.modelUnavailable': 'Model kullanılamıyor',
|
||||
'chat.runError.title.upstreamUnavailable': 'Hizmet geçici olarak kullanılamıyor',
|
||||
@@ -139,28 +139,28 @@ export const tr: Dict = {
|
||||
'chat.runError.rateLimitedMessage': 'Model hizmetinin kullanım sınırına ulaştınız. Biraz bekleyip yeniden deneyin ya da başka bir modele veya hizmete geçin.',
|
||||
'chat.runError.modelWindowLimitMessage': 'Şu anda yoğunluk var. {retryAt} sonrasında tekrar deneyin. Bu istek için ücret alınmadı.',
|
||||
'chat.runError.modelWindowLimitMessageNoTime': 'Şu anda yoğunluk var. Kısa süre sonra tekrar deneyin. Bu istek için ücret alınmadı.',
|
||||
'chat.runError.membershipConcurrencyLimitMessage': 'Üyeliğinizin eşzamanlı görev sınırı dolu. {retryAt} saatine kadar bekleyip yeniden deneyin veya başka bir aracıya geçin. Hemen yeniden denemek yardımcı olmaz.',
|
||||
'chat.runError.membershipConcurrencyLimitMessageNoTime': 'Üyeliğinizin eşzamanlı görev sınırı dolu. Başka bir görev bitince yeniden deneyin veya başka bir aracıya geçin.',
|
||||
'chat.runError.membershipConcurrencyLimitMessage': 'Üyeliğinizin eşzamanlı görev sınırı dolu. {retryAt} saatine kadar bekleyip yeniden deneyin veya başka bir ajana geçin. Hemen yeniden denemek yardımcı olmaz.',
|
||||
'chat.runError.membershipConcurrencyLimitMessageNoTime': 'Üyeliğinizin eşzamanlı görev sınırı dolu. Başka bir görev bitince yeniden deneyin veya başka bir ajana geçin.',
|
||||
'chat.runError.upstreamUnavailableMessage': 'Model hizmeti geçici olarak kullanılamıyor — genellikle üst kaynak kararsızlığı veya bir ağ/proxy sorunu. Birazdan yeniden deneyin.',
|
||||
'chat.runError.toolLoopMessage': '{agent} aynı işlemi ilerleme olmadan tekrarladı ve durduruldu. Hedef dosyayı veya komutu kontrol edip yeniden deneyin.',
|
||||
'chat.runError.outputInvalidMessage': 'Model geçersiz çıktı üretti ve bu tur kesildi. Yeniden denemek genellikle sorunu giderir.',
|
||||
'chat.runError.runtimeConfigMessage': 'Seçilen aracının çalışma zamanı yapılandırması geçersiz, bu yüzden çalıştırma başlatılamadı. En son sürüme güncelleyin veya destek ile iletişime geçin.',
|
||||
'chat.runError.runtimeConfigMessage': 'Seçilen ajanın çalışma zamanı yapılandırması geçersiz, bu yüzden çalıştırma başlatılamadı. En son sürüme güncelleyin veya destek ile iletişime geçin.',
|
||||
'chat.runError.title.quotaExhausted': "Kota doldu",
|
||||
'chat.runError.title.timedOut': "Zaman aşımı",
|
||||
'chat.runError.title.emptyOutput': "Çıktı yok",
|
||||
'chat.runError.title.sessionExpired': "Oturum süresi doldu",
|
||||
'chat.runError.title.gitBashMissing': "Git Bash yok",
|
||||
'chat.runError.title.cpuUnsupported': "İşlemci desteklenmiyor",
|
||||
'chat.runError.title.cliSessionRefused': "Aracı sürümü uyumsuz",
|
||||
'chat.runError.title.cliSessionRefused': "Ajan sürümü uyumsuz",
|
||||
'chat.runError.quotaExhaustedMessage': "Model hizmetinizin kotası veya faturalandırma limiti doldu, bu yüzden yeniden denemek işe yaramaz. Sağlayıcınızda bakiye yükleyin ya da başka bir modele veya hizmete geçin.",
|
||||
'chat.runError.workspaceCreditsMessage': "Çalışma alanınızın kredisi bitti. Kredi ekleyin (veya çalışma alanı sahibinden yükleme yapmasını isteyin) ya da başka bir modele veya hizmete geçin.",
|
||||
'chat.runError.timedOutMessage': "Bu çalışma çok uzun sürdü ve durduruldu. Yeniden deneyin veya görevi küçültüp tekrar deneyin.",
|
||||
'chat.runError.inactivityTimeoutMessage': "Aracı çok uzun süre yeni çıktı üretmedi ve zaman aşımı nedeniyle durduruldu. Yeniden denemek genellikle onu sürdürür.",
|
||||
'chat.runError.emptyOutputMessage': "Aracı herhangi bir çıktı üretmeden sona erdi. Bu genellikle geçicidir, yeniden deneyin.",
|
||||
'chat.runError.inactivityTimeoutMessage': "Ajan çok uzun süre yeni çıktı üretmedi ve zaman aşımı nedeniyle durduruldu. Yeniden denemek genellikle onu sürdürür.",
|
||||
'chat.runError.emptyOutputMessage': "Ajan herhangi bir çıktı üretmeden sona erdi. Bu genellikle geçicidir, yeniden deneyin.",
|
||||
'chat.runError.sessionExpiredMessage': "Sürdürülen oturumun süresi dolmuştu. Sıfırlandı, bu yüzden yeni bir çalışma başlatmak için yeniden deneyin.",
|
||||
'chat.runError.gitBashMissingMessage': "Bu aracıyı Windows'ta çalıştırmak için Git Bash gerekir ancak bulunamadı. Git for Windows'u kurup yeniden deneyin.",
|
||||
'chat.runError.cpuUnsupportedMessage': "Bu aracının çalışma zamanı, bu cihazın CPU'sunda bulunmayan bir komut seti (AVX2) gerektirdiğinden başlatılamıyor. Uyumlu çalışma zamanı içeren en son OpenDesign sürümüne güncelleyin.",
|
||||
'chat.runError.title.agentCrashed': 'Aracı beklenmedik şekilde kapandı',
|
||||
'chat.runError.gitBashMissingMessage': "Bu ajanı Windows'ta çalıştırmak için Git Bash gerekir ancak bulunamadı. Git for Windows'u kurup yeniden deneyin.",
|
||||
'chat.runError.cpuUnsupportedMessage': "Bu ajanın çalışma zamanı, bu cihazın CPU'sunda bulunmayan bir komut seti (AVX2) gerektirdiğinden başlatılamıyor. Uyumlu çalışma zamanı içeren en son OpenDesign sürümüne güncelleyin.",
|
||||
'chat.runError.title.agentCrashed': 'Ajan beklenmedik şekilde kapandı',
|
||||
'chat.runError.agentCrashedMessage': '{agent} nedenini söylemeden kapandı. Yeniden denemek genelde işe yarar; sürekli oluyorsa günlükleri bize gönderin.',
|
||||
'chat.runError.title.accountSuspended': 'Hesap geçici olarak askıya alındı',
|
||||
'chat.runError.accountSuspendedMessage': 'Bu hesapta olağan dışı bir ödeme riski tespit ettik. Yanlışlık olduğunu düşünüyorsanız bize ulaşın, inceleyelim.',
|
||||
@@ -168,8 +168,8 @@ export const tr: Dict = {
|
||||
'chat.runError.cliSessionRefusedMessage':
|
||||
"{agent} bir oturum başlatmayı reddetti. Yüklü sürüm genellikle Open Design ile uyumlu değildir; farklı bir sürüme geçip yeniden deneyin.",
|
||||
'chat.runError.strategyTaskStateMismatchMessage': "Bu görev, strateji kalite kapısı tarafından zaten durdurulduğundan formun bu turu devam edemiyor. İsteği yeniden deneyin veya yeni bir istek başlatın.",
|
||||
'chat.runError.agentReplyIncompleteMessage': "Aracının yanıtı, bu adımı kaydetmek için Open Design tarafından beklenen işaret olmadan geldi; bu yüzden görev ilerleyemedi. Gönderdiklerinizin hiçbiri kaybolmadı, bu ara sıra olan bir durum ve yeniden denemek genelde işe yarar.",
|
||||
'chat.runError.clarificationRepeatedMessage': "Aracı ikinci kez daha fazla ayrıntı istedi, ancak bir görevde yalnızca tek bir soru turuna yer var; bu yüzden burada durdu. Verdiğiniz yanıtlar konuşmada duruyor — tekrar denemek isteği baştan çalıştırır ve eklemek istediğiniz ayrıntıları en baştan yazarsanız genellikle tek tur yeter.",
|
||||
'chat.runError.agentReplyIncompleteMessage': "Ajanın yanıtı, bu adımı kaydetmek için Open Design tarafından beklenen işaret olmadan geldi; bu yüzden görev ilerleyemedi. Gönderdiklerinizin hiçbiri kaybolmadı, bu ara sıra olan bir durum ve yeniden denemek genelde işe yarar.",
|
||||
'chat.runError.clarificationRepeatedMessage': "Ajan ikinci kez daha fazla ayrıntı istedi, ancak bir görevde yalnızca tek bir soru turuna yer var; bu yüzden burada durdu. Verdiğiniz yanıtlar konuşmada duruyor — tekrar denemek isteği baştan çalıştırır ve eklemek istediğiniz ayrıntıları en baştan yazarsanız genellikle tek tur yeter.",
|
||||
'chat.runError.clientEnvironmentMessage': 'İstek bir proxy veya kurumsal ağ üzerinden gitmiş görünüyor ve {agent} onu reddetti ({cause}). Farklı bir ağ çıkışı deneyin ya da Ayarlardan proxy ayarını değiştirin.',
|
||||
'chat.runError.clientEnvironmentCause.certificate': 'sertifika doğrulaması başarısız',
|
||||
'chat.runError.clientEnvironmentCause.proxy': 'proxy yapılandırması sorunu',
|
||||
@@ -3822,7 +3822,7 @@ export const tr: Dict = {
|
||||
'settings.notifySoundTwoToneDown': 'Alçalan iki ton',
|
||||
'settings.notifySoundThud': 'Boğuk vuruş',
|
||||
'settings.skills': 'Yetenekler',
|
||||
'settings.skillsHint': 'Aracının görev sırasında çağırabileceği işlevsel yetenekler',
|
||||
'settings.skillsHint': 'Ajanın görev sırasında çağırabileceği işlevsel yetenekler',
|
||||
'settings.skillsNew': 'Yeni yetenek',
|
||||
'settings.skillsEmpty': 'Soldan bir yetenek seçin veya yeni bir yetenek oluşturun.',
|
||||
'settings.skillsEdit': 'Düzenle',
|
||||
|
||||
@@ -442,7 +442,7 @@ export const zhCN: Dict = {
|
||||
"settings.modeAria": "执行模式",
|
||||
"settings.protocolAria": "API 协议",
|
||||
"settings.modeDaemon": "本机 CLI",
|
||||
"settings.modeDaemonHelp": "通过本机的代码代理 CLI 执行",
|
||||
"settings.modeDaemonHelp": "通过本机的代码智能体 CLI 执行",
|
||||
"settings.modeDaemonOffline": "后台守护进程未运行",
|
||||
"settings.modeDaemonOfflineMeta": "守护进程未运行",
|
||||
"settings.modeDaemonInstalledMeta": "已安装 {count} 个",
|
||||
@@ -455,7 +455,7 @@ export const zhCN: Dict = {
|
||||
"BYOK 无法读写或修改项目文件;需要改代码时请使用本机 CLI。",
|
||||
"settings.byokDraftNotice":
|
||||
"填写必填项后即可保存此提供商;当前配置将继续保持生效。",
|
||||
"settings.codeAgent": "代码代理",
|
||||
"settings.codeAgent": "代码智能体",
|
||||
"settings.codeAgentHint": "选择用来运行提示词的 CLI。",
|
||||
"settings.rescan": "↻ 重新扫描",
|
||||
"settings.rescanTitle": "重新扫描 PATH",
|
||||
@@ -490,13 +490,13 @@ export const zhCN: Dict = {
|
||||
"settings.agentInstall.pathHint":
|
||||
"如果你通过 npm 或 Homebrew 安装了 CLI,但仍显示为未安装,请确认该工具的 bin 目录已加入 OpenDesign daemon 继承的 PATH(在 macOS 上,Terminal 与 GUI 应用的 PATH 可能不同)。请参阅 QUICKSTART.md(“Local agent CLI and PATH” 章节)。",
|
||||
"settings.agentInstall.stepOpenLinks":
|
||||
"在目标代理卡片上打开“安装”或“文档”链接。",
|
||||
"在目标智能体卡片上打开“安装”或“文档”链接。",
|
||||
"settings.agentInstall.stepAuth":
|
||||
"返回 OpenDesign 之前,请先在对应 CLI 中完成认证(登录或添加 API 凭据)。",
|
||||
"settings.agentInstall.stepRescan": "在此区域点击“重新扫描”。",
|
||||
"settings.agentInstall.stepSelect": "当代理显示为已安装后,选择该代理卡片。",
|
||||
"settings.agentInstall.stepSelect": "当智能体显示为已安装后,选择该智能体卡片。",
|
||||
"settings.noAgentsDetected":
|
||||
"尚未检测到任何代理。请安装 Claude Code、Codex、OpenCode、Cursor Agent、Qwen 或 GitHub Copilot CLI 中的一个,然后点击「重新扫描」。",
|
||||
"尚未检测到任何智能体。请安装 Claude Code、Codex、OpenCode、Cursor Agent、Qwen 或 GitHub Copilot CLI 中的一个,然后点击「重新扫描」。",
|
||||
"settings.agentInstalledGroup": "你的 CLI({count})",
|
||||
"settings.agentInstallGroup": "可安装({count})",
|
||||
"settings.agentAuthRequired": "需要认证",
|
||||
@@ -614,7 +614,7 @@ export const zhCN: Dict = {
|
||||
"settings.dshSetupInstalling": "正在安装…",
|
||||
"settings.dshSetupRequired": "需要安装连接组件",
|
||||
"settings.anthropicApi": "Anthropic API",
|
||||
"settings.noAgentSelected": "尚未选择代理",
|
||||
"settings.noAgentSelected": "尚未选择智能体",
|
||||
"settings.language": "界面语言",
|
||||
"settings.languageHint": "切换界面语言,设置仅保存在当前浏览器。",
|
||||
"settings.agentModelHead": "模型:",
|
||||
@@ -648,7 +648,7 @@ export const zhCN: Dict = {
|
||||
"settings.mediaProvidersHint": "连接图片、视频、音频和搜索提供商。",
|
||||
"settings.mcpServerTitle": "OpenDesign MCP",
|
||||
"settings.mcpServerHint":
|
||||
"将 OpenDesign 作为 MCP 服务器暴露给你的编码代理。",
|
||||
"将 OpenDesign 作为 MCP 服务器暴露给你的编码智能体。",
|
||||
"settings.externalMcpTitle": "外部 MCP",
|
||||
"settings.externalMcpHint":
|
||||
"接入外部服务的 MCP 工具(Higgsfield、GitHub 等)。",
|
||||
@@ -1732,7 +1732,7 @@ export const zhCN: Dict = {
|
||||
"routines.errorPickProject":
|
||||
"请选择要复用的项目,或切换为“每次运行新建项目”。",
|
||||
"routines.errorAgentEmptyOutput":
|
||||
"代理已完成运行但未产生任何输出。模型或提供商可能返回了空响应,请检查代理日志中的上游错误。",
|
||||
"智能体已完成运行但未产生任何输出。模型或提供商可能返回了空响应,请检查智能体日志中的上游错误。",
|
||||
"entry.githubStarLabel": "Star",
|
||||
"entry.githubStarTitle": "为我们在 GitHub 点亮 Star",
|
||||
"entry.githubStarAria": "在 GitHub 上为 OpenDesign 点亮 Star",
|
||||
@@ -1767,7 +1767,7 @@ export const zhCN: Dict = {
|
||||
"connectors.aboutLabel": "简介",
|
||||
"connectors.detailsLabel": "详情",
|
||||
"connectors.statusLabel": "状态",
|
||||
"connectors.category.aiAgents": "AI 代理",
|
||||
"connectors.category.aiAgents": "AI 智能体",
|
||||
"connectors.category.aiInfrastructure": "AI 基础设施",
|
||||
"connectors.category.accounting": "会计",
|
||||
"connectors.category.admin": "管理",
|
||||
@@ -1920,14 +1920,14 @@ export const zhCN: Dict = {
|
||||
"newproj.designSystem": "设计体系",
|
||||
"newproj.dsNoneFreeform": "不指定 — 自由发挥",
|
||||
"newproj.dsNoneSubtitleEmpty": "不使用体系 token,由你决定整体配色",
|
||||
"newproj.dsNoneSubtitleSelected": "跳过体系 token,由代理自行选择配色。",
|
||||
"newproj.dsNoneSubtitleSelected": "跳过体系 token,由智能体自行选择配色。",
|
||||
"newproj.dsCategoryFallback": "设计体系",
|
||||
"newproj.dsSearch": "搜索设计体系…",
|
||||
"newproj.dsModeAria": "选择模式",
|
||||
"newproj.dsModeSingle": "单选",
|
||||
"newproj.dsModeMulti": "多选",
|
||||
"newproj.dsNoneTitle": "不指定 — 自由发挥",
|
||||
"newproj.dsNoneSub": "跳过体系 token,由代理自行选择配色。",
|
||||
"newproj.dsNoneSub": "跳过体系 token,由智能体自行选择配色。",
|
||||
"newproj.dsEmpty": "没有匹配「{query}」的设计体系。",
|
||||
"newproj.dsFootSingular": "只作为灵感参考。",
|
||||
"newproj.dsFootPlural": "只作为灵感参考。",
|
||||
@@ -2103,7 +2103,7 @@ export const zhCN: Dict = {
|
||||
"avatar.anthropicApi": "Anthropic API",
|
||||
"avatar.useLocal": "使用本机 CLI",
|
||||
"avatar.useApi": "使用 API · BYOK",
|
||||
"avatar.codeAgent": "代码代理",
|
||||
"avatar.codeAgent": "代码智能体",
|
||||
"avatar.rescan": "重新扫描 PATH",
|
||||
"avatar.amrConsole": "OpenDesign Cloud 账户",
|
||||
"avatar.amrConsoleMeta": "余额与充值",
|
||||
@@ -2112,7 +2112,7 @@ export const zhCN: Dict = {
|
||||
"avatar.metaActive": "使用中",
|
||||
"avatar.metaOffline": "未运行",
|
||||
"avatar.metaSelected": "已选",
|
||||
"avatar.noAgentSelected": "尚未选择代理",
|
||||
"avatar.noAgentSelected": "尚未选择智能体",
|
||||
"avatar.modelSection": "模型",
|
||||
"avatar.modelLabel": "模型",
|
||||
"avatar.reasoningLabel": "推理",
|
||||
@@ -2149,7 +2149,7 @@ export const zhCN: Dict = {
|
||||
"inlineSwitcher.modelDefault": "默认",
|
||||
"inlineSwitcher.noAgent": "未选择",
|
||||
"inlineSwitcher.modeLabel": "模式",
|
||||
"inlineSwitcher.agentLabel": "代理",
|
||||
"inlineSwitcher.agentLabel": "智能体",
|
||||
"inlineSwitcher.providerLabel": "服务商",
|
||||
"inlineSwitcher.modelLabel": "模型",
|
||||
"inlineSwitcher.useCli": "使用本地 CLI",
|
||||
@@ -3414,7 +3414,7 @@ export const zhCN: Dict = {
|
||||
"fileViewer.exportPdf": "导出为 PDF",
|
||||
"fileViewer.exportPdfAllSlides": "导出为 PDF(全部幻灯片)",
|
||||
"fileViewer.exportPptxBusy": "请等待当前任务完成。",
|
||||
"fileViewer.exportPptxHint": "请求代理将此设计转换为 PPTX。",
|
||||
"fileViewer.exportPptxHint": "请求智能体将此设计转换为 PPTX。",
|
||||
"fileViewer.exportPptxNa": "此处暂不支持导出 PPTX。",
|
||||
'fileViewer.exportDaemonUnreachable': '无法连接到 daemon,请重试。',
|
||||
"fileViewer.exportZip": "下载为 .zip",
|
||||
@@ -3729,7 +3729,7 @@ export const zhCN: Dict = {
|
||||
"assistant.possiblePromptInjection": "可能的提示词注入",
|
||||
"assistant.designSystemDirectionLocked": "已选择当前设计系统,视觉方向已锁定。",
|
||||
"assistant.waitingFirstOutput": "等待首批输出中",
|
||||
"assistant.statusBootingAgent": "正在启动代理",
|
||||
"assistant.statusBootingAgent": "正在启动智能体",
|
||||
"assistant.statusPreparing": "准备中…",
|
||||
"assistant.statusStarting": "启动中",
|
||||
"assistant.statusRequesting": "正在发送请求",
|
||||
@@ -3786,9 +3786,9 @@ export const zhCN: Dict = {
|
||||
"qf.otherOption": "其他",
|
||||
"qf.ownAnswer": "自己填",
|
||||
"qf.required": "必填",
|
||||
"qf.lockedSubmitted": "答案已发送,代理将在本次会话后续使用。",
|
||||
"qf.lockedSubmitted": "答案已发送,智能体将在本次会话后续使用。",
|
||||
"qf.lockedPrev": "该表单来自此前的对话。",
|
||||
"qf.hint": "挑选合适的选项;可选项可以跳过,代理会使用合理的默认值。",
|
||||
"qf.hint": "挑选合适的选项;可选项可以跳过,智能体会使用合理的默认值。",
|
||||
"qf.submitDefault": "下一步",
|
||||
"qf.submitDisabledTitle": "请先填写必填项",
|
||||
"qf.submitTitle": "下一步",
|
||||
@@ -3861,10 +3861,10 @@ export const zhCN: Dict = {
|
||||
"critiqueTheater.replaySpeedLive": "实时",
|
||||
"critiqueTheater.replaySpeedFast": "快进",
|
||||
"critiqueTheater.settingsNav": "设计评审团",
|
||||
"critiqueTheater.settingsNavHint": "为代理运行启用五人设计评审",
|
||||
"critiqueTheater.settingsEnabledLabel": "在代理运行期间显示设计评审团",
|
||||
"critiqueTheater.settingsNavHint": "为智能体运行启用五人设计评审",
|
||||
"critiqueTheater.settingsEnabledLabel": "在智能体运行期间显示设计评审团",
|
||||
"critiqueTheater.settingsEnabledDescription":
|
||||
"启用后,五人评审面板会在代理生成时同时显示,并在交付前对结果评分。你可以随时中断。",
|
||||
"启用后,五人评审面板会在智能体生成时同时显示,并在交付前对结果评分。你可以随时中断。",
|
||||
"critiqueTheater.settingsEnabledProjectHint":
|
||||
"已为该项目保存。该项目的新运行将在服务端经过设计评审团。",
|
||||
"critiqueTheater.settingsEnabledNoProjectHint":
|
||||
@@ -4628,7 +4628,7 @@ export const zhCN: Dict = {
|
||||
"automations.templatesEmptyBody": "换一个筛选条件,或从空白自动化开始。",
|
||||
"automations.useTemplate": "使用模板",
|
||||
"automations.promptPlaceholder":
|
||||
"告诉代理按此计划运行什么,或用 @ 提及上下文...",
|
||||
"告诉智能体按此计划运行什么,或用 @ 提及上下文...",
|
||||
"automations.runHistoryLoading": "正在加载运行历史…",
|
||||
"automations.runHistoryEmpty": "还没有运行记录。",
|
||||
"automations.runHistoryTitle": "运行历史",
|
||||
|
||||
@@ -120,19 +120,19 @@ export const zhTW: Dict = {
|
||||
"chat.runError.title.membershipConcurrencyLimit": "並行任務已達上限",
|
||||
"chat.runError.title.strategyTaskHalted": "任務已被品質門攔下",
|
||||
"chat.runError.title.agentReplyIncomplete": "回覆已收到,但沒能記錄下來",
|
||||
"chat.runError.title.clarificationRepeated": "智慧體又問了一個問題",
|
||||
"chat.runError.title.clarificationRepeated": "智能體又問了一個問題",
|
||||
"chat.runError.title.clientEnvironment": "網路環境不對",
|
||||
"chat.runError.title.generic": "任務執行失敗",
|
||||
"chat.runError.title.artifactMissing": "未產生檔案產物",
|
||||
"chat.runError.signInMessage.amr":
|
||||
"OpenDesign Cloud 智慧體尚未登入,前往登入即可正常使用",
|
||||
"OpenDesign Cloud 智能體尚未登入,前往登入即可正常使用",
|
||||
"chat.runError.signInMessage.other":
|
||||
"{agent}尚未登入,請在本機檢查登入狀態。推薦使用 OpenDesign Cloud 智慧體,更穩定划算",
|
||||
"chat.runError.agentFallback": "智慧體",
|
||||
"{agent}尚未登入,請在本機檢查登入狀態。推薦使用 OpenDesign Cloud 智能體,更穩定划算",
|
||||
"chat.runError.agentFallback": "智能體",
|
||||
"chat.runError.sourceLabel": "查看錯誤詳情",
|
||||
"chat.runError.sourceExpandAria": "展開錯誤原始碼",
|
||||
"chat.runError.sourceCollapseAria": "收合錯誤原始碼",
|
||||
"chat.runError.title.cliMissing": "智慧體尚未安裝",
|
||||
"chat.runError.title.cliMissing": "智能體尚未安裝",
|
||||
"chat.runError.title.promptTooLarge": "內容過長",
|
||||
"chat.runError.title.modelUnavailable": "模型不可用",
|
||||
"chat.runError.title.upstreamUnavailable": "服務暫時無法使用",
|
||||
@@ -145,19 +145,19 @@ export const zhTW: Dict = {
|
||||
"chat.runError.rateLimitedMessage": "已觸發模型服務的用量上限。請稍後重試,或切換到其他模型/服務。",
|
||||
"chat.runError.modelWindowLimitMessage": "高峰期繁忙,請在 {retryAt} 後嘗試(本次請求未扣費)",
|
||||
"chat.runError.modelWindowLimitMessageNoTime": "高峰期繁忙,請稍後再試(本次請求未扣費)",
|
||||
"chat.runError.membershipConcurrencyLimitMessage": "目前會員的並行任務已滿。請等到 {retryAt} 後重試,或切換到其他智慧代理;立即重試不會恢復。",
|
||||
"chat.runError.membershipConcurrencyLimitMessageNoTime": "目前會員的並行任務已滿。請等待其他任務結束後重試,或切換到其他智慧代理;立即重試不會恢復。",
|
||||
"chat.runError.membershipConcurrencyLimitMessage": "目前會員的並行任務已滿。請等到 {retryAt} 後重試,或切換到其他智能體;立即重試不會恢復。",
|
||||
"chat.runError.membershipConcurrencyLimitMessageNoTime": "目前會員的並行任務已滿。請等待其他任務結束後重試,或切換到其他智能體;立即重試不會恢復。",
|
||||
"chat.runError.upstreamUnavailableMessage": "模型服務暫時無法使用,通常是上游波動或網路/代理問題。請稍後重試。",
|
||||
"chat.runError.toolLoopMessage": "{agent} 不斷重複同一操作卻沒有進展,已自動停止。請檢查目標檔案或指令後重試。",
|
||||
"chat.runError.outputInvalidMessage": "模型輸出了異常內容,本輪已被中斷。通常重試即可恢復。",
|
||||
"chat.runError.runtimeConfigMessage": "所選智慧體的執行階段設定有誤,無法啟動本輪任務。請更新到最新版本或聯絡支援。",
|
||||
"chat.runError.runtimeConfigMessage": "所選智能體的執行階段設定有誤,無法啟動本輪任務。請更新到最新版本或聯絡支援。",
|
||||
"chat.runError.title.quotaExhausted": "額度已用盡",
|
||||
"chat.runError.title.timedOut": "執行逾時",
|
||||
"chat.runError.title.emptyOutput": "沒有任何輸出",
|
||||
"chat.runError.title.sessionExpired": "工作階段已過期",
|
||||
"chat.runError.title.gitBashMissing": "缺少 Git Bash",
|
||||
"chat.runError.title.cpuUnsupported": "處理器不支援",
|
||||
"chat.runError.title.cliSessionRefused": "智慧體版本不相容",
|
||||
"chat.runError.title.cliSessionRefused": "智能體版本不相容",
|
||||
"chat.runError.quotaExhaustedMessage": "所用模型服務的額度或帳單上限已用盡,重試也無法恢復。請前往對應服務儲值,或切換到其他模型/服務。",
|
||||
"chat.runError.workspaceCreditsMessage": "工作區額度已用盡。請儲值(或聯絡工作區管理員補充),或切換到其他模型/服務。",
|
||||
"chat.runError.timedOutMessage": "本次執行耗時過長已被中斷。請重試,或縮小任務範圍後再試。",
|
||||
@@ -166,7 +166,7 @@ export const zhTW: Dict = {
|
||||
"chat.runError.sessionExpiredMessage": "要恢復的工作階段已過期,已為你重置。重試即可開始一次全新執行。",
|
||||
"chat.runError.gitBashMissingMessage": "在 Windows 上執行此智能體需要 Git Bash,但找不到。請安裝 Git for Windows 後重試。",
|
||||
"chat.runError.cpuUnsupportedMessage": "此智能體的執行時需要此裝置處理器不支援的指令集(AVX2),因此無法啟動。請將 OpenDesign 更新到最新版本,新版本附帶相容的執行時。",
|
||||
"chat.runError.title.agentCrashed": "智慧體意外結束",
|
||||
"chat.runError.title.agentCrashed": "智能體意外結束",
|
||||
"chat.runError.agentCrashedMessage": "{agent} 意外結束了,它沒說為什麼。重試通常就能恢復;反覆出現的話,把日誌傳給我們。",
|
||||
"chat.runError.title.accountSuspended": "帳號暫時被停用",
|
||||
"chat.runError.accountSuspendedMessage": "偵測到異常的付款風險。如果你覺得是誤判,聯絡我們,我們來查。",
|
||||
@@ -174,8 +174,8 @@ export const zhTW: Dict = {
|
||||
"chat.runError.cliSessionRefusedMessage":
|
||||
"{agent} 拒絕開始工作階段。通常是目前版本與 Open Design 不相容,換一個版本後重試。",
|
||||
"chat.runError.strategyTaskStateMismatchMessage": "該任務已被策略品質門攔下,本輪表單無法繼續提交。請重試請求或重新發起一次任務。",
|
||||
"chat.runError.agentReplyIncompleteMessage": "智慧體的回覆裡缺少 Open Design 記錄這一步所需的標記,任務因此沒能繼續。你提交的內容沒有遺失;這屬於偶發情況,重試一次通常就好了。",
|
||||
"chat.runError.clarificationRepeatedMessage": "智慧體還想再確認一些資訊,於是又問了一次;但一個任務只允許一輪提問,所以停在了這裡。你的回答仍然保留在對話裡——重試會把請求重新跑一遍,把要補充的資訊一起寫進去,通常一輪就能問清楚。",
|
||||
"chat.runError.agentReplyIncompleteMessage": "智能體的回覆裡缺少 Open Design 記錄這一步所需的標記,任務因此沒能繼續。你提交的內容沒有遺失;這屬於偶發情況,重試一次通常就好了。",
|
||||
"chat.runError.clarificationRepeatedMessage": "智能體還想再確認一些資訊,於是又問了一次;但一個任務只允許一輪提問,所以停在了這裡。你的回答仍然保留在對話裡——重試會把請求重新跑一遍,把要補充的資訊一起寫進去,通常一輪就能問清楚。",
|
||||
"chat.runError.clientEnvironmentMessage": "看起來走了代理或公司網路,{agent} 拒絕了請求({cause})。換一個網路出口,或在設定裡調整代理。",
|
||||
"chat.runError.clientEnvironmentCause.certificate": "憑證驗證失敗",
|
||||
"chat.runError.clientEnvironmentCause.proxy": "代理設定有問題",
|
||||
@@ -442,7 +442,7 @@ export const zhTW: Dict = {
|
||||
"settings.modeAria": "執行模式",
|
||||
"settings.protocolAria": "API 協定",
|
||||
"settings.modeDaemon": "本機 CLI",
|
||||
"settings.modeDaemonHelp": "透過本機的程式碼代理 CLI 執行",
|
||||
"settings.modeDaemonHelp": "透過本機的程式碼智能體 CLI 執行",
|
||||
"settings.modeDaemonOffline": "背景守護程序未執行",
|
||||
"settings.modeDaemonOfflineMeta": "守護程序未執行",
|
||||
"settings.modeDaemonInstalledMeta": "已安裝 {count} 個",
|
||||
@@ -455,7 +455,7 @@ export const zhTW: Dict = {
|
||||
"BYOK 無法讀取、寫入或編輯專案檔案。需要變更程式碼時,請使用 Local CLI。",
|
||||
"settings.byokDraftNotice":
|
||||
"填寫必填欄位後即可儲存此供應商;目前的設定將繼續維持生效。",
|
||||
"settings.codeAgent": "程式碼代理",
|
||||
"settings.codeAgent": "程式碼智能體",
|
||||
"settings.codeAgentHint": "選擇用來執行提示詞的 CLI。",
|
||||
"settings.rescan": "↻ 重新掃描",
|
||||
"settings.rescanTitle": "重新掃描 PATH",
|
||||
@@ -491,13 +491,13 @@ export const zhTW: Dict = {
|
||||
"settings.agentInstall.pathHint":
|
||||
"如果你透過 npm 或 Homebrew 安裝了 CLI,但仍顯示為未安裝,請確認該工具的 bin 目錄已加入 OpenDesign daemon 繼承的 PATH(在 macOS 上,Terminal 與 GUI 應用的 PATH 可能不同)。請參閱 QUICKSTART.md(「Local agent CLI and PATH」章節)。",
|
||||
"settings.agentInstall.stepOpenLinks":
|
||||
"在目標代理卡片上開啟「安裝」或「文件」連結。",
|
||||
"在目標智能體卡片上開啟「安裝」或「文件」連結。",
|
||||
"settings.agentInstall.stepAuth":
|
||||
"返回 OpenDesign 前,請先在對應 CLI 完成驗證(登入或新增 API 憑證)。",
|
||||
"settings.agentInstall.stepRescan": "在此區域點擊「重新掃描」。",
|
||||
"settings.agentInstall.stepSelect": "當代理顯示為已安裝後,選擇該代理卡片。",
|
||||
"settings.agentInstall.stepSelect": "當智能體顯示為已安裝後,選擇該智能體卡片。",
|
||||
"settings.noAgentsDetected":
|
||||
"尚未偵測到任何代理。請安裝 Claude Code、Codex、OpenCode、Cursor Agent 或 Qwen 其中之一,然後點擊「重新掃描」。",
|
||||
"尚未偵測到任何智能體。請安裝 Claude Code、Codex、OpenCode、Cursor Agent 或 Qwen 其中之一,然後點擊「重新掃描」。",
|
||||
"settings.agentInstalledGroup": "你的 CLI({count})",
|
||||
"settings.agentInstallGroup": "可安裝({count})",
|
||||
"settings.agentAuthRequired": "需要認證",
|
||||
@@ -615,7 +615,7 @@ export const zhTW: Dict = {
|
||||
"settings.dshSetupInstalling": "正在安裝…",
|
||||
"settings.dshSetupRequired": "需要安裝連接元件",
|
||||
"settings.anthropicApi": "Anthropic API",
|
||||
"settings.noAgentSelected": "尚未選擇代理",
|
||||
"settings.noAgentSelected": "尚未選擇智能體",
|
||||
"settings.language": "介面語言",
|
||||
"settings.languageHint": "切換介面語言,設定僅儲存在當前瀏覽器。",
|
||||
"settings.agentModelHead": "模型:",
|
||||
@@ -649,7 +649,7 @@ export const zhTW: Dict = {
|
||||
"settings.mediaProvidersHint": "連接圖片、影片、音訊和搜尋供應商。",
|
||||
"settings.mcpServerTitle": "OpenDesign MCP",
|
||||
"settings.mcpServerHint":
|
||||
"將 OpenDesign 作為 MCP 伺服器暴露給你的編碼代理。",
|
||||
"將 OpenDesign 作為 MCP 伺服器暴露給你的編碼智能體。",
|
||||
"settings.externalMcpTitle": "外部 MCP",
|
||||
"settings.externalMcpHint":
|
||||
"接入外部服務的 MCP 工具(Higgsfield、GitHub 等)。",
|
||||
@@ -1665,7 +1665,7 @@ export const zhTW: Dict = {
|
||||
"routines.newAutomation": "新增自動化",
|
||||
"routines.loading": "載入中…",
|
||||
"routines.empty": "尚無自動化工作。",
|
||||
"routines.emptyHint": "點選「新增自動化」即可安排一次無人值守的代理執行。",
|
||||
"routines.emptyHint": "點選「新增自動化」即可安排一次無人值守的智能體執行。",
|
||||
"routines.runHistoryLoading": "正在載入執行記錄…",
|
||||
"routines.runHistoryEmpty": "尚無執行記錄。",
|
||||
"routines.fieldName": "名稱",
|
||||
@@ -1738,7 +1738,7 @@ export const zhTW: Dict = {
|
||||
"routines.errorPickProject":
|
||||
"請選擇要重複使用的專案,或切換為「每次執行建立新專案」。",
|
||||
"routines.errorAgentEmptyOutput":
|
||||
"代理已完成執行但未產生任何輸出。模型或提供商可能返回了空回應,請檢查代理日誌中的上游錯誤。",
|
||||
"智能體已完成執行但未產生任何輸出。模型或提供商可能返回了空回應,請檢查智能體日誌中的上游錯誤。",
|
||||
"entry.githubStarLabel": "星標",
|
||||
"entry.githubStarTitle": "在 GitHub 為我們點亮 Star",
|
||||
"entry.githubStarAria": "在 GitHub 為 OpenDesign 點亮 Star",
|
||||
@@ -1774,7 +1774,7 @@ export const zhTW: Dict = {
|
||||
"connectors.aboutLabel": "簡介",
|
||||
"connectors.detailsLabel": "詳情",
|
||||
"connectors.statusLabel": "狀態",
|
||||
"connectors.category.aiAgents": "AI 代理",
|
||||
"connectors.category.aiAgents": "AI 智能體",
|
||||
"connectors.category.aiInfrastructure": "AI 基礎設施",
|
||||
"connectors.category.accounting": "會計",
|
||||
"connectors.category.admin": "管理",
|
||||
@@ -1928,14 +1928,14 @@ export const zhTW: Dict = {
|
||||
"newproj.designSystem": "設計系統",
|
||||
"newproj.dsNoneFreeform": "不指定 — 自由發揮",
|
||||
"newproj.dsNoneSubtitleEmpty": "不使用系統 token,由你決定整體配色",
|
||||
"newproj.dsNoneSubtitleSelected": "跳過系統 token,由代理自行選擇配色。",
|
||||
"newproj.dsNoneSubtitleSelected": "跳過系統 token,由智能體自行選擇配色。",
|
||||
"newproj.dsCategoryFallback": "設計系統",
|
||||
"newproj.dsSearch": "搜尋設計系統…",
|
||||
"newproj.dsModeAria": "選擇模式",
|
||||
"newproj.dsModeSingle": "單選",
|
||||
"newproj.dsModeMulti": "多選",
|
||||
"newproj.dsNoneTitle": "不指定 — 自由發揮",
|
||||
"newproj.dsNoneSub": "跳過系統 token,由代理自行選擇配色。",
|
||||
"newproj.dsNoneSub": "跳過系統 token,由智能體自行選擇配色。",
|
||||
"newproj.dsEmpty": "沒有符合「{query}」的設計系統。",
|
||||
"newproj.dsFootSingular": "只作為靈感參考。",
|
||||
"newproj.dsFootPlural": "只作為靈感參考。",
|
||||
@@ -2111,7 +2111,7 @@ export const zhTW: Dict = {
|
||||
"avatar.anthropicApi": "Anthropic API",
|
||||
"avatar.useLocal": "使用本機 CLI",
|
||||
"avatar.useApi": "使用 API · BYOK",
|
||||
"avatar.codeAgent": "程式碼代理",
|
||||
"avatar.codeAgent": "程式碼智能體",
|
||||
"avatar.rescan": "重新掃描 PATH",
|
||||
"avatar.amrConsole": "OpenDesign Cloud 帳戶",
|
||||
"avatar.amrConsoleMeta": "餘額與儲值",
|
||||
@@ -2120,7 +2120,7 @@ export const zhTW: Dict = {
|
||||
"avatar.metaActive": "使用中",
|
||||
"avatar.metaOffline": "未執行",
|
||||
"avatar.metaSelected": "已選",
|
||||
"avatar.noAgentSelected": "尚未選擇代理",
|
||||
"avatar.noAgentSelected": "尚未選擇智能體",
|
||||
"avatar.modelSection": "模型",
|
||||
"avatar.modelLabel": "模型",
|
||||
"avatar.reasoningLabel": "推理",
|
||||
@@ -2157,7 +2157,7 @@ export const zhTW: Dict = {
|
||||
"inlineSwitcher.modelDefault": "預設",
|
||||
"inlineSwitcher.noAgent": "未選擇",
|
||||
"inlineSwitcher.modeLabel": "模式",
|
||||
"inlineSwitcher.agentLabel": "代理",
|
||||
"inlineSwitcher.agentLabel": "智能體",
|
||||
"inlineSwitcher.providerLabel": "服務商",
|
||||
"inlineSwitcher.modelLabel": "模型",
|
||||
"inlineSwitcher.useCli": "使用本機 CLI",
|
||||
@@ -3039,7 +3039,7 @@ export const zhTW: Dict = {
|
||||
"designFiles.selectAll": "全選",
|
||||
"designFiles.dropTitle": "⤓ 把檔案拖到這裡",
|
||||
"designFiles.dropDesc":
|
||||
"圖片、文件、參考資料或資料夾 — 智慧體都會用作上下文。",
|
||||
"圖片、文件、參考資料或資料夾 — 智能體都會用作上下文。",
|
||||
"designFiles.dropLabel": "拖曳檔案到這裡",
|
||||
"designFiles.upload.title": "上傳一張圖片",
|
||||
"designFiles.paste.title": "將文字貼上為檔案",
|
||||
@@ -3162,11 +3162,11 @@ export const zhTW: Dict = {
|
||||
"designFiles.usefulInfoTip8":
|
||||
"在 X 上關注 @OpenDesignHQ,第一時間了解新功能。",
|
||||
"designFiles.usefulInfoTip9":
|
||||
"把圖片、文件甚至整個資料夾拖到目前面板,智慧體都會用作上下文。",
|
||||
"把圖片、文件甚至整個資料夾拖到目前面板,智能體都會用作上下文。",
|
||||
"designFiles.usefulInfoTip10":
|
||||
"點「新建草圖」手繪一個版面,讓智慧體照著生成。",
|
||||
"點「新建草圖」手繪一個版面,讓智能體照著生成。",
|
||||
"designFiles.usefulInfoTip11":
|
||||
"在預覽中圈選任意元素發表評論,智慧體會針對性修改。",
|
||||
"在預覽中圈選任意元素發表評論,智能體會針對性修改。",
|
||||
"designFiles.usefulInfoTip12": "生成結果不滿意?直接圈選標註比重新描述更快。",
|
||||
"designFiles.usefulInfoTip13": "設計可以一鍵匯出為 PDF、圖片或獨立 HTML。",
|
||||
"designFiles.usefulInfoTip14":
|
||||
@@ -3423,7 +3423,7 @@ export const zhTW: Dict = {
|
||||
"fileViewer.exportPdf": "匯出為 PDF",
|
||||
"fileViewer.exportPdfAllSlides": "匯出為 PDF(全部投影片)",
|
||||
"fileViewer.exportPptxBusy": "請等待當前任務完成。",
|
||||
"fileViewer.exportPptxHint": "請求代理將此設計轉換為 PPTX。",
|
||||
"fileViewer.exportPptxHint": "請求智能體將此設計轉換為 PPTX。",
|
||||
"fileViewer.exportPptxNa": "此處暫不支援匯出 PPTX。",
|
||||
'fileViewer.exportDaemonUnreachable': '無法連線到 daemon,請重試。',
|
||||
"fileViewer.exportZip": "下載為 .zip",
|
||||
@@ -3739,7 +3739,7 @@ export const zhTW: Dict = {
|
||||
"assistant.possiblePromptInjection": "可能的提示詞注入",
|
||||
"assistant.designSystemDirectionLocked": "已選擇目前的設計系統,視覺方向已鎖定。",
|
||||
"assistant.waitingFirstOutput": "等待首批輸出中",
|
||||
"assistant.statusBootingAgent": "正在啟動代理",
|
||||
"assistant.statusBootingAgent": "正在啟動智能體",
|
||||
"assistant.statusPreparing": "準備中...",
|
||||
"assistant.statusStarting": "啟動中",
|
||||
"assistant.statusRequesting": "正在傳送請求",
|
||||
@@ -3796,9 +3796,9 @@ export const zhTW: Dict = {
|
||||
"qf.otherOption": "其他",
|
||||
"qf.ownAnswer": "自己填",
|
||||
"qf.required": "必填",
|
||||
"qf.lockedSubmitted": "答案已傳送,代理將在本次工作階段後續使用。",
|
||||
"qf.lockedSubmitted": "答案已傳送,智能體將在本次工作階段後續使用。",
|
||||
"qf.lockedPrev": "該表單來自先前的對話。",
|
||||
"qf.hint": "挑選合適的選項;可選項可以跳過,代理會使用合理的預設值。",
|
||||
"qf.hint": "挑選合適的選項;可選項可以跳過,智能體會使用合理的預設值。",
|
||||
"qf.submitDefault": "下一步",
|
||||
"qf.submitDisabledTitle": "請先填寫必填項",
|
||||
"qf.submitTitle": "下一步",
|
||||
@@ -3857,7 +3857,7 @@ export const zhTW: Dict = {
|
||||
"critiqueTheater.belowThresholdBadge": "低於門檻",
|
||||
"critiqueTheater.timedOutBadge": "已逾時",
|
||||
"critiqueTheater.failedHeading": "執行失敗",
|
||||
"critiqueTheater.failedReasonCliExit": "智慧體 CLI 在評審完成前異常結束。",
|
||||
"critiqueTheater.failedReasonCliExit": "智能體 CLI 在評審完成前異常結束。",
|
||||
"critiqueTheater.failedReasonPerRoundTimeout": "某一輪超出了時間預算。",
|
||||
"critiqueTheater.failedReasonTotalTimeout": "整次執行超出了總時間預算。",
|
||||
"critiqueTheater.failedReasonOrchestrator": "編排器內部錯誤。",
|
||||
@@ -3869,10 +3869,10 @@ export const zhTW: Dict = {
|
||||
"critiqueTheater.replaySpeedLive": "即時",
|
||||
"critiqueTheater.replaySpeedFast": "快進",
|
||||
"critiqueTheater.settingsNav": "設計評審團",
|
||||
"critiqueTheater.settingsNavHint": "為代理執行啟用五人設計評審",
|
||||
"critiqueTheater.settingsEnabledLabel": "在代理執行期間顯示設計評審團",
|
||||
"critiqueTheater.settingsNavHint": "為智能體執行啟用五人設計評審",
|
||||
"critiqueTheater.settingsEnabledLabel": "在智能體執行期間顯示設計評審團",
|
||||
"critiqueTheater.settingsEnabledDescription":
|
||||
"啟用後,五人評審面板會在代理產生時同步進行,並在交付前為結果評分。可隨時中斷。",
|
||||
"啟用後,五人評審面板會在智能體產生時同步進行,並在交付前為結果評分。可隨時中斷。",
|
||||
"critiqueTheater.settingsEnabledProjectHint":
|
||||
"已為此專案儲存。此專案的新執行將在伺服器端經過設計評審團。",
|
||||
"critiqueTheater.settingsEnabledNoProjectHint":
|
||||
@@ -4037,7 +4037,7 @@ export const zhTW: Dict = {
|
||||
"settings.notifySoundTwoToneDown": "下行雙音",
|
||||
"settings.notifySoundThud": "低響",
|
||||
"settings.skills": "技能",
|
||||
"settings.skillsHint": "代理可在任務中呼叫的功能技能",
|
||||
"settings.skillsHint": "智能體可在任務中呼叫的功能技能",
|
||||
"settings.skillsNew": "新增技能",
|
||||
"settings.skillsEmpty": "請於左側選擇一個技能,或新增一個。",
|
||||
"settings.skillsEdit": "編輯",
|
||||
@@ -4220,7 +4220,7 @@ export const zhTW: Dict = {
|
||||
"settings.memoryProfileTabCaption": "你的身分與預設偏好",
|
||||
"settings.memoryProfileTitle": "你的工作檔案",
|
||||
"settings.memoryProfileHint":
|
||||
"關於你和你預設偏好的幾項資訊。記憶會在每次任務前注入這些內容,讓代理人能從簡短的需求推斷你的意圖。",
|
||||
"關於你和你預設偏好的幾項資訊。記憶會在每次任務前注入這些內容,讓智能體能從簡短的需求推斷你的意圖。",
|
||||
"settings.memoryProfileName": "工作檔案",
|
||||
"settings.memoryProfileDescription":
|
||||
"角色、公司、領域、受眾、品味,以及助理應重複使用的預設偏好。",
|
||||
@@ -4593,7 +4593,7 @@ export const zhTW: Dict = {
|
||||
"diagnostics.exporting": "匯出中…",
|
||||
"diagnostics.exportSuccess": "診斷日誌已儲存至 {path}",
|
||||
"diagnostics.exportFailed": "匯出診斷日誌失敗:{message}",
|
||||
"automations.eyebrow": "定時智慧體工作階段",
|
||||
"automations.eyebrow": "定時智能體工作階段",
|
||||
"automations.title": "自動化",
|
||||
"automations.lede": "為專案工作、Orbit 摘要與即時看板規劃週期性對話。",
|
||||
"automations.summaryAria": "自動化概覽",
|
||||
@@ -4776,7 +4776,7 @@ export const zhTW: Dict = {
|
||||
"mcpClient.forwardedAcpNote":
|
||||
"標記為 stdio only 的 ACP 介面卡只會從此清單接收 stdio 類型的 MCP 伺服器;HTTP 與 SSE 項目會在啟動時被捨棄。",
|
||||
"mcpClient.notForwardedNote":
|
||||
"對於這些智慧體,請在其各自的設定檔中設定 MCP 伺服器(例如 ~/.codex/config.toml、~/.gemini/settings.json);下方的伺服器在那裡不會生效。",
|
||||
"對於這些智能體,請在其各自的設定檔中設定 MCP 伺服器(例如 ~/.codex/config.toml、~/.gemini/settings.json);下方的伺服器在那裡不會生效。",
|
||||
|
||||
// Brands library + extraction
|
||||
"brand.libraryTitle": "品牌套件",
|
||||
@@ -5277,7 +5277,7 @@ export const zhTW: Dict = {
|
||||
'library.kindLinks': '連結',
|
||||
'library.sourceAll': '全部來源',
|
||||
'library.sourceClipper': '剪藏擴充功能',
|
||||
'library.sourceAgent': '智慧代理',
|
||||
'library.sourceAgent': '智能體',
|
||||
'library.sourceDesignSystem': '設計系統',
|
||||
'library.sourceGenerated': 'AI 生成',
|
||||
'library.viewMode': '檢視模式',
|
||||
@@ -5289,7 +5289,7 @@ export const zhTW: Dict = {
|
||||
'library.refreshTooltip': '依目前篩選條件重新載入列表',
|
||||
'library.sync': '同步',
|
||||
'library.syncing': '同步中…',
|
||||
'library.syncTooltip': '將你的設計系統與智慧代理產生的成果拉取到素材庫',
|
||||
'library.syncTooltip': '將你的設計系統與智能體產生的成果拉取到素材庫',
|
||||
'library.upload': '上傳',
|
||||
'library.uploadTooltip': '將圖片、字型或檔案上傳到素材庫',
|
||||
'library.selectedCount': '已選 {count} 項',
|
||||
@@ -5348,7 +5348,7 @@ export const zhTW: Dict = {
|
||||
'mcp.categoryUtilities': '實用工具',
|
||||
'mcp.categoryUtilitiesHint': '檔案系統、網路請求、GitHub 等通用工具。',
|
||||
'mcp.categoryWebCapture': '網頁擷取',
|
||||
'mcp.categoryWebCaptureHint': '把 URL 算繪成圖片,讓智慧代理看到自己做出來的東西。',
|
||||
'mcp.categoryWebCaptureHint': '把 URL 算繪成圖片,讓智能體看到自己做出來的東西。',
|
||||
'mcp.checking': '檢查中…',
|
||||
'mcp.clickConnectHint': '點擊「連線」,透過服務商的 OAuth 流程授予 OpenDesign 存取權限。',
|
||||
'mcp.closePicker': '關閉選擇器',
|
||||
@@ -5545,7 +5545,7 @@ export const zhTW: Dict = {
|
||||
'dsCreate.githubComposioCheckingDesc': '正在背景檢查連接器狀態;連結匯入不受影響。',
|
||||
'dsCreate.githubComposioConnectedAsDesc': 'Composio GitHub 連接器已以 {account} 身分連線;當本機無法讀取儲存庫時可作為備援方式。',
|
||||
'dsCreate.githubComposioConnectedDesc': '當本機無法讀取儲存庫時,可使用 Composio GitHub 連接器作為備援方式。',
|
||||
'dsCreate.githubComposioDefaultDesc': '為代理工具提供 Composio GitHub 連接器存取;儲存庫連結仍可透過本機 git 或 GitHub CLI 使用。',
|
||||
'dsCreate.githubComposioDefaultDesc': '為智能體工具提供 Composio GitHub 連接器存取;儲存庫連結仍可透過本機 git 或 GitHub CLI 使用。',
|
||||
'dsCreate.githubComposioErrorDesc': '請重新連線 Composio GitHub 連接器,或繼續使用本機 git/GitHub CLI。',
|
||||
'dsCreate.githubComposioNotConfiguredDesc': '僅當此專案需要以連接器為基礎的 GitHub 工具時,才新增 Composio API 金鑰。',
|
||||
'dsCreate.githubComposioPendingDesc': '請在 Composio 授權視窗中完成操作;本機 GitHub 匯入仍然可用。',
|
||||
@@ -5583,7 +5583,7 @@ export const zhTW: Dict = {
|
||||
'dsFlow.agentMsgReady': '你的設計系統草稿已就緒。你可以查看「設計系統」分頁、檢查產生的檔案、發布它,或在這裡讓我做修改。',
|
||||
'dsFlow.agentMsgRevision': '我正在把你的回饋套用到設計系統上。修訂進行期間,你可以繼續查看目前草稿。',
|
||||
'dsFlow.agentMsgTokenRebuild': '我正在準備一份供審閱的 token 契約重建。在修訂被接受之前,目前生效的契約不會改變。',
|
||||
'dsFlow.agentPushLayer': '代理推送層',
|
||||
'dsFlow.agentPushLayer': '智能體推送層',
|
||||
'dsFlow.assetsLabel': '資產',
|
||||
'dsFlow.auditNeedsRepair': '{summary} 請在執行修復前查看稽核詳情。',
|
||||
'dsFlow.brandFontsMissingBody': '在新增品牌字型檔案之前,排版預覽將使用替代的網頁字型。',
|
||||
@@ -5636,7 +5636,7 @@ export const zhTW: Dict = {
|
||||
'dsFlow.packagePillReady': '混合模式就緒',
|
||||
'dsFlow.packageStructured': '結構化匯入套件',
|
||||
'dsFlow.pendingRevision': '待處理的修訂',
|
||||
'dsFlow.pickLocalAgentFirst': '請先選擇一個本機代理,然後讓 OpenDesign 更新這個設計系統。',
|
||||
'dsFlow.pickLocalAgentFirst': '請先選擇一個本機智能體,然後讓 OpenDesign 更新這個設計系統。',
|
||||
'dsFlow.previewPages': '預覽頁面',
|
||||
'dsFlow.proposedChanges': '建議的變更',
|
||||
'dsFlow.publishCardReady': 'OpenDesign 已可供審閱。請對目前的成果給出回饋,確認它對後續專案有用後再發布。',
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { ar } from '../../src/i18n/locales/ar';
|
||||
import { fa } from '../../src/i18n/locales/fa';
|
||||
import { tr } from '../../src/i18n/locales/tr';
|
||||
import { zhCN } from '../../src/i18n/locales/zh-CN';
|
||||
import { zhTW } from '../../src/i18n/locales/zh-TW';
|
||||
import type { Dict } from '../../src/i18n/types';
|
||||
|
||||
/**
|
||||
* Each locale gets exactly one word for the "AI agent" concept.
|
||||
*
|
||||
* The dictionaries drifted because run-error cards were added in batches over
|
||||
* several months and each batch picked its own wording, so a single language
|
||||
* ended up naming one product concept two or three different ways
|
||||
* (see TRANSLATIONS.md → "agent" in the zh-CN ↔ zh-TW glossary).
|
||||
*
|
||||
* Two things are deliberately NOT policed here:
|
||||
*
|
||||
* - Bare English "Agent". It is a ruled-in house style: developer-facing
|
||||
* surfaces (MCP setup, integrations, `useEverywhere`) keep the English
|
||||
* proper noun while end-user surfaces translate it. Every locale does this
|
||||
* and it is intentional.
|
||||
* - Words that merely look like the agent term but mean something else in
|
||||
* that language — a network proxy, a marketing agency, a generic tool, an
|
||||
* MCP client. Those live in the per-locale allowlists below, keyed by the
|
||||
* dictionary key so a reviewer can check each one against its English
|
||||
* source.
|
||||
*/
|
||||
|
||||
/** Collect the dictionary keys whose value contains `pattern`. */
|
||||
function keysMatching(dict: Dict, pattern: RegExp): string[] {
|
||||
return Object.entries(dict)
|
||||
.filter(([, value]) => typeof value === 'string' && pattern.test(value))
|
||||
.map(([key]) => key)
|
||||
.sort();
|
||||
}
|
||||
|
||||
describe('agent terminology is consistent within each locale', () => {
|
||||
it('zh-TW names the agent 智能體 and nothing else', () => {
|
||||
// 代理 is also the Chinese word for a network proxy, and 代理商 is a
|
||||
// marketing agency. These keys use it in one of those senses.
|
||||
const nonAgentProxyOrAgency = [
|
||||
'chat.connectionDropped',
|
||||
'chat.runError.clientEnvironmentCause.proxy',
|
||||
'chat.runError.clientEnvironmentMessage',
|
||||
'chat.runError.upstreamUnavailableMessage',
|
||||
'settings.baseUrlDefaultHint',
|
||||
'settings.cliEnvHint',
|
||||
'settings.cliEnvTitle',
|
||||
'settings.onboardingRoleAgency',
|
||||
'settings.onboardingUseAgency',
|
||||
].sort();
|
||||
|
||||
// Retired spellings of the agent concept.
|
||||
expect(keysMatching(zhTW, /智慧體/)).toEqual([]);
|
||||
expect(keysMatching(zhTW, /智慧代理/)).toEqual([]);
|
||||
expect(keysMatching(zhTW, /代理人/)).toEqual([]);
|
||||
|
||||
// A Traditional Chinese file must never carry the Simplified spelling.
|
||||
expect(keysMatching(zhTW, /智能体/)).toEqual([]);
|
||||
|
||||
// Whatever 代理 is left must be a proxy or an agency, never an agent.
|
||||
expect(keysMatching(zhTW, /代理/)).toEqual(nonAgentProxyOrAgency);
|
||||
});
|
||||
|
||||
it('zh-CN names the agent 智能体 and nothing else', () => {
|
||||
const nonAgentProxyOrAgency = [
|
||||
'chat.connectionDropped',
|
||||
'chat.runError.clientEnvironmentCause.proxy',
|
||||
'chat.runError.clientEnvironmentMessage',
|
||||
'chat.runError.upstreamUnavailableMessage',
|
||||
'settings.baseUrlDefaultHint',
|
||||
'settings.cliEnvHint',
|
||||
'settings.cliEnvTitle',
|
||||
'settings.onboardingRoleAgency',
|
||||
'settings.onboardingUseAgency',
|
||||
].sort();
|
||||
|
||||
// A Simplified Chinese file must never carry the Traditional spelling.
|
||||
expect(keysMatching(zhCN, /智能體/)).toEqual([]);
|
||||
expect(keysMatching(zhCN, /智慧体/)).toEqual([]);
|
||||
expect(keysMatching(zhCN, /代理人/)).toEqual([]);
|
||||
|
||||
expect(keysMatching(zhCN, /代理/)).toEqual(nonAgentProxyOrAgency);
|
||||
});
|
||||
|
||||
it('ar names the agent وكيل, never عميل', () => {
|
||||
// عميل means "client" / "customer". It is correct for an MCP *client* and
|
||||
// for agency clients; it is wrong for the coding agent.
|
||||
const nonAgentClient = [
|
||||
'chat.example2Prompt',
|
||||
'settings.mediaProviderComingSoonHint',
|
||||
'settings.onboardingUseAgency',
|
||||
'useEverywhere.section.cli.intro',
|
||||
'useEverywhere.section.mcp.bullet1',
|
||||
'useEverywhere.section.mcp.footer',
|
||||
'useEverywhere.section.mcp.intro',
|
||||
'useEverywhere.section.mcp.snippet1',
|
||||
].sort();
|
||||
|
||||
expect(keysMatching(ar, /عميل|عملاء/)).toEqual(nonAgentClient);
|
||||
});
|
||||
|
||||
it('fa names the agent عامل, never the transliteration ایجنت', () => {
|
||||
expect(keysMatching(fa, /ایجنت/)).toEqual([]);
|
||||
});
|
||||
|
||||
it('tr names the agent ajan, never aracı', () => {
|
||||
// Turkish `araç` means "tool" and inflects to aracı / aracını / aracınız,
|
||||
// and `aracılığıyla` means "by way of". Those are unrelated to the agent
|
||||
// and must survive untouched.
|
||||
const nonAgentToolOrVia = [
|
||||
'chat.runError.cliMissingMessage',
|
||||
'common.exportImageFailed',
|
||||
'dsManager.emptyTemplates',
|
||||
'fileViewer.exportImageFailed',
|
||||
'fileViewer.markTool',
|
||||
'settings.agentInstall.pathHint',
|
||||
'settings.codeAgentHint',
|
||||
'settings.memoryStarterUserDesc',
|
||||
'settings.onboardingSourceAiTool',
|
||||
'useEverywhere.section.cli.bullet2',
|
||||
'useEverywhere.section.mcp.bullet2',
|
||||
'useEverywhere.section.mcp.intro',
|
||||
'useEverywhere.section.overview.intro',
|
||||
].sort();
|
||||
|
||||
expect(keysMatching(tr, /aracı/i)).toEqual(nonAgentToolOrVia);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user