Browse Source

fix(app): translations

Adam 2 weeks ago
parent
commit
f252e3234c

+ 95 - 107
packages/app/src/i18n/ar.ts

@@ -16,11 +16,9 @@ export const dict = {
   "command.category.permissions": "أذونات",
   "command.category.workspace": "مساحة عمل",
   "command.category.settings": "إعدادات",
-
   "theme.scheme.system": "نظام",
   "theme.scheme.light": "فاتح",
   "theme.scheme.dark": "داكن",
-
   "command.sidebar.toggle": "تبديل الشريط الجانبي",
   "command.project.open": "فتح مشروع",
   "command.provider.connect": "اتصال بموفر",
@@ -31,17 +29,13 @@ export const dict = {
   "command.session.previous.unseen": "الجلسة غير المقروءة السابقة",
   "command.session.next.unseen": "الجلسة غير المقروءة التالية",
   "command.session.archive": "أرشفة الجلسة",
-
   "command.palette": "لوحة الأوامر",
-
   "command.theme.cycle": "تغيير السمة",
   "command.theme.set": "استخدام السمة: {{theme}}",
   "command.theme.scheme.cycle": "تغيير مخطط الألوان",
   "command.theme.scheme.set": "استخدام مخطط الألوان: {{scheme}}",
-
   "command.language.cycle": "تغيير اللغة",
   "command.language.set": "استخدام اللغة: {{language}}",
-
   "command.session.new": "جلسة جديدة",
   "command.file.open": "فتح ملف",
   "command.tab.close": "إغلاق علامة التبويب",
@@ -72,6 +66,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "قبول التعديلات تلقائيًا",
   "command.permissions.autoaccept.disable": "إيقاف قبول التعديلات تلقائيًا",
   "command.workspace.toggle": "تبديل مساحات العمل",
+  "command.workspace.toggle.description": "تمكين أو تعطيل مساحات العمل المتعددة في الشريط الجانبي",
   "command.session.undo": "تراجع",
   "command.session.undo.description": "تراجع عن الرسالة الأخيرة",
   "command.session.redo": "إعادة",
@@ -84,32 +79,30 @@ export const dict = {
   "command.session.share.description": "مشاركة هذه الجلسة ونسخ الرابط إلى الحافظة",
   "command.session.unshare": "إلغاء مشاركة الجلسة",
   "command.session.unshare.description": "إيقاف مشاركة هذه الجلسة",
-
   "palette.search.placeholder": "البحث في الملفات والأوامر والجلسات",
   "palette.empty": "لا توجد نتائج",
   "palette.group.commands": "الأوامر",
   "palette.group.files": "الملفات",
-
   "dialog.provider.search.placeholder": "البحث عن موفرين",
   "dialog.provider.empty": "لم يتم العثور على موفرين",
   "dialog.provider.group.popular": "شائع",
   "dialog.provider.group.other": "آخر",
   "dialog.provider.tag.recommended": "موصى به",
+  "dialog.provider.opencode.note": "نماذج مختارة تتضمن Claude و GPT و Gemini والمزيد",
   "dialog.provider.anthropic.note": "اتصل باستخدام Claude Pro/Max أو مفتاح API",
-  "dialog.provider.openai.note": "اتصل باستخدام ChatGPT Pro/Plus أو مفتاح API",
   "dialog.provider.copilot.note": "اتصل باستخدام Copilot أو مفتاح API",
-
+  "dialog.provider.openai.note": "اتصل باستخدام ChatGPT Pro/Plus أو مفتاح API",
+  "dialog.provider.google.note": "نماذج Gemini لاستجابات سريعة ومنظمة",
+  "dialog.provider.openrouter.note": "الوصول إلى جميع النماذج المدعومة من موفر واحد",
+  "dialog.provider.vercel.note": "وصول موحد إلى نماذج الذكاء الاصطناعي مع توجيه ذكي",
   "dialog.model.select.title": "تحديد نموذج",
   "dialog.model.search.placeholder": "البحث عن نماذج",
   "dialog.model.empty": "لا توجد نتائج للنماذج",
   "dialog.model.manage": "إدارة النماذج",
   "dialog.model.manage.description": "تخصيص النماذج التي تظهر في محدد النماذج.",
-
   "dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من OpenCode",
   "dialog.model.unpaid.addMore.title": "إضافة المزيد من النماذج من موفرين مشهورين",
-
   "dialog.provider.viewAll": "عرض المزيد من الموفرين",
-
   "provider.connect.title": "اتصال {{provider}}",
   "provider.connect.title.anthropicProMax": "تسجيل الدخول باستخدام Claude Pro/Max",
   "provider.connect.selectMethod": "حدد طريقة تسجيل الدخول لـ {{provider}}.",
@@ -117,34 +110,64 @@ export const dict = {
   "provider.connect.status.inProgress": "جارٍ التفويض...",
   "provider.connect.status.waiting": "في انتظار التفويض...",
   "provider.connect.status.failed": "فشل التفويض: {{error}}",
-  "provider.connect.apiKey.description":
-    "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
+  "provider.connect.apiKey.description": "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
   "provider.connect.apiKey.label": "مفتاح واجهة برمجة تطبيقات {{provider}}",
   "provider.connect.apiKey.placeholder": "مفتاح API",
   "provider.connect.apiKey.required": "مفتاح API مطلوب",
-  "provider.connect.opencodeZen.line1":
-    "يمنحك OpenCode Zen الوصول إلى مجموعة مختارة من النماذج الموثوقة والمحسنة لوكلاء البرمجة.",
-  "provider.connect.opencodeZen.line2":
-    "باستخدام مفتاح API واحد، ستحصل على إمكانية الوصول إلى نماذج مثل Claude و GPT و Gemini و GLM والمزيد.",
+  "provider.connect.opencodeZen.line1": "يمنحك OpenCode Zen الوصول إلى مجموعة مختارة من النماذج الموثوقة والمحسنة لوكلاء البرمجة.",
+  "provider.connect.opencodeZen.line2": "باستخدام مفتاح API واحد، ستحصل على إمكانية الوصول إلى نماذج مثل Claude و GPT و Gemini و GLM والمزيد.",
   "provider.connect.opencodeZen.visit.prefix": "قم بزيارة ",
   "provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
   "provider.connect.opencodeZen.visit.suffix": " للحصول على مفتاح API الخاص بك.",
   "provider.connect.oauth.code.visit.prefix": "قم بزيارة ",
   "provider.connect.oauth.code.visit.link": "هذا الرابط",
-  "provider.connect.oauth.code.visit.suffix":
-    " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
+  "provider.connect.oauth.code.visit.suffix": " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
   "provider.connect.oauth.code.label": "رمز تفويض {{method}}",
   "provider.connect.oauth.code.placeholder": "رمز التفويض",
   "provider.connect.oauth.code.required": "رمز التفويض مطلوب",
   "provider.connect.oauth.code.invalid": "رمز التفويض غير صالح",
   "provider.connect.oauth.auto.visit.prefix": "قم بزيارة ",
   "provider.connect.oauth.auto.visit.link": "هذا الرابط",
-  "provider.connect.oauth.auto.visit.suffix":
-    " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
+  "provider.connect.oauth.auto.visit.suffix": " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
   "provider.connect.oauth.auto.confirmationCode": "رمز التأكيد",
   "provider.connect.toast.connected.title": "تم توصيل {{provider}}",
   "provider.connect.toast.connected.description": "نماذج {{provider}} متاحة الآن للاستخدام.",
-
+  "provider.custom.title": "موفر مخصص",
+  "provider.custom.description.prefix": "تكوين موفر متوافق مع OpenAI. راجع ",
+  "provider.custom.description.link": "وثائق تكوين الموفر",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "معرف الموفر",
+  "provider.custom.field.providerID.placeholder": "myprovider",
+  "provider.custom.field.providerID.description": "أحرف صغيرة، أرقام، شرطات، أو شرطات سفلية",
+  "provider.custom.field.name.label": "اسم العرض",
+  "provider.custom.field.name.placeholder": "موفر الذكاء الاصطناعي الخاص بي",
+  "provider.custom.field.baseURL.label": "عنوان URL الأساسي",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "مفتاح API",
+  "provider.custom.field.apiKey.placeholder": "مفتاح API",
+  "provider.custom.field.apiKey.description": "اختياري. اتركه فارغًا إذا كنت تدير المصادقة عبر الترويسات.",
+  "provider.custom.models.label": "النماذج",
+  "provider.custom.models.id.label": "المعرف",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "الاسم",
+  "provider.custom.models.name.placeholder": "اسم العرض",
+  "provider.custom.models.remove": "إزالة النموذج",
+  "provider.custom.models.add": "إضافة نموذج",
+  "provider.custom.headers.label": "الترويسات (اختياري)",
+  "provider.custom.headers.key.label": "ترويسة",
+  "provider.custom.headers.key.placeholder": "Header-Name",
+  "provider.custom.headers.value.label": "القيمة",
+  "provider.custom.headers.value.placeholder": "قيمة",
+  "provider.custom.headers.remove": "إزالة الترويسة",
+  "provider.custom.headers.add": "إضافة ترويسة",
+  "provider.custom.error.providerID.required": "معرف الموفر مطلوب",
+  "provider.custom.error.providerID.format": "استخدم أحرفًا صغيرة، أرقامًا، شرطات، أو شرطات سفلية",
+  "provider.custom.error.providerID.exists": "معرف الموفر هذا موجود بالفعل",
+  "provider.custom.error.name.required": "اسم العرض مطلوب",
+  "provider.custom.error.baseURL.required": "عنوان URL الأساسي مطلوب",
+  "provider.custom.error.baseURL.format": "يجب أن يبدأ بـ http:// أو https://",
+  "provider.custom.error.required": "مطلوب",
+  "provider.custom.error.duplicate": "مكرر",
   "provider.disconnect.toast.disconnected.title": "تم فصل {{provider}}",
   "provider.disconnect.toast.disconnected.description": "لم تعد نماذج {{provider}} متاحة.",
   "model.tag.free": "مجاني",
@@ -163,9 +186,9 @@ export const dict = {
   "model.tooltip.reasoning.allowed": "يسمح بالاستنتاج",
   "model.tooltip.reasoning.none": "بدون استنتاج",
   "model.tooltip.context": "حد السياق {{limit}}",
-
   "common.search.placeholder": "بحث",
   "common.goBack": "رجوع",
+  "common.goForward": "انتقل للأمام",
   "common.loading": "جارٍ التحميل",
   "common.loading.ellipsis": "...",
   "common.cancel": "إلغاء",
@@ -176,14 +199,12 @@ export const dict = {
   "common.saving": "جارٍ الحفظ...",
   "common.default": "افتراضي",
   "common.attachment": "مرفق",
-
   "prompt.placeholder.shell": "أدخل أمر shell...",
-  "prompt.placeholder.normal": 'اسأل أي شيء... "{{example}}"',
+  "prompt.placeholder.normal": "اسأل أي شيء... \"{{example}}\"",
   "prompt.placeholder.summarizeComments": "لخّص التعليقات…",
   "prompt.placeholder.summarizeComment": "لخّص التعليق…",
   "prompt.mode.shell": "Shell",
   "prompt.mode.shell.exit": "esc للخروج",
-
   "prompt.example.1": "إصلاح TODO في قاعدة التعليمات البرمجية",
   "prompt.example.2": "ما هو المكدس التقني لهذا المشروع؟",
   "prompt.example.3": "إصلاح الاختبارات المعطلة",
@@ -209,7 +230,6 @@ export const dict = {
   "prompt.example.23": "إضافة ترقيم الصفحات إلى هذه القائمة",
   "prompt.example.24": "إنشاء أمر CLI لـ...",
   "prompt.example.25": "كيف تعمل متغيرات البيئة هنا؟",
-
   "prompt.popover.emptyResults": "لا توجد نتائج مطابقة",
   "prompt.popover.emptyCommands": "لا توجد أوامر مطابقة",
   "prompt.dropzone.label": "أفلت الصور أو ملفات PDF هنا",
@@ -225,7 +245,6 @@ export const dict = {
   "prompt.attachment.remove": "إزالة المرفق",
   "prompt.action.send": "إرسال",
   "prompt.action.stop": "توقف",
-
   "prompt.toast.pasteUnsupported.title": "لصق غير مدعوم",
   "prompt.toast.pasteUnsupported.description": "يمكن لصق الصور أو ملفات PDF فقط هنا.",
   "prompt.toast.modelAgentRequired.title": "حدد وكيلاً ونموذجاً",
@@ -236,24 +255,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "فشل إرسال الأمر",
   "prompt.toast.promptSendFailed.title": "فشل إرسال الموجه",
   "prompt.toast.promptSendFailed.description": "تعذر استرداد الجلسة",
-
   "dialog.mcp.title": "MCPs",
   "dialog.mcp.description": "{{enabled}} من {{total}} مفعل",
   "dialog.mcp.empty": "لم يتم تكوين MCPs",
-
   "dialog.lsp.empty": "تم الكشف تلقائيًا عن LSPs من أنواع الملفات",
   "dialog.plugins.empty": "الإضافات المكونة في opencode.json",
-
   "mcp.status.connected": "متصل",
   "mcp.status.failed": "فشل",
   "mcp.status.needs_auth": "يحتاج إلى مصادقة",
   "mcp.status.disabled": "معطل",
-
   "dialog.fork.empty": "لا توجد رسائل للتفرع منها",
-
   "dialog.directory.search.placeholder": "البحث في المجلدات",
   "dialog.directory.empty": "لم يتم العثور على مجلدات",
-
   "dialog.server.title": "الخوادم",
   "dialog.server.description": "تبديل خادم OpenCode الذي يتصل به هذا التطبيق.",
   "dialog.server.search.placeholder": "البحث في الخوادم",
@@ -265,20 +278,17 @@ export const dict = {
   "dialog.server.add.checking": "جارٍ التحقق...",
   "dialog.server.add.button": "إضافة خادم",
   "dialog.server.default.title": "الخادم الافتراضي",
-  "dialog.server.default.description":
-    "الاتصال بهذا الخادم عند بدء تشغيل التطبيق بدلاً من بدء خادم محلي. يتطلب إعادة التشغيل.",
+  "dialog.server.default.description": "الاتصال بهذا الخادم عند بدء تشغيل التطبيق بدلاً من بدء خادم محلي. يتطلب إعادة التشغيل.",
   "dialog.server.default.none": "لم يتم تحديد خادم",
   "dialog.server.default.set": "تعيين الخادم الحالي كافتراضي",
   "dialog.server.default.clear": "مسح",
   "dialog.server.action.remove": "إزالة الخادم",
-
   "dialog.server.menu.edit": "تعديل",
   "dialog.server.menu.default": "تعيين كافتراضي",
   "dialog.server.menu.defaultRemove": "إزالة الافتراضي",
   "dialog.server.menu.delete": "حذف",
   "dialog.server.current": "الخادم الحالي",
   "dialog.server.status.default": "افتراضي",
-
   "dialog.project.edit.title": "تحرير المشروع",
   "dialog.project.edit.name": "الاسم",
   "dialog.project.edit.icon": "أيقونة",
@@ -287,21 +297,18 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "موصى به: 128x128px",
   "dialog.project.edit.color": "لون",
   "dialog.project.edit.color.select": "اختر لون {{color}}",
-
   "dialog.project.edit.worktree.startup": "سكريبت بدء تشغيل مساحة العمل",
   "dialog.project.edit.worktree.startup.description": "يتم تشغيله بعد إنشاء مساحة عمل جديدة (شجرة عمل).",
   "dialog.project.edit.worktree.startup.placeholder": "مثال: bun install",
   "context.breakdown.title": "تفصيل السياق",
-  "context.breakdown.note": 'تفصيل تقريبي لرموز الإدخال. يشمل "أخرى" تعريفات الأدوات والنفقات العامة.',
+  "context.breakdown.note": "تفصيل تقريبي لرموز الإدخال. يشمل \"أخرى\" تعريفات الأدوات والنفقات العامة.",
   "context.breakdown.system": "النظام",
   "context.breakdown.user": "المستخدم",
   "context.breakdown.assistant": "المساعد",
   "context.breakdown.tool": "استدعاءات الأداة",
   "context.breakdown.other": "أخرى",
-
   "context.systemPrompt.title": "موجه النظام",
   "context.rawMessages.title": "الرسائل الخام",
-
   "context.stats.session": "جلسة",
   "context.stats.messages": "رسائل",
   "context.stats.provider": "موفر",
@@ -318,34 +325,42 @@ export const dict = {
   "context.stats.totalCost": "التكلفة الإجمالية",
   "context.stats.sessionCreated": "تم إنشاء الجلسة",
   "context.stats.lastActivity": "آخر نشاط",
-
   "context.usage.tokens": "رموز",
   "context.usage.usage": "استخدام",
   "context.usage.cost": "تكلفة",
   "context.usage.clickToView": "انقر لعرض السياق",
   "context.usage.view": "عرض استخدام السياق",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "لغة",
   "toast.language.description": "تم التبديل إلى {{language}}",
-
   "toast.theme.title": "تم تبديل السمة",
   "toast.scheme.title": "مخطط الألوان",
-
-  "toast.permissions.autoaccept.on.title": "قبول التعديلات تلقائيًا",
-  "toast.permissions.autoaccept.on.description": "سيتم الموافقة تلقائيًا على أذونات التحرير والكتابة",
-  "toast.permissions.autoaccept.off.title": "توقف قبول التعديلات تلقائيًا",
-  "toast.permissions.autoaccept.off.description": "ستتطلب أذونات التحرير والكتابة موافقة",
-
   "toast.workspace.enabled.title": "تم تمكين مساحات العمل",
   "toast.workspace.enabled.description": "الآن يتم عرض عدة worktrees في الشريط الجانبي",
   "toast.workspace.disabled.title": "تم تعطيل مساحات العمل",
   "toast.workspace.disabled.description": "يتم عرض worktree الرئيسي فقط في الشريط الجانبي",
-
+  "toast.permissions.autoaccept.on.title": "قبول التعديلات تلقائيًا",
+  "toast.permissions.autoaccept.on.description": "سيتم الموافقة تلقائيًا على أذونات التحرير والكتابة",
+  "toast.permissions.autoaccept.off.title": "توقف قبول التعديلات تلقائيًا",
+  "toast.permissions.autoaccept.off.description": "ستتطلب أذونات التحرير والكتابة موافقة",
   "toast.model.none.title": "لم يتم تحديد نموذج",
   "toast.model.none.description": "قم بتوصيل موفر لتلخيص هذه الجلسة",
-
   "toast.file.loadFailed.title": "فشل تحميل الملف",
-
   "toast.file.listFailed.title": "فشل سرد الملفات",
   "toast.context.noLineSelection.title": "لا يوجد تحديد للأسطر",
   "toast.context.noLineSelection.description": "حدد نطاق أسطر في تبويب ملف أولاً.",
@@ -354,19 +369,15 @@ export const dict = {
   "toast.session.share.success.description": "تم نسخ عنوان URL للمشاركة إلى الحافظة!",
   "toast.session.share.failed.title": "فشل مشاركة الجلسة",
   "toast.session.share.failed.description": "حدث خطأ أثناء مشاركة الجلسة",
-
   "toast.session.unshare.success.title": "تم إلغاء مشاركة الجلسة",
   "toast.session.unshare.success.description": "تم إلغاء مشاركة الجلسة بنجاح!",
   "toast.session.unshare.failed.title": "فشل إلغاء مشاركة الجلسة",
   "toast.session.unshare.failed.description": "حدث خطأ أثناء إلغاء مشاركة الجلسة",
-
   "toast.session.listFailed.title": "فشل تحميل الجلسات لـ {{project}}",
-
   "toast.update.title": "تحديث متاح",
   "toast.update.description": "نسخة جديدة من OpenCode ({{version}}) متاحة الآن للتثبيت.",
   "toast.update.action.installRestart": "تثبيت وإعادة تشغيل",
   "toast.update.action.notYet": "ليس الآن",
-
   "error.page.title": "حدث خطأ ما",
   "error.page.description": "حدث خطأ أثناء تحميل التطبيق.",
   "error.page.details.label": "تفاصيل الخطأ",
@@ -377,12 +388,9 @@ export const dict = {
   "error.page.report.prefix": "يرجى الإبلاغ عن هذا الخطأ لفريق OpenCode",
   "error.page.report.discord": "على Discord",
   "error.page.version": "الإصدار: {{version}}",
-
-  "error.dev.rootNotFound":
-    "لم يتم العثور على العنصر الجذري. هل نسيت إضافته إلى index.html؟ أو ربما تمت كتابة سمة id بشكل خاطئ؟",
-
+  "error.dev.rootNotFound": "لم يتم العثور على العنصر الجذري. هل نسيت إضافته إلى index.html؟ أو ربما تمت كتابة سمة id بشكل خاطئ؟",
   "error.globalSync.connectFailed": "تعذر الاتصال بالخادم. هل هناك خادم يعمل في `{{url}}`؟",
-
+  "directory.error.invalidUrl": "دليل غير صالح في عنوان URL.",
   "error.chain.unknown": "خطأ غير معروف",
   "error.chain.causedBy": "بسبب:",
   "error.chain.apiError": "خطأ API",
@@ -392,31 +400,26 @@ export const dict = {
   "error.chain.didYouMean": "هل كنت تعني: {{suggestions}}",
   "error.chain.modelNotFound": "النموذج غير موجود: {{provider}}/{{model}}",
   "error.chain.checkConfig": "تحقق من أسماء الموفر/النموذج في التكوين (opencode.json)",
-  "error.chain.mcpFailed": 'فشل خادم MCP "{{name}}". لاحظ أن OpenCode لا يدعم مصادقة MCP بعد.',
+  "error.chain.mcpFailed": "فشل خادم MCP \"{{name}}\". لاحظ أن OpenCode لا يدعم مصادقة MCP بعد.",
   "error.chain.providerAuthFailed": "فشلت مصادقة الموفر ({{provider}}): {{message}}",
-  "error.chain.providerInitFailed": 'فشل تهيئة الموفر "{{provider}}". تحقق من بيانات الاعتماد والتكوين.',
+  "error.chain.providerInitFailed": "فشل تهيئة الموفر \"{{provider}}\". تحقق من بيانات الاعتماد والتكوين.",
   "error.chain.configJsonInvalid": "ملف التكوين في {{path}} ليس JSON(C) صالحًا",
   "error.chain.configJsonInvalidWithMessage": "ملف التكوين في {{path}} ليس JSON(C) صالحًا: {{message}}",
-  "error.chain.configDirectoryTypo":
-    'الدليل "{{dir}}" في {{path}} غير صالح. أعد تسمية الدليل إلى "{{suggestion}}" أو قم بإزالته. هذا خطأ مطبعي شائع.',
+  "error.chain.configDirectoryTypo": "الدليل \"{{dir}}\" في {{path}} غير صالح. أعد تسمية الدليل إلى \"{{suggestion}}\" أو قم بإزالته. هذا خطأ مطبعي شائع.",
   "error.chain.configFrontmatterError": "فشل تحليل frontmatter في {{path}}:\n{{message}}",
   "error.chain.configInvalid": "ملف التكوين في {{path}} غير صالح",
   "error.chain.configInvalidWithMessage": "ملف التكوين في {{path}} غير صالح: {{message}}",
-
   "notification.permission.title": "مطلوب إذن",
   "notification.permission.description": "{{sessionTitle}} في {{projectName}} يحتاج إلى إذن",
   "notification.question.title": "سؤال",
   "notification.question.description": "{{sessionTitle}} في {{projectName}} لديه سؤال",
   "notification.action.goToSession": "انتقل إلى الجلسة",
-
   "notification.session.responseReady.title": "الاستجابة جاهزة",
   "notification.session.error.title": "خطأ في الجلسة",
   "notification.session.error.fallbackDescription": "حدث خطأ",
-
   "home.recentProjects": "المشاريع الحديثة",
   "home.empty.title": "لا توجد مشاريع حديثة",
   "home.empty.description": "ابدأ بفتح مشروع محلي",
-
   "session.tab.session": "جلسة",
   "session.tab.review": "مراجعة",
   "session.tab.context": "سياق",
@@ -435,17 +438,18 @@ export const dict = {
   "session.messages.loadEarlier": "تحميل الرسائل السابقة",
   "session.messages.loading": "جارٍ تحميل الرسائل...",
   "session.messages.jumpToLatest": "الانتقال إلى الأحدث",
-
   "session.context.addToContext": "إضافة {{selection}} إلى السياق",
-
   "session.new.worktree.main": "الفرع الرئيسي",
   "session.new.worktree.mainWithBranch": "الفرع الرئيسي ({{branch}})",
   "session.new.worktree.create": "إنشاء شجرة عمل جديدة",
   "session.new.lastModified": "آخر تعديل",
-
   "session.header.search.placeholder": "بحث {{project}}",
   "session.header.searchFiles": "بحث عن الملفات",
-
+  "session.header.openIn": "فتح في",
+  "session.header.open.action": "فتح {{app}}",
+  "session.header.open.ariaLabel": "فتح في {{app}}",
+  "session.header.open.menu": "خيارات الفتح",
+  "session.header.open.copyPath": "نسخ المسار",
   "status.popover.trigger": "الحالة",
   "status.popover.ariaLabel": "إعدادات الخوادم",
   "status.popover.tab.servers": "الخوادم",
@@ -453,7 +457,6 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "الإضافات",
   "status.popover.action.manageServers": "إدارة الخوادم",
-
   "session.share.popover.title": "نشر على الويب",
   "session.share.popover.description.shared": "هذه الجلسة عامة على الويب. يمكن لأي شخص لديه الرابط الوصول إليها.",
   "session.share.popover.description.unshared": "شارك الجلسة علنًا على الويب. ستكون متاحة لأي شخص لديه الرابط.",
@@ -465,10 +468,8 @@ export const dict = {
   "session.share.action.view": "عرض",
   "session.share.copy.copied": "تم النسخ",
   "session.share.copy.copyLink": "نسخ الرابط",
-
   "lsp.tooltip.none": "لا توجد خوادم LSP",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "جارٍ تحميل الموجه...",
   "terminal.loading": "جارٍ تحميل المحطة الطرفية...",
   "terminal.title": "محطة طرفية",
@@ -476,7 +477,6 @@ export const dict = {
   "terminal.close": "إغلاق المحطة الطرفية",
   "terminal.connectionLost.title": "فقد الاتصال",
   "terminal.connectionLost.description": "انقطع اتصال المحطة الطرفية. يمكن أن يحدث هذا عند إعادة تشغيل الخادم.",
-
   "common.closeTab": "إغلاق علامة التبويب",
   "common.dismiss": "رفض",
   "common.requestFailed": "فشل الطلب",
@@ -490,7 +490,6 @@ export const dict = {
   "common.edit": "تحرير",
   "common.loadMore": "تحميل المزيد",
   "common.key.esc": "ESC",
-
   "sidebar.menu.toggle": "تبديل القائمة",
   "sidebar.nav.projectsAndSessions": "المشاريع والجلسات",
   "sidebar.settings": "الإعدادات",
@@ -502,21 +501,19 @@ export const dict = {
   "sidebar.gettingStarted.line2": "قم بتوصيل أي موفر لاستخدام النماذج، بما في ذلك Claude و GPT و Gemini وما إلى ذلك.",
   "sidebar.project.recentSessions": "الجلسات الحديثة",
   "sidebar.project.viewAllSessions": "عرض جميع الجلسات",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "سطح المكتب",
   "settings.section.server": "الخادم",
   "settings.tab.general": "عام",
   "settings.tab.shortcuts": "اختصارات",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.title": "تكامل WSL",
+  "settings.desktop.wsl.description": "تشغيل خادم OpenCode داخل WSL على Windows.",
   "settings.general.section.appearance": "المظهر",
   "settings.general.section.notifications": "إشعارات النظام",
   "settings.general.section.updates": "التحديثات",
   "settings.general.section.sounds": "المؤثرات الصوتية",
-
+  "settings.general.section.display": "شاشة العرض",
   "settings.general.row.language.title": "اللغة",
   "settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode",
   "settings.general.row.appearance.title": "المظهر",
@@ -525,10 +522,11 @@ export const dict = {
   "settings.general.row.theme.description": "تخصيص سمة OpenCode.",
   "settings.general.row.font.title": "الخط",
   "settings.general.row.font.description": "تخصيص الخط الأحادي المستخدم في كتل التعليمات البرمجية",
-
+  "settings.general.row.wayland.title": "استخدام Wayland الأصلي",
+  "settings.general.row.wayland.description": "تعطيل التراجع إلى X11 على Wayland. يتطلب إعادة التشغيل.",
+  "settings.general.row.wayland.tooltip": "على Linux مع شاشات بمعدلات تحديث مختلطة، يمكن أن يكون Wayland الأصلي أكثر استقرارًا.",
   "settings.general.row.releaseNotes.title": "ملاحظات الإصدار",
-  "settings.general.row.releaseNotes.description": 'عرض نوافذ "ما الجديد" المنبثقة بعد التحديثات',
-
+  "settings.general.row.releaseNotes.description": "عرض نوافذ \"ما الجديد\" المنبثقة بعد التحديثات",
   "settings.updates.row.startup.title": "التحقق من التحديثات عند بدء التشغيل",
   "settings.updates.row.startup.description": "التحقق تلقائيًا من التحديثات عند تشغيل OpenCode",
   "settings.updates.row.check.title": "التحقق من التحديثات",
@@ -594,21 +592,18 @@ export const dict = {
   "sound.option.yup04": "نعم 04",
   "sound.option.yup05": "نعم 05",
   "sound.option.yup06": "نعم 06",
-
   "settings.general.notifications.agent.title": "وكيل",
   "settings.general.notifications.agent.description": "عرض إشعار النظام عندما يكتمل الوكيل أو يحتاج إلى اهتمام",
   "settings.general.notifications.permissions.title": "أذونات",
   "settings.general.notifications.permissions.description": "عرض إشعار النظام عند الحاجة إلى إذن",
   "settings.general.notifications.errors.title": "أخطاء",
   "settings.general.notifications.errors.description": "عرض إشعار النظام عند حدوث خطأ",
-
   "settings.general.sounds.agent.title": "وكيل",
   "settings.general.sounds.agent.description": "تشغيل صوت عندما يكتمل الوكيل أو يحتاج إلى اهتمام",
   "settings.general.sounds.permissions.title": "أذونات",
   "settings.general.sounds.permissions.description": "تشغيل صوت عند الحاجة إلى إذن",
   "settings.general.sounds.errors.title": "أخطاء",
   "settings.general.sounds.errors.description": "تشغيل صوت عند حدوث خطأ",
-
   "settings.shortcuts.title": "اختصارات لوحة المفاتيح",
   "settings.shortcuts.reset.button": "إعادة التعيين إلى الافتراضيات",
   "settings.shortcuts.reset.toast.title": "تم إعادة تعيين الاختصارات",
@@ -619,14 +614,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "اضغط على المفاتيح",
   "settings.shortcuts.search.placeholder": "البحث في الاختصارات",
   "settings.shortcuts.search.empty": "لم يتم العثور على اختصارات",
-
   "settings.shortcuts.group.general": "عام",
   "settings.shortcuts.group.session": "جلسة",
   "settings.shortcuts.group.navigation": "تصفح",
   "settings.shortcuts.group.modelAndAgent": "النموذج والوكيل",
   "settings.shortcuts.group.terminal": "المحطة الطرفية",
   "settings.shortcuts.group.prompt": "موجه",
-
   "settings.providers.title": "الموفرون",
   "settings.providers.description": "ستكون إعدادات الموفر قابلة للتكوين هنا.",
   "settings.providers.section.connected": "الموفرون المتصلون",
@@ -644,21 +637,17 @@ export const dict = {
   "settings.commands.description": "ستكون إعدادات الأمر قابلة للتكوين هنا.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "ستكون إعدادات MCP قابلة للتكوين هنا.",
-
   "settings.permissions.title": "الأذونات",
   "settings.permissions.description": "تحكم في الأدوات التي يمكن للخادم استخدامها بشكل افتراضي.",
   "settings.permissions.section.tools": "الأدوات",
   "settings.permissions.toast.updateFailed.title": "فشل تحديث الأذونات",
-
   "settings.permissions.action.allow": "سماح",
   "settings.permissions.action.ask": "سؤال",
   "settings.permissions.action.deny": "رفض",
-
   "settings.permissions.tool.read.title": "قراءة",
   "settings.permissions.tool.read.description": "قراءة ملف (يطابق مسار الملف)",
   "settings.permissions.tool.edit.title": "تحرير",
-  "settings.permissions.tool.edit.description":
-    "تعديل الملفات، بما في ذلك التحرير والكتابة والتصحيحات والتحرير المتعدد",
+  "settings.permissions.tool.edit.description": "تعديل الملفات، بما في ذلك التحرير والكتابة والتصحيحات والتحرير المتعدد",
   "settings.permissions.tool.glob.title": "Glob",
   "settings.permissions.tool.glob.description": "مطابقة الملفات باستخدام أنماط glob",
   "settings.permissions.tool.grep.title": "Grep",
@@ -667,9 +656,9 @@ export const dict = {
   "settings.permissions.tool.list.description": "سرد الملفات داخل دليل",
   "settings.permissions.tool.bash.title": "Bash",
   "settings.permissions.tool.bash.description": "تشغيل أوامر shell",
-  "settings.permissions.tool.task.title": "Task",
+  "settings.permissions.tool.task.title": "مهمة",
   "settings.permissions.tool.task.description": "تشغيل الوكلاء الفرعيين",
-  "settings.permissions.tool.skill.title": "Skill",
+  "settings.permissions.tool.skill.title": "مهارة",
   "settings.permissions.tool.skill.description": "تحميل مهارة بالاسم",
   "settings.permissions.tool.lsp.title": "LSP",
   "settings.permissions.tool.lsp.description": "تشغيل استعلامات خادم اللغة",
@@ -687,12 +676,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "الوصول إلى الملفات خارج دليل المشروع",
   "settings.permissions.tool.doom_loop.title": "حلقة الموت",
   "settings.permissions.tool.doom_loop.description": "اكتشاف استدعاءات الأدوات المتكررة بمدخلات متطابقة",
-
   "session.delete.failed.title": "فشل حذف الجلسة",
   "session.delete.title": "حذف الجلسة",
-  "session.delete.confirm": 'حذف الجلسة "{{name}}"؟',
+  "session.delete.confirm": "حذف الجلسة \"{{name}}\"؟",
   "session.delete.button": "حذف الجلسة",
-
   "workspace.new": "مساحة عمل جديدة",
   "workspace.type.local": "محلي",
   "workspace.type.sandbox": "صندوق رمل",
@@ -709,13 +696,14 @@ export const dict = {
   "workspace.status.clean": "لم يتم اكتشاف تغييرات غير مدمجة.",
   "workspace.status.dirty": "تم اكتشاف تغييرات غير مدمجة في مساحة العمل هذه.",
   "workspace.delete.title": "حذف مساحة العمل",
-  "workspace.delete.confirm": 'حذف مساحة العمل "{{name}}"؟',
+  "workspace.delete.confirm": "حذف مساحة العمل \"{{name}}\"؟",
   "workspace.delete.button": "حذف مساحة العمل",
   "workspace.reset.title": "إعادة تعيين مساحة العمل",
-  "workspace.reset.confirm": 'إعادة تعيين مساحة العمل "{{name}}"؟',
+  "workspace.reset.confirm": "إعادة تعيين مساحة العمل \"{{name}}\"؟",
   "workspace.reset.button": "إعادة تعيين مساحة العمل",
   "workspace.reset.archived.none": "لن تتم أرشفة أي جلسات نشطة.",
   "workspace.reset.archived.one": "ستتم أرشفة جلسة واحدة.",
   "workspace.reset.archived.many": "ستتم أرشفة {{count}} جلسات.",
   "workspace.reset.note": "سيؤدي هذا إلى إعادة تعيين مساحة العمل لتتطابق مع الفرع الافتراضي.",
 }
+

+ 99 - 117
packages/app/src/i18n/br.ts

@@ -16,11 +16,9 @@ export const dict = {
   "command.category.permissions": "Permissões",
   "command.category.workspace": "Espaço de trabalho",
   "command.category.settings": "Configurações",
-
   "theme.scheme.system": "Sistema",
   "theme.scheme.light": "Claro",
   "theme.scheme.dark": "Escuro",
-
   "command.sidebar.toggle": "Alternar barra lateral",
   "command.project.open": "Abrir projeto",
   "command.provider.connect": "Conectar provedor",
@@ -31,17 +29,13 @@ export const dict = {
   "command.session.previous.unseen": "Sessão não lida anterior",
   "command.session.next.unseen": "Próxima sessão não lida",
   "command.session.archive": "Arquivar sessão",
-
   "command.palette": "Paleta de comandos",
-
   "command.theme.cycle": "Alternar tema",
   "command.theme.set": "Usar tema: {{theme}}",
   "command.theme.scheme.cycle": "Alternar esquema de cores",
   "command.theme.scheme.set": "Usar esquema de cores: {{scheme}}",
-
   "command.language.cycle": "Alternar idioma",
   "command.language.set": "Usar idioma: {{language}}",
-
   "command.session.new": "Nova sessão",
   "command.file.open": "Abrir arquivo",
   "command.tab.close": "Fechar aba",
@@ -72,6 +66,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Aceitar edições automaticamente",
   "command.permissions.autoaccept.disable": "Parar de aceitar edições automaticamente",
   "command.workspace.toggle": "Alternar espaços de trabalho",
+  "command.workspace.toggle.description": "Habilitar ou desabilitar múltiplos espaços de trabalho na barra lateral",
   "command.session.undo": "Desfazer",
   "command.session.undo.description": "Desfazer a última mensagem",
   "command.session.redo": "Refazer",
@@ -84,32 +79,30 @@ export const dict = {
   "command.session.share.description": "Compartilhar esta sessão e copiar a URL para a área de transferência",
   "command.session.unshare": "Parar de compartilhar sessão",
   "command.session.unshare.description": "Parar de compartilhar esta sessão",
-
   "palette.search.placeholder": "Buscar arquivos, comandos e sessões",
   "palette.empty": "Nenhum resultado encontrado",
   "palette.group.commands": "Comandos",
   "palette.group.files": "Arquivos",
-
   "dialog.provider.search.placeholder": "Buscar provedores",
   "dialog.provider.empty": "Nenhum provedor encontrado",
   "dialog.provider.group.popular": "Popular",
   "dialog.provider.group.other": "Outro",
   "dialog.provider.tag.recommended": "Recomendado",
+  "dialog.provider.opencode.note": "Modelos selecionados incluindo Claude, GPT, Gemini e mais",
   "dialog.provider.anthropic.note": "Conectar com Claude Pro/Max ou chave de API",
-  "dialog.provider.openai.note": "Conectar com ChatGPT Pro/Plus ou chave de API",
   "dialog.provider.copilot.note": "Conectar com Copilot ou chave de API",
-
+  "dialog.provider.openai.note": "Conectar com ChatGPT Pro/Plus ou chave de API",
+  "dialog.provider.google.note": "Modelos Gemini para respostas rápidas e estruturadas",
+  "dialog.provider.openrouter.note": "Acesse todos os modelos suportados de um único provedor",
+  "dialog.provider.vercel.note": "Acesso unificado a modelos de IA com roteamento inteligente",
   "dialog.model.select.title": "Selecionar modelo",
   "dialog.model.search.placeholder": "Buscar modelos",
   "dialog.model.empty": "Nenhum resultado de modelo",
   "dialog.model.manage": "Gerenciar modelos",
   "dialog.model.manage.description": "Personalizar quais modelos aparecem no seletor de modelos.",
-
   "dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo OpenCode",
   "dialog.model.unpaid.addMore.title": "Adicionar mais modelos de provedores populares",
-
   "dialog.provider.viewAll": "Ver mais provedores",
-
   "provider.connect.title": "Conectar {{provider}}",
   "provider.connect.title.anthropicProMax": "Entrar com Claude Pro/Max",
   "provider.connect.selectMethod": "Selecionar método de login para {{provider}}.",
@@ -117,34 +110,64 @@ export const dict = {
   "provider.connect.status.inProgress": "Autorização em andamento...",
   "provider.connect.status.waiting": "Aguardando autorização...",
   "provider.connect.status.failed": "Autorização falhou: {{error}}",
-  "provider.connect.apiKey.description":
-    "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no OpenCode.",
+  "provider.connect.apiKey.description": "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no OpenCode.",
   "provider.connect.apiKey.label": "Chave de API do {{provider}}",
   "provider.connect.apiKey.placeholder": "Chave de API",
   "provider.connect.apiKey.required": "A chave de API é obrigatória",
-  "provider.connect.opencodeZen.line1":
-    "OpenCode Zen oferece acesso a um conjunto selecionado de modelos confiáveis otimizados para agentes de código.",
-  "provider.connect.opencodeZen.line2":
-    "Com uma única chave de API você terá acesso a modelos como Claude, GPT, Gemini, GLM e mais.",
+  "provider.connect.opencodeZen.line1": "OpenCode Zen oferece acesso a um conjunto selecionado de modelos confiáveis otimizados para agentes de código.",
+  "provider.connect.opencodeZen.line2": "Com uma única chave de API você terá acesso a modelos como Claude, GPT, Gemini, GLM e mais.",
   "provider.connect.opencodeZen.visit.prefix": "Visite ",
   "provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
   "provider.connect.opencodeZen.visit.suffix": " para obter sua chave de API.",
   "provider.connect.oauth.code.visit.prefix": "Visite ",
   "provider.connect.oauth.code.visit.link": "este link",
-  "provider.connect.oauth.code.visit.suffix":
-    " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no OpenCode.",
+  "provider.connect.oauth.code.visit.suffix": " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no OpenCode.",
   "provider.connect.oauth.code.label": "Código de autorização {{method}}",
   "provider.connect.oauth.code.placeholder": "Código de autorização",
   "provider.connect.oauth.code.required": "O código de autorização é obrigatório",
   "provider.connect.oauth.code.invalid": "Código de autorização inválido",
   "provider.connect.oauth.auto.visit.prefix": "Visite ",
   "provider.connect.oauth.auto.visit.link": "este link",
-  "provider.connect.oauth.auto.visit.suffix":
-    " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no OpenCode.",
+  "provider.connect.oauth.auto.visit.suffix": " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no OpenCode.",
   "provider.connect.oauth.auto.confirmationCode": "Código de confirmação",
   "provider.connect.toast.connected.title": "{{provider}} conectado",
   "provider.connect.toast.connected.description": "Modelos do {{provider}} agora estão disponíveis para uso.",
-
+  "provider.custom.title": "Provedor personalizado",
+  "provider.custom.description.prefix": "Configure um provedor compatível com OpenAI. Veja a ",
+  "provider.custom.description.link": "documentação de configuração do provedor",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID do Provedor",
+  "provider.custom.field.providerID.placeholder": "meuprovedor",
+  "provider.custom.field.providerID.description": "Letras minúsculas, números, hifens ou sublinhados",
+  "provider.custom.field.name.label": "Nome de exibição",
+  "provider.custom.field.name.placeholder": "Meu Provedor de IA",
+  "provider.custom.field.baseURL.label": "URL Base",
+  "provider.custom.field.baseURL.placeholder": "https://api.meuprovedor.com/v1",
+  "provider.custom.field.apiKey.label": "Chave de API",
+  "provider.custom.field.apiKey.placeholder": "Chave de API",
+  "provider.custom.field.apiKey.description": "Opcional. Deixe em branco se gerenciar autenticação via cabeçalhos.",
+  "provider.custom.models.label": "Modelos",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "id-do-modelo",
+  "provider.custom.models.name.label": "Nome",
+  "provider.custom.models.name.placeholder": "Nome de Exibição",
+  "provider.custom.models.remove": "Remover modelo",
+  "provider.custom.models.add": "Adicionar modelo",
+  "provider.custom.headers.label": "Cabeçalhos (opcional)",
+  "provider.custom.headers.key.label": "Cabeçalho",
+  "provider.custom.headers.key.placeholder": "Nome-Do-Cabeçalho",
+  "provider.custom.headers.value.label": "Valor",
+  "provider.custom.headers.value.placeholder": "valor",
+  "provider.custom.headers.remove": "Remover cabeçalho",
+  "provider.custom.headers.add": "Adicionar cabeçalho",
+  "provider.custom.error.providerID.required": "ID do Provedor é obrigatório",
+  "provider.custom.error.providerID.format": "Use letras minúsculas, números, hifens ou sublinhados",
+  "provider.custom.error.providerID.exists": "Esse ID de provedor já existe",
+  "provider.custom.error.name.required": "Nome de exibição é obrigatório",
+  "provider.custom.error.baseURL.required": "URL Base é obrigatória",
+  "provider.custom.error.baseURL.format": "Deve começar com http:// ou https://",
+  "provider.custom.error.required": "Obrigatório",
+  "provider.custom.error.duplicate": "Duplicado",
   "provider.disconnect.toast.disconnected.title": "{{provider}} desconectado",
   "provider.disconnect.toast.disconnected.description": "Os modelos de {{provider}} não estão mais disponíveis.",
   "model.tag.free": "Grátis",
@@ -163,9 +186,9 @@ export const dict = {
   "model.tooltip.reasoning.allowed": "Permite raciocínio",
   "model.tooltip.reasoning.none": "Sem raciocínio",
   "model.tooltip.context": "Limite de contexto {{limit}}",
-
   "common.search.placeholder": "Buscar",
   "common.goBack": "Voltar",
+  "common.goForward": "Avançar",
   "common.loading": "Carregando",
   "common.loading.ellipsis": "...",
   "common.cancel": "Cancelar",
@@ -176,14 +199,12 @@ export const dict = {
   "common.saving": "Salvando...",
   "common.default": "Padrão",
   "common.attachment": "anexo",
-
   "prompt.placeholder.shell": "Digite comando do shell...",
-  "prompt.placeholder.normal": 'Pergunte qualquer coisa... "{{example}}"',
+  "prompt.placeholder.normal": "Pergunte qualquer coisa... \"{{example}}\"",
   "prompt.placeholder.summarizeComments": "Resumir comentários…",
   "prompt.placeholder.summarizeComment": "Resumir comentário…",
   "prompt.mode.shell": "Shell",
   "prompt.mode.shell.exit": "esc para sair",
-
   "prompt.example.1": "Corrigir um TODO no código",
   "prompt.example.2": "Qual é a stack tecnológica deste projeto?",
   "prompt.example.3": "Corrigir testes quebrados",
@@ -209,7 +230,6 @@ export const dict = {
   "prompt.example.23": "Adicionar paginação a esta lista",
   "prompt.example.24": "Criar um comando CLI para...",
   "prompt.example.25": "Como funcionam as variáveis de ambiente aqui?",
-
   "prompt.popover.emptyResults": "Nenhum resultado correspondente",
   "prompt.popover.emptyCommands": "Nenhum comando correspondente",
   "prompt.dropzone.label": "Solte imagens ou PDFs aqui",
@@ -225,7 +245,6 @@ export const dict = {
   "prompt.attachment.remove": "Remover anexo",
   "prompt.action.send": "Enviar",
   "prompt.action.stop": "Parar",
-
   "prompt.toast.pasteUnsupported.title": "Colagem não suportada",
   "prompt.toast.pasteUnsupported.description": "Somente imagens ou PDFs podem ser colados aqui.",
   "prompt.toast.modelAgentRequired.title": "Selecione um agente e modelo",
@@ -236,23 +255,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "Falha ao enviar comando",
   "prompt.toast.promptSendFailed.title": "Falha ao enviar prompt",
   "prompt.toast.promptSendFailed.description": "Não foi possível recuperar a sessão",
-
   "dialog.mcp.title": "MCPs",
-  "dialog.mcp.description": "{{enabled}} de {{total}} habilitados",
+  "dialog.mcp.description": "{{enabled}} of {{total}} habilitados",
   "dialog.mcp.empty": "Nenhum MCP configurado",
-
   "dialog.lsp.empty": "LSPs detectados automaticamente pelos tipos de arquivo",
   "dialog.plugins.empty": "Plugins configurados em opencode.json",
   "mcp.status.connected": "conectado",
   "mcp.status.failed": "falhou",
   "mcp.status.needs_auth": "precisa de autenticação",
   "mcp.status.disabled": "desabilitado",
-
   "dialog.fork.empty": "Nenhuma mensagem para bifurcar",
-
   "dialog.directory.search.placeholder": "Buscar pastas",
   "dialog.directory.empty": "Nenhuma pasta encontrada",
-
   "dialog.server.title": "Servidores",
   "dialog.server.description": "Trocar para qual servidor OpenCode este aplicativo se conecta.",
   "dialog.server.search.placeholder": "Buscar servidores",
@@ -264,13 +278,11 @@ export const dict = {
   "dialog.server.add.checking": "Verificando...",
   "dialog.server.add.button": "Adicionar",
   "dialog.server.default.title": "Servidor padrão",
-  "dialog.server.default.description":
-    "Conectar a este servidor na inicialização do aplicativo ao invés de iniciar um servidor local. Requer reinicialização.",
+  "dialog.server.default.description": "Conectar a este servidor na inicialização do aplicativo ao invés de iniciar um servidor local. Requer reinicialização.",
   "dialog.server.default.none": "Nenhum servidor selecionado",
   "dialog.server.default.set": "Definir servidor atual como padrão",
   "dialog.server.default.clear": "Limpar",
   "dialog.server.action.remove": "Remover servidor",
-
   "dialog.server.menu.edit": "Editar",
   "dialog.server.menu.default": "Definir como padrão",
   "dialog.server.menu.defaultRemove": "Remover padrão",
@@ -288,19 +300,15 @@ export const dict = {
   "dialog.project.edit.worktree.startup": "Script de inicialização do espaço de trabalho",
   "dialog.project.edit.worktree.startup.description": "Executa após criar um novo espaço de trabalho (worktree).",
   "dialog.project.edit.worktree.startup.placeholder": "ex: bun install",
-
   "context.breakdown.title": "Detalhamento do Contexto",
-  "context.breakdown.note":
-    'Detalhamento aproximado dos tokens de entrada. "Outros" inclui definições de ferramentas e overhead.',
+  "context.breakdown.note": "Detalhamento aproximado dos tokens de entrada. \"Outros\" inclui definições de ferramentas e overhead.",
   "context.breakdown.system": "Sistema",
   "context.breakdown.user": "Usuário",
   "context.breakdown.assistant": "Assistente",
   "context.breakdown.tool": "Chamadas de Ferramentas",
   "context.breakdown.other": "Outros",
-
   "context.systemPrompt.title": "Prompt do Sistema",
   "context.rawMessages.title": "Mensagens brutas",
-
   "context.stats.session": "Sessão",
   "context.stats.messages": "Mensagens",
   "context.stats.provider": "Provedor",
@@ -317,34 +325,42 @@ export const dict = {
   "context.stats.totalCost": "Custo Total",
   "context.stats.sessionCreated": "Sessão Criada",
   "context.stats.lastActivity": "Última Atividade",
-
   "context.usage.tokens": "Tokens",
   "context.usage.usage": "Uso",
   "context.usage.cost": "Custo",
   "context.usage.clickToView": "Clique para ver o contexto",
   "context.usage.view": "Ver uso do contexto",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "Idioma",
   "toast.language.description": "Alterado para {{language}}",
-
   "toast.theme.title": "Tema alterado",
   "toast.scheme.title": "Esquema de cores",
-
-  "toast.permissions.autoaccept.on.title": "Aceitando edições automaticamente",
-  "toast.permissions.autoaccept.on.description": "Permissões de edição e escrita serão aprovadas automaticamente",
-  "toast.permissions.autoaccept.off.title": "Parou de aceitar edições automaticamente",
-  "toast.permissions.autoaccept.off.description": "Permissões de edição e escrita exigirão aprovação",
-
   "toast.workspace.enabled.title": "Espaços de trabalho ativados",
   "toast.workspace.enabled.description": "Várias worktrees agora são exibidas na barra lateral",
   "toast.workspace.disabled.title": "Espaços de trabalho desativados",
   "toast.workspace.disabled.description": "Apenas a worktree principal é exibida na barra lateral",
-
+  "toast.permissions.autoaccept.on.title": "Aceitando edições automaticamente",
+  "toast.permissions.autoaccept.on.description": "Permissões de edição e escrita serão aprovadas automaticamente",
+  "toast.permissions.autoaccept.off.title": "Parou de aceitar edições automaticamente",
+  "toast.permissions.autoaccept.off.description": "Permissões de edição e escrita exigirão aprovação",
   "toast.model.none.title": "Nenhum modelo selecionado",
   "toast.model.none.description": "Conecte um provedor para resumir esta sessão",
-
   "toast.file.loadFailed.title": "Falha ao carregar arquivo",
-
   "toast.file.listFailed.title": "Falha ao listar arquivos",
   "toast.context.noLineSelection.title": "Nenhuma seleção de linhas",
   "toast.context.noLineSelection.description": "Selecione primeiro um intervalo de linhas em uma aba de arquivo.",
@@ -353,19 +369,15 @@ export const dict = {
   "toast.session.share.success.description": "URL compartilhada copiada para a área de transferência!",
   "toast.session.share.failed.title": "Falha ao compartilhar sessão",
   "toast.session.share.failed.description": "Ocorreu um erro ao compartilhar a sessão",
-
   "toast.session.unshare.success.title": "Sessão não compartilhada",
   "toast.session.unshare.success.description": "Sessão deixou de ser compartilhada com sucesso!",
   "toast.session.unshare.failed.title": "Falha ao parar de compartilhar sessão",
   "toast.session.unshare.failed.description": "Ocorreu um erro ao parar de compartilhar a sessão",
-
   "toast.session.listFailed.title": "Falha ao carregar sessões para {{project}}",
-
   "toast.update.title": "Atualização disponível",
   "toast.update.description": "Uma nova versão do OpenCode ({{version}}) está disponível para instalação.",
   "toast.update.action.installRestart": "Instalar e reiniciar",
   "toast.update.action.notYet": "Agora não",
-
   "error.page.title": "Algo deu errado",
   "error.page.description": "Ocorreu um erro ao carregar a aplicação.",
   "error.page.details.label": "Detalhes do Erro",
@@ -376,12 +388,9 @@ export const dict = {
   "error.page.report.prefix": "Por favor, reporte este erro para a equipe do OpenCode",
   "error.page.report.discord": "no Discord",
   "error.page.version": "Versão: {{version}}",
-
-  "error.dev.rootNotFound":
-    "Elemento raiz não encontrado. Você esqueceu de adicioná-lo ao seu index.html? Ou talvez o atributo id foi escrito incorretamente?",
-
+  "error.dev.rootNotFound": "Elemento raiz não encontrado. Você esqueceu de adicioná-lo ao seu index.html? Ou talvez o atributo id foi escrito incorretamente?",
   "error.globalSync.connectFailed": "Não foi possível conectar ao servidor. Há um servidor executando em `{{url}}`?",
-
+  "directory.error.invalidUrl": "Diretório inválido na URL.",
   "error.chain.unknown": "Erro desconhecido",
   "error.chain.causedBy": "Causado por:",
   "error.chain.apiError": "Erro de API",
@@ -391,33 +400,26 @@ export const dict = {
   "error.chain.didYouMean": "Você quis dizer: {{suggestions}}",
   "error.chain.modelNotFound": "Modelo não encontrado: {{provider}}/{{model}}",
   "error.chain.checkConfig": "Verifique os nomes de provedor/modelo na sua configuração (opencode.json)",
-  "error.chain.mcpFailed": 'Servidor MCP "{{name}}" falhou. Nota: OpenCode ainda não suporta autenticação MCP.',
+  "error.chain.mcpFailed": "Servidor MCP \"{{name}}\" falhou. Nota: OpenCode ainda não suporta autenticação MCP.",
   "error.chain.providerAuthFailed": "Autenticação do provedor falhou ({{provider}}): {{message}}",
-  "error.chain.providerInitFailed":
-    'Falha ao inicializar provedor "{{provider}}". Verifique credenciais e configuração.',
+  "error.chain.providerInitFailed": "Falha ao inicializar provedor \"{{provider}}\". Verifique credenciais e configuração.",
   "error.chain.configJsonInvalid": "Arquivo de configuração em {{path}} não é um JSON(C) válido",
-  "error.chain.configJsonInvalidWithMessage":
-    "Arquivo de configuração em {{path}} não é um JSON(C) válido: {{message}}",
-  "error.chain.configDirectoryTypo":
-    'Diretório "{{dir}}" em {{path}} não é válido. Renomeie o diretório para "{{suggestion}}" ou remova-o. Este é um erro de digitação comum.',
+  "error.chain.configJsonInvalidWithMessage": "Arquivo de configuração em {{path}} não é um JSON(C) válido: {{message}}",
+  "error.chain.configDirectoryTypo": "Diretório \"{{dir}}\" em {{path}} não é válido. Renomeie o diretório para \"{{suggestion}}\" ou remova-o. Este é um erro de digitação comum.",
   "error.chain.configFrontmatterError": "Falha ao analisar frontmatter em {{path}}:\n{{message}}",
   "error.chain.configInvalid": "Arquivo de configuração em {{path}} é inválido",
   "error.chain.configInvalidWithMessage": "Arquivo de configuração em {{path}} é inválido: {{message}}",
-
   "notification.permission.title": "Permissão necessária",
   "notification.permission.description": "{{sessionTitle}} em {{projectName}} precisa de permissão",
   "notification.question.title": "Pergunta",
   "notification.question.description": "{{sessionTitle}} em {{projectName}} tem uma pergunta",
   "notification.action.goToSession": "Ir para sessão",
-
   "notification.session.responseReady.title": "Resposta pronta",
   "notification.session.error.title": "Erro na sessão",
   "notification.session.error.fallbackDescription": "Ocorreu um erro",
-
   "home.recentProjects": "Projetos recentes",
   "home.empty.title": "Nenhum projeto recente",
   "home.empty.description": "Comece abrindo um projeto local",
-
   "session.tab.session": "Sessão",
   "session.tab.review": "Revisão",
   "session.tab.context": "Contexto",
@@ -436,17 +438,18 @@ export const dict = {
   "session.messages.loadEarlier": "Carregar mensagens anteriores",
   "session.messages.loading": "Carregando mensagens...",
   "session.messages.jumpToLatest": "Ir para a mais recente",
-
   "session.context.addToContext": "Adicionar {{selection}} ao contexto",
-
   "session.new.worktree.main": "Branch principal",
   "session.new.worktree.mainWithBranch": "Branch principal ({{branch}})",
   "session.new.worktree.create": "Criar novo worktree",
   "session.new.lastModified": "Última modificação",
-
   "session.header.search.placeholder": "Buscar {{project}}",
   "session.header.searchFiles": "Buscar arquivos",
-
+  "session.header.openIn": "Abrir em",
+  "session.header.open.action": "Abrir {{app}}",
+  "session.header.open.ariaLabel": "Abrir em {{app}}",
+  "session.header.open.menu": "Opções de abertura",
+  "session.header.open.copyPath": "Copiar caminho",
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Configurações de servidores",
   "status.popover.tab.servers": "Servidores",
@@ -454,12 +457,9 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "Plugins",
   "status.popover.action.manageServers": "Gerenciar servidores",
-
   "session.share.popover.title": "Publicar na web",
-  "session.share.popover.description.shared":
-    "Esta sessão é pública na web. Está acessível para qualquer pessoa com o link.",
-  "session.share.popover.description.unshared":
-    "Compartilhar sessão publicamente na web. Estará acessível para qualquer pessoa com o link.",
+  "session.share.popover.description.shared": "Esta sessão é pública na web. Está acessível para qualquer pessoa com o link.",
+  "session.share.popover.description.unshared": "Compartilhar sessão publicamente na web. Estará acessível para qualquer pessoa com o link.",
   "session.share.action.share": "Compartilhar",
   "session.share.action.publish": "Publicar",
   "session.share.action.publishing": "Publicando...",
@@ -468,19 +468,15 @@ export const dict = {
   "session.share.action.view": "Ver",
   "session.share.copy.copied": "Copiado",
   "session.share.copy.copyLink": "Copiar link",
-
   "lsp.tooltip.none": "Nenhum servidor LSP",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "Carregando prompt...",
   "terminal.loading": "Carregando terminal...",
   "terminal.title": "Terminal",
   "terminal.title.numbered": "Terminal {{number}}",
   "terminal.close": "Fechar terminal",
   "terminal.connectionLost.title": "Conexão Perdida",
-  "terminal.connectionLost.description":
-    "A conexão do terminal foi interrompida. Isso pode acontecer quando o servidor reinicia.",
-
+  "terminal.connectionLost.description": "A conexão do terminal foi interrompida. Isso pode acontecer quando o servidor reinicia.",
   "common.closeTab": "Fechar aba",
   "common.dismiss": "Descartar",
   "common.requestFailed": "Requisição falhou",
@@ -494,7 +490,6 @@ export const dict = {
   "common.edit": "Editar",
   "common.loadMore": "Carregar mais",
   "common.key.esc": "ESC",
-
   "sidebar.menu.toggle": "Alternar menu",
   "sidebar.nav.projectsAndSessions": "Projetos e sessões",
   "sidebar.settings": "Configurações",
@@ -506,7 +501,6 @@ export const dict = {
   "sidebar.gettingStarted.line2": "Conecte qualquer provedor para usar modelos, incluindo Claude, GPT, Gemini etc.",
   "sidebar.project.recentSessions": "Sessões recentes",
   "sidebar.project.viewAllSessions": "Ver todas as sessões",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "Desktop",
   "settings.section.server": "Servidor",
@@ -514,13 +508,12 @@ export const dict = {
   "settings.tab.shortcuts": "Atalhos",
   "settings.desktop.section.wsl": "WSL",
   "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.description": "Executar o servidor OpenCode dentro do WSL no Windows.",
   "settings.general.section.appearance": "Aparência",
   "settings.general.section.notifications": "Notificações do sistema",
   "settings.general.section.updates": "Atualizações",
   "settings.general.section.sounds": "Efeitos sonoros",
-
+  "settings.general.section.display": "Tela",
   "settings.general.row.language.title": "Idioma",
   "settings.general.row.language.description": "Alterar o idioma de exibição do OpenCode",
   "settings.general.row.appearance.title": "Aparência",
@@ -529,10 +522,11 @@ export const dict = {
   "settings.general.row.theme.description": "Personalize como o OpenCode é tematizado.",
   "settings.general.row.font.title": "Fonte",
   "settings.general.row.font.description": "Personalize a fonte monoespaçada usada em blocos de código",
-
+  "settings.general.row.wayland.title": "Usar Wayland nativo",
+  "settings.general.row.wayland.description": "Desabilitar fallback X11 no Wayland. Requer reinicialização.",
+  "settings.general.row.wayland.tooltip": "No Linux com monitores de taxas de atualização mistas, Wayland nativo pode ser mais estável.",
   "settings.general.row.releaseNotes.title": "Notas da versão",
-  "settings.general.row.releaseNotes.description": 'Mostrar pop-ups de "Novidades" após atualizações',
-
+  "settings.general.row.releaseNotes.description": "Mostrar pop-ups de \"Novidades\" após atualizações",
   "settings.updates.row.startup.title": "Verificar atualizações ao iniciar",
   "settings.updates.row.startup.description": "Verificar atualizações automaticamente quando o OpenCode iniciar",
   "settings.updates.row.check.title": "Verificar atualizações",
@@ -598,23 +592,18 @@ export const dict = {
   "sound.option.yup04": "Sim 04",
   "sound.option.yup05": "Sim 05",
   "sound.option.yup06": "Sim 06",
-
   "settings.general.notifications.agent.title": "Agente",
-  "settings.general.notifications.agent.description":
-    "Mostrar notificação do sistema quando o agente estiver completo ou precisar de atenção",
+  "settings.general.notifications.agent.description": "Mostrar notificação do sistema quando o agente estiver completo ou precisar de atenção",
   "settings.general.notifications.permissions.title": "Permissões",
-  "settings.general.notifications.permissions.description":
-    "Mostrar notificação do sistema quando uma permissão for necessária",
+  "settings.general.notifications.permissions.description": "Mostrar notificação do sistema quando uma permissão for necessária",
   "settings.general.notifications.errors.title": "Erros",
   "settings.general.notifications.errors.description": "Mostrar notificação do sistema quando ocorrer um erro",
-
   "settings.general.sounds.agent.title": "Agente",
   "settings.general.sounds.agent.description": "Reproduzir som quando o agente estiver completo ou precisar de atenção",
   "settings.general.sounds.permissions.title": "Permissões",
   "settings.general.sounds.permissions.description": "Reproduzir som quando uma permissão for necessária",
   "settings.general.sounds.errors.title": "Erros",
   "settings.general.sounds.errors.description": "Reproduzir som quando ocorrer um erro",
-
   "settings.shortcuts.title": "Atalhos de teclado",
   "settings.shortcuts.reset.button": "Redefinir para padrões",
   "settings.shortcuts.reset.toast.title": "Atalhos redefinidos",
@@ -625,14 +614,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "Pressione teclas",
   "settings.shortcuts.search.placeholder": "Buscar atalhos",
   "settings.shortcuts.search.empty": "Nenhum atalho encontrado",
-
   "settings.shortcuts.group.general": "Geral",
   "settings.shortcuts.group.session": "Sessão",
   "settings.shortcuts.group.navigation": "Navegação",
   "settings.shortcuts.group.modelAndAgent": "Modelo e agente",
   "settings.shortcuts.group.terminal": "Terminal",
   "settings.shortcuts.group.prompt": "Prompt",
-
   "settings.providers.title": "Provedores",
   "settings.providers.description": "Configurações de provedores estarão disponíveis aqui.",
   "settings.providers.section.connected": "Provedores conectados",
@@ -650,21 +637,17 @@ export const dict = {
   "settings.commands.description": "Configurações de comandos estarão disponíveis aqui.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "Configurações de MCP estarão disponíveis aqui.",
-
   "settings.permissions.title": "Permissões",
   "settings.permissions.description": "Controle quais ferramentas o servidor pode usar por padrão.",
   "settings.permissions.section.tools": "Ferramentas",
   "settings.permissions.toast.updateFailed.title": "Falha ao atualizar permissões",
-
   "settings.permissions.action.allow": "Permitir",
   "settings.permissions.action.ask": "Perguntar",
   "settings.permissions.action.deny": "Negar",
-
   "settings.permissions.tool.read.title": "Ler",
   "settings.permissions.tool.read.description": "Ler um arquivo (corresponde ao caminho do arquivo)",
   "settings.permissions.tool.edit.title": "Editar",
-  "settings.permissions.tool.edit.description":
-    "Modificar arquivos, incluindo edições, escritas, patches e multi-edições",
+  "settings.permissions.tool.edit.description": "Modificar arquivos, incluindo edições, escritas, patches e multi-edições",
   "settings.permissions.tool.glob.title": "Glob",
   "settings.permissions.tool.glob.description": "Corresponder arquivos usando padrões glob",
   "settings.permissions.tool.grep.title": "Grep",
@@ -693,12 +676,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "Acessar arquivos fora do diretório do projeto",
   "settings.permissions.tool.doom_loop.title": "Loop Infinito",
   "settings.permissions.tool.doom_loop.description": "Detectar chamadas de ferramentas repetidas com entrada idêntica",
-
   "session.delete.failed.title": "Falha ao excluir sessão",
   "session.delete.title": "Excluir sessão",
-  "session.delete.confirm": 'Excluir sessão "{{name}}"?',
+  "session.delete.confirm": "Excluir sessão \"{{name}}\"?",
   "session.delete.button": "Excluir sessão",
-
   "workspace.new": "Novo espaço de trabalho",
   "workspace.type.local": "local",
   "workspace.type.sandbox": "sandbox",
@@ -715,13 +696,14 @@ export const dict = {
   "workspace.status.clean": "Nenhuma alteração não mesclada detectada.",
   "workspace.status.dirty": "Alterações não mescladas detectadas neste espaço de trabalho.",
   "workspace.delete.title": "Excluir espaço de trabalho",
-  "workspace.delete.confirm": 'Excluir espaço de trabalho "{{name}}"?',
+  "workspace.delete.confirm": "Excluir espaço de trabalho \"{{name}}\"?",
   "workspace.delete.button": "Excluir espaço de trabalho",
   "workspace.reset.title": "Redefinir espaço de trabalho",
-  "workspace.reset.confirm": 'Redefinir espaço de trabalho "{{name}}"?',
+  "workspace.reset.confirm": "Redefinir espaço de trabalho \"{{name}}\"?",
   "workspace.reset.button": "Redefinir espaço de trabalho",
   "workspace.reset.archived.none": "Nenhuma sessão ativa será arquivada.",
   "workspace.reset.archived.one": "1 sessão será arquivada.",
   "workspace.reset.archived.many": "{{count}} sessões serão arquivadas.",
   "workspace.reset.note": "Isso redefinirá o espaço de trabalho para corresponder ao branch padrão.",
 }
+

+ 53 - 3
packages/app/src/i18n/bs.ts

@@ -150,6 +150,44 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} povezan",
   "provider.connect.toast.connected.description": "{{provider}} modeli su sada dostupni za korištenje.",
 
+  "provider.custom.title": "Prilagođeni provajder",
+  "provider.custom.description.prefix": "Konfiguriši OpenAI-kompatibilnog provajdera. Pogledaj ",
+  "provider.custom.description.link": "dokumentaciju za konfiguraciju provajdera",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID provajdera",
+  "provider.custom.field.providerID.placeholder": "mojprovajder",
+  "provider.custom.field.providerID.description": "Mala slova, brojevi, crtice ili donje crte",
+  "provider.custom.field.name.label": "Prikazano ime",
+  "provider.custom.field.name.placeholder": "Moj AI Provajder",
+  "provider.custom.field.baseURL.label": "Bazni URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.mojprovajder.com/v1",
+  "provider.custom.field.apiKey.label": "API ključ",
+  "provider.custom.field.apiKey.placeholder": "API ključ",
+  "provider.custom.field.apiKey.description":
+    "Opcionalno. Ostavi prazno ako upravljaš autentifikacijom putem zaglavlja.",
+  "provider.custom.models.label": "Modeli",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "Ime",
+  "provider.custom.models.name.placeholder": "Prikazano ime",
+  "provider.custom.models.remove": "Ukloni model",
+  "provider.custom.models.add": "Dodaj model",
+  "provider.custom.headers.label": "Zaglavlja (opcionalno)",
+  "provider.custom.headers.key.label": "Zaglavlje",
+  "provider.custom.headers.key.placeholder": "Ime-Zaglavlja",
+  "provider.custom.headers.value.label": "Vrijednost",
+  "provider.custom.headers.value.placeholder": "vrijednost",
+  "provider.custom.headers.remove": "Ukloni zaglavlje",
+  "provider.custom.headers.add": "Dodaj zaglavlje",
+  "provider.custom.error.providerID.required": "ID provajdera je obavezan",
+  "provider.custom.error.providerID.format": "Koristi mala slova, brojeve, crtice ili donje crte",
+  "provider.custom.error.providerID.exists": "Taj ID provajdera već postoji",
+  "provider.custom.error.name.required": "Prikazano ime je obavezno",
+  "provider.custom.error.baseURL.required": "Bazni URL je obavezan",
+  "provider.custom.error.baseURL.format": "Mora početi sa http:// ili https://",
+  "provider.custom.error.required": "Obavezno",
+  "provider.custom.error.duplicate": "Duplikat",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} odspojen",
   "provider.disconnect.toast.disconnected.description": "{{provider}} modeli više nisu dostupni.",
 
@@ -408,6 +446,7 @@ export const dict = {
     "Korijenski element nije pronađen. Da li si zaboravio da ga dodaš u index.html? Ili je možda id atribut pogrešno napisan?",
 
   "error.globalSync.connectFailed": "Nije moguće povezati se na server. Da li server radi na `{{url}}`?",
+  "directory.error.invalidUrl": "Nevažeći direktorij u URL-u.",
 
   "error.chain.unknown": "Nepoznata greška",
   "error.chain.causedBy": "Uzrok:",
@@ -417,7 +456,7 @@ export const dict = {
   "error.chain.responseBody": "Tijelo odgovora:\n{{body}}",
   "error.chain.didYouMean": "Da li si mislio: {{suggestions}}",
   "error.chain.modelNotFound": "Model nije pronađen: {{provider}}/{{model}}",
-  "error.chain.checkConfig": "Provjeri konfiguraciju (opencode.json) - nazive provajdera/modela",
+  "error.chain.checkConfig": "Provjeri konfiguraciju (opencode.json) provider/model names",
   "error.chain.mcpFailed": 'MCP server "{{name}}" nije uspio. Napomena: OpenCode još ne podržava MCP autentifikaciju.',
   "error.chain.providerAuthFailed": "Autentifikacija provajdera nije uspjela ({{provider}}): {{message}}",
   "error.chain.providerInitFailed":
@@ -474,6 +513,11 @@ export const dict = {
 
   "session.header.search.placeholder": "Pretraži {{project}}",
   "session.header.searchFiles": "Pretraži datoteke",
+  "session.header.openIn": "Otvori u",
+  "session.header.open.action": "Otvori {{app}}",
+  "session.header.open.ariaLabel": "Otvori u {{app}}",
+  "session.header.open.menu": "Opcije otvaranja",
+  "session.header.open.copyPath": "Kopiraj putanju",
 
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Konfiguracije servera",
@@ -540,13 +584,14 @@ export const dict = {
   "settings.tab.general": "Opšte",
   "settings.tab.shortcuts": "Prečice",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "WSL integracija",
+  "settings.desktop.wsl.description": "Pokreni OpenCode server unutar WSL-a na Windowsu.",
 
   "settings.general.section.appearance": "Izgled",
   "settings.general.section.notifications": "Sistemske obavijesti",
   "settings.general.section.updates": "Ažuriranja",
   "settings.general.section.sounds": "Zvučni efekti",
+  "settings.general.section.display": "Prikaz",
 
   "settings.general.row.language.title": "Jezik",
   "settings.general.row.language.description": "Promijeni jezik prikaza u OpenCode-u",
@@ -557,6 +602,11 @@ export const dict = {
   "settings.general.row.font.title": "Font",
   "settings.general.row.font.description": "Prilagodi monospace font koji se koristi u blokovima koda",
 
+  "settings.general.row.wayland.title": "Koristi nativni Wayland",
+  "settings.general.row.wayland.description": "Onemogući X11 fallback na Waylandu. Zahtijeva restart.",
+  "settings.general.row.wayland.tooltip":
+    "Na Linuxu sa monitorima miješanih stopa osvježavanja, nativni Wayland može biti stabilniji.",
+
   "settings.general.row.releaseNotes.title": "Bilješke o izdanju",
   "settings.general.row.releaseNotes.description": 'Prikaži iskačuće prozore "Šta je novo" nakon ažuriranja',
 

+ 79 - 7
packages/app/src/i18n/da.ts

@@ -72,6 +72,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Accepter ændringer automatisk",
   "command.permissions.autoaccept.disable": "Stop automatisk accept af ændringer",
   "command.workspace.toggle": "Skift arbejdsområder",
+  "command.workspace.toggle.description": "Aktiver eller deaktiver flere arbejdsområder i sidebjælken",
   "command.session.undo": "Fortryd",
   "command.session.undo.description": "Fortryd den sidste besked",
   "command.session.redo": "Omgør",
@@ -95,9 +96,13 @@ export const dict = {
   "dialog.provider.group.popular": "Populære",
   "dialog.provider.group.other": "Andre",
   "dialog.provider.tag.recommended": "Anbefalet",
-  "dialog.provider.anthropic.note": "Forbind med Claude Pro/Max eller API-nøgle",
-  "dialog.provider.openai.note": "Forbind med ChatGPT Pro/Plus eller API-nøgle",
-  "dialog.provider.copilot.note": "Forbind med Copilot eller API-nøgle",
+  "dialog.provider.opencode.note": "Udvalgte modeller inklusive Claude, GPT, Gemini og flere",
+  "dialog.provider.anthropic.note": "Direkte adgang til Claude-modeller, inklusive Pro og Max",
+  "dialog.provider.copilot.note": "Claude-modeller til kodningsassistance",
+  "dialog.provider.openai.note": "GPT-modeller til hurtige, kompetente generelle AI-opgaver",
+  "dialog.provider.google.note": "Gemini-modeller til hurtige, strukturerede svar",
+  "dialog.provider.openrouter.note": "Få adgang til alle understøttede modeller fra én udbyder",
+  "dialog.provider.vercel.note": "Samlet adgang til AI-modeller med smart routing",
 
   "dialog.model.select.title": "Vælg model",
   "dialog.model.search.placeholder": "Søg modeller",
@@ -145,6 +150,43 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} forbundet",
   "provider.connect.toast.connected.description": "{{provider}} modeller er nu tilgængelige.",
 
+  "provider.custom.title": "Brugerdefineret udbyder",
+  "provider.custom.description.prefix": "Konfigurer en OpenAI-kompatibel udbyder. Se ",
+  "provider.custom.description.link": "dokumentation for udbyderkonfiguration",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "Udbyder-ID",
+  "provider.custom.field.providerID.placeholder": "minudbyder",
+  "provider.custom.field.providerID.description": "Små bogstaver, tal, bindestreger eller understregninger",
+  "provider.custom.field.name.label": "Visningsnavn",
+  "provider.custom.field.name.placeholder": "Min AI-udbyder",
+  "provider.custom.field.baseURL.label": "Basis-URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.minudbyder.dk/v1",
+  "provider.custom.field.apiKey.label": "API-nøgle",
+  "provider.custom.field.apiKey.placeholder": "API-nøgle",
+  "provider.custom.field.apiKey.description": "Valgfri. Lad være tom, hvis du administrerer godkendelse via headers.",
+  "provider.custom.models.label": "Modeller",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "Navn",
+  "provider.custom.models.name.placeholder": "Visningsnavn",
+  "provider.custom.models.remove": "Fjern model",
+  "provider.custom.models.add": "Tilføj model",
+  "provider.custom.headers.label": "Headers (valgfri)",
+  "provider.custom.headers.key.label": "Header",
+  "provider.custom.headers.key.placeholder": "Header-Navn",
+  "provider.custom.headers.value.label": "Værdi",
+  "provider.custom.headers.value.placeholder": "værdi",
+  "provider.custom.headers.remove": "Fjern header",
+  "provider.custom.headers.add": "Tilføj header",
+  "provider.custom.error.providerID.required": "Udbyder-ID er påkrævet",
+  "provider.custom.error.providerID.format": "Brug små bogstaver, tal, bindestreger eller understregninger",
+  "provider.custom.error.providerID.exists": "Dette udbyder-ID findes allerede",
+  "provider.custom.error.name.required": "Visningsnavn er påkrævet",
+  "provider.custom.error.baseURL.required": "Basis-URL er påkrævet",
+  "provider.custom.error.baseURL.format": "Skal starte med http:// eller https://",
+  "provider.custom.error.required": "Påkrævet",
+  "provider.custom.error.duplicate": "Duplikeret",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} frakoblet",
   "provider.disconnect.toast.disconnected.description": "Modeller fra {{provider}} er ikke længere tilgængelige.",
   "model.tag.free": "Gratis",
@@ -166,6 +208,7 @@ export const dict = {
   "model.tooltip.context": "Kontekstgrænse {{limit}}",
   "common.search.placeholder": "Søg",
   "common.goBack": "Gå tilbage",
+  "common.goForward": "Naviger fremad",
   "common.loading": "Indlæser",
   "common.loading.ellipsis": "...",
   "common.cancel": "Annuller",
@@ -308,10 +351,10 @@ export const dict = {
   "context.stats.provider": "Udbyder",
   "context.stats.model": "Model",
   "context.stats.limit": "Kontekstgrænse",
-  "context.stats.totalTokens": "Total Tokens",
+  "context.stats.totalTokens": "Samlede tokens",
   "context.stats.usage": "Forbrug",
-  "context.stats.inputTokens": "Input Tokens",
-  "context.stats.outputTokens": "Output Tokens",
+  "context.stats.inputTokens": "Input-tokens",
+  "context.stats.outputTokens": "Output-tokens",
   "context.stats.reasoningTokens": "Tænke Tokens",
   "context.stats.cacheTokens": "Cache Tokens (læs/skriv)",
   "context.stats.userMessages": "Brugerbeskeder",
@@ -326,6 +369,23 @@ export const dict = {
   "context.usage.clickToView": "Klik for at se kontekst",
   "context.usage.view": "Se kontekstforbrug",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "Sprog",
   "toast.language.description": "Skiftede til {{language}}",
 
@@ -383,6 +443,7 @@ export const dict = {
     "Rodelement ikke fundet. Har du glemt at tilføje det til din index.html? Eller måske er id-attributten stavet forkert?",
 
   "error.globalSync.connectFailed": "Kunne ikke forbinde til server. Kører der en server på `{{url}}`?",
+  "directory.error.invalidUrl": "Ugyldig mappe i URL.",
 
   "error.chain.unknown": "Ukendt fejl",
   "error.chain.causedBy": "Forårsaget af:",
@@ -447,6 +508,11 @@ export const dict = {
 
   "session.header.search.placeholder": "Søg {{project}}",
   "session.header.searchFiles": "Søg efter filer",
+  "session.header.openIn": "Åbn i",
+  "session.header.open.action": "Åbn {{app}}",
+  "session.header.open.ariaLabel": "Åbn i {{app}}",
+  "session.header.open.menu": "Åbningsmuligheder",
+  "session.header.open.copyPath": "Kopier sti",
 
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Serverkonfigurationer",
@@ -514,12 +580,13 @@ export const dict = {
   "settings.tab.shortcuts": "Genveje",
   "settings.desktop.section.wsl": "WSL",
   "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.description": "Kør OpenCode-serveren inde i WSL på Windows.",
 
   "settings.general.section.appearance": "Udseende",
   "settings.general.section.notifications": "Systemmeddelelser",
   "settings.general.section.updates": "Opdateringer",
   "settings.general.section.sounds": "Lydeffekter",
+  "settings.general.section.display": "Skærm",
 
   "settings.general.row.language.title": "Sprog",
   "settings.general.row.language.description": "Ændr visningssproget for OpenCode",
@@ -530,6 +597,11 @@ export const dict = {
   "settings.general.row.font.title": "Skrifttype",
   "settings.general.row.font.description": "Tilpas mono-skrifttypen brugt i kodeblokke",
 
+  "settings.general.row.wayland.title": "Brug native Wayland",
+  "settings.general.row.wayland.description": "Deaktiver X11-fallback på Wayland. Kræver genstart.",
+  "settings.general.row.wayland.tooltip":
+    "På Linux med skærme med blandet opdateringshastighed kan native Wayland være mere stabilt.",
+
   "settings.general.row.releaseNotes.title": "Udgivelsesnoter",
   "settings.general.row.releaseNotes.description": 'Vis "Hvad er nyt"-popups efter opdateringer',
 

+ 69 - 128
packages/app/src/i18n/de.ts

@@ -19,12 +19,10 @@ export const dict = {
   "command.category.agent": "Agent",
   "command.category.permissions": "Berechtigungen",
   "command.category.workspace": "Arbeitsbereich",
-
   "command.category.settings": "Einstellungen",
   "theme.scheme.system": "System",
   "theme.scheme.light": "Hell",
   "theme.scheme.dark": "Dunkel",
-
   "command.sidebar.toggle": "Seitenleiste umschalten",
   "command.project.open": "Projekt öffnen",
   "command.provider.connect": "Anbieter verbinden",
@@ -35,17 +33,13 @@ export const dict = {
   "command.session.previous.unseen": "Vorherige ungelesene Sitzung",
   "command.session.next.unseen": "Nächste ungelesene Sitzung",
   "command.session.archive": "Sitzung archivieren",
-
   "command.palette": "Befehlspalette",
-
   "command.theme.cycle": "Thema wechseln",
   "command.theme.set": "Thema verwenden: {{theme}}",
   "command.theme.scheme.cycle": "Farbschema wechseln",
   "command.theme.scheme.set": "Farbschema verwenden: {{scheme}}",
-
   "command.language.cycle": "Sprache wechseln",
   "command.language.set": "Sprache verwenden: {{language}}",
-
   "command.session.new": "Neue Sitzung",
   "command.file.open": "Datei öffnen",
   "command.tab.close": "Tab schließen",
@@ -76,6 +70,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Änderungen automatisch akzeptieren",
   "command.permissions.autoaccept.disable": "Automatische Annahme von Änderungen stoppen",
   "command.workspace.toggle": "Arbeitsbereiche umschalten",
+  "command.workspace.toggle.description": "Mehrere Arbeitsbereiche in der Seitenleiste aktivieren oder deaktivieren",
   "command.session.undo": "Rückgängig",
   "command.session.undo.description": "Letzte Nachricht rückgängig machen",
   "command.session.redo": "Wiederherstellen",
@@ -88,32 +83,30 @@ export const dict = {
   "command.session.share.description": "Diese Sitzung teilen und URL in die Zwischenablage kopieren",
   "command.session.unshare": "Teilen der Sitzung aufheben",
   "command.session.unshare.description": "Teilen dieser Sitzung beenden",
-
   "palette.search.placeholder": "Dateien, Befehle und Sitzungen durchsuchen",
   "palette.empty": "Keine Ergebnisse gefunden",
   "palette.group.commands": "Befehle",
   "palette.group.files": "Dateien",
-
   "dialog.provider.search.placeholder": "Anbieter durchsuchen",
   "dialog.provider.empty": "Keine Anbieter gefunden",
   "dialog.provider.group.popular": "Beliebt",
   "dialog.provider.group.other": "Andere",
   "dialog.provider.tag.recommended": "Empfohlen",
+  "dialog.provider.opencode.note": "Kuratierte Modelle inklusive Claude, GPT, Gemini und mehr",
   "dialog.provider.anthropic.note": "Mit Claude Pro/Max oder API-Schlüssel verbinden",
-  "dialog.provider.openai.note": "Mit ChatGPT Pro/Plus oder API-Schlüssel verbinden",
   "dialog.provider.copilot.note": "Mit Copilot oder API-Schlüssel verbinden",
-
+  "dialog.provider.openai.note": "Mit ChatGPT Pro/Plus oder API-Schlüssel verbinden",
+  "dialog.provider.google.note": "Gemini-Modelle für schnelle, strukturierte Antworten",
+  "dialog.provider.openrouter.note": "Zugriff auf alle unterstützten Modelle über einen Anbieter",
+  "dialog.provider.vercel.note": "Einheitlicher Zugriff auf KI-Modelle mit intelligentem Routing",
   "dialog.model.select.title": "Modell auswählen",
   "dialog.model.search.placeholder": "Modelle durchsuchen",
   "dialog.model.empty": "Keine Modellergebnisse",
   "dialog.model.manage": "Modelle verwalten",
   "dialog.model.manage.description": "Anpassen, welche Modelle in der Modellauswahl erscheinen.",
-
   "dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von OpenCode",
   "dialog.model.unpaid.addMore.title": "Weitere Modelle von beliebten Anbietern hinzufügen",
-
   "dialog.provider.viewAll": "Mehr Anbieter anzeigen",
-
   "provider.connect.title": "{{provider}} verbinden",
   "provider.connect.title.anthropicProMax": "Mit Claude Pro/Max anmelden",
   "provider.connect.selectMethod": "Anmeldemethode für {{provider}} auswählen.",
@@ -121,34 +114,28 @@ export const dict = {
   "provider.connect.status.inProgress": "Autorisierung läuft...",
   "provider.connect.status.waiting": "Warten auf Autorisierung...",
   "provider.connect.status.failed": "Autorisierung fehlgeschlagen: {{error}}",
-  "provider.connect.apiKey.description":
-    "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
+  "provider.connect.apiKey.description": "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
   "provider.connect.apiKey.label": "{{provider}} API-Schlüssel",
   "provider.connect.apiKey.placeholder": "API-Schlüssel",
   "provider.connect.apiKey.required": "API-Schlüssel ist erforderlich",
-  "provider.connect.opencodeZen.line1":
-    "OpenCode Zen bietet Ihnen Zugriff auf eine kuratierte Auswahl zuverlässiger, optimierter Modelle für Coding-Agenten.",
-  "provider.connect.opencodeZen.line2":
-    "Mit einem einzigen API-Schlüssel erhalten Sie Zugriff auf Modelle wie Claude, GPT, Gemini, GLM und mehr.",
+  "provider.connect.opencodeZen.line1": "OpenCode Zen bietet Ihnen Zugriff auf eine kuratierte Auswahl zuverlässiger, optimierter Modelle für Coding-Agenten.",
+  "provider.connect.opencodeZen.line2": "Mit einem einzigen API-Schlüssel erhalten Sie Zugriff auf Modelle wie Claude, GPT, Gemini, GLM und mehr.",
   "provider.connect.opencodeZen.visit.prefix": "Besuchen Sie ",
   "provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
   "provider.connect.opencodeZen.visit.suffix": ", um Ihren API-Schlüssel zu erhalten.",
   "provider.connect.oauth.code.visit.prefix": "Besuchen Sie ",
   "provider.connect.oauth.code.visit.link": "diesen Link",
-  "provider.connect.oauth.code.visit.suffix":
-    ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
+  "provider.connect.oauth.code.visit.suffix": ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
   "provider.connect.oauth.code.label": "{{method}} Autorisierungscode",
   "provider.connect.oauth.code.placeholder": "Autorisierungscode",
   "provider.connect.oauth.code.required": "Autorisierungscode ist erforderlich",
   "provider.connect.oauth.code.invalid": "Ungültiger Autorisierungscode",
   "provider.connect.oauth.auto.visit.prefix": "Besuchen Sie ",
   "provider.connect.oauth.auto.visit.link": "diesen Link",
-  "provider.connect.oauth.auto.visit.suffix":
-    " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
+  "provider.connect.oauth.auto.visit.suffix": " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
   "provider.connect.oauth.auto.confirmationCode": "Bestätigungscode",
   "provider.connect.toast.connected.title": "{{provider}} verbunden",
   "provider.connect.toast.connected.description": "{{provider}} Modelle sind jetzt verfügbar.",
-
   "provider.custom.title": "Benutzerdefinierter Anbieter",
   "provider.custom.description.prefix": "Konfigurieren Sie einen OpenAI-kompatiblen Anbieter. Siehe die ",
   "provider.custom.description.link": "Anbieter-Konfigurationsdokumente",
@@ -162,8 +149,7 @@ export const dict = {
   "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
   "provider.custom.field.apiKey.label": "API-Schlüssel",
   "provider.custom.field.apiKey.placeholder": "API-Schlüssel",
-  "provider.custom.field.apiKey.description":
-    "Optional. Leer lassen, wenn Sie die Authentifizierung über Header verwalten.",
+  "provider.custom.field.apiKey.description": "Optional. Leer lassen, wenn Sie die Authentifizierung über Header verwalten.",
   "provider.custom.models.label": "Modelle",
   "provider.custom.models.id.label": "ID",
   "provider.custom.models.id.placeholder": "model-id",
@@ -186,12 +172,10 @@ export const dict = {
   "provider.custom.error.baseURL.format": "Muss mit http:// oder https:// beginnen",
   "provider.custom.error.required": "Erforderlich",
   "provider.custom.error.duplicate": "Duplikat",
-
   "provider.disconnect.toast.disconnected.title": "{{provider}} getrennt",
   "provider.disconnect.toast.disconnected.description": "Die {{provider}}-Modelle sind nicht mehr verfügbar.",
   "model.tag.free": "Kostenlos",
   "model.tag.latest": "Neueste",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -201,13 +185,14 @@ export const dict = {
   "model.input.image": "Bild",
   "model.input.audio": "Audio",
   "model.input.video": "Video",
-  "model.input.pdf": "pdf",
+  "model.input.pdf": "PDF",
   "model.tooltip.allows": "Erlaubt: {{inputs}}",
   "model.tooltip.reasoning.allowed": "Erlaubt Reasoning",
   "model.tooltip.reasoning.none": "Kein Reasoning",
   "model.tooltip.context": "Kontextlimit {{limit}}",
   "common.search.placeholder": "Suchen",
   "common.goBack": "Zurück",
+  "common.goForward": "Vorwärts navigieren",
   "common.loading": "Laden",
   "common.loading.ellipsis": "...",
   "common.cancel": "Abbrechen",
@@ -218,14 +203,12 @@ export const dict = {
   "common.saving": "Speichert...",
   "common.default": "Standard",
   "common.attachment": "Anhang",
-
   "prompt.placeholder.shell": "Shell-Befehl eingeben...",
-  "prompt.placeholder.normal": 'Fragen Sie alles... "{{example}}"',
+  "prompt.placeholder.normal": "Fragen Sie alles... \"{{example}}\"",
   "prompt.placeholder.summarizeComments": "Kommentare zusammenfassen…",
   "prompt.placeholder.summarizeComment": "Kommentar zusammenfassen…",
   "prompt.mode.shell": "Shell",
   "prompt.mode.shell.exit": "esc zum Verlassen",
-
   "prompt.example.1": "Ein TODO in der Codebasis beheben",
   "prompt.example.2": "Was ist der Tech-Stack dieses Projekts?",
   "prompt.example.3": "Fehlerhafte Tests beheben",
@@ -251,14 +234,13 @@ export const dict = {
   "prompt.example.23": "Paginierung zu dieser Liste hinzufügen",
   "prompt.example.24": "CLI-Befehl erstellen für...",
   "prompt.example.25": "Wie funktionieren Umgebungsvariablen hier?",
-
   "prompt.popover.emptyResults": "Keine passenden Ergebnisse",
   "prompt.popover.emptyCommands": "Keine passenden Befehle",
   "prompt.dropzone.label": "Bilder oder PDFs hier ablegen",
   "prompt.dropzone.file.label": "Ablegen zum @Erwähnen der Datei",
   "prompt.slash.badge.custom": "benutzerdefiniert",
-  "prompt.slash.badge.skill": "skill",
-  "prompt.slash.badge.mcp": "mcp",
+  "prompt.slash.badge.skill": "Skill",
+  "prompt.slash.badge.mcp": "MCP",
   "prompt.context.active": "aktiv",
   "prompt.context.includeActiveFile": "Aktive Datei einbeziehen",
   "prompt.context.removeActiveFile": "Aktive Datei aus dem Kontext entfernen",
@@ -267,36 +249,28 @@ export const dict = {
   "prompt.attachment.remove": "Anhang entfernen",
   "prompt.action.send": "Senden",
   "prompt.action.stop": "Stopp",
-
   "prompt.toast.pasteUnsupported.title": "Nicht unterstütztes Einfügen",
   "prompt.toast.pasteUnsupported.description": "Hier können nur Bilder oder PDFs eingefügt werden.",
   "prompt.toast.modelAgentRequired.title": "Wählen Sie einen Agenten und ein Modell",
-  "prompt.toast.modelAgentRequired.description":
-    "Wählen Sie einen Agenten und ein Modell, bevor Sie eine Eingabe senden.",
+  "prompt.toast.modelAgentRequired.description": "Wählen Sie einen Agenten und ein Modell, bevor Sie eine Eingabe senden.",
   "prompt.toast.worktreeCreateFailed.title": "Worktree konnte nicht erstellt werden",
   "prompt.toast.sessionCreateFailed.title": "Sitzung konnte nicht erstellt werden",
   "prompt.toast.shellSendFailed.title": "Shell-Befehl konnte nicht gesendet werden",
   "prompt.toast.commandSendFailed.title": "Befehl konnte nicht gesendet werden",
   "prompt.toast.promptSendFailed.title": "Eingabe konnte nicht gesendet werden",
   "prompt.toast.promptSendFailed.description": "Sitzung konnte nicht abgerufen werden",
-
   "dialog.mcp.title": "MCPs",
   "dialog.mcp.description": "{{enabled}} von {{total}} aktiviert",
   "dialog.mcp.empty": "Keine MCPs konfiguriert",
-
   "dialog.lsp.empty": "LSPs automatisch nach Dateityp erkannt",
   "dialog.plugins.empty": "In opencode.json konfigurierte Plugins",
-
   "mcp.status.connected": "verbunden",
   "mcp.status.failed": "fehlgeschlagen",
   "mcp.status.needs_auth": "benötigt Authentifizierung",
   "mcp.status.disabled": "deaktiviert",
-
   "dialog.fork.empty": "Keine Nachrichten zum Abzweigen vorhanden",
-
   "dialog.directory.search.placeholder": "Ordner durchsuchen",
   "dialog.directory.empty": "Keine Ordner gefunden",
-
   "dialog.server.title": "Server",
   "dialog.server.description": "Wechseln Sie den OpenCode-Server, mit dem sich diese App verbindet.",
   "dialog.server.search.placeholder": "Server durchsuchen",
@@ -308,20 +282,17 @@ export const dict = {
   "dialog.server.add.checking": "Prüfen...",
   "dialog.server.add.button": "Server hinzufügen",
   "dialog.server.default.title": "Standardserver",
-  "dialog.server.default.description":
-    "Beim App-Start mit diesem Server verbinden, anstatt einen lokalen Server zu starten. Erfordert Neustart.",
+  "dialog.server.default.description": "Beim App-Start mit diesem Server verbinden, anstatt einen lokalen Server zu starten. Erfordert Neustart.",
   "dialog.server.default.none": "Kein Server ausgewählt",
   "dialog.server.default.set": "Aktuellen Server als Standard setzen",
   "dialog.server.default.clear": "Löschen",
   "dialog.server.action.remove": "Server entfernen",
-
   "dialog.server.menu.edit": "Bearbeiten",
   "dialog.server.menu.default": "Als Standard festlegen",
   "dialog.server.menu.defaultRemove": "Standard entfernen",
   "dialog.server.menu.delete": "Löschen",
   "dialog.server.current": "Aktueller Server",
   "dialog.server.status.default": "Standard",
-
   "dialog.project.edit.title": "Projekt bearbeiten",
   "dialog.project.edit.name": "Name",
   "dialog.project.edit.icon": "Icon",
@@ -330,23 +301,18 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "Empfohlen: 128x128px",
   "dialog.project.edit.color": "Farbe",
   "dialog.project.edit.color.select": "{{color}}-Farbe auswählen",
-
   "dialog.project.edit.worktree.startup": "Startup-Skript für Arbeitsbereich",
-  "dialog.project.edit.worktree.startup.description":
-    "Wird nach dem Erstellen eines neuen Arbeitsbereichs (Worktree) ausgeführt.",
+  "dialog.project.edit.worktree.startup.description": "Wird nach dem Erstellen eines neuen Arbeitsbereichs (Worktree) ausgeführt.",
   "dialog.project.edit.worktree.startup.placeholder": "z. B. bun install",
   "context.breakdown.title": "Kontext-Aufschlüsselung",
-  "context.breakdown.note":
-    'Ungefähre Aufschlüsselung der Eingabe-Token. "Andere" beinhaltet Werkzeugdefinitionen und Overhead.',
+  "context.breakdown.note": "Ungefähre Aufschlüsselung der Eingabe-Token. \"Andere\" beinhaltet Werkzeugdefinitionen und Overhead.",
   "context.breakdown.system": "System",
   "context.breakdown.user": "Benutzer",
   "context.breakdown.assistant": "Assistent",
   "context.breakdown.tool": "Werkzeugaufrufe",
   "context.breakdown.other": "Andere",
-
   "context.systemPrompt.title": "System-Prompt",
   "context.rawMessages.title": "Rohdaten der Nachrichten",
-
   "context.stats.session": "Sitzung",
   "context.stats.messages": "Nachrichten",
   "context.stats.provider": "Anbieter",
@@ -363,29 +329,42 @@ export const dict = {
   "context.stats.totalCost": "Gesamtkosten",
   "context.stats.sessionCreated": "Sitzung erstellt",
   "context.stats.lastActivity": "Letzte Aktivität",
-
   "context.usage.tokens": "Token",
   "context.usage.usage": "Nutzung",
   "context.usage.cost": "Kosten",
   "context.usage.clickToView": "Klicken, um Kontext anzuzeigen",
   "context.usage.view": "Kontextnutzung anzeigen",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "Sprache",
   "toast.language.description": "Zu {{language}} gewechselt",
-
   "toast.theme.title": "Thema gewechselt",
   "toast.scheme.title": "Farbschema",
-
+  "toast.workspace.enabled.title": "Arbeitsbereiche aktiviert",
+  "toast.workspace.enabled.description": "Mehrere Worktrees werden jetzt in der Seitenleiste angezeigt",
+  "toast.workspace.disabled.title": "Arbeitsbereiche deaktiviert",
+  "toast.workspace.disabled.description": "Nur der Haupt-Worktree wird in der Seitenleiste angezeigt",
   "toast.permissions.autoaccept.on.title": "Änderungen werden automatisch akzeptiert",
   "toast.permissions.autoaccept.on.description": "Bearbeitungs- und Schreibrechte werden automatisch genehmigt",
   "toast.permissions.autoaccept.off.title": "Automatische Annahme von Änderungen gestoppt",
   "toast.permissions.autoaccept.off.description": "Bearbeitungs- und Schreibrechte erfordern Genehmigung",
-
   "toast.model.none.title": "Kein Modell ausgewählt",
   "toast.model.none.description": "Verbinden Sie einen Anbieter, um diese Sitzung zusammenzufassen",
-
   "toast.file.loadFailed.title": "Datei konnte nicht geladen werden",
-
   "toast.file.listFailed.title": "Dateien konnten nicht aufgelistet werden",
   "toast.context.noLineSelection.title": "Keine Zeilenauswahl",
   "toast.context.noLineSelection.description": "Wählen Sie zuerst einen Zeilenbereich in einem Datei-Tab aus.",
@@ -394,19 +373,15 @@ export const dict = {
   "toast.session.share.success.description": "Teilen-URL in die Zwischenablage kopiert!",
   "toast.session.share.failed.title": "Sitzung konnte nicht geteilt werden",
   "toast.session.share.failed.description": "Beim Teilen der Sitzung ist ein Fehler aufgetreten",
-
   "toast.session.unshare.success.title": "Teilen der Sitzung aufgehoben",
   "toast.session.unshare.success.description": "Teilen der Sitzung erfolgreich aufgehoben!",
   "toast.session.unshare.failed.title": "Aufheben des Teilens fehlgeschlagen",
   "toast.session.unshare.failed.description": "Beim Aufheben des Teilens ist ein Fehler aufgetreten",
-
   "toast.session.listFailed.title": "Sitzungen für {{project}} konnten nicht geladen werden",
-
   "toast.update.title": "Update verfügbar",
   "toast.update.description": "Eine neue Version von OpenCode ({{version}}) ist zur Installation verfügbar.",
   "toast.update.action.installRestart": "Installieren und neu starten",
   "toast.update.action.notYet": "Noch nicht",
-
   "error.page.title": "Etwas ist schiefgelaufen",
   "error.page.description": "Beim Laden der Anwendung ist ein Fehler aufgetreten.",
   "error.page.details.label": "Fehlerdetails",
@@ -417,13 +392,9 @@ export const dict = {
   "error.page.report.prefix": "Bitte melden Sie diesen Fehler dem OpenCode-Team",
   "error.page.report.discord": "auf Discord",
   "error.page.version": "Version: {{version}}",
-
-  "error.dev.rootNotFound":
-    "Wurzelelement nicht gefunden. Haben Sie vergessen, es in Ihre index.html aufzunehmen? Oder wurde das id-Attribut falsch geschrieben?",
-
+  "error.dev.rootNotFound": "Wurzelelement nicht gefunden. Haben Sie vergessen, es in Ihre index.html aufzunehmen? Oder wurde das id-Attribut falsch geschrieben?",
   "error.globalSync.connectFailed": "Verbindung zum Server fehlgeschlagen. Läuft ein Server unter `{{url}}`?",
   "directory.error.invalidUrl": "Ungültiges Verzeichnis in der URL.",
-
   "error.chain.unknown": "Unbekannter Fehler",
   "error.chain.causedBy": "Verursacht durch:",
   "error.chain.apiError": "API-Fehler",
@@ -433,34 +404,26 @@ export const dict = {
   "error.chain.didYouMean": "Meinten Sie: {{suggestions}}",
   "error.chain.modelNotFound": "Modell nicht gefunden: {{provider}}/{{model}}",
   "error.chain.checkConfig": "Überprüfen Sie Ihre Konfiguration (opencode.json) auf Anbieter-/Modellnamen",
-  "error.chain.mcpFailed":
-    'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: OpenCode unterstützt noch keine MCP-Authentifizierung.',
+  "error.chain.mcpFailed": "MCP-Server \"{{name}}\" fehlgeschlagen. Hinweis: OpenCode unterstützt noch keine MCP-Authentifizierung.",
   "error.chain.providerAuthFailed": "Anbieter-Authentifizierung fehlgeschlagen ({{provider}}): {{message}}",
-  "error.chain.providerInitFailed":
-    'Anbieter "{{provider}}" konnte nicht initialisiert werden. Überprüfen Sie Anmeldeinformationen und Konfiguration.',
+  "error.chain.providerInitFailed": "Anbieter \"{{provider}}\" konnte nicht initialisiert werden. Überprüfen Sie Anmeldeinformationen und Konfiguration.",
   "error.chain.configJsonInvalid": "Konfigurationsdatei unter {{path}} ist kein gültiges JSON(C)",
-  "error.chain.configJsonInvalidWithMessage":
-    "Konfigurationsdatei unter {{path}} ist kein gültiges JSON(C): {{message}}",
-  "error.chain.configDirectoryTypo":
-    'Verzeichnis "{{dir}}" in {{path}} ist ungültig. Benennen Sie das Verzeichnis in "{{suggestion}}" um oder entfernen Sie es. Dies ist ein häufiger Tippfehler.',
+  "error.chain.configJsonInvalidWithMessage": "Konfigurationsdatei unter {{path}} ist kein gültiges JSON(C): {{message}}",
+  "error.chain.configDirectoryTypo": "Verzeichnis \"{{dir}}\" in {{path}} ist ungültig. Benennen Sie das Verzeichnis in \"{{suggestion}}\" um oder entfernen Sie es. Dies ist ein häufiger Tippfehler.",
   "error.chain.configFrontmatterError": "Frontmatter in {{path}} konnte nicht geparst werden:\n{{message}}",
   "error.chain.configInvalid": "Konfigurationsdatei unter {{path}} ist ungültig",
   "error.chain.configInvalidWithMessage": "Konfigurationsdatei unter {{path}} ist ungültig: {{message}}",
-
   "notification.permission.title": "Berechtigung erforderlich",
   "notification.permission.description": "{{sessionTitle}} in {{projectName}} benötigt Berechtigung",
   "notification.question.title": "Frage",
   "notification.question.description": "{{sessionTitle}} in {{projectName}} hat eine Frage",
   "notification.action.goToSession": "Zur Sitzung gehen",
-
   "notification.session.responseReady.title": "Antwort bereit",
   "notification.session.error.title": "Sitzungsfehler",
   "notification.session.error.fallbackDescription": "Ein Fehler ist aufgetreten",
-
   "home.recentProjects": "Letzte Projekte",
   "home.empty.title": "Keine letzten Projekte",
   "home.empty.description": "Starten Sie, indem Sie ein lokales Projekt öffnen",
-
   "session.tab.session": "Sitzung",
   "session.tab.review": "Überprüfung",
   "session.tab.context": "Kontext",
@@ -478,18 +441,19 @@ export const dict = {
   "session.messages.loadingEarlier": "Lade frühere Nachrichten...",
   "session.messages.loadEarlier": "Frühere Nachrichten laden",
   "session.messages.loading": "Lade Nachrichten...",
-
   "session.messages.jumpToLatest": "Zum neuesten springen",
   "session.context.addToContext": "{{selection}} zum Kontext hinzufügen",
-
   "session.new.worktree.main": "Haupt-Branch",
   "session.new.worktree.mainWithBranch": "Haupt-Branch ({{branch}})",
   "session.new.worktree.create": "Neuen Worktree erstellen",
   "session.new.lastModified": "Zuletzt geändert",
-
   "session.header.search.placeholder": "{{project}} durchsuchen",
   "session.header.searchFiles": "Dateien suchen",
-
+  "session.header.openIn": "Öffnen in",
+  "session.header.open.action": "{{app}} öffnen",
+  "session.header.open.ariaLabel": "In {{app}} öffnen",
+  "session.header.open.menu": "Öffnen-Optionen",
+  "session.header.open.copyPath": "Pfad kopieren",
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Serverkonfigurationen",
   "status.popover.tab.servers": "Server",
@@ -497,12 +461,9 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "Plugins",
   "status.popover.action.manageServers": "Server verwalten",
-
   "session.share.popover.title": "Im Web veröffentlichen",
-  "session.share.popover.description.shared":
-    "Diese Sitzung ist öffentlich im Web. Sie ist für jeden mit dem Link zugänglich.",
-  "session.share.popover.description.unshared":
-    "Sitzung öffentlich im Web teilen. Sie wird für jeden mit dem Link zugänglich sein.",
+  "session.share.popover.description.shared": "Diese Sitzung ist öffentlich im Web. Sie ist für jeden mit dem Link zugänglich.",
+  "session.share.popover.description.unshared": "Sitzung öffentlich im Web teilen. Sie wird für jeden mit dem Link zugänglich sein.",
   "session.share.action.share": "Teilen",
   "session.share.action.publish": "Veröffentlichen",
   "session.share.action.publishing": "Veröffentliche...",
@@ -511,19 +472,15 @@ export const dict = {
   "session.share.action.view": "Ansehen",
   "session.share.copy.copied": "Kopiert",
   "session.share.copy.copyLink": "Link kopieren",
-
   "lsp.tooltip.none": "Keine LSP-Server",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "Lade Prompt...",
   "terminal.loading": "Lade Terminal...",
   "terminal.title": "Terminal",
   "terminal.title.numbered": "Terminal {{number}}",
   "terminal.close": "Terminal schließen",
-
   "terminal.connectionLost.title": "Verbindung verloren",
-  "terminal.connectionLost.description":
-    "Die Terminalverbindung wurde unterbrochen. Das kann passieren, wenn der Server neu startet.",
+  "terminal.connectionLost.description": "Die Terminalverbindung wurde unterbrochen. Das kann passieren, wenn der Server neu startet.",
   "common.closeTab": "Tab schließen",
   "common.dismiss": "Verwerfen",
   "common.requestFailed": "Anfrage fehlgeschlagen",
@@ -536,7 +493,6 @@ export const dict = {
   "common.close": "Schließen",
   "common.edit": "Bearbeiten",
   "common.loadMore": "Mehr laden",
-
   "common.key.esc": "ESC",
   "sidebar.menu.toggle": "Menü umschalten",
   "sidebar.nav.projectsAndSessions": "Projekte und Sitzungen",
@@ -546,25 +502,22 @@ export const dict = {
   "sidebar.workspaces.disable": "Arbeitsbereiche deaktivieren",
   "sidebar.gettingStarted.title": "Erste Schritte",
   "sidebar.gettingStarted.line1": "OpenCode enthält kostenlose Modelle, damit Sie sofort loslegen können.",
-  "sidebar.gettingStarted.line2":
-    "Verbinden Sie einen beliebigen Anbieter, um Modelle wie Claude, GPT, Gemini usw. zu nutzen.",
+  "sidebar.gettingStarted.line2": "Verbinden Sie einen beliebigen Anbieter, um Modelle wie Claude, GPT, Gemini usw. zu nutzen.",
   "sidebar.project.recentSessions": "Letzte Sitzungen",
   "sidebar.project.viewAllSessions": "Alle Sitzungen anzeigen",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "Desktop",
   "settings.section.server": "Server",
   "settings.tab.general": "Allgemein",
   "settings.tab.shortcuts": "Tastenkombinationen",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.title": "WSL-Integration",
+  "settings.desktop.wsl.description": "OpenCode-Server innerhalb von WSL unter Windows ausführen.",
   "settings.general.section.appearance": "Erscheinungsbild",
   "settings.general.section.notifications": "Systembenachrichtigungen",
   "settings.general.section.updates": "Updates",
   "settings.general.section.sounds": "Soundeffekte",
-
+  "settings.general.section.display": "Anzeige",
   "settings.general.row.language.title": "Sprache",
   "settings.general.row.language.description": "Die Anzeigesprache für OpenCode ändern",
   "settings.general.row.appearance.title": "Erscheinungsbild",
@@ -573,10 +526,11 @@ export const dict = {
   "settings.general.row.theme.description": "Das Thema von OpenCode anpassen.",
   "settings.general.row.font.title": "Schriftart",
   "settings.general.row.font.description": "Die in Codeblöcken verwendete Monospace-Schriftart anpassen",
-
+  "settings.general.row.wayland.title": "Natives Wayland verwenden",
+  "settings.general.row.wayland.description": "X11-Fallback unter Wayland deaktivieren. Erfordert Neustart.",
+  "settings.general.row.wayland.tooltip": "Unter Linux mit Monitoren unterschiedlicher Bildwiederholraten kann natives Wayland stabiler sein.",
   "settings.general.row.releaseNotes.title": "Versionshinweise",
-  "settings.general.row.releaseNotes.description": '"Neuigkeiten"-Pop-ups nach Updates anzeigen',
-
+  "settings.general.row.releaseNotes.description": "\"Neuigkeiten\"-Pop-ups nach Updates anzeigen",
   "settings.updates.row.startup.title": "Beim Start nach Updates suchen",
   "settings.updates.row.startup.description": "Beim Start von OpenCode automatisch nach Updates suchen",
   "settings.updates.row.check.title": "Nach Updates suchen",
@@ -585,7 +539,6 @@ export const dict = {
   "settings.updates.action.checking": "Wird geprüft...",
   "settings.updates.toast.latest.title": "Du bist auf dem neuesten Stand",
   "settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von OpenCode.",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -644,21 +597,17 @@ export const dict = {
   "sound.option.yup05": "Ja 05",
   "sound.option.yup06": "Ja 06",
   "settings.general.notifications.agent.title": "Agent",
-  "settings.general.notifications.agent.description":
-    "Systembenachrichtigung anzeigen, wenn der Agent fertig ist oder Aufmerksamkeit benötigt",
+  "settings.general.notifications.agent.description": "Systembenachrichtigung anzeigen, wenn der Agent fertig ist oder Aufmerksamkeit benötigt",
   "settings.general.notifications.permissions.title": "Berechtigungen",
-  "settings.general.notifications.permissions.description":
-    "Systembenachrichtigung anzeigen, wenn eine Berechtigung erforderlich ist",
+  "settings.general.notifications.permissions.description": "Systembenachrichtigung anzeigen, wenn eine Berechtigung erforderlich ist",
   "settings.general.notifications.errors.title": "Fehler",
   "settings.general.notifications.errors.description": "Systembenachrichtigung anzeigen, wenn ein Fehler auftritt",
-
   "settings.general.sounds.agent.title": "Agent",
   "settings.general.sounds.agent.description": "Ton abspielen, wenn der Agent fertig ist oder Aufmerksamkeit benötigt",
   "settings.general.sounds.permissions.title": "Berechtigungen",
   "settings.general.sounds.permissions.description": "Ton abspielen, wenn eine Berechtigung erforderlich ist",
   "settings.general.sounds.errors.title": "Fehler",
   "settings.general.sounds.errors.description": "Ton abspielen, wenn ein Fehler auftritt",
-
   "settings.shortcuts.title": "Tastenkombinationen",
   "settings.shortcuts.reset.button": "Auf Standard zurücksetzen",
   "settings.shortcuts.reset.toast.title": "Tastenkombinationen zurückgesetzt",
@@ -669,14 +618,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "Tasten drücken",
   "settings.shortcuts.search.placeholder": "Tastenkürzel suchen",
   "settings.shortcuts.search.empty": "Keine Tastenkürzel gefunden",
-
   "settings.shortcuts.group.general": "Allgemein",
   "settings.shortcuts.group.session": "Sitzung",
   "settings.shortcuts.group.navigation": "Navigation",
   "settings.shortcuts.group.modelAndAgent": "Modell und Agent",
   "settings.shortcuts.group.terminal": "Terminal",
   "settings.shortcuts.group.prompt": "Prompt",
-
   "settings.providers.title": "Anbieter",
   "settings.providers.description": "Anbietereinstellungen können hier konfiguriert werden.",
   "settings.providers.section.connected": "Verbundene Anbieter",
@@ -694,21 +641,17 @@ export const dict = {
   "settings.commands.description": "Befehlseinstellungen können hier konfiguriert werden.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "MCP-Einstellungen können hier konfiguriert werden.",
-
   "settings.permissions.title": "Berechtigungen",
   "settings.permissions.description": "Steuern Sie, welche Tools der Server standardmäßig verwenden darf.",
   "settings.permissions.section.tools": "Tools",
   "settings.permissions.toast.updateFailed.title": "Berechtigungen konnten nicht aktualisiert werden",
-
   "settings.permissions.action.allow": "Erlauben",
   "settings.permissions.action.ask": "Fragen",
   "settings.permissions.action.deny": "Verweigern",
-
   "settings.permissions.tool.read.title": "Lesen",
   "settings.permissions.tool.read.description": "Lesen einer Datei (stimmt mit dem Dateipfad überein)",
   "settings.permissions.tool.edit.title": "Bearbeiten",
-  "settings.permissions.tool.edit.description":
-    "Dateien ändern, einschließlich Bearbeitungen, Schreibvorgängen, Patches und Mehrfachbearbeitungen",
+  "settings.permissions.tool.edit.description": "Dateien ändern, einschließlich Bearbeitungen, Schreibvorgängen, Patches und Mehrfachbearbeitungen",
   "settings.permissions.tool.glob.title": "Glob",
   "settings.permissions.tool.glob.description": "Dateien mithilfe von Glob-Mustern abgleichen",
   "settings.permissions.tool.grep.title": "Grep",
@@ -737,12 +680,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "Zugriff auf Dateien außerhalb des Projektverzeichnisses",
   "settings.permissions.tool.doom_loop.title": "Doom Loop",
   "settings.permissions.tool.doom_loop.description": "Wiederholte Tool-Aufrufe mit identischer Eingabe erkennen",
-
   "session.delete.failed.title": "Sitzung konnte nicht gelöscht werden",
   "session.delete.title": "Sitzung löschen",
-  "session.delete.confirm": 'Sitzung "{{name}}" löschen?',
+  "session.delete.confirm": "Sitzung \"{{name}}\" löschen?",
   "session.delete.button": "Sitzung löschen",
-
   "workspace.new": "Neuer Arbeitsbereich",
   "workspace.type.local": "lokal",
   "workspace.type.sandbox": "Sandbox",
@@ -759,13 +700,13 @@ export const dict = {
   "workspace.status.clean": "Keine nicht zusammengeführten Änderungen erkannt.",
   "workspace.status.dirty": "Nicht zusammengeführte Änderungen in diesem Arbeitsbereich erkannt.",
   "workspace.delete.title": "Arbeitsbereich löschen",
-  "workspace.delete.confirm": 'Arbeitsbereich "{{name}}" löschen?',
+  "workspace.delete.confirm": "Arbeitsbereich \"{{name}}\" löschen?",
   "workspace.delete.button": "Arbeitsbereich löschen",
   "workspace.reset.title": "Arbeitsbereich zurücksetzen",
-  "workspace.reset.confirm": 'Arbeitsbereich "{{name}}" zurücksetzen?',
+  "workspace.reset.confirm": "Arbeitsbereich \"{{name}}\" zurücksetzen?",
   "workspace.reset.button": "Arbeitsbereich zurücksetzen",
   "workspace.reset.archived.none": "Keine aktiven Sitzungen werden archiviert.",
   "workspace.reset.archived.one": "1 Sitzung wird archiviert.",
   "workspace.reset.archived.many": "{{count}} Sitzungen werden archiviert.",
-  "workspace.reset.note": "Dadurch wird der Arbeitsbereich auf den Standard-Branch zurückgesetzt.",
+  "workspace.reset.note": "Dadurch wird der Arbeitsbereich auf den Standard-Branch zurückgesetzt."
 } satisfies Partial<Record<Keys, string>>

+ 96 - 19
packages/app/src/i18n/es.ts

@@ -15,8 +15,8 @@ export const dict = {
   "command.category.agent": "Agente",
   "command.category.permissions": "Permisos",
   "command.category.workspace": "Espacio de trabajo",
-
   "command.category.settings": "Ajustes",
+
   "theme.scheme.system": "Sistema",
   "theme.scheme.light": "Claro",
   "theme.scheme.dark": "Oscuro",
@@ -72,6 +72,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Aceptar ediciones automáticamente",
   "command.permissions.autoaccept.disable": "Dejar de aceptar ediciones automáticamente",
   "command.workspace.toggle": "Alternar espacios de trabajo",
+  "command.workspace.toggle.description": "Habilitar o deshabilitar múltiples espacios de trabajo en la barra lateral",
   "command.session.undo": "Deshacer",
   "command.session.undo.description": "Deshacer el último mensaje",
   "command.session.redo": "Rehacer",
@@ -95,9 +96,13 @@ export const dict = {
   "dialog.provider.group.popular": "Popular",
   "dialog.provider.group.other": "Otro",
   "dialog.provider.tag.recommended": "Recomendado",
-  "dialog.provider.anthropic.note": "Conectar con Claude Pro/Max o clave API",
-  "dialog.provider.openai.note": "Conectar con ChatGPT Pro/Plus o clave API",
-  "dialog.provider.copilot.note": "Conectar con Copilot o clave API",
+  "dialog.provider.opencode.note": "Modelos seleccionados incluyendo Claude, GPT, Gemini y más",
+  "dialog.provider.anthropic.note": "Acceso directo a modelos Claude, incluyendo Pro y Max",
+  "dialog.provider.copilot.note": "Modelos Claude para asistencia de codificación",
+  "dialog.provider.openai.note": "Modelos GPT para tareas de IA generales rápidas y capaces",
+  "dialog.provider.google.note": "Modelos Gemini para respuestas rápidas y estructuradas",
+  "dialog.provider.openrouter.note": "Accede a todos los modelos soportados desde un solo proveedor",
+  "dialog.provider.vercel.note": "Acceso unificado a modelos de IA con enrutamiento inteligente",
 
   "dialog.model.select.title": "Seleccionar modelo",
   "dialog.model.search.placeholder": "Buscar modelos",
@@ -145,11 +150,48 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} conectado",
   "provider.connect.toast.connected.description": "Los modelos de {{provider}} ahora están disponibles para usar.",
 
+  "provider.custom.title": "Proveedor personalizado",
+  "provider.custom.description.prefix": "Configurar un proveedor compatible con OpenAI. Ver la ",
+  "provider.custom.description.link": "documentación de configuración del proveedor",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID del proveedor",
+  "provider.custom.field.providerID.placeholder": "miproveedor",
+  "provider.custom.field.providerID.description": "Letras minúsculas, números, guiones o guiones bajos",
+  "provider.custom.field.name.label": "Nombre para mostrar",
+  "provider.custom.field.name.placeholder": "Mi Proveedor de IA",
+  "provider.custom.field.baseURL.label": "URL base",
+  "provider.custom.field.baseURL.placeholder": "https://api.miproveedor.com/v1",
+  "provider.custom.field.apiKey.label": "Clave API",
+  "provider.custom.field.apiKey.placeholder": "Clave API",
+  "provider.custom.field.apiKey.description": "Opcional. Dejar vacío si gestionas la autenticación mediante cabeceras.",
+  "provider.custom.models.label": "Modelos",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "id-modelo",
+  "provider.custom.models.name.label": "Nombre",
+  "provider.custom.models.name.placeholder": "Nombre para mostrar",
+  "provider.custom.models.remove": "Eliminar modelo",
+  "provider.custom.models.add": "Añadir modelo",
+  "provider.custom.headers.label": "Cabeceras (opcional)",
+  "provider.custom.headers.key.label": "Cabecera",
+  "provider.custom.headers.key.placeholder": "Nombre-Cabecera",
+  "provider.custom.headers.value.label": "Valor",
+  "provider.custom.headers.value.placeholder": "valor",
+  "provider.custom.headers.remove": "Eliminar cabecera",
+  "provider.custom.headers.add": "Añadir cabecera",
+  "provider.custom.error.providerID.required": "El ID del proveedor es obligatorio",
+  "provider.custom.error.providerID.format": "Usa letras minúsculas, números, guiones o guiones bajos",
+  "provider.custom.error.providerID.exists": "Ese ID de proveedor ya existe",
+  "provider.custom.error.name.required": "El nombre para mostrar es obligatorio",
+  "provider.custom.error.baseURL.required": "La URL base es obligatoria",
+  "provider.custom.error.baseURL.format": "Debe comenzar con http:// o https://",
+  "provider.custom.error.required": "Obligatorio",
+  "provider.custom.error.duplicate": "Duplicado",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} desconectado",
   "provider.disconnect.toast.disconnected.description": "Los modelos de {{provider}} ya no están disponibles.",
+
   "model.tag.free": "Gratis",
   "model.tag.latest": "Último",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -164,8 +206,10 @@ export const dict = {
   "model.tooltip.reasoning.allowed": "Permite razonamiento",
   "model.tooltip.reasoning.none": "Sin razonamiento",
   "model.tooltip.context": "Límite de contexto {{limit}}",
+
   "common.search.placeholder": "Buscar",
   "common.goBack": "Volver",
+  "common.goForward": "Avanzar",
   "common.loading": "Cargando",
   "common.loading.ellipsis": "...",
   "common.cancel": "Cancelar",
@@ -287,11 +331,11 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "Recomendado: 128x128px",
   "dialog.project.edit.color": "Color",
   "dialog.project.edit.color.select": "Seleccionar color {{color}}",
-
   "dialog.project.edit.worktree.startup": "Script de inicio del espacio de trabajo",
   "dialog.project.edit.worktree.startup.description":
     "Se ejecuta después de crear un nuevo espacio de trabajo (árbol de trabajo).",
   "dialog.project.edit.worktree.startup.placeholder": "p. ej. bun install",
+
   "context.breakdown.title": "Desglose de Contexto",
   "context.breakdown.note":
     'Desglose aproximado de tokens de entrada. "Otro" incluye definiciones de herramientas y sobrecarga.',
@@ -327,30 +371,48 @@ export const dict = {
   "context.usage.clickToView": "Haz clic para ver contexto",
   "context.usage.view": "Ver uso del contexto",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "Idioma",
   "toast.language.description": "Cambiado a {{language}}",
 
   "toast.theme.title": "Tema cambiado",
   "toast.scheme.title": "Esquema de color",
 
-  "toast.permissions.autoaccept.on.title": "Aceptando ediciones automáticamente",
-  "toast.permissions.autoaccept.on.description": "Los permisos de edición y escritura serán aprobados automáticamente",
-  "toast.permissions.autoaccept.off.title": "Se dejó de aceptar ediciones automáticamente",
-  "toast.permissions.autoaccept.off.description": "Los permisos de edición y escritura requerirán aprobación",
-
   "toast.workspace.enabled.title": "Espacios de trabajo habilitados",
   "toast.workspace.enabled.description": "Ahora se muestran varios worktrees en la barra lateral",
   "toast.workspace.disabled.title": "Espacios de trabajo deshabilitados",
   "toast.workspace.disabled.description": "Solo se muestra el worktree principal en la barra lateral",
 
+  "toast.permissions.autoaccept.on.title": "Aceptando ediciones automáticamente",
+  "toast.permissions.autoaccept.on.description": "Los permisos de edición y escritura serán aprobados automáticamente",
+  "toast.permissions.autoaccept.off.title": "Se dejó de aceptar ediciones automáticamente",
+  "toast.permissions.autoaccept.off.description": "Los permisos de edición y escritura requerirán aprobación",
+
   "toast.model.none.title": "Ningún modelo seleccionado",
   "toast.model.none.description": "Conecta un proveedor para resumir esta sesión",
 
   "toast.file.loadFailed.title": "Fallo al cargar archivo",
-
   "toast.file.listFailed.title": "Fallo al listar archivos",
+
   "toast.context.noLineSelection.title": "Sin selección de líneas",
   "toast.context.noLineSelection.description": "Primero selecciona un rango de líneas en una pestaña de archivo.",
+
   "toast.session.share.copyFailed.title": "Fallo al copiar URL al portapapeles",
   "toast.session.share.success.title": "Sesión compartida",
   "toast.session.share.success.description": "¡URL compartida copiada al portapapeles!",
@@ -384,6 +446,7 @@ export const dict = {
     "Elemento raíz no encontrado. ¿Olvidaste añadirlo a tu index.html? ¿O tal vez el atributo id está mal escrito?",
 
   "error.globalSync.connectFailed": "No se pudo conectar al servidor. ¿Hay un servidor ejecutándose en `{{url}}`?",
+  "directory.error.invalidUrl": "URL de directorio inválida.",
 
   "error.chain.unknown": "Error desconocido",
   "error.chain.causedBy": "Causado por:",
@@ -431,15 +494,17 @@ export const dict = {
   "session.review.loadingChanges": "Cargando cambios...",
   "session.review.empty": "No hay cambios en esta sesión aún",
   "session.review.noChanges": "Sin cambios",
+
   "session.files.selectToOpen": "Selecciona un archivo para abrir",
   "session.files.all": "Todos los archivos",
   "session.files.binaryContent": "Archivo binario (el contenido no puede ser mostrado)",
+
   "session.messages.renderEarlier": "Renderizar mensajes anteriores",
   "session.messages.loadingEarlier": "Cargando mensajes anteriores...",
   "session.messages.loadEarlier": "Cargar mensajes anteriores",
   "session.messages.loading": "Cargando mensajes...",
-
   "session.messages.jumpToLatest": "Ir al último",
+
   "session.context.addToContext": "Añadir {{selection}} al contexto",
 
   "session.new.worktree.main": "Rama principal",
@@ -449,6 +514,11 @@ export const dict = {
 
   "session.header.search.placeholder": "Buscar {{project}}",
   "session.header.searchFiles": "Buscar archivos",
+  "session.header.openIn": "Abrir en",
+  "session.header.open.action": "Abrir {{app}}",
+  "session.header.open.ariaLabel": "Abrir en {{app}}",
+  "session.header.open.menu": "Opciones de apertura",
+  "session.header.open.copyPath": "Copiar ruta",
 
   "status.popover.trigger": "Estado",
   "status.popover.ariaLabel": "Configuraciones del servidor",
@@ -480,10 +550,10 @@ export const dict = {
   "terminal.title": "Terminal",
   "terminal.title.numbered": "Terminal {{number}}",
   "terminal.close": "Cerrar terminal",
-
   "terminal.connectionLost.title": "Conexión perdida",
   "terminal.connectionLost.description":
     "La conexión del terminal se interrumpió. Esto puede ocurrir cuando el servidor se reinicia.",
+
   "common.closeTab": "Cerrar pestaña",
   "common.dismiss": "Descartar",
   "common.requestFailed": "Solicitud fallida",
@@ -496,8 +566,8 @@ export const dict = {
   "common.close": "Cerrar",
   "common.edit": "Editar",
   "common.loadMore": "Cargar más",
-
   "common.key.esc": "ESC",
+
   "sidebar.menu.toggle": "Alternar menú",
   "sidebar.nav.projectsAndSessions": "Proyectos y sesiones",
   "sidebar.settings": "Ajustes",
@@ -511,18 +581,20 @@ export const dict = {
   "sidebar.project.viewAllSessions": "Ver todas las sesiones",
 
   "app.name.desktop": "OpenCode Desktop",
+
   "settings.section.desktop": "Escritorio",
   "settings.section.server": "Servidor",
   "settings.tab.general": "General",
   "settings.tab.shortcuts": "Atajos",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "Integración con WSL",
+  "settings.desktop.wsl.description": "Ejecutar el servidor OpenCode dentro de WSL en Windows.",
 
   "settings.general.section.appearance": "Apariencia",
   "settings.general.section.notifications": "Notificaciones del sistema",
   "settings.general.section.updates": "Actualizaciones",
   "settings.general.section.sounds": "Efectos de sonido",
+  "settings.general.section.display": "Pantalla",
 
   "settings.general.row.language.title": "Idioma",
   "settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode",
@@ -531,7 +603,12 @@ export const dict = {
   "settings.general.row.theme.title": "Tema",
   "settings.general.row.theme.description": "Personaliza el tema de OpenCode.",
   "settings.general.row.font.title": "Fuente",
-  "settings.general.row.font.description": "Personaliza la fuente mono usada en bloques de código",
+  "settings.general.row.font.description": "Personaliza la fuente monoespaciada usada en bloques de código",
+
+  "settings.general.row.wayland.title": "Usar Wayland nativo",
+  "settings.general.row.wayland.description": "Deshabilitar fallback a X11 en Wayland. Requiere reinicio.",
+  "settings.general.row.wayland.tooltip":
+    "En Linux con monitores de frecuencia de actualización mixta, Wayland nativo puede ser más estable.",
 
   "settings.general.row.releaseNotes.title": "Notas de la versión",
   "settings.general.row.releaseNotes.description":
@@ -545,7 +622,6 @@ export const dict = {
   "settings.updates.action.checking": "Buscando...",
   "settings.updates.toast.latest.title": "Estás al día",
   "settings.updates.toast.latest.description": "Estás usando la última versión de OpenCode.",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -603,6 +679,7 @@ export const dict = {
   "sound.option.yup04": "Sí 04",
   "sound.option.yup05": "Sí 05",
   "sound.option.yup06": "Sí 06",
+
   "settings.general.notifications.agent.title": "Agente",
   "settings.general.notifications.agent.description":
     "Mostrar notificación del sistema cuando el agente termine o necesite atención",

+ 77 - 80
packages/app/src/i18n/fr.ts

@@ -15,12 +15,10 @@ export const dict = {
   "command.category.agent": "Agent",
   "command.category.permissions": "Permissions",
   "command.category.workspace": "Espace de travail",
-
   "command.category.settings": "Paramètres",
   "theme.scheme.system": "Système",
   "theme.scheme.light": "Clair",
   "theme.scheme.dark": "Sombre",
-
   "command.sidebar.toggle": "Basculer la barre latérale",
   "command.project.open": "Ouvrir un projet",
   "command.provider.connect": "Connecter un fournisseur",
@@ -31,23 +29,19 @@ export const dict = {
   "command.session.previous.unseen": "Session non lue précédente",
   "command.session.next.unseen": "Session non lue suivante",
   "command.session.archive": "Archiver la session",
-
   "command.palette": "Palette de commandes",
-
   "command.theme.cycle": "Changer de thème",
   "command.theme.set": "Utiliser le thème : {{theme}}",
   "command.theme.scheme.cycle": "Changer de schéma de couleurs",
   "command.theme.scheme.set": "Utiliser le schéma de couleurs : {{scheme}}",
-
   "command.language.cycle": "Changer de langue",
   "command.language.set": "Utiliser la langue : {{language}}",
-
   "command.session.new": "Nouvelle session",
   "command.file.open": "Ouvrir un fichier",
   "command.tab.close": "Fermer l'onglet",
   "command.context.addSelection": "Ajouter la sélection au contexte",
   "command.context.addSelection.description": "Ajouter les lignes sélectionnées du fichier actuel",
-  "command.input.focus": "Focus input",
+  "command.input.focus": "Focus sur l'entrée",
   "command.terminal.toggle": "Basculer le terminal",
   "command.fileTree.toggle": "Basculer l'arborescence des fichiers",
   "command.review.toggle": "Basculer la revue",
@@ -72,6 +66,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Accepter automatiquement les modifications",
   "command.permissions.autoaccept.disable": "Arrêter l'acceptation automatique des modifications",
   "command.workspace.toggle": "Basculer les espaces de travail",
+  "command.workspace.toggle.description": "Activer ou désactiver plusieurs espaces de travail dans la barre latérale",
   "command.session.undo": "Annuler",
   "command.session.undo.description": "Annuler le dernier message",
   "command.session.redo": "Rétablir",
@@ -84,32 +79,30 @@ export const dict = {
   "command.session.share.description": "Partager cette session et copier l'URL dans le presse-papiers",
   "command.session.unshare": "Ne plus partager la session",
   "command.session.unshare.description": "Arrêter de partager cette session",
-
   "palette.search.placeholder": "Rechercher des fichiers, des commandes et des sessions",
   "palette.empty": "Aucun résultat trouvé",
   "palette.group.commands": "Commandes",
   "palette.group.files": "Fichiers",
-
   "dialog.provider.search.placeholder": "Rechercher des fournisseurs",
   "dialog.provider.empty": "Aucun fournisseur trouvé",
   "dialog.provider.group.popular": "Populaire",
   "dialog.provider.group.other": "Autre",
   "dialog.provider.tag.recommended": "Recommandé",
+  "dialog.provider.opencode.note": "Modèles sélectionnés incluant Claude, GPT, Gemini et plus",
   "dialog.provider.anthropic.note": "Connectez-vous avec Claude Pro/Max ou une clé API",
-  "dialog.provider.openai.note": "Connectez-vous avec ChatGPT Pro/Plus ou une clé API",
   "dialog.provider.copilot.note": "Connectez-vous avec Copilot ou une clé API",
-
+  "dialog.provider.openai.note": "Connectez-vous avec ChatGPT Pro/Plus ou une clé API",
+  "dialog.provider.google.note": "Modèles Gemini pour des réponses rapides et structurées",
+  "dialog.provider.openrouter.note": "Accédez à tous les modèles pris en charge depuis un seul fournisseur",
+  "dialog.provider.vercel.note": "Accès unifié aux modèles d'IA avec routage intelligent",
   "dialog.model.select.title": "Sélectionner un modèle",
   "dialog.model.search.placeholder": "Rechercher des modèles",
   "dialog.model.empty": "Aucun résultat de modèle",
   "dialog.model.manage": "Gérer les modèles",
   "dialog.model.manage.description": "Personnalisez les modèles qui apparaissent dans le sélecteur.",
-
   "dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par OpenCode",
   "dialog.model.unpaid.addMore.title": "Ajouter plus de modèles de fournisseurs populaires",
-
   "dialog.provider.viewAll": "Voir plus de fournisseurs",
-
   "provider.connect.title": "Connecter {{provider}}",
   "provider.connect.title.anthropicProMax": "Connexion avec Claude Pro/Max",
   "provider.connect.selectMethod": "Sélectionnez la méthode de connexion pour {{provider}}.",
@@ -144,12 +137,46 @@ export const dict = {
   "provider.connect.oauth.auto.confirmationCode": "Code de confirmation",
   "provider.connect.toast.connected.title": "{{provider}} connecté",
   "provider.connect.toast.connected.description": "Les modèles {{provider}} sont maintenant disponibles.",
-
+  "provider.custom.title": "Fournisseur personnalisé",
+  "provider.custom.description.prefix": "Configurer un fournisseur compatible OpenAI. Voir la ",
+  "provider.custom.description.link": "doc de config fournisseur",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID du fournisseur",
+  "provider.custom.field.providerID.placeholder": "monfournisseur",
+  "provider.custom.field.providerID.description": "Lettres minuscules, chiffres, traits d'union ou tirets bas",
+  "provider.custom.field.name.label": "Nom d'affichage",
+  "provider.custom.field.name.placeholder": "Mon fournisseur IA",
+  "provider.custom.field.baseURL.label": "URL de base",
+  "provider.custom.field.baseURL.placeholder": "https://api.monfournisseur.com/v1",
+  "provider.custom.field.apiKey.label": "Clé API",
+  "provider.custom.field.apiKey.placeholder": "Clé API",
+  "provider.custom.field.apiKey.description": "Optionnel. Laisser vide si vous gérez l'auth via les en-têtes.",
+  "provider.custom.models.label": "Modèles",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "id-modele",
+  "provider.custom.models.name.label": "Nom",
+  "provider.custom.models.name.placeholder": "Nom d'affichage",
+  "provider.custom.models.remove": "Supprimer le modèle",
+  "provider.custom.models.add": "Ajouter un modèle",
+  "provider.custom.headers.label": "En-têtes (optionnel)",
+  "provider.custom.headers.key.label": "En-tête",
+  "provider.custom.headers.key.placeholder": "Nom-En-Tête",
+  "provider.custom.headers.value.label": "Valeur",
+  "provider.custom.headers.value.placeholder": "valeur",
+  "provider.custom.headers.remove": "Supprimer l'en-tête",
+  "provider.custom.headers.add": "Ajouter un en-tête",
+  "provider.custom.error.providerID.required": "L'ID du fournisseur est requis",
+  "provider.custom.error.providerID.format": "Utilisez des lettres minuscules, chiffres, traits d'union ou tirets bas",
+  "provider.custom.error.providerID.exists": "Cet ID de fournisseur existe déjà",
+  "provider.custom.error.name.required": "Le nom d'affichage est requis",
+  "provider.custom.error.baseURL.required": "L'URL de base est requise",
+  "provider.custom.error.baseURL.format": "Doit commencer par http:// ou https://",
+  "provider.custom.error.required": "Requis",
+  "provider.custom.error.duplicate": "Doublon",
   "provider.disconnect.toast.disconnected.title": "{{provider}} déconnecté",
   "provider.disconnect.toast.disconnected.description": "Les modèles {{provider}} ne sont plus disponibles.",
   "model.tag.free": "Gratuit",
   "model.tag.latest": "Dernier",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -166,6 +193,7 @@ export const dict = {
   "model.tooltip.context": "Limite de contexte {{limit}}",
   "common.search.placeholder": "Rechercher",
   "common.goBack": "Retour",
+  "common.goForward": "Avancer",
   "common.loading": "Chargement",
   "common.loading.ellipsis": "...",
   "common.cancel": "Annuler",
@@ -176,14 +204,12 @@ export const dict = {
   "common.saving": "Enregistrement...",
   "common.default": "Défaut",
   "common.attachment": "pièce jointe",
-
   "prompt.placeholder.shell": "Entrez une commande shell...",
   "prompt.placeholder.normal": 'Demandez n\'importe quoi... "{{example}}"',
   "prompt.placeholder.summarizeComments": "Résumer les commentaires…",
   "prompt.placeholder.summarizeComment": "Résumer le commentaire…",
   "prompt.mode.shell": "Shell",
   "prompt.mode.shell.exit": "esc pour quitter",
-
   "prompt.example.1": "Corriger un TODO dans la base de code",
   "prompt.example.2": "Quelle est la pile technique de ce projet ?",
   "prompt.example.3": "Réparer les tests échoués",
@@ -209,7 +235,6 @@ export const dict = {
   "prompt.example.23": "Ajouter la pagination à cette liste",
   "prompt.example.24": "Créer une commande CLI pour...",
   "prompt.example.25": "Comment fonctionnent les variables d'environnement ici ?",
-
   "prompt.popover.emptyResults": "Aucun résultat correspondant",
   "prompt.popover.emptyCommands": "Aucune commande correspondante",
   "prompt.dropzone.label": "Déposez des images ou des PDF ici",
@@ -225,7 +250,6 @@ export const dict = {
   "prompt.attachment.remove": "Supprimer la pièce jointe",
   "prompt.action.send": "Envoyer",
   "prompt.action.stop": "Arrêter",
-
   "prompt.toast.pasteUnsupported.title": "Collage non supporté",
   "prompt.toast.pasteUnsupported.description": "Seules les images ou les PDF peuvent être collés ici.",
   "prompt.toast.modelAgentRequired.title": "Sélectionnez un agent et un modèle",
@@ -236,24 +260,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "Échec de l'envoi de la commande",
   "prompt.toast.promptSendFailed.title": "Échec de l'envoi du message",
   "prompt.toast.promptSendFailed.description": "Impossible de récupérer la session",
-
   "dialog.mcp.title": "MCPs",
   "dialog.mcp.description": "{{enabled}} sur {{total}} activés",
   "dialog.mcp.empty": "Aucun MCP configuré",
-
   "dialog.lsp.empty": "LSPs détectés automatiquement par type de fichier",
   "dialog.plugins.empty": "Plugins configurés dans opencode.json",
-
   "mcp.status.connected": "connecté",
   "mcp.status.failed": "échoué",
   "mcp.status.needs_auth": "nécessite auth",
   "mcp.status.disabled": "désactivé",
-
   "dialog.fork.empty": "Aucun message à partir duquel bifurquer",
-
   "dialog.directory.search.placeholder": "Rechercher des dossiers",
   "dialog.directory.empty": "Aucun dossier trouvé",
-
   "dialog.server.title": "Serveurs",
   "dialog.server.description": "Changez le serveur OpenCode auquel cette application se connecte.",
   "dialog.server.search.placeholder": "Rechercher des serveurs",
@@ -271,14 +289,12 @@ export const dict = {
   "dialog.server.default.set": "Définir le serveur actuel comme défaut",
   "dialog.server.default.clear": "Effacer",
   "dialog.server.action.remove": "Supprimer le serveur",
-
   "dialog.server.menu.edit": "Modifier",
   "dialog.server.menu.default": "Définir par défaut",
   "dialog.server.menu.defaultRemove": "Supprimer par défaut",
   "dialog.server.menu.delete": "Supprimer",
   "dialog.server.current": "Serveur actuel",
   "dialog.server.status.default": "Défaut",
-
   "dialog.project.edit.title": "Modifier le projet",
   "dialog.project.edit.name": "Nom",
   "dialog.project.edit.icon": "Icône",
@@ -287,7 +303,6 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "Recommandé : 128x128px",
   "dialog.project.edit.color": "Couleur",
   "dialog.project.edit.color.select": "Sélectionner la couleur {{color}}",
-
   "dialog.project.edit.worktree.startup": "Script de démarrage de l'espace de travail",
   "dialog.project.edit.worktree.startup.description":
     "S'exécute après la création d'un nouvel espace de travail (arbre de travail).",
@@ -300,10 +315,8 @@ export const dict = {
   "context.breakdown.assistant": "Assistant",
   "context.breakdown.tool": "Appels d'outils",
   "context.breakdown.other": "Autre",
-
   "context.systemPrompt.title": "Prompt système",
   "context.rawMessages.title": "Messages bruts",
-
   "context.stats.session": "Session",
   "context.stats.messages": "Messages",
   "context.stats.provider": "Fournisseur",
@@ -320,36 +333,44 @@ export const dict = {
   "context.stats.totalCost": "Coût total",
   "context.stats.sessionCreated": "Session créée",
   "context.stats.lastActivity": "Dernière activité",
-
   "context.usage.tokens": "Jetons",
   "context.usage.usage": "Utilisation",
   "context.usage.cost": "Coût",
   "context.usage.clickToView": "Cliquez pour voir le contexte",
   "context.usage.view": "Voir l'utilisation du contexte",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "Langue",
   "toast.language.description": "Passé à {{language}}",
-
   "toast.theme.title": "Thème changé",
   "toast.scheme.title": "Schéma de couleurs",
-
+  "toast.workspace.enabled.title": "Espaces de travail activés",
+  "toast.workspace.enabled.description": "Plusieurs worktrees sont désormais affichés dans la barre latérale",
+  "toast.workspace.disabled.title": "Espaces de travail désactivés",
+  "toast.workspace.disabled.description": "Seul le worktree principal est affiché dans la barre latérale",
   "toast.permissions.autoaccept.on.title": "Acceptation auto des modifications",
   "toast.permissions.autoaccept.on.description":
     "Les permissions de modification et d'écriture seront automatiquement approuvées",
   "toast.permissions.autoaccept.off.title": "Arrêt acceptation auto des modifications",
   "toast.permissions.autoaccept.off.description":
     "Les permissions de modification et d'écriture nécessiteront une approbation",
-
-  "toast.workspace.enabled.title": "Espaces de travail activés",
-  "toast.workspace.enabled.description": "Plusieurs worktrees sont désormais affichés dans la barre latérale",
-  "toast.workspace.disabled.title": "Espaces de travail désactivés",
-  "toast.workspace.disabled.description": "Seul le worktree principal est affiché dans la barre latérale",
-
   "toast.model.none.title": "Aucun modèle sélectionné",
   "toast.model.none.description": "Connectez un fournisseur pour résumer cette session",
-
   "toast.file.loadFailed.title": "Échec du chargement du fichier",
-
   "toast.file.listFailed.title": "Échec de la liste des fichiers",
   "toast.context.noLineSelection.title": "Aucune sélection de lignes",
   "toast.context.noLineSelection.description": "Sélectionnez d'abord une plage de lignes dans un onglet de fichier.",
@@ -358,20 +379,16 @@ export const dict = {
   "toast.session.share.success.description": "URL de partage copiée dans le presse-papiers !",
   "toast.session.share.failed.title": "Échec du partage de la session",
   "toast.session.share.failed.description": "Une erreur s'est produite lors du partage de la session",
-
   "toast.session.unshare.success.title": "Session non partagée",
   "toast.session.unshare.success.description": "Session non partagée avec succès !",
   "toast.session.unshare.failed.title": "Échec de l'annulation du partage",
   "toast.session.unshare.failed.description": "Une erreur s'est produite lors de l'annulation du partage de la session",
-
   "toast.session.listFailed.title": "Échec du chargement des sessions pour {{project}}",
-
   "toast.update.title": "Mise à jour disponible",
   "toast.update.description":
     "Une nouvelle version d'OpenCode ({{version}}) est maintenant disponible pour installation.",
   "toast.update.action.installRestart": "Installer et redémarrer",
   "toast.update.action.notYet": "Pas encore",
-
   "error.page.title": "Quelque chose s'est mal passé",
   "error.page.description": "Une erreur s'est produite lors du chargement de l'application.",
   "error.page.details.label": "Détails de l'erreur",
@@ -382,13 +399,11 @@ export const dict = {
   "error.page.report.prefix": "Veuillez signaler cette erreur à l'équipe OpenCode",
   "error.page.report.discord": "sur Discord",
   "error.page.version": "Version : {{version}}",
-
   "error.dev.rootNotFound":
     "Élément racine introuvable. Avez-vous oublié de l'ajouter à votre index.html ? Ou peut-être que l'attribut id est mal orthographié ?",
-
   "error.globalSync.connectFailed":
     "Impossible de se connecter au serveur. Y a-t-il un serveur en cours d'exécution à `{{url}}` ?",
-
+  "directory.error.invalidUrl": "Répertoire invalide dans l'URL.",
   "error.chain.unknown": "Erreur inconnue",
   "error.chain.causedBy": "Causé par :",
   "error.chain.apiError": "Erreur API",
@@ -411,21 +426,17 @@ export const dict = {
   "error.chain.configFrontmatterError": "Échec de l'analyse du frontmatter dans {{path}} :\n{{message}}",
   "error.chain.configInvalid": "Le fichier de configuration à {{path}} est invalide",
   "error.chain.configInvalidWithMessage": "Le fichier de configuration à {{path}} est invalide : {{message}}",
-
   "notification.permission.title": "Permission requise",
   "notification.permission.description": "{{sessionTitle}} dans {{projectName}} a besoin d'une permission",
   "notification.question.title": "Question",
   "notification.question.description": "{{sessionTitle}} dans {{projectName}} a une question",
   "notification.action.goToSession": "Aller à la session",
-
   "notification.session.responseReady.title": "Réponse prête",
   "notification.session.error.title": "Erreur de session",
   "notification.session.error.fallbackDescription": "Une erreur s'est produite",
-
   "home.recentProjects": "Projets récents",
   "home.empty.title": "Aucun projet récent",
   "home.empty.description": "Commencez par ouvrir un projet local",
-
   "session.tab.session": "Session",
   "session.tab.review": "Revue",
   "session.tab.context": "Contexte",
@@ -443,18 +454,19 @@ export const dict = {
   "session.messages.loadingEarlier": "Chargement des messages précédents...",
   "session.messages.loadEarlier": "Charger les messages précédents",
   "session.messages.loading": "Chargement des messages...",
-
   "session.messages.jumpToLatest": "Aller au dernier",
   "session.context.addToContext": "Ajouter {{selection}} au contexte",
-
   "session.new.worktree.main": "Branche principale",
   "session.new.worktree.mainWithBranch": "Branche principale ({{branch}})",
   "session.new.worktree.create": "Créer un nouvel arbre de travail",
   "session.new.lastModified": "Dernière modification",
-
   "session.header.search.placeholder": "Rechercher {{project}}",
   "session.header.searchFiles": "Rechercher des fichiers",
-
+  "session.header.openIn": "Ouvrir dans",
+  "session.header.open.action": "Ouvrir {{app}}",
+  "session.header.open.ariaLabel": "Ouvrir dans {{app}}",
+  "session.header.open.menu": "Options d'ouverture",
+  "session.header.open.copyPath": "Copier le chemin",
   "status.popover.trigger": "Statut",
   "status.popover.ariaLabel": "Configurations des serveurs",
   "status.popover.tab.servers": "Serveurs",
@@ -462,7 +474,6 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "Plugins",
   "status.popover.action.manageServers": "Gérer les serveurs",
-
   "session.share.popover.title": "Publier sur le web",
   "session.share.popover.description.shared":
     "Cette session est publique sur le web. Elle est accessible à toute personne disposant du lien.",
@@ -476,16 +487,13 @@ export const dict = {
   "session.share.action.view": "Voir",
   "session.share.copy.copied": "Copié",
   "session.share.copy.copyLink": "Copier le lien",
-
   "lsp.tooltip.none": "Aucun serveur LSP",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "Chargement du prompt...",
   "terminal.loading": "Chargement du terminal...",
   "terminal.title": "Terminal",
   "terminal.title.numbered": "Terminal {{number}}",
   "terminal.close": "Fermer le terminal",
-
   "terminal.connectionLost.title": "Connexion perdue",
   "terminal.connectionLost.description":
     "La connexion au terminal a été interrompue. Cela peut arriver lorsque le serveur redémarre.",
@@ -501,7 +509,6 @@ export const dict = {
   "common.close": "Fermer",
   "common.edit": "Modifier",
   "common.loadMore": "Charger plus",
-
   "common.key.esc": "ESC",
   "sidebar.menu.toggle": "Basculer le menu",
   "sidebar.nav.projectsAndSessions": "Projets et sessions",
@@ -516,21 +523,19 @@ export const dict = {
     "Connectez n'importe quel fournisseur pour utiliser des modèles, y compris Claude, GPT, Gemini etc.",
   "sidebar.project.recentSessions": "Sessions récentes",
   "sidebar.project.viewAllSessions": "Voir toutes les sessions",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "Bureau",
   "settings.section.server": "Serveur",
   "settings.tab.general": "Général",
   "settings.tab.shortcuts": "Raccourcis",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.title": "Intégration WSL",
+  "settings.desktop.wsl.description": "Exécuter le serveur OpenCode dans WSL sur Windows.",
   "settings.general.section.appearance": "Apparence",
   "settings.general.section.notifications": "Notifications système",
   "settings.general.section.updates": "Mises à jour",
   "settings.general.section.sounds": "Effets sonores",
-
+  "settings.general.section.display": "Affichage",
   "settings.general.row.language.title": "Langue",
   "settings.general.row.language.description": "Changer la langue d'affichage pour OpenCode",
   "settings.general.row.appearance.title": "Apparence",
@@ -539,10 +544,12 @@ export const dict = {
   "settings.general.row.theme.description": "Personnaliser le thème d'OpenCode.",
   "settings.general.row.font.title": "Police",
   "settings.general.row.font.description": "Personnaliser la police mono utilisée dans les blocs de code",
-
+  "settings.general.row.wayland.title": "Utiliser Wayland natif",
+  "settings.general.row.wayland.description": "Désactiver le repli X11 sur Wayland. Nécessite un redémarrage.",
+  "settings.general.row.wayland.tooltip":
+    "Sur Linux avec des moniteurs à taux de rafraîchissement mixte, Wayland natif peut être plus stable.",
   "settings.general.row.releaseNotes.title": "Notes de version",
   "settings.general.row.releaseNotes.description": 'Afficher des pop-ups "Quoi de neuf" après les mises à jour',
-
   "settings.updates.row.startup.title": "Vérifier les mises à jour au démarrage",
   "settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'OpenCode",
   "settings.updates.row.check.title": "Vérifier les mises à jour",
@@ -551,7 +558,6 @@ export const dict = {
   "settings.updates.action.checking": "Vérification...",
   "settings.updates.toast.latest.title": "Vous êtes à jour",
   "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'OpenCode.",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -617,14 +623,12 @@ export const dict = {
     "Afficher une notification système lorsqu'une permission est requise",
   "settings.general.notifications.errors.title": "Erreurs",
   "settings.general.notifications.errors.description": "Afficher une notification système lorsqu'une erreur se produit",
-
   "settings.general.sounds.agent.title": "Agent",
   "settings.general.sounds.agent.description": "Jouer un son lorsque l'agent a terminé ou nécessite une attention",
   "settings.general.sounds.permissions.title": "Permissions",
   "settings.general.sounds.permissions.description": "Jouer un son lorsqu'une permission est requise",
   "settings.general.sounds.errors.title": "Erreurs",
   "settings.general.sounds.errors.description": "Jouer un son lorsqu'une erreur se produit",
-
   "settings.shortcuts.title": "Raccourcis clavier",
   "settings.shortcuts.reset.button": "Rétablir les défauts",
   "settings.shortcuts.reset.toast.title": "Raccourcis réinitialisés",
@@ -635,14 +639,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "Appuyez sur les touches",
   "settings.shortcuts.search.placeholder": "Rechercher des raccourcis",
   "settings.shortcuts.search.empty": "Aucun raccourci trouvé",
-
   "settings.shortcuts.group.general": "Général",
   "settings.shortcuts.group.session": "Session",
   "settings.shortcuts.group.navigation": "Navigation",
   "settings.shortcuts.group.modelAndAgent": "Modèle et agent",
   "settings.shortcuts.group.terminal": "Terminal",
   "settings.shortcuts.group.prompt": "Prompt",
-
   "settings.providers.title": "Fournisseurs",
   "settings.providers.description": "Les paramètres des fournisseurs seront configurables ici.",
   "settings.providers.section.connected": "Fournisseurs connectés",
@@ -660,16 +662,13 @@ export const dict = {
   "settings.commands.description": "Les paramètres des commandes seront configurables ici.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "Les paramètres MCP seront configurables ici.",
-
   "settings.permissions.title": "Permissions",
   "settings.permissions.description": "Contrôlez les outils que le serveur peut utiliser par défaut.",
   "settings.permissions.section.tools": "Outils",
   "settings.permissions.toast.updateFailed.title": "Échec de la mise à jour des permissions",
-
   "settings.permissions.action.allow": "Autoriser",
   "settings.permissions.action.ask": "Demander",
   "settings.permissions.action.deny": "Refuser",
-
   "settings.permissions.tool.read.title": "Lire",
   "settings.permissions.tool.read.description": "Lecture d'un fichier (correspond au chemin du fichier)",
   "settings.permissions.tool.edit.title": "Modifier",
@@ -704,12 +703,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "Accéder aux fichiers en dehors du répertoire du projet",
   "settings.permissions.tool.doom_loop.title": "Boucle infernale",
   "settings.permissions.tool.doom_loop.description": "Détecter les appels d'outils répétés avec une entrée identique",
-
   "session.delete.failed.title": "Échec de la suppression de la session",
   "session.delete.title": "Supprimer la session",
   "session.delete.confirm": 'Supprimer la session "{{name}}" ?',
   "session.delete.button": "Supprimer la session",
-
   "workspace.new": "Nouvel espace de travail",
   "workspace.type.local": "local",
   "workspace.type.sandbox": "bac à sable",

+ 81 - 79
packages/app/src/i18n/ja.ts

@@ -15,12 +15,10 @@ export const dict = {
   "command.category.agent": "エージェント",
   "command.category.permissions": "権限",
   "command.category.workspace": "ワークスペース",
-
   "command.category.settings": "設定",
   "theme.scheme.system": "システム",
   "theme.scheme.light": "ライト",
   "theme.scheme.dark": "ダーク",
-
   "command.sidebar.toggle": "サイドバーの切り替え",
   "command.project.open": "プロジェクトを開く",
   "command.provider.connect": "プロバイダーに接続",
@@ -31,17 +29,13 @@ export const dict = {
   "command.session.previous.unseen": "前の未読セッション",
   "command.session.next.unseen": "次の未読セッション",
   "command.session.archive": "セッションをアーカイブ",
-
   "command.palette": "コマンドパレット",
-
   "command.theme.cycle": "テーマの切り替え",
   "command.theme.set": "テーマを使用: {{theme}}",
   "command.theme.scheme.cycle": "配色の切り替え",
   "command.theme.scheme.set": "配色を使用: {{scheme}}",
-
   "command.language.cycle": "言語の切り替え",
   "command.language.set": "言語を使用: {{language}}",
-
   "command.session.new": "新しいセッション",
   "command.file.open": "ファイルを開く",
   "command.tab.close": "タブを閉じる",
@@ -72,6 +66,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "編集を自動承認",
   "command.permissions.autoaccept.disable": "編集の自動承認を停止",
   "command.workspace.toggle": "ワークスペースを切り替え",
+  "command.workspace.toggle.description": "サイドバーでの複数のワークスペースの有効化・無効化",
   "command.session.undo": "元に戻す",
   "command.session.undo.description": "最後のメッセージを元に戻す",
   "command.session.redo": "やり直す",
@@ -84,32 +79,30 @@ export const dict = {
   "command.session.share.description": "このセッションを共有しURLをクリップボードにコピー",
   "command.session.unshare": "セッションの共有を停止",
   "command.session.unshare.description": "このセッションの共有を停止",
-
   "palette.search.placeholder": "ファイル、コマンド、セッションを検索",
   "palette.empty": "結果が見つかりません",
   "palette.group.commands": "コマンド",
   "palette.group.files": "ファイル",
-
   "dialog.provider.search.placeholder": "プロバイダーを検索",
   "dialog.provider.empty": "プロバイダーが見つかりません",
   "dialog.provider.group.popular": "人気",
   "dialog.provider.group.other": "その他",
   "dialog.provider.tag.recommended": "推奨",
+  "dialog.provider.opencode.note": "Claude, GPT, Geminiなどを含む厳選されたモデル",
   "dialog.provider.anthropic.note": "Claude Pro/MaxまたはAPIキーで接続",
-  "dialog.provider.openai.note": "ChatGPT Pro/PlusまたはAPIキーで接続",
   "dialog.provider.copilot.note": "CopilotまたはAPIキーで接続",
-
+  "dialog.provider.openai.note": "ChatGPT Pro/PlusまたはAPIキーで接続",
+  "dialog.provider.google.note": "高速で構造化された応答のためのGeminiモデル",
+  "dialog.provider.openrouter.note": "1つのプロバイダーからすべてのサポートされているモデルにアクセス",
+  "dialog.provider.vercel.note": "スマートルーターによるAIモデルへの統合アクセス",
   "dialog.model.select.title": "モデルを選択",
   "dialog.model.search.placeholder": "モデルを検索",
   "dialog.model.empty": "モデルが見つかりません",
   "dialog.model.manage": "モデルを管理",
   "dialog.model.manage.description": "モデルセレクターに表示するモデルをカスタマイズします。",
-
   "dialog.model.unpaid.freeModels.title": "OpenCodeが提供する無料モデル",
   "dialog.model.unpaid.addMore.title": "人気のプロバイダーからモデルを追加",
-
   "dialog.provider.viewAll": "さらにプロバイダーを表示",
-
   "provider.connect.title": "{{provider}}を接続",
   "provider.connect.title.anthropicProMax": "Claude Pro/Maxでログイン",
   "provider.connect.selectMethod": "{{provider}}のログイン方法を選択してください。",
@@ -143,12 +136,46 @@ export const dict = {
   "provider.connect.oauth.auto.confirmationCode": "確認コード",
   "provider.connect.toast.connected.title": "{{provider}}が接続されました",
   "provider.connect.toast.connected.description": "{{provider}}モデルが使用可能になりました。",
-
+  "provider.custom.title": "カスタムプロバイダー",
+  "provider.custom.description.prefix": "OpenAI互換のプロバイダーを設定します。詳細は",
+  "provider.custom.description.link": "プロバイダー設定ドキュメント",
+  "provider.custom.description.suffix": "をご覧ください。",
+  "provider.custom.field.providerID.label": "プロバイダーID",
+  "provider.custom.field.providerID.placeholder": "myprovider",
+  "provider.custom.field.providerID.description": "小文字、数字、ハイフン、アンダースコア",
+  "provider.custom.field.name.label": "表示名",
+  "provider.custom.field.name.placeholder": "My AI Provider",
+  "provider.custom.field.baseURL.label": "ベースURL",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "APIキー",
+  "provider.custom.field.apiKey.placeholder": "APIキー",
+  "provider.custom.field.apiKey.description": "オプション。ヘッダーで認証を管理する場合は空のままにしてください。",
+  "provider.custom.models.label": "モデル",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "名前",
+  "provider.custom.models.name.placeholder": "表示名",
+  "provider.custom.models.remove": "モデルを削除",
+  "provider.custom.models.add": "モデルを追加",
+  "provider.custom.headers.label": "ヘッダー (オプション)",
+  "provider.custom.headers.key.label": "ヘッダー",
+  "provider.custom.headers.key.placeholder": "Header-Name",
+  "provider.custom.headers.value.label": "値",
+  "provider.custom.headers.value.placeholder": "value",
+  "provider.custom.headers.remove": "ヘッダーを削除",
+  "provider.custom.headers.add": "ヘッダーを追加",
+  "provider.custom.error.providerID.required": "プロバイダーIDが必要です",
+  "provider.custom.error.providerID.format": "小文字、数字、ハイフン、アンダースコアを使用してください",
+  "provider.custom.error.providerID.exists": "そのプロバイダーIDは既に存在します",
+  "provider.custom.error.name.required": "表示名が必要です",
+  "provider.custom.error.baseURL.required": "ベースURLが必要です",
+  "provider.custom.error.baseURL.format": "http:// または https:// で始まる必要があります",
+  "provider.custom.error.required": "必須",
+  "provider.custom.error.duplicate": "重複",
   "provider.disconnect.toast.disconnected.title": "{{provider}}が切断されました",
   "provider.disconnect.toast.disconnected.description": "{{provider}}のモデルは利用できなくなりました。",
   "model.tag.free": "無料",
   "model.tag.latest": "最新",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -165,6 +192,7 @@ export const dict = {
   "model.tooltip.context": "コンテキスト上限 {{limit}}",
   "common.search.placeholder": "検索",
   "common.goBack": "戻る",
+  "common.goForward": "進む",
   "common.loading": "読み込み中",
   "common.loading.ellipsis": "...",
   "common.cancel": "キャンセル",
@@ -175,14 +203,12 @@ export const dict = {
   "common.saving": "保存中...",
   "common.default": "デフォルト",
   "common.attachment": "添付ファイル",
-
   "prompt.placeholder.shell": "シェルコマンドを入力...",
   "prompt.placeholder.normal": '何でも聞いてください... "{{example}}"',
   "prompt.placeholder.summarizeComments": "コメントを要約…",
   "prompt.placeholder.summarizeComment": "コメントを要約…",
-  "prompt.mode.shell": "Shell",
+  "prompt.mode.shell": "シェル",
   "prompt.mode.shell.exit": "escで終了",
-
   "prompt.example.1": "コードベースのTODOを修正",
   "prompt.example.2": "このプロジェクトの技術スタックは何ですか?",
   "prompt.example.3": "壊れたテストを修正",
@@ -208,7 +234,6 @@ export const dict = {
   "prompt.example.23": "このリストにページネーションを追加",
   "prompt.example.24": "〜のCLIコマンドを作成",
   "prompt.example.25": "ここでは環境変数はどう機能しますか?",
-
   "prompt.popover.emptyResults": "一致する結果がありません",
   "prompt.popover.emptyCommands": "一致するコマンドがありません",
   "prompt.dropzone.label": "画像またはPDFをここにドロップ",
@@ -224,7 +249,6 @@ export const dict = {
   "prompt.attachment.remove": "添付ファイルを削除",
   "prompt.action.send": "送信",
   "prompt.action.stop": "停止",
-
   "prompt.toast.pasteUnsupported.title": "サポートされていない貼り付け",
   "prompt.toast.pasteUnsupported.description": "ここでは画像またはPDFのみ貼り付け可能です。",
   "prompt.toast.modelAgentRequired.title": "エージェントとモデルを選択",
@@ -235,24 +259,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "コマンドの送信に失敗しました",
   "prompt.toast.promptSendFailed.title": "プロンプトの送信に失敗しました",
   "prompt.toast.promptSendFailed.description": "セッションを取得できませんでした",
-
   "dialog.mcp.title": "MCP",
   "dialog.mcp.description": "{{total}}個中{{enabled}}個が有効",
   "dialog.mcp.empty": "MCPが設定されていません",
-
   "dialog.lsp.empty": "ファイルタイプから自動検出されたLSP",
   "dialog.plugins.empty": "opencode.jsonで設定されたプラグイン",
-
   "mcp.status.connected": "接続済み",
   "mcp.status.failed": "失敗",
   "mcp.status.needs_auth": "認証が必要",
   "mcp.status.disabled": "無効",
-
   "dialog.fork.empty": "フォーク元のメッセージがありません",
-
   "dialog.directory.search.placeholder": "フォルダを検索",
   "dialog.directory.empty": "フォルダが見つかりません",
-
   "dialog.server.title": "サーバー",
   "dialog.server.description": "このアプリが接続するOpenCodeサーバーを切り替えます。",
   "dialog.server.search.placeholder": "サーバーを検索",
@@ -270,14 +288,12 @@ export const dict = {
   "dialog.server.default.set": "現在のサーバーをデフォルトに設定",
   "dialog.server.default.clear": "クリア",
   "dialog.server.action.remove": "サーバーを削除",
-
   "dialog.server.menu.edit": "編集",
   "dialog.server.menu.default": "デフォルトに設定",
   "dialog.server.menu.defaultRemove": "デフォルト設定を解除",
   "dialog.server.menu.delete": "削除",
   "dialog.server.current": "現在のサーバー",
   "dialog.server.status.default": "デフォルト",
-
   "dialog.project.edit.title": "プロジェクトを編集",
   "dialog.project.edit.name": "名前",
   "dialog.project.edit.icon": "アイコン",
@@ -286,7 +302,6 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "推奨: 128x128px",
   "dialog.project.edit.color": "色",
   "dialog.project.edit.color.select": "{{color}}の色を選択",
-
   "dialog.project.edit.worktree.startup": "ワークスペース起動スクリプト",
   "dialog.project.edit.worktree.startup.description":
     "新しいワークスペース (ワークツリー) を作成した後に実行されます。",
@@ -298,10 +313,8 @@ export const dict = {
   "context.breakdown.assistant": "アシスタント",
   "context.breakdown.tool": "ツール呼び出し",
   "context.breakdown.other": "その他",
-
   "context.systemPrompt.title": "システムプロンプト",
   "context.rawMessages.title": "生のメッセージ",
-
   "context.stats.session": "セッション",
   "context.stats.messages": "メッセージ",
   "context.stats.provider": "プロバイダー",
@@ -318,29 +331,42 @@ export const dict = {
   "context.stats.totalCost": "総コスト",
   "context.stats.sessionCreated": "セッション作成日時",
   "context.stats.lastActivity": "最終アクティビティ",
-
   "context.usage.tokens": "トークン",
   "context.usage.usage": "使用量",
   "context.usage.cost": "コスト",
   "context.usage.clickToView": "クリックしてコンテキストを表示",
   "context.usage.view": "コンテキスト使用量を表示",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "言語",
   "toast.language.description": "{{language}}に切り替えました",
-
   "toast.theme.title": "テーマが切り替わりました",
   "toast.scheme.title": "配色",
-
+  "toast.workspace.enabled.title": "ワークスペースが有効になりました",
+  "toast.workspace.enabled.description": "サイドバーに複数のワークツリーが表示されます",
+  "toast.workspace.disabled.title": "ワークスペースが無効になりました",
+  "toast.workspace.disabled.description": "サイドバーにはメインのワークツリーのみが表示されます",
   "toast.permissions.autoaccept.on.title": "編集を自動承認中",
   "toast.permissions.autoaccept.on.description": "編集と書き込みの権限は自動的に承認されます",
   "toast.permissions.autoaccept.off.title": "編集の自動承認を停止しました",
   "toast.permissions.autoaccept.off.description": "編集と書き込みの権限には承認が必要です",
-
   "toast.model.none.title": "モデルが選択されていません",
   "toast.model.none.description": "このセッションを要約するにはプロバイダーを接続してください",
-
   "toast.file.loadFailed.title": "ファイルの読み込みに失敗しました",
-
   "toast.file.listFailed.title": "ファイル一覧の取得に失敗しました",
   "toast.context.noLineSelection.title": "行が選択されていません",
   "toast.context.noLineSelection.description": "まずファイルタブで行範囲を選択してください。",
@@ -349,19 +375,15 @@ export const dict = {
   "toast.session.share.success.description": "共有URLをクリップボードにコピーしました!",
   "toast.session.share.failed.title": "セッションの共有に失敗しました",
   "toast.session.share.failed.description": "セッションの共有中にエラーが発生しました",
-
   "toast.session.unshare.success.title": "セッションの共有を解除しました",
   "toast.session.unshare.success.description": "セッションの共有解除に成功しました!",
   "toast.session.unshare.failed.title": "セッションの共有解除に失敗しました",
   "toast.session.unshare.failed.description": "セッションの共有解除中にエラーが発生しました",
-
   "toast.session.listFailed.title": "{{project}}のセッション読み込みに失敗しました",
-
   "toast.update.title": "アップデートが利用可能です",
   "toast.update.description": "OpenCodeの新しいバージョン ({{version}}) がインストール可能です。",
   "toast.update.action.installRestart": "インストールして再起動",
   "toast.update.action.notYet": "今はしない",
-
   "error.page.title": "問題が発生しました",
   "error.page.description": "アプリケーションの読み込み中にエラーが発生しました。",
   "error.page.details.label": "エラー詳細",
@@ -372,12 +394,10 @@ export const dict = {
   "error.page.report.prefix": "このエラーをOpenCodeチームに報告してください: ",
   "error.page.report.discord": "Discord",
   "error.page.version": "バージョン: {{version}}",
-
   "error.dev.rootNotFound":
     "ルート要素が見つかりません。index.htmlに追加するのを忘れていませんか?またはid属性のスペルが間違っていませんか?",
-
   "error.globalSync.connectFailed": "サーバーに接続できませんでした。`{{url}}`でサーバーが実行されていますか?",
-
+  "directory.error.invalidUrl": "URL内のディレクトリが無効です。",
   "error.chain.unknown": "不明なエラー",
   "error.chain.causedBy": "原因:",
   "error.chain.apiError": "APIエラー",
@@ -398,21 +418,17 @@ export const dict = {
   "error.chain.configFrontmatterError": "{{path}} のフロントマターの解析に失敗しました:\n{{message}}",
   "error.chain.configInvalid": "{{path}} の設定ファイルが無効です",
   "error.chain.configInvalidWithMessage": "{{path}} の設定ファイルが無効です: {{message}}",
-
   "notification.permission.title": "権限が必要です",
   "notification.permission.description": "{{projectName}} の {{sessionTitle}} が権限を必要としています",
   "notification.question.title": "質問",
   "notification.question.description": "{{projectName}} の {{sessionTitle}} から質問があります",
   "notification.action.goToSession": "セッションへ移動",
-
   "notification.session.responseReady.title": "応答の準備ができました",
   "notification.session.error.title": "セッションエラー",
   "notification.session.error.fallbackDescription": "エラーが発生しました",
-
   "home.recentProjects": "最近のプロジェクト",
   "home.empty.title": "最近のプロジェクトはありません",
   "home.empty.description": "ローカルプロジェクトを開いて始めましょう",
-
   "session.tab.session": "セッション",
   "session.tab.review": "レビュー",
   "session.tab.context": "コンテキスト",
@@ -430,18 +446,19 @@ export const dict = {
   "session.messages.loadingEarlier": "以前のメッセージを読み込み中...",
   "session.messages.loadEarlier": "以前のメッセージを読み込む",
   "session.messages.loading": "メッセージを読み込み中...",
-
   "session.messages.jumpToLatest": "最新へジャンプ",
   "session.context.addToContext": "{{selection}}をコンテキストに追加",
-
   "session.new.worktree.main": "メインブランチ",
   "session.new.worktree.mainWithBranch": "メインブランチ ({{branch}})",
   "session.new.worktree.create": "新しいワークツリーを作成",
   "session.new.lastModified": "最終更新",
-
   "session.header.search.placeholder": "{{project}}を検索",
   "session.header.searchFiles": "ファイルを検索",
-
+  "session.header.openIn": "で開く",
+  "session.header.open.action": "{{app}}を開く",
+  "session.header.open.ariaLabel": "{{app}}で開く",
+  "session.header.open.menu": "開くオプション",
+  "session.header.open.copyPath": "パスをコピー",
   "status.popover.trigger": "ステータス",
   "status.popover.ariaLabel": "サーバー設定",
   "status.popover.tab.servers": "サーバー",
@@ -449,7 +466,6 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "プラグイン",
   "status.popover.action.manageServers": "サーバーを管理",
-
   "session.share.popover.title": "ウェブで公開",
   "session.share.popover.description.shared":
     "このセッションはウェブで公開されています。リンクを知っている人なら誰でもアクセスできます。",
@@ -463,16 +479,13 @@ export const dict = {
   "session.share.action.view": "表示",
   "session.share.copy.copied": "コピーしました",
   "session.share.copy.copyLink": "リンクをコピー",
-
   "lsp.tooltip.none": "LSPサーバーなし",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "プロンプトを読み込み中...",
   "terminal.loading": "ターミナルを読み込み中...",
   "terminal.title": "ターミナル",
   "terminal.title.numbered": "ターミナル {{number}}",
   "terminal.close": "ターミナルを閉じる",
-
   "terminal.connectionLost.title": "接続が失われました",
   "terminal.connectionLost.description":
     "ターミナルの接続が中断されました。これはサーバーが再起動したときに発生することがあります。",
@@ -488,7 +501,6 @@ export const dict = {
   "common.close": "閉じる",
   "common.edit": "編集",
   "common.loadMore": "さらに読み込む",
-
   "common.key.esc": "ESC",
   "sidebar.menu.toggle": "メニューを切り替え",
   "sidebar.nav.projectsAndSessions": "プロジェクトとセッション",
@@ -501,21 +513,19 @@ export const dict = {
   "sidebar.gettingStarted.line2": "プロバイダーを接続して、Claude、GPT、Geminiなどのモデルを使用できます。",
   "sidebar.project.recentSessions": "最近のセッション",
   "sidebar.project.viewAllSessions": "すべてのセッションを表示",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "デスクトップ",
   "settings.section.server": "サーバー",
   "settings.tab.general": "一般",
   "settings.tab.shortcuts": "ショートカット",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.title": "WSL統合",
+  "settings.desktop.wsl.description": "Windows上のWSL内でOpenCodeサーバーを実行します。",
   "settings.general.section.appearance": "外観",
   "settings.general.section.notifications": "システム通知",
   "settings.general.section.updates": "アップデート",
   "settings.general.section.sounds": "効果音",
-
+  "settings.general.section.display": "ディスプレイ",
   "settings.general.row.language.title": "言語",
   "settings.general.row.language.description": "OpenCodeの表示言語を変更します",
   "settings.general.row.appearance.title": "外観",
@@ -524,10 +534,12 @@ export const dict = {
   "settings.general.row.theme.description": "OpenCodeのテーマをカスタマイズします。",
   "settings.general.row.font.title": "フォント",
   "settings.general.row.font.description": "コードブロックで使用する等幅フォントをカスタマイズします",
-
+  "settings.general.row.wayland.title": "ネイティブWaylandを使用",
+  "settings.general.row.wayland.description": "WaylandでのX11フォールバックを無効にします。再起動が必要です。",
+  "settings.general.row.wayland.tooltip":
+    "リフレッシュレートが混在するモニターを使用しているLinuxでは、ネイティブWaylandの方が安定する場合があります。",
   "settings.general.row.releaseNotes.title": "リリースノート",
   "settings.general.row.releaseNotes.description": "アップデート後に「新機能」ポップアップを表示",
-
   "settings.updates.row.startup.title": "起動時にアップデートを確認",
   "settings.updates.row.startup.description": "OpenCode の起動時に自動でアップデートを確認します",
   "settings.updates.row.check.title": "アップデートを確認",
@@ -536,7 +548,6 @@ export const dict = {
   "settings.updates.action.checking": "確認中...",
   "settings.updates.toast.latest.title": "最新です",
   "settings.updates.toast.latest.description": "OpenCode は最新バージョンです。",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -601,14 +612,12 @@ export const dict = {
   "settings.general.notifications.permissions.description": "権限が必要な場合にシステム通知を表示します",
   "settings.general.notifications.errors.title": "エラー",
   "settings.general.notifications.errors.description": "エラーが発生した場合にシステム通知を表示します",
-
   "settings.general.sounds.agent.title": "エージェント",
   "settings.general.sounds.agent.description": "エージェントが完了したか、注意が必要な場合に音を再生します",
   "settings.general.sounds.permissions.title": "権限",
   "settings.general.sounds.permissions.description": "権限が必要な場合に音を再生します",
   "settings.general.sounds.errors.title": "エラー",
   "settings.general.sounds.errors.description": "エラーが発生した場合に音を再生します",
-
   "settings.shortcuts.title": "キーボードショートカット",
   "settings.shortcuts.reset.button": "デフォルトにリセット",
   "settings.shortcuts.reset.toast.title": "ショートカットをリセットしました",
@@ -619,14 +628,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "キーを押してください",
   "settings.shortcuts.search.placeholder": "ショートカットを検索",
   "settings.shortcuts.search.empty": "ショートカットが見つかりません",
-
   "settings.shortcuts.group.general": "一般",
   "settings.shortcuts.group.session": "セッション",
   "settings.shortcuts.group.navigation": "ナビゲーション",
   "settings.shortcuts.group.modelAndAgent": "モデルとエージェント",
   "settings.shortcuts.group.terminal": "ターミナル",
   "settings.shortcuts.group.prompt": "プロンプト",
-
   "settings.providers.title": "プロバイダー",
   "settings.providers.description": "プロバイダー設定はここで構成できます。",
   "settings.providers.section.connected": "接続済みプロバイダー",
@@ -644,16 +651,13 @@ export const dict = {
   "settings.commands.description": "コマンド設定はここで構成できます。",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "MCP設定はここで構成できます。",
-
   "settings.permissions.title": "権限",
   "settings.permissions.description": "サーバーがデフォルトで使用できるツールを制御します。",
   "settings.permissions.section.tools": "ツール",
   "settings.permissions.toast.updateFailed.title": "権限の更新に失敗しました",
-
   "settings.permissions.action.allow": "許可",
   "settings.permissions.action.ask": "確認",
   "settings.permissions.action.deny": "拒否",
-
   "settings.permissions.tool.read.title": "読み込み",
   "settings.permissions.tool.read.description": "ファイルの読み込み (ファイルパスに一致)",
   "settings.permissions.tool.edit.title": "編集",
@@ -676,22 +680,20 @@ export const dict = {
   "settings.permissions.tool.todoread.description": "Todoリストの読み込み",
   "settings.permissions.tool.todowrite.title": "Todo書き込み",
   "settings.permissions.tool.todowrite.description": "Todoリストの更新",
-  "settings.permissions.tool.webfetch.title": "Web Fetch",
+  "settings.permissions.tool.webfetch.title": "Web取得",
   "settings.permissions.tool.webfetch.description": "URLからコンテンツを取得",
-  "settings.permissions.tool.websearch.title": "Web Search",
+  "settings.permissions.tool.websearch.title": "Web検索",
   "settings.permissions.tool.websearch.description": "ウェブを検索",
-  "settings.permissions.tool.codesearch.title": "Code Search",
+  "settings.permissions.tool.codesearch.title": "コード検索",
   "settings.permissions.tool.codesearch.description": "ウェブ上のコードを検索",
   "settings.permissions.tool.external_directory.title": "外部ディレクトリ",
   "settings.permissions.tool.external_directory.description": "プロジェクトディレクトリ外のファイルへのアクセス",
-  "settings.permissions.tool.doom_loop.title": "Doom Loop",
+  "settings.permissions.tool.doom_loop.title": "無限ループ",
   "settings.permissions.tool.doom_loop.description": "同一入力による繰り返しのツール呼び出しを検出",
-
   "session.delete.failed.title": "セッションの削除に失敗しました",
   "session.delete.title": "セッションの削除",
   "session.delete.confirm": 'セッション "{{name}}" を削除しますか?',
   "session.delete.button": "セッションを削除",
-
   "workspace.new": "新しいワークスペース",
   "workspace.type.local": "ローカル",
   "workspace.type.sandbox": "サンドボックス",

+ 80 - 83
packages/app/src/i18n/ko.ts

@@ -19,12 +19,10 @@ export const dict = {
   "command.category.agent": "에이전트",
   "command.category.permissions": "권한",
   "command.category.workspace": "작업 공간",
-
   "command.category.settings": "설정",
   "theme.scheme.system": "시스템",
   "theme.scheme.light": "라이트",
   "theme.scheme.dark": "다크",
-
   "command.sidebar.toggle": "사이드바 토글",
   "command.project.open": "프로젝트 열기",
   "command.provider.connect": "공급자 연결",
@@ -35,17 +33,13 @@ export const dict = {
   "command.session.previous.unseen": "이전 읽지 않은 세션",
   "command.session.next.unseen": "다음 읽지 않은 세션",
   "command.session.archive": "세션 보관",
-
   "command.palette": "명령 팔레트",
-
   "command.theme.cycle": "테마 순환",
   "command.theme.set": "테마 사용: {{theme}}",
   "command.theme.scheme.cycle": "색상 테마 순환",
   "command.theme.scheme.set": "색상 테마 사용: {{scheme}}",
-
   "command.language.cycle": "언어 순환",
   "command.language.set": "언어 사용: {{language}}",
-
   "command.session.new": "새 세션",
   "command.file.open": "파일 열기",
   "command.tab.close": "탭 닫기",
@@ -76,6 +70,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "편집 자동 수락",
   "command.permissions.autoaccept.disable": "편집 자동 수락 중지",
   "command.workspace.toggle": "작업 공간 전환",
+  "command.workspace.toggle.description": "사이드바에서 다중 작업 공간 활성화 또는 비활성화",
   "command.session.undo": "실행 취소",
   "command.session.undo.description": "마지막 메시지 실행 취소",
   "command.session.redo": "다시 실행",
@@ -88,32 +83,30 @@ export const dict = {
   "command.session.share.description": "이 세션을 공유하고 URL을 클립보드에 복사",
   "command.session.unshare": "세션 공유 중지",
   "command.session.unshare.description": "이 세션 공유 중지",
-
   "palette.search.placeholder": "파일, 명령어 및 세션 검색",
   "palette.empty": "결과 없음",
   "palette.group.commands": "명령어",
   "palette.group.files": "파일",
-
   "dialog.provider.search.placeholder": "공급자 검색",
   "dialog.provider.empty": "공급자 없음",
   "dialog.provider.group.popular": "인기",
   "dialog.provider.group.other": "기타",
   "dialog.provider.tag.recommended": "추천",
+  "dialog.provider.opencode.note": "Claude, GPT, Gemini 등을 포함한 엄선된 모델",
   "dialog.provider.anthropic.note": "Claude Pro/Max 또는 API 키로 연결",
-  "dialog.provider.openai.note": "ChatGPT Pro/Plus 또는 API 키로 연결",
   "dialog.provider.copilot.note": "Copilot 또는 API 키로 연결",
-
+  "dialog.provider.openai.note": "ChatGPT Pro/Plus 또는 API 키로 연결",
+  "dialog.provider.google.note": "빠르고 구조화된 응답을 위한 Gemini 모델",
+  "dialog.provider.openrouter.note": "모든 지원 모델을 단일 공급자에서 액세스",
+  "dialog.provider.vercel.note": "스마트 라우팅을 통한 AI 모델 통합 액세스",
   "dialog.model.select.title": "모델 선택",
   "dialog.model.search.placeholder": "모델 검색",
   "dialog.model.empty": "모델 결과 없음",
   "dialog.model.manage": "모델 관리",
   "dialog.model.manage.description": "모델 선택기에 표시할 모델 사용자 지정",
-
   "dialog.model.unpaid.freeModels.title": "OpenCode에서 제공하는 무료 모델",
   "dialog.model.unpaid.addMore.title": "인기 공급자의 모델 추가",
-
   "dialog.provider.viewAll": "더 많은 공급자 보기",
-
   "provider.connect.title": "{{provider}} 연결",
   "provider.connect.title.anthropicProMax": "Claude Pro/Max로 로그인",
   "provider.connect.selectMethod": "{{provider}} 로그인 방법 선택",
@@ -129,10 +122,10 @@ export const dict = {
   "provider.connect.opencodeZen.line1":
     "OpenCode Zen은 코딩 에이전트를 위해 최적화된 신뢰할 수 있는 엄선된 모델에 대한 액세스를 제공합니다.",
   "provider.connect.opencodeZen.line2": "단일 API 키로 Claude, GPT, Gemini, GLM 등 다양한 모델에 액세스할 수 있습니다.",
-  "provider.connect.opencodeZen.visit.prefix": "",
+  "provider.connect.opencodeZen.visit.prefix": "다음 ",
   "provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
-  "provider.connect.opencodeZen.visit.suffix": " 방문하여 API 키를 받으세요.",
-  "provider.connect.oauth.code.visit.prefix": "",
+  "provider.connect.opencodeZen.visit.suffix": " 방문하여 API 키를 받으세요.",
+  "provider.connect.oauth.code.visit.prefix": "다음 ",
   "provider.connect.oauth.code.visit.link": "이 링크",
   "provider.connect.oauth.code.visit.suffix":
     "를 방문하여 인증 코드를 받아 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.",
@@ -140,19 +133,53 @@ export const dict = {
   "provider.connect.oauth.code.placeholder": "인증 코드",
   "provider.connect.oauth.code.required": "인증 코드가 필요합니다",
   "provider.connect.oauth.code.invalid": "유효하지 않은 인증 코드",
-  "provider.connect.oauth.auto.visit.prefix": "",
+  "provider.connect.oauth.auto.visit.prefix": "다음 ",
   "provider.connect.oauth.auto.visit.link": "이 링크",
   "provider.connect.oauth.auto.visit.suffix":
     "를 방문하고 아래 코드를 입력하여 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.",
   "provider.connect.oauth.auto.confirmationCode": "확인 코드",
   "provider.connect.toast.connected.title": "{{provider}} 연결됨",
   "provider.connect.toast.connected.description": "이제 {{provider}} 모델을 사용할 수 있습니다.",
-
+  "provider.custom.title": "사용자 지정 공급자",
+  "provider.custom.description.prefix": "OpenAI 호환 공급자를 구성합니다. ",
+  "provider.custom.description.link": "공급자 구성 문서",
+  "provider.custom.description.suffix": "를 참조하세요.",
+  "provider.custom.field.providerID.label": "공급자 ID",
+  "provider.custom.field.providerID.placeholder": "myprovider",
+  "provider.custom.field.providerID.description": "소문자, 숫자, 하이픈 또는 밑줄",
+  "provider.custom.field.name.label": "표시 이름",
+  "provider.custom.field.name.placeholder": "내 AI 공급자",
+  "provider.custom.field.baseURL.label": "기본 URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "API 키",
+  "provider.custom.field.apiKey.placeholder": "API 키",
+  "provider.custom.field.apiKey.description": "선택 사항입니다. 헤더를 통해 인증을 관리하는 경우 비워 두세요.",
+  "provider.custom.models.label": "모델",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "이름",
+  "provider.custom.models.name.placeholder": "표시 이름",
+  "provider.custom.models.remove": "모델 제거",
+  "provider.custom.models.add": "모델 추가",
+  "provider.custom.headers.label": "헤더 (선택 사항)",
+  "provider.custom.headers.key.label": "헤더",
+  "provider.custom.headers.key.placeholder": "헤더 이름",
+  "provider.custom.headers.value.label": "값",
+  "provider.custom.headers.value.placeholder": "값",
+  "provider.custom.headers.remove": "헤더 제거",
+  "provider.custom.headers.add": "헤더 추가",
+  "provider.custom.error.providerID.required": "공급자 ID가 필요합니다",
+  "provider.custom.error.providerID.format": "소문자, 숫자, 하이픈 또는 밑줄을 사용하세요",
+  "provider.custom.error.providerID.exists": "해당 공급자 ID가 이미 존재합니다",
+  "provider.custom.error.name.required": "표시 이름이 필요합니다",
+  "provider.custom.error.baseURL.required": "기본 URL이 필요합니다",
+  "provider.custom.error.baseURL.format": "http:// 또는 https://로 시작해야 합니다",
+  "provider.custom.error.required": "필수",
+  "provider.custom.error.duplicate": "중복",
   "provider.disconnect.toast.disconnected.title": "{{provider}} 연결 해제됨",
   "provider.disconnect.toast.disconnected.description": "{{provider}} 모델을 더 이상 사용할 수 없습니다.",
   "model.tag.free": "무료",
   "model.tag.latest": "최신",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -169,6 +196,7 @@ export const dict = {
   "model.tooltip.context": "컨텍스트 제한 {{limit}}",
   "common.search.placeholder": "검색",
   "common.goBack": "뒤로 가기",
+  "common.goForward": "앞으로 가기",
   "common.loading": "로딩 중",
   "common.loading.ellipsis": "...",
   "common.cancel": "취소",
@@ -179,14 +207,12 @@ export const dict = {
   "common.saving": "저장 중...",
   "common.default": "기본값",
   "common.attachment": "첨부 파일",
-
   "prompt.placeholder.shell": "셸 명령어 입력...",
   "prompt.placeholder.normal": '무엇이든 물어보세요... "{{example}}"',
   "prompt.placeholder.summarizeComments": "댓글 요약…",
   "prompt.placeholder.summarizeComment": "댓글 요약…",
   "prompt.mode.shell": "셸",
   "prompt.mode.shell.exit": "종료하려면 esc",
-
   "prompt.example.1": "코드베이스의 TODO 수정",
   "prompt.example.2": "이 프로젝트의 기술 스택이 무엇인가요?",
   "prompt.example.3": "고장 난 테스트 수정",
@@ -212,7 +238,6 @@ export const dict = {
   "prompt.example.23": "이 목록에 페이지네이션 추가",
   "prompt.example.24": "...를 위한 CLI 명령어 생성",
   "prompt.example.25": "여기서 환경 변수는 어떻게 작동하나요?",
-
   "prompt.popover.emptyResults": "일치하는 결과 없음",
   "prompt.popover.emptyCommands": "일치하는 명령어 없음",
   "prompt.dropzone.label": "이미지나 PDF를 여기에 드롭하세요",
@@ -228,7 +253,6 @@ export const dict = {
   "prompt.attachment.remove": "첨부 파일 제거",
   "prompt.action.send": "전송",
   "prompt.action.stop": "중지",
-
   "prompt.toast.pasteUnsupported.title": "지원되지 않는 붙여넣기",
   "prompt.toast.pasteUnsupported.description": "이미지나 PDF만 붙여넣을 수 있습니다.",
   "prompt.toast.modelAgentRequired.title": "에이전트 및 모델 선택",
@@ -239,24 +263,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "명령 전송 실패",
   "prompt.toast.promptSendFailed.title": "프롬프트 전송 실패",
   "prompt.toast.promptSendFailed.description": "세션을 가져올 수 없습니다",
-
   "dialog.mcp.title": "MCP",
   "dialog.mcp.description": "{{total}}개 중 {{enabled}}개 활성화됨",
   "dialog.mcp.empty": "구성된 MCP 없음",
-
   "dialog.lsp.empty": "파일 유형에서 자동 감지된 LSP",
   "dialog.plugins.empty": "opencode.json에 구성된 플러그인",
-
   "mcp.status.connected": "연결됨",
   "mcp.status.failed": "실패",
   "mcp.status.needs_auth": "인증 필요",
   "mcp.status.disabled": "비활성화됨",
-
   "dialog.fork.empty": "분기할 메시지 없음",
-
   "dialog.directory.search.placeholder": "폴더 검색",
   "dialog.directory.empty": "폴더 없음",
-
   "dialog.server.title": "서버",
   "dialog.server.description": "이 앱이 연결할 OpenCode 서버를 전환합니다.",
   "dialog.server.search.placeholder": "서버 검색",
@@ -274,14 +292,12 @@ export const dict = {
   "dialog.server.default.set": "현재 서버를 기본값으로 설정",
   "dialog.server.default.clear": "지우기",
   "dialog.server.action.remove": "서버 제거",
-
   "dialog.server.menu.edit": "편집",
   "dialog.server.menu.default": "기본값으로 설정",
   "dialog.server.menu.defaultRemove": "기본값 제거",
   "dialog.server.menu.delete": "삭제",
   "dialog.server.current": "현재 서버",
   "dialog.server.status.default": "기본값",
-
   "dialog.project.edit.title": "프로젝트 편집",
   "dialog.project.edit.name": "이름",
   "dialog.project.edit.icon": "아이콘",
@@ -290,7 +306,6 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "권장: 128x128px",
   "dialog.project.edit.color": "색상",
   "dialog.project.edit.color.select": "{{color}} 색상 선택",
-
   "dialog.project.edit.worktree.startup": "작업 공간 시작 스크립트",
   "dialog.project.edit.worktree.startup.description": "새 작업 공간(작업 트리)을 만든 뒤 실행됩니다.",
   "dialog.project.edit.worktree.startup.placeholder": "예: bun install",
@@ -301,10 +316,8 @@ export const dict = {
   "context.breakdown.assistant": "어시스턴트",
   "context.breakdown.tool": "도구 호출",
   "context.breakdown.other": "기타",
-
   "context.systemPrompt.title": "시스템 프롬프트",
   "context.rawMessages.title": "원시 메시지",
-
   "context.stats.session": "세션",
   "context.stats.messages": "메시지",
   "context.stats.provider": "공급자",
@@ -321,34 +334,42 @@ export const dict = {
   "context.stats.totalCost": "총 비용",
   "context.stats.sessionCreated": "세션 생성됨",
   "context.stats.lastActivity": "최근 활동",
-
   "context.usage.tokens": "토큰",
   "context.usage.usage": "사용량",
   "context.usage.cost": "비용",
   "context.usage.clickToView": "컨텍스트를 보려면 클릭",
   "context.usage.view": "컨텍스트 사용량 보기",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "언어",
   "toast.language.description": "{{language}}(으)로 전환됨",
-
   "toast.theme.title": "테마 전환됨",
   "toast.scheme.title": "색상 테마",
-
-  "toast.permissions.autoaccept.on.title": "편집 자동 수락 중",
-  "toast.permissions.autoaccept.on.description": "편집 및 쓰기 권한이 자동으로 승인됩니다",
-  "toast.permissions.autoaccept.off.title": "편집 자동 수락 중지됨",
-  "toast.permissions.autoaccept.off.description": "편집 및 쓰기 권한 승인이 필요합니다",
-
   "toast.workspace.enabled.title": "작업 공간 활성화됨",
   "toast.workspace.enabled.description": "이제 사이드바에 여러 작업 트리가 표시됩니다",
   "toast.workspace.disabled.title": "작업 공간 비활성화됨",
   "toast.workspace.disabled.description": "사이드바에 메인 작업 트리만 표시됩니다",
-
+  "toast.permissions.autoaccept.on.title": "편집 자동 수락 중",
+  "toast.permissions.autoaccept.on.description": "편집 및 쓰기 권한이 자동으로 승인됩니다",
+  "toast.permissions.autoaccept.off.title": "편집 자동 수락 중지됨",
+  "toast.permissions.autoaccept.off.description": "편집 및 쓰기 권한 승인이 필요합니다",
   "toast.model.none.title": "선택된 모델 없음",
   "toast.model.none.description": "이 세션을 요약하려면 공급자를 연결하세요",
-
   "toast.file.loadFailed.title": "파일 로드 실패",
-
   "toast.file.listFailed.title": "파일 목록을 불러오지 못했습니다",
   "toast.context.noLineSelection.title": "줄 선택 없음",
   "toast.context.noLineSelection.description": "먼저 파일 탭에서 줄 범위를 선택하세요.",
@@ -357,19 +378,15 @@ export const dict = {
   "toast.session.share.success.description": "공유 URL이 클립보드에 복사되었습니다!",
   "toast.session.share.failed.title": "세션 공유 실패",
   "toast.session.share.failed.description": "세션을 공유하는 동안 오류가 발생했습니다",
-
   "toast.session.unshare.success.title": "세션 공유 해제됨",
   "toast.session.unshare.success.description": "세션 공유가 성공적으로 해제되었습니다!",
   "toast.session.unshare.failed.title": "세션 공유 해제 실패",
   "toast.session.unshare.failed.description": "세션 공유를 해제하는 동안 오류가 발생했습니다",
-
   "toast.session.listFailed.title": "{{project}}에 대한 세션을 로드하지 못했습니다",
-
   "toast.update.title": "업데이트 가능",
   "toast.update.description": "OpenCode의 새 버전({{version}})을 설치할 수 있습니다.",
   "toast.update.action.installRestart": "설치 및 다시 시작",
   "toast.update.action.notYet": "나중에",
-
   "error.page.title": "문제가 발생했습니다",
   "error.page.description": "애플리케이션을 로드하는 동안 오류가 발생했습니다.",
   "error.page.details.label": "오류 세부 정보",
@@ -380,12 +397,10 @@ export const dict = {
   "error.page.report.prefix": "이 오류를 OpenCode 팀에 제보해 주세요: ",
   "error.page.report.discord": "Discord",
   "error.page.version": "버전: {{version}}",
-
   "error.dev.rootNotFound":
     "루트 요소를 찾을 수 없습니다. index.html에 추가하는 것을 잊으셨나요? 또는 id 속성의 철자가 틀렸을 수 있습니다.",
-
   "error.globalSync.connectFailed": "서버에 연결할 수 없습니다. `{{url}}`에서 서버가 실행 중인가요?",
-
+  "directory.error.invalidUrl": "URL에 유효하지 않은 디렉터리가 있습니다.",
   "error.chain.unknown": "알 수 없는 오류",
   "error.chain.causedBy": "원인:",
   "error.chain.apiError": "API 오류",
@@ -405,21 +420,17 @@ export const dict = {
   "error.chain.configFrontmatterError": "{{path}}의 frontmatter 파싱 실패:\n{{message}}",
   "error.chain.configInvalid": "{{path}}의 구성 파일이 유효하지 않습니다",
   "error.chain.configInvalidWithMessage": "{{path}}의 구성 파일이 유효하지 않습니다: {{message}}",
-
   "notification.permission.title": "권한 필요",
   "notification.permission.description": "{{projectName}}의 {{sessionTitle}}에서 권한이 필요합니다",
   "notification.question.title": "질문",
   "notification.question.description": "{{projectName}}의 {{sessionTitle}}에서 질문이 있습니다",
   "notification.action.goToSession": "세션으로 이동",
-
   "notification.session.responseReady.title": "응답 준비됨",
   "notification.session.error.title": "세션 오류",
   "notification.session.error.fallbackDescription": "오류가 발생했습니다",
-
   "home.recentProjects": "최근 프로젝트",
   "home.empty.title": "최근 프로젝트 없음",
   "home.empty.description": "로컬 프로젝트를 열어 시작하세요",
-
   "session.tab.session": "세션",
   "session.tab.review": "검토",
   "session.tab.context": "컨텍스트",
@@ -437,18 +448,19 @@ export const dict = {
   "session.messages.loadingEarlier": "이전 메시지 로드 중...",
   "session.messages.loadEarlier": "이전 메시지 로드",
   "session.messages.loading": "메시지 로드 중...",
-
   "session.messages.jumpToLatest": "최신으로 이동",
   "session.context.addToContext": "컨텍스트에 {{selection}} 추가",
-
   "session.new.worktree.main": "메인 브랜치",
   "session.new.worktree.mainWithBranch": "메인 브랜치 ({{branch}})",
   "session.new.worktree.create": "새 작업 트리 생성",
   "session.new.lastModified": "최근 수정",
-
   "session.header.search.placeholder": "{{project}} 검색",
   "session.header.searchFiles": "파일 검색",
-
+  "session.header.openIn": "다음에서 열기",
+  "session.header.open.action": "{{app}} 열기",
+  "session.header.open.ariaLabel": "{{app}}에서 열기",
+  "session.header.open.menu": "열기 옵션",
+  "session.header.open.copyPath": "경로 복사",
   "status.popover.trigger": "상태",
   "status.popover.ariaLabel": "서버 구성",
   "status.popover.tab.servers": "서버",
@@ -456,7 +468,6 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "플러그인",
   "status.popover.action.manageServers": "서버 관리",
-
   "session.share.popover.title": "웹에 게시",
   "session.share.popover.description.shared": "이 세션은 웹에 공개되었습니다. 링크가 있는 누구나 액세스할 수 있습니다.",
   "session.share.popover.description.unshared":
@@ -469,16 +480,13 @@ export const dict = {
   "session.share.action.view": "보기",
   "session.share.copy.copied": "복사됨",
   "session.share.copy.copyLink": "링크 복사",
-
   "lsp.tooltip.none": "LSP 서버 없음",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "프롬프트 로드 중...",
   "terminal.loading": "터미널 로드 중...",
   "terminal.title": "터미널",
   "terminal.title.numbered": "터미널 {{number}}",
   "terminal.close": "터미널 닫기",
-
   "terminal.connectionLost.title": "연결 끊김",
   "terminal.connectionLost.description":
     "터미널 연결이 중단되었습니다. 서버가 재시작하면 이런 일이 발생할 수 있습니다.",
@@ -494,7 +502,6 @@ export const dict = {
   "common.close": "닫기",
   "common.edit": "편집",
   "common.loadMore": "더 불러오기",
-
   "common.key.esc": "ESC",
   "sidebar.menu.toggle": "메뉴 토글",
   "sidebar.nav.projectsAndSessions": "프로젝트 및 세션",
@@ -507,21 +514,19 @@ export const dict = {
   "sidebar.gettingStarted.line2": "Claude, GPT, Gemini 등을 포함한 모델을 사용하려면 공급자를 연결하세요.",
   "sidebar.project.recentSessions": "최근 세션",
   "sidebar.project.viewAllSessions": "모든 세션 보기",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "데스크톱",
   "settings.section.server": "서버",
   "settings.tab.general": "일반",
   "settings.tab.shortcuts": "단축키",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
+  "settings.desktop.wsl.title": "WSL 통합",
+  "settings.desktop.wsl.description": "Windows의 WSL 내부에서 OpenCode 서버를 실행합니다.",
   "settings.general.section.appearance": "모양",
   "settings.general.section.notifications": "시스템 알림",
   "settings.general.section.updates": "업데이트",
   "settings.general.section.sounds": "효과음",
-
+  "settings.general.section.display": "디스플레이",
   "settings.general.row.language.title": "언어",
   "settings.general.row.language.description": "OpenCode 표시 언어 변경",
   "settings.general.row.appearance.title": "모양",
@@ -530,10 +535,12 @@ export const dict = {
   "settings.general.row.theme.description": "OpenCode 테마 사용자 지정",
   "settings.general.row.font.title": "글꼴",
   "settings.general.row.font.description": "코드 블록에 사용되는 고정폭 글꼴 사용자 지정",
-
+  "settings.general.row.wayland.title": "네이티브 Wayland 사용",
+  "settings.general.row.wayland.description": "Wayland에서 X11 폴백을 비활성화합니다. 다시 시작해야 합니다.",
+  "settings.general.row.wayland.tooltip":
+    "혼합 주사율 모니터가 있는 Linux에서는 네이티브 Wayland가 더 안정적일 수 있습니다.",
   "settings.general.row.releaseNotes.title": "릴리스 노트",
   "settings.general.row.releaseNotes.description": "업데이트 후 '새 소식' 팝업 표시",
-
   "settings.updates.row.startup.title": "시작 시 업데이트 확인",
   "settings.updates.row.startup.description": "OpenCode를 실행할 때 업데이트를 자동으로 확인합니다",
   "settings.updates.row.check.title": "업데이트 확인",
@@ -542,7 +549,6 @@ export const dict = {
   "settings.updates.action.checking": "확인 중...",
   "settings.updates.toast.latest.title": "최신 상태입니다",
   "settings.updates.toast.latest.description": "현재 최신 버전의 OpenCode를 사용 중입니다.",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -606,14 +612,12 @@ export const dict = {
   "settings.general.notifications.permissions.description": "권한이 필요할 때 시스템 알림 표시",
   "settings.general.notifications.errors.title": "오류",
   "settings.general.notifications.errors.description": "오류가 발생했을 때 시스템 알림 표시",
-
   "settings.general.sounds.agent.title": "에이전트",
   "settings.general.sounds.agent.description": "에이전트가 완료되거나 주의가 필요할 때 소리 재생",
   "settings.general.sounds.permissions.title": "권한",
   "settings.general.sounds.permissions.description": "권한이 필요할 때 소리 재생",
   "settings.general.sounds.errors.title": "오류",
   "settings.general.sounds.errors.description": "오류가 발생했을 때 소리 재생",
-
   "settings.shortcuts.title": "키보드 단축키",
   "settings.shortcuts.reset.button": "기본값으로 초기화",
   "settings.shortcuts.reset.toast.title": "단축키 초기화됨",
@@ -624,14 +628,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "키 누르기",
   "settings.shortcuts.search.placeholder": "단축키 검색",
   "settings.shortcuts.search.empty": "단축키를 찾을 수 없습니다",
-
   "settings.shortcuts.group.general": "일반",
   "settings.shortcuts.group.session": "세션",
   "settings.shortcuts.group.navigation": "탐색",
   "settings.shortcuts.group.modelAndAgent": "모델 및 에이전트",
   "settings.shortcuts.group.terminal": "터미널",
   "settings.shortcuts.group.prompt": "프롬프트",
-
   "settings.providers.title": "공급자",
   "settings.providers.description": "공급자 설정은 여기서 구성할 수 있습니다.",
   "settings.providers.section.connected": "연결된 공급자",
@@ -649,16 +651,13 @@ export const dict = {
   "settings.commands.description": "명령어 설정은 여기서 구성할 수 있습니다.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "MCP 설정은 여기서 구성할 수 있습니다.",
-
   "settings.permissions.title": "권한",
   "settings.permissions.description": "서버가 기본적으로 사용할 수 있는 도구를 제어합니다.",
   "settings.permissions.section.tools": "도구",
   "settings.permissions.toast.updateFailed.title": "권한 업데이트 실패",
-
   "settings.permissions.action.allow": "허용",
   "settings.permissions.action.ask": "묻기",
   "settings.permissions.action.deny": "거부",
-
   "settings.permissions.tool.read.title": "읽기",
   "settings.permissions.tool.read.description": "파일 읽기 (파일 경로와 일치)",
   "settings.permissions.tool.edit.title": "편집",
@@ -691,12 +690,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "프로젝트 디렉터리 외부의 파일에 액세스",
   "settings.permissions.tool.doom_loop.title": "무한 반복",
   "settings.permissions.tool.doom_loop.description": "동일한 입력으로 반복되는 도구 호출 감지",
-
   "session.delete.failed.title": "세션 삭제 실패",
   "session.delete.title": "세션 삭제",
   "session.delete.confirm": '"{{name}}" 세션을 삭제하시겠습니까?',
   "session.delete.button": "세션 삭제",
-
   "workspace.new": "새 작업 공간",
   "workspace.type.local": "로컬",
   "workspace.type.sandbox": "샌드박스",

+ 91 - 13
packages/app/src/i18n/no.ts

@@ -75,6 +75,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Godta endringer automatisk",
   "command.permissions.autoaccept.disable": "Slutt å godta endringer automatisk",
   "command.workspace.toggle": "Veksle arbeidsområder",
+  "command.workspace.toggle.description": "Enable or disable multiple workspaces in the sidebar",
   "command.session.undo": "Angre",
   "command.session.undo.description": "Angre siste melding",
   "command.session.redo": "Gjør om",
@@ -98,9 +99,13 @@ export const dict = {
   "dialog.provider.group.popular": "Populære",
   "dialog.provider.group.other": "Andre",
   "dialog.provider.tag.recommended": "Anbefalt",
-  "dialog.provider.anthropic.note": "Koble til med Claude Pro/Max eller API-nøkkel",
-  "dialog.provider.openai.note": "Koble til med ChatGPT Pro/Plus eller API-nøkkel",
-  "dialog.provider.copilot.note": "Koble til med Copilot eller API-nøkkel",
+  "dialog.provider.opencode.note": "Utvalgte modeller inkludert Claude, GPT, Gemini og mer",
+  "dialog.provider.anthropic.note": "Direkte tilgang til Claude-modeller, inkludert Pro og Max",
+  "dialog.provider.copilot.note": "Claude-modeller for kodeassistanse",
+  "dialog.provider.openai.note": "GPT-modeller for raske, dyktige generelle AI-oppgaver",
+  "dialog.provider.google.note": "Gemini-modeller for raske, strukturerte svar",
+  "dialog.provider.openrouter.note": "Tilgang til alle støttede modeller fra én leverandør",
+  "dialog.provider.vercel.note": "Enhetlig tilgang til AI-modeller med smart ruting",
 
   "dialog.model.select.title": "Velg modell",
   "dialog.model.search.placeholder": "Søk etter modeller",
@@ -148,8 +153,46 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} tilkoblet",
   "provider.connect.toast.connected.description": "{{provider}}-modeller er nå tilgjengelige.",
 
+  "provider.custom.title": "Egendefinert leverandør",
+  "provider.custom.description.prefix": "Konfigurer en OpenAI-kompatibel leverandør. Se ",
+  "provider.custom.description.link": "dokumentasjon for leverandørkonfigurasjon",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "Leverandør-ID",
+  "provider.custom.field.providerID.placeholder": "minleverandør",
+  "provider.custom.field.providerID.description": "Små bokstaver, tall, bindestreker eller understreker",
+  "provider.custom.field.name.label": "Visningsnavn",
+  "provider.custom.field.name.placeholder": "Min AI-leverandør",
+  "provider.custom.field.baseURL.label": "Base-URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "API-nøkkel",
+  "provider.custom.field.apiKey.placeholder": "API-nøkkel",
+  "provider.custom.field.apiKey.description": "Valgfritt. La stå tomt hvis du administrerer autentisering via headers.",
+  "provider.custom.models.label": "Modeller",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "modell-id",
+  "provider.custom.models.name.label": "Navn",
+  "provider.custom.models.name.placeholder": "Visningsnavn",
+  "provider.custom.models.remove": "Fjern modell",
+  "provider.custom.models.add": "Legg til modell",
+  "provider.custom.headers.label": "Headers (valgfritt)",
+  "provider.custom.headers.key.label": "Header",
+  "provider.custom.headers.key.placeholder": "Header-Navn",
+  "provider.custom.headers.value.label": "Verdi",
+  "provider.custom.headers.value.placeholder": "verdi",
+  "provider.custom.headers.remove": "Fjern header",
+  "provider.custom.headers.add": "Legg til header",
+  "provider.custom.error.providerID.required": "Leverandør-ID er påkrevd",
+  "provider.custom.error.providerID.format": "Bruk små bokstaver, tall, bindestreker eller understreker",
+  "provider.custom.error.providerID.exists": "Den leverandør-IDen finnes allerede",
+  "provider.custom.error.name.required": "Visningsnavn er påkrevd",
+  "provider.custom.error.baseURL.required": "Base-URL er påkrevd",
+  "provider.custom.error.baseURL.format": "Må starte med http:// eller https://",
+  "provider.custom.error.required": "Påkrevd",
+  "provider.custom.error.duplicate": "Duplikat",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} frakoblet",
   "provider.disconnect.toast.disconnected.description": "Modeller fra {{provider}} er ikke lenger tilgjengelige.",
+
   "model.tag.free": "Gratis",
   "model.tag.latest": "Nyeste",
   "model.provider.anthropic": "Anthropic",
@@ -169,6 +212,7 @@ export const dict = {
 
   "common.search.placeholder": "Søk",
   "common.goBack": "Gå tilbake",
+  "common.goForward": "Navigate forward",
   "common.loading": "Laster",
   "common.loading.ellipsis": "...",
   "common.cancel": "Avbryt",
@@ -290,10 +334,10 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "Anbefalt: 128x128px",
   "dialog.project.edit.color": "Farge",
   "dialog.project.edit.color.select": "Velg fargen {{color}}",
-
   "dialog.project.edit.worktree.startup": "Oppstartsskript for arbeidsområde",
   "dialog.project.edit.worktree.startup.description": "Kjører etter at et nytt arbeidsområde (worktree) er opprettet.",
   "dialog.project.edit.worktree.startup.placeholder": "f.eks. bun install",
+
   "context.breakdown.title": "Kontekstfordeling",
   "context.breakdown.note": 'Omtrentlig fordeling av input-tokens. "Annet" inkluderer verktøydefinisjoner og overhead.',
   "context.breakdown.system": "System",
@@ -328,30 +372,48 @@ export const dict = {
   "context.usage.clickToView": "Klikk for å se kontekst",
   "context.usage.view": "Se kontekstforbruk",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "Språk",
   "toast.language.description": "Byttet til {{language}}",
 
   "toast.theme.title": "Tema byttet",
   "toast.scheme.title": "Fargevalg",
 
-  "toast.permissions.autoaccept.on.title": "Godtar endringer automatisk",
-  "toast.permissions.autoaccept.on.description": "Redigerings- og skrivetillatelser vil bli godkjent automatisk",
-  "toast.permissions.autoaccept.off.title": "Sluttet å godta endringer automatisk",
-  "toast.permissions.autoaccept.off.description": "Redigerings- og skrivetillatelser vil kreve godkjenning",
-
   "toast.workspace.enabled.title": "Arbeidsområder aktivert",
   "toast.workspace.enabled.description": "Flere worktrees vises nå i sidefeltet",
   "toast.workspace.disabled.title": "Arbeidsområder deaktivert",
   "toast.workspace.disabled.description": "Kun hoved-worktree vises i sidefeltet",
 
+  "toast.permissions.autoaccept.on.title": "Godtar endringer automatisk",
+  "toast.permissions.autoaccept.on.description": "Redigerings- og skrivetillatelser vil bli godkjent automatisk",
+  "toast.permissions.autoaccept.off.title": "Sluttet å godta endringer automatisk",
+  "toast.permissions.autoaccept.off.description": "Redigerings- og skrivetillatelser vil kreve godkjenning",
+
   "toast.model.none.title": "Ingen modell valgt",
   "toast.model.none.description": "Koble til en leverandør for å oppsummere denne sesjonen",
 
   "toast.file.loadFailed.title": "Kunne ikke laste fil",
-
   "toast.file.listFailed.title": "Kunne ikke liste filer",
+
   "toast.context.noLineSelection.title": "Ingen linjevalg",
   "toast.context.noLineSelection.description": "Velg først et linjeområde i en filfane.",
+
   "toast.session.share.copyFailed.title": "Kunne ikke kopiere URL til utklippstavlen",
   "toast.session.share.success.title": "Sesjon delt",
   "toast.session.share.success.description": "Delings-URL kopiert til utklippstavlen!",
@@ -385,6 +447,7 @@ export const dict = {
     "Rotelement ikke funnet. Glemte du å legge det til i index.html? Eller kanskje id-attributten er feilstavet?",
 
   "error.globalSync.connectFailed": "Kunne ikke koble til server. Kjører det en server på `{{url}}`?",
+  "directory.error.invalidUrl": "Invalid directory in URL.",
 
   "error.chain.unknown": "Ukjent feil",
   "error.chain.causedBy": "Forårsaket av:",
@@ -431,9 +494,11 @@ export const dict = {
   "session.review.loadingChanges": "Laster endringer...",
   "session.review.empty": "Ingen endringer i denne sesjonen ennå",
   "session.review.noChanges": "Ingen endringer",
+
   "session.files.selectToOpen": "Velg en fil å åpne",
   "session.files.all": "Alle filer",
   "session.files.binaryContent": "Binær fil (innhold kan ikke vises)",
+
   "session.messages.renderEarlier": "Vis tidligere meldinger",
   "session.messages.loadingEarlier": "Laster inn tidligere meldinger...",
   "session.messages.loadEarlier": "Last inn tidligere meldinger",
@@ -449,6 +514,11 @@ export const dict = {
 
   "session.header.search.placeholder": "Søk i {{project}}",
   "session.header.searchFiles": "Søk etter filer",
+  "session.header.openIn": "Åpne i",
+  "session.header.open.action": "Åpne {{app}}",
+  "session.header.open.ariaLabel": "Åpne i {{app}}",
+  "session.header.open.menu": "Åpne alternativer",
+  "session.header.open.copyPath": "Kopier bane",
 
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Serverkonfigurasjoner",
@@ -511,18 +581,20 @@ export const dict = {
   "sidebar.project.viewAllSessions": "Vis alle sesjoner",
 
   "app.name.desktop": "OpenCode Desktop",
+
   "settings.section.desktop": "Skrivebord",
   "settings.section.server": "Server",
   "settings.tab.general": "Generelt",
   "settings.tab.shortcuts": "Snarveier",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "WSL-integrasjon",
+  "settings.desktop.wsl.description": "Kjør OpenCode-serveren i WSL på Windows.",
 
   "settings.general.section.appearance": "Utseende",
   "settings.general.section.notifications": "Systemvarsler",
   "settings.general.section.updates": "Oppdateringer",
   "settings.general.section.sounds": "Lydeffekter",
+  "settings.general.section.display": "Skjerm",
 
   "settings.general.row.language.title": "Språk",
   "settings.general.row.language.description": "Endre visningsspråket for OpenCode",
@@ -533,6 +605,11 @@ export const dict = {
   "settings.general.row.font.title": "Skrift",
   "settings.general.row.font.description": "Tilpass mono-skriften som brukes i kodeblokker",
 
+  "settings.general.row.wayland.title": "Bruk innebygd Wayland",
+  "settings.general.row.wayland.description": "Deaktiver X11-fallback på Wayland. Krever omstart.",
+  "settings.general.row.wayland.tooltip":
+    "På Linux med skjermer med blandet oppdateringsfrekvens kan innebygd Wayland være mer stabilt.",
+
   "settings.general.row.releaseNotes.title": "Utgivelsesnotater",
   "settings.general.row.releaseNotes.description": 'Vis "Hva er nytt"-vinduer etter oppdateringer',
 
@@ -544,7 +621,6 @@ export const dict = {
   "settings.updates.action.checking": "Sjekker...",
   "settings.updates.toast.latest.title": "Du er oppdatert",
   "settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av OpenCode.",
-
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",
@@ -602,6 +678,7 @@ export const dict = {
   "sound.option.yup04": "Ja 04",
   "sound.option.yup05": "Ja 05",
   "sound.option.yup06": "Ja 06",
+
   "settings.general.notifications.agent.title": "Agent",
   "settings.general.notifications.agent.description":
     "Vis systemvarsel når agenten er ferdig eller trenger oppmerksomhet",
@@ -700,6 +777,7 @@ export const dict = {
   "session.delete.title": "Slett sesjon",
   "session.delete.confirm": 'Slette sesjonen "{{name}}"?',
   "session.delete.button": "Slett sesjon",
+
   "workspace.new": "Nytt arbeidsområde",
   "workspace.type.local": "lokal",
   "workspace.type.sandbox": "sandkasse",

+ 91 - 111
packages/app/src/i18n/pl.ts

@@ -16,11 +16,9 @@ export const dict = {
   "command.category.permissions": "Uprawnienia",
   "command.category.workspace": "Przestrzeń robocza",
   "command.category.settings": "Ustawienia",
-
   "theme.scheme.system": "Systemowy",
   "theme.scheme.light": "Jasny",
   "theme.scheme.dark": "Ciemny",
-
   "command.sidebar.toggle": "Przełącz pasek boczny",
   "command.project.open": "Otwórz projekt",
   "command.provider.connect": "Połącz dostawcę",
@@ -31,17 +29,13 @@ export const dict = {
   "command.session.previous.unseen": "Poprzednia nieprzeczytana sesja",
   "command.session.next.unseen": "Następna nieprzeczytana sesja",
   "command.session.archive": "Zarchiwizuj sesję",
-
   "command.palette": "Paleta poleceń",
-
   "command.theme.cycle": "Przełącz motyw",
   "command.theme.set": "Użyj motywu: {{theme}}",
   "command.theme.scheme.cycle": "Przełącz schemat kolorów",
   "command.theme.scheme.set": "Użyj schematu kolorów: {{scheme}}",
-
   "command.language.cycle": "Przełącz język",
   "command.language.set": "Użyj języka: {{language}}",
-
   "command.session.new": "Nowa sesja",
   "command.file.open": "Otwórz plik",
   "command.tab.close": "Zamknij kartę",
@@ -72,6 +66,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Automatyczne akceptowanie edycji",
   "command.permissions.autoaccept.disable": "Zatrzymaj automatyczne akceptowanie edycji",
   "command.workspace.toggle": "Przełącz przestrzenie robocze",
+  "command.workspace.toggle.description": "Włącz lub wyłącz wiele przestrzeni roboczych na pasku bocznym",
   "command.session.undo": "Cofnij",
   "command.session.undo.description": "Cofnij ostatnią wiadomość",
   "command.session.redo": "Ponów",
@@ -84,32 +79,30 @@ export const dict = {
   "command.session.share.description": "Udostępnij tę sesję i skopiuj URL do schowka",
   "command.session.unshare": "Przestań udostępniać sesję",
   "command.session.unshare.description": "Zatrzymaj udostępnianie tej sesji",
-
   "palette.search.placeholder": "Szukaj plików, poleceń i sesji",
   "palette.empty": "Brak wyników",
   "palette.group.commands": "Polecenia",
   "palette.group.files": "Pliki",
-
   "dialog.provider.search.placeholder": "Szukaj dostawców",
   "dialog.provider.empty": "Nie znaleziono dostawców",
   "dialog.provider.group.popular": "Popularne",
   "dialog.provider.group.other": "Inne",
   "dialog.provider.tag.recommended": "Zalecane",
-  "dialog.provider.anthropic.note": "Połącz z Claude Pro/Max lub kluczem API",
-  "dialog.provider.openai.note": "Połącz z ChatGPT Pro/Plus lub kluczem API",
-  "dialog.provider.copilot.note": "Połącz z Copilot lub kluczem API",
-
+  "dialog.provider.opencode.note": "Wyselekcjonowane modele, w tym Claude, GPT, Gemini i inne",
+  "dialog.provider.anthropic.note": "Bezpośredni dostęp do modeli Claude, w tym Pro i Max",
+  "dialog.provider.copilot.note": "Modele Claude do pomocy w kodowaniu",
+  "dialog.provider.openai.note": "Modele GPT do szybkich i wszechstronnych zadań AI",
+  "dialog.provider.google.note": "Modele Gemini do szybkich i ustrukturyzowanych odpowiedzi",
+  "dialog.provider.openrouter.note": "Dostęp do wszystkich obsługiwanych modeli od jednego dostawcy",
+  "dialog.provider.vercel.note": "Ujednolicony dostęp do modeli AI z inteligentnym routingiem",
   "dialog.model.select.title": "Wybierz model",
   "dialog.model.search.placeholder": "Szukaj modeli",
   "dialog.model.empty": "Brak wyników modelu",
   "dialog.model.manage": "Zarządzaj modelami",
   "dialog.model.manage.description": "Dostosuj, które modele pojawiają się w wyborze modelu.",
-
   "dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez OpenCode",
   "dialog.model.unpaid.addMore.title": "Dodaj więcej modeli od popularnych dostawców",
-
   "dialog.provider.viewAll": "Zobacz więcej dostawców",
-
   "provider.connect.title": "Połącz {{provider}}",
   "provider.connect.title.anthropicProMax": "Zaloguj się z Claude Pro/Max",
   "provider.connect.selectMethod": "Wybierz metodę logowania dla {{provider}}.",
@@ -117,34 +110,64 @@ export const dict = {
   "provider.connect.status.inProgress": "Autoryzacja w toku...",
   "provider.connect.status.waiting": "Oczekiwanie na autoryzację...",
   "provider.connect.status.failed": "Autoryzacja nie powiodła się: {{error}}",
-  "provider.connect.apiKey.description":
-    "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w OpenCode.",
+  "provider.connect.apiKey.description": "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w OpenCode.",
   "provider.connect.apiKey.label": "Klucz API {{provider}}",
   "provider.connect.apiKey.placeholder": "Klucz API",
   "provider.connect.apiKey.required": "Klucz API jest wymagany",
-  "provider.connect.opencodeZen.line1":
-    "OpenCode Zen daje dostęp do wybranego zestawu niezawodnych, zoptymalizowanych modeli dla agentów kodujących.",
-  "provider.connect.opencodeZen.line2":
-    "Z jednym kluczem API uzyskasz dostęp do modeli takich jak Claude, GPT, Gemini, GLM i więcej.",
+  "provider.connect.opencodeZen.line1": "OpenCode Zen daje dostęp do wybranego zestawu niezawodnych, zoptymalizowanych modeli dla agentów kodujących.",
+  "provider.connect.opencodeZen.line2": "Z jednym kluczem API uzyskasz dostęp do modeli takich jak Claude, GPT, Gemini, GLM i więcej.",
   "provider.connect.opencodeZen.visit.prefix": "Odwiedź ",
   "provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
   "provider.connect.opencodeZen.visit.suffix": ", aby odebrać swój klucz API.",
   "provider.connect.oauth.code.visit.prefix": "Odwiedź ",
   "provider.connect.oauth.code.visit.link": "ten link",
-  "provider.connect.oauth.code.visit.suffix":
-    ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w OpenCode.",
+  "provider.connect.oauth.code.visit.suffix": ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w OpenCode.",
   "provider.connect.oauth.code.label": "Kod autoryzacyjny {{method}}",
   "provider.connect.oauth.code.placeholder": "Kod autoryzacyjny",
   "provider.connect.oauth.code.required": "Kod autoryzacyjny jest wymagany",
   "provider.connect.oauth.code.invalid": "Nieprawidłowy kod autoryzacyjny",
   "provider.connect.oauth.auto.visit.prefix": "Odwiedź ",
   "provider.connect.oauth.auto.visit.link": "ten link",
-  "provider.connect.oauth.auto.visit.suffix":
-    " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w OpenCode.",
+  "provider.connect.oauth.auto.visit.suffix": " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w OpenCode.",
   "provider.connect.oauth.auto.confirmationCode": "Kod potwierdzający",
   "provider.connect.toast.connected.title": "Połączono {{provider}}",
   "provider.connect.toast.connected.description": "Modele {{provider}} są teraz dostępne do użycia.",
-
+  "provider.custom.title": "Dostawca niestandardowy",
+  "provider.custom.description.prefix": "Skonfiguruj dostawcę zgodnego z OpenAI. Zobacz ",
+  "provider.custom.description.link": "dokumentację konfiguracji dostawcy",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID dostawcy",
+  "provider.custom.field.providerID.placeholder": "mojdostawca",
+  "provider.custom.field.providerID.description": "Małe litery, cyfry, łączniki lub podkreślenia",
+  "provider.custom.field.name.label": "Nazwa wyświetlana",
+  "provider.custom.field.name.placeholder": "Mój Dostawca AI",
+  "provider.custom.field.baseURL.label": "Bazowy URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.mojdostawca.com/v1",
+  "provider.custom.field.apiKey.label": "Klucz API",
+  "provider.custom.field.apiKey.placeholder": "Klucz API",
+  "provider.custom.field.apiKey.description": "Opcjonalne. Pozostaw puste, jeśli zarządzasz autoryzacją przez nagłówki.",
+  "provider.custom.models.label": "Modele",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "Nazwa",
+  "provider.custom.models.name.placeholder": "Nazwa wyświetlana",
+  "provider.custom.models.remove": "Usuń model",
+  "provider.custom.models.add": "Dodaj model",
+  "provider.custom.headers.label": "Nagłówki (opcjonalne)",
+  "provider.custom.headers.key.label": "Nagłówek",
+  "provider.custom.headers.key.placeholder": "Nazwa-Naglowka",
+  "provider.custom.headers.value.label": "Wartość",
+  "provider.custom.headers.value.placeholder": "wartość",
+  "provider.custom.headers.remove": "Usuń nagłówek",
+  "provider.custom.headers.add": "Dodaj nagłówek",
+  "provider.custom.error.providerID.required": "ID dostawcy jest wymagane",
+  "provider.custom.error.providerID.format": "Używaj małych liter, cyfr, łączników lub podkreśleń",
+  "provider.custom.error.providerID.exists": "To ID dostawcy już istnieje",
+  "provider.custom.error.name.required": "Nazwa wyświetlana jest wymagana",
+  "provider.custom.error.baseURL.required": "Bazowy URL jest wymagany",
+  "provider.custom.error.baseURL.format": "Musi zaczynać się od http:// lub https://",
+  "provider.custom.error.required": "Wymagane",
+  "provider.custom.error.duplicate": "Duplikat",
   "provider.disconnect.toast.disconnected.title": "Rozłączono {{provider}}",
   "provider.disconnect.toast.disconnected.description": "Modele {{provider}} nie są już dostępne.",
   "model.tag.free": "Darmowy",
@@ -163,9 +186,9 @@ export const dict = {
   "model.tooltip.reasoning.allowed": "Obsługuje wnioskowanie",
   "model.tooltip.reasoning.none": "Brak wnioskowania",
   "model.tooltip.context": "Limit kontekstu {{limit}}",
-
   "common.search.placeholder": "Szukaj",
   "common.goBack": "Wstecz",
+  "common.goForward": "Dalej",
   "common.loading": "Ładowanie",
   "common.loading.ellipsis": "...",
   "common.cancel": "Anuluj",
@@ -176,14 +199,12 @@ export const dict = {
   "common.saving": "Zapisywanie...",
   "common.default": "Domyślny",
   "common.attachment": "załącznik",
-
   "prompt.placeholder.shell": "Wpisz polecenie terminala...",
   "prompt.placeholder.normal": 'Zapytaj o cokolwiek... "{{example}}"',
   "prompt.placeholder.summarizeComments": "Podsumuj komentarze…",
   "prompt.placeholder.summarizeComment": "Podsumuj komentarz…",
   "prompt.mode.shell": "Terminal",
   "prompt.mode.shell.exit": "esc aby wyjść",
-
   "prompt.example.1": "Napraw TODO w bazie kodu",
   "prompt.example.2": "Jaki jest stos technologiczny tego projektu?",
   "prompt.example.3": "Napraw zepsute testy",
@@ -209,7 +230,6 @@ export const dict = {
   "prompt.example.23": "Dodaj stronicowanie do tej listy",
   "prompt.example.24": "Utwórz polecenie CLI dla...",
   "prompt.example.25": "Jak działają tutaj zmienne środowiskowe?",
-
   "prompt.popover.emptyResults": "Brak pasujących wyników",
   "prompt.popover.emptyCommands": "Brak pasujących poleceń",
   "prompt.dropzone.label": "Upuść obrazy lub pliki PDF tutaj",
@@ -225,7 +245,6 @@ export const dict = {
   "prompt.attachment.remove": "Usuń załącznik",
   "prompt.action.send": "Wyślij",
   "prompt.action.stop": "Zatrzymaj",
-
   "prompt.toast.pasteUnsupported.title": "Nieobsługiwane wklejanie",
   "prompt.toast.pasteUnsupported.description": "Tylko obrazy lub pliki PDF mogą być tutaj wklejane.",
   "prompt.toast.modelAgentRequired.title": "Wybierz agenta i model",
@@ -236,24 +255,18 @@ export const dict = {
   "prompt.toast.commandSendFailed.title": "Nie udało się wysłać polecenia",
   "prompt.toast.promptSendFailed.title": "Nie udało się wysłać zapytania",
   "prompt.toast.promptSendFailed.description": "Nie udało się pobrać sesji",
-
   "dialog.mcp.title": "MCP",
   "dialog.mcp.description": "{{enabled}} z {{total}} włączone",
   "dialog.mcp.empty": "Brak skonfigurowanych MCP",
-
   "dialog.lsp.empty": "LSP wykryte automatycznie na podstawie typów plików",
   "dialog.plugins.empty": "Wtyczki skonfigurowane w opencode.json",
-
   "mcp.status.connected": "połączono",
   "mcp.status.failed": "niepowodzenie",
   "mcp.status.needs_auth": "wymaga autoryzacji",
   "mcp.status.disabled": "wyłączone",
-
   "dialog.fork.empty": "Brak wiadomości do rozwidlenia",
-
   "dialog.directory.search.placeholder": "Szukaj folderów",
   "dialog.directory.empty": "Nie znaleziono folderów",
-
   "dialog.server.title": "Serwery",
   "dialog.server.description": "Przełącz serwer OpenCode, z którym łączy się ta aplikacja.",
   "dialog.server.search.placeholder": "Szukaj serwerów",
@@ -265,20 +278,17 @@ export const dict = {
   "dialog.server.add.checking": "Sprawdzanie...",
   "dialog.server.add.button": "Dodaj serwer",
   "dialog.server.default.title": "Domyślny serwer",
-  "dialog.server.default.description":
-    "Połącz z tym serwerem przy uruchomieniu aplikacji zamiast uruchamiać lokalny serwer. Wymaga restartu.",
+  "dialog.server.default.description": "Połącz z tym serwerem przy uruchomieniu aplikacji zamiast uruchamiać lokalny serwer. Wymaga restartu.",
   "dialog.server.default.none": "Nie wybrano serwera",
   "dialog.server.default.set": "Ustaw bieżący serwer jako domyślny",
   "dialog.server.default.clear": "Wyczyść",
   "dialog.server.action.remove": "Usuń serwer",
-
   "dialog.server.menu.edit": "Edytuj",
   "dialog.server.menu.default": "Ustaw jako domyślny",
   "dialog.server.menu.defaultRemove": "Usuń domyślny",
   "dialog.server.menu.delete": "Usuń",
   "dialog.server.current": "Obecny serwer",
   "dialog.server.status.default": "Domyślny",
-
   "dialog.project.edit.title": "Edytuj projekt",
   "dialog.project.edit.name": "Nazwa",
   "dialog.project.edit.icon": "Ikona",
@@ -287,10 +297,8 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "Zalecane: 128x128px",
   "dialog.project.edit.color": "Kolor",
   "dialog.project.edit.color.select": "Wybierz kolor {{color}}",
-
   "dialog.project.edit.worktree.startup": "Skrypt uruchamiania przestrzeni roboczej",
-  "dialog.project.edit.worktree.startup.description":
-    "Uruchamiany po utworzeniu nowej przestrzeni roboczej (drzewa roboczego).",
+  "dialog.project.edit.worktree.startup.description": "Runs after creating a new workspace (worktree).",
   "dialog.project.edit.worktree.startup.placeholder": "np. bun install",
   "context.breakdown.title": "Podział kontekstu",
   "context.breakdown.note": 'Przybliżony podział tokenów wejściowych. "Inne" obejmuje definicje narzędzi i narzut.',
@@ -299,10 +307,8 @@ export const dict = {
   "context.breakdown.assistant": "Asystent",
   "context.breakdown.tool": "Wywołania narzędzi",
   "context.breakdown.other": "Inne",
-
   "context.systemPrompt.title": "Prompt systemowy",
   "context.rawMessages.title": "Surowe wiadomości",
-
   "context.stats.session": "Sesja",
   "context.stats.messages": "Wiadomości",
   "context.stats.provider": "Dostawca",
@@ -319,34 +325,42 @@ export const dict = {
   "context.stats.totalCost": "Całkowity koszt",
   "context.stats.sessionCreated": "Utworzono sesję",
   "context.stats.lastActivity": "Ostatnia aktywność",
-
   "context.usage.tokens": "Tokeny",
   "context.usage.usage": "Użycie",
   "context.usage.cost": "Koszt",
   "context.usage.clickToView": "Kliknij, aby zobaczyć kontekst",
   "context.usage.view": "Pokaż użycie kontekstu",
-
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
   "toast.language.title": "Język",
   "toast.language.description": "Przełączono na {{language}}",
-
   "toast.theme.title": "Przełączono motyw",
   "toast.scheme.title": "Schemat kolorów",
-
-  "toast.permissions.autoaccept.on.title": "Automatyczne akceptowanie edycji",
-  "toast.permissions.autoaccept.on.description": "Uprawnienia do edycji i zapisu będą automatycznie zatwierdzane",
-  "toast.permissions.autoaccept.off.title": "Zatrzymano automatyczne akceptowanie edycji",
-  "toast.permissions.autoaccept.off.description": "Uprawnienia do edycji i zapisu będą wymagały zatwierdzenia",
-
   "toast.workspace.enabled.title": "Przestrzenie robocze włączone",
   "toast.workspace.enabled.description": "Kilka worktree jest teraz wyświetlanych na pasku bocznym",
   "toast.workspace.disabled.title": "Przestrzenie robocze wyłączone",
   "toast.workspace.disabled.description": "Tylko główny worktree jest wyświetlany na pasku bocznym",
-
+  "toast.permissions.autoaccept.on.title": "Automatyczne akceptowanie edycji",
+  "toast.permissions.autoaccept.on.description": "Uprawnienia do edycji i zapisu będą automatycznie zatwierdzane",
+  "toast.permissions.autoaccept.off.title": "Zatrzymano automatyczne akceptowanie edycji",
+  "toast.permissions.autoaccept.off.description": "Uprawnienia do edycji i zapisu będą wymagały zatwierdzenia",
   "toast.model.none.title": "Nie wybrano modelu",
   "toast.model.none.description": "Połącz dostawcę, aby podsumować tę sesję",
-
   "toast.file.loadFailed.title": "Nie udało się załadować pliku",
-
   "toast.file.listFailed.title": "Nie udało się wyświetlić listy plików",
   "toast.context.noLineSelection.title": "Brak zaznaczenia linii",
   "toast.context.noLineSelection.description": "Najpierw wybierz zakres linii w zakładce pliku.",
@@ -355,19 +369,15 @@ export const dict = {
   "toast.session.share.success.description": "Link udostępniania skopiowany do schowka!",
   "toast.session.share.failed.title": "Nie udało się udostępnić sesji",
   "toast.session.share.failed.description": "Wystąpił błąd podczas udostępniania sesji",
-
   "toast.session.unshare.success.title": "Zatrzymano udostępnianie sesji",
   "toast.session.unshare.success.description": "Udostępnianie sesji zostało pomyślnie zatrzymane!",
   "toast.session.unshare.failed.title": "Nie udało się zatrzymać udostępniania sesji",
   "toast.session.unshare.failed.description": "Wystąpił błąd podczas zatrzymywania udostępniania sesji",
-
   "toast.session.listFailed.title": "Nie udało się załadować sesji dla {{project}}",
-
   "toast.update.title": "Dostępna aktualizacja",
   "toast.update.description": "Nowa wersja OpenCode ({{version}}) jest teraz dostępna do instalacji.",
   "toast.update.action.installRestart": "Zainstaluj i zrestartuj",
   "toast.update.action.notYet": "Jeszcze nie",
-
   "error.page.title": "Coś poszło nie tak",
   "error.page.description": "Wystąpił błąd podczas ładowania aplikacji.",
   "error.page.details.label": "Szczegóły błędu",
@@ -378,12 +388,9 @@ export const dict = {
   "error.page.report.prefix": "Proszę zgłosić ten błąd do zespołu OpenCode",
   "error.page.report.discord": "na Discordzie",
   "error.page.version": "Wersja: {{version}}",
-
-  "error.dev.rootNotFound":
-    "Nie znaleziono elementu głównego. Czy zapomniałeś dodać go do swojego index.html? A może atrybut id został błędnie wpisany?",
-
+  "error.dev.rootNotFound": "Nie znaleziono elementu głównego. Czy zapomniałeś dodać go do swojego index.html? A może atrybut id został błędnie wpisany?",
   "error.globalSync.connectFailed": "Nie można połączyć się z serwerem. Czy serwer działa pod adresem `{{url}}`?",
-
+  "directory.error.invalidUrl": "Nieprawidłowy katalog w URL.",
   "error.chain.unknown": "Nieznany błąd",
   "error.chain.causedBy": "Spowodowany przez:",
   "error.chain.apiError": "Błąd API",
@@ -393,33 +400,26 @@ export const dict = {
   "error.chain.didYouMean": "Czy miałeś na myśli: {{suggestions}}",
   "error.chain.modelNotFound": "Model nie znaleziony: {{provider}}/{{model}}",
   "error.chain.checkConfig": "Sprawdź swoją konfigurację (opencode.json) nazwy dostawców/modeli",
-  "error.chain.mcpFailed":
-    'Serwer MCP "{{name}}" nie powiódł się. Uwaga, OpenCode nie obsługuje jeszcze uwierzytelniania MCP.',
+  "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, OpenCode does not support MCP authentication yet.',
   "error.chain.providerAuthFailed": "Uwierzytelnianie dostawcy nie powiodło się ({{provider}}): {{message}}",
-  "error.chain.providerInitFailed":
-    'Nie udało się zainicjować dostawcy "{{provider}}". Sprawdź poświadczenia i konfigurację.',
+  "error.chain.providerInitFailed": 'Nie udało się zainicjować dostawcy "{{provider}}". Sprawdź poświadczenia i konfigurację.',
   "error.chain.configJsonInvalid": "Plik konfiguracyjny w {{path}} nie jest poprawnym JSON(C)",
   "error.chain.configJsonInvalidWithMessage": "Plik konfiguracyjny w {{path}} nie jest poprawnym JSON(C): {{message}}",
-  "error.chain.configDirectoryTypo":
-    'Katalog "{{dir}}" w {{path}} jest nieprawidłowy. Zmień nazwę katalogu na "{{suggestion}}" lub usuń go. To częsta literówka.',
+  "error.chain.configDirectoryTypo": 'Katalog "{{dir}}" w {{path}} jest nieprawidłowy. Zmień nazwę katalogu na "{{suggestion}}" lub usuń go. To częsta literówka.',
   "error.chain.configFrontmatterError": "Nie udało się przetworzyć frontmatter w {{path}}:\n{{message}}",
   "error.chain.configInvalid": "Plik konfiguracyjny w {{path}} jest nieprawidłowy",
   "error.chain.configInvalidWithMessage": "Plik konfiguracyjny w {{path}} jest nieprawidłowy: {{message}}",
-
   "notification.permission.title": "Wymagane uprawnienie",
   "notification.permission.description": "{{sessionTitle}} w {{projectName}} potrzebuje uprawnienia",
   "notification.question.title": "Pytanie",
   "notification.question.description": "{{sessionTitle}} w {{projectName}} ma pytanie",
   "notification.action.goToSession": "Przejdź do sesji",
-
   "notification.session.responseReady.title": "Odpowiedź gotowa",
   "notification.session.error.title": "Błąd sesji",
   "notification.session.error.fallbackDescription": "Wystąpił błąd",
-
   "home.recentProjects": "Ostatnie projekty",
   "home.empty.title": "Brak ostatnich projektów",
   "home.empty.description": "Zacznij od otwarcia lokalnego projektu",
-
   "session.tab.session": "Sesja",
   "session.tab.review": "Przegląd",
   "session.tab.context": "Kontekst",
@@ -438,17 +438,18 @@ export const dict = {
   "session.messages.loadEarlier": "Załaduj wcześniejsze wiadomości",
   "session.messages.loading": "Ładowanie wiadomości...",
   "session.messages.jumpToLatest": "Przejdź do najnowszych",
-
   "session.context.addToContext": "Dodaj {{selection}} do kontekstu",
-
   "session.new.worktree.main": "Główna gałąź",
   "session.new.worktree.mainWithBranch": "Główna gałąź ({{branch}})",
   "session.new.worktree.create": "Utwórz nowe drzewo robocze",
   "session.new.lastModified": "Ostatnio zmodyfikowano",
-
   "session.header.search.placeholder": "Szukaj {{project}}",
   "session.header.searchFiles": "Szukaj plików",
-
+  "session.header.openIn": "Otwórz w",
+  "session.header.open.action": "Otwórz {{app}}",
+  "session.header.open.ariaLabel": "Otwórz w {{app}}",
+  "session.header.open.menu": "Opcje otwierania",
+  "session.header.open.copyPath": "Kopiuj ścieżkę",
   "status.popover.trigger": "Status",
   "status.popover.ariaLabel": "Konfiguracje serwerów",
   "status.popover.tab.servers": "Serwery",
@@ -456,12 +457,9 @@ export const dict = {
   "status.popover.tab.lsp": "LSP",
   "status.popover.tab.plugins": "Wtyczki",
   "status.popover.action.manageServers": "Zarządzaj serwerami",
-
   "session.share.popover.title": "Opublikuj w sieci",
-  "session.share.popover.description.shared":
-    "Ta sesja jest publiczna w sieci. Jest dostępna dla każdego, kto posiada link.",
-  "session.share.popover.description.unshared":
-    "Udostępnij sesję publicznie w sieci. Będzie dostępna dla każdego, kto posiada link.",
+  "session.share.popover.description.shared": "Ta sesja jest publiczna w sieci. Jest dostępna dla każdego, kto posiada link.",
+  "session.share.popover.description.unshared": "Udostępnij sesję publicznie w sieci. Będzie dostępna dla każdego, kto posiada link.",
   "session.share.action.share": "Udostępnij",
   "session.share.action.publish": "Opublikuj",
   "session.share.action.publishing": "Publikowanie...",
@@ -470,19 +468,15 @@ export const dict = {
   "session.share.action.view": "Widok",
   "session.share.copy.copied": "Skopiowano",
   "session.share.copy.copyLink": "Kopiuj link",
-
   "lsp.tooltip.none": "Brak serwerów LSP",
   "lsp.label.connected": "{{count}} LSP",
-
   "prompt.loading": "Ładowanie promptu...",
   "terminal.loading": "Ładowanie terminala...",
   "terminal.title": "Terminal",
   "terminal.title.numbered": "Terminal {{number}}",
   "terminal.close": "Zamknij terminal",
   "terminal.connectionLost.title": "Utracono połączenie",
-  "terminal.connectionLost.description":
-    "Połączenie z terminalem zostało przerwane. Może się to zdarzyć przy restarcie serwera.",
-
+  "terminal.connectionLost.description": "Połączenie z terminalem zostało przerwane. Może się to zdarzyć przy restarcie serwera.",
   "common.closeTab": "Zamknij kartę",
   "common.dismiss": "Odrzuć",
   "common.requestFailed": "Żądanie nie powiodło się",
@@ -496,7 +490,6 @@ export const dict = {
   "common.edit": "Edytuj",
   "common.loadMore": "Załaduj więcej",
   "common.key.esc": "ESC",
-
   "sidebar.menu.toggle": "Przełącz menu",
   "sidebar.nav.projectsAndSessions": "Projekty i sesje",
   "sidebar.settings": "Ustawienia",
@@ -508,7 +501,6 @@ export const dict = {
   "sidebar.gettingStarted.line2": "Połącz dowolnego dostawcę, aby używać modeli, w tym Claude, GPT, Gemini itp.",
   "sidebar.project.recentSessions": "Ostatnie sesje",
   "sidebar.project.viewAllSessions": "Zobacz wszystkie sesje",
-
   "app.name.desktop": "OpenCode Desktop",
   "settings.section.desktop": "Pulpit",
   "settings.section.server": "Serwer",
@@ -517,12 +509,11 @@ export const dict = {
   "settings.desktop.section.wsl": "WSL",
   "settings.desktop.wsl.title": "WSL integration",
   "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
-
   "settings.general.section.appearance": "Wygląd",
   "settings.general.section.notifications": "Powiadomienia systemowe",
   "settings.general.section.updates": "Aktualizacje",
   "settings.general.section.sounds": "Efekty dźwiękowe",
-
+  "settings.general.section.display": "Ekran",
   "settings.general.row.language.title": "Język",
   "settings.general.row.language.description": "Zmień język wyświetlania dla OpenCode",
   "settings.general.row.appearance.title": "Wygląd",
@@ -531,10 +522,11 @@ export const dict = {
   "settings.general.row.theme.description": "Dostosuj motyw OpenCode.",
   "settings.general.row.font.title": "Czcionka",
   "settings.general.row.font.description": "Dostosuj czcionkę mono używaną w blokach kodu",
-
+  "settings.general.row.wayland.title": "Użyj natywnego Wayland",
+  "settings.general.row.wayland.description": "Wyłącz fallback X11 na Wayland. Wymaga restartu.",
+  "settings.general.row.wayland.tooltip": "Na Linuxie z monitorami o różnym odświeżaniu, natywny Wayland może być bardziej stabilny.",
   "settings.general.row.releaseNotes.title": "Informacje o wydaniu",
   "settings.general.row.releaseNotes.description": 'Pokazuj wyskakujące okna "Co nowego" po aktualizacjach',
-
   "settings.updates.row.startup.title": "Sprawdzaj aktualizacje przy uruchomieniu",
   "settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania OpenCode",
   "settings.updates.row.check.title": "Sprawdź aktualizacje",
@@ -600,23 +592,18 @@ export const dict = {
   "sound.option.yup04": "Yup 04",
   "sound.option.yup05": "Yup 05",
   "sound.option.yup06": "Yup 06",
-
   "settings.general.notifications.agent.title": "Agent",
-  "settings.general.notifications.agent.description":
-    "Pokaż powiadomienie systemowe, gdy agent zakończy pracę lub wymaga uwagi",
+  "settings.general.notifications.agent.description": "Pokaż powiadomienie systemowe, gdy agent zakończy pracę lub wymaga uwagi",
   "settings.general.notifications.permissions.title": "Uprawnienia",
-  "settings.general.notifications.permissions.description":
-    "Pokaż powiadomienie systemowe, gdy wymagane jest uprawnienie",
+  "settings.general.notifications.permissions.description": "Pokaż powiadomienie systemowe, gdy wymagane jest uprawnienie",
   "settings.general.notifications.errors.title": "Błędy",
   "settings.general.notifications.errors.description": "Pokaż powiadomienie systemowe, gdy wystąpi błąd",
-
   "settings.general.sounds.agent.title": "Agent",
   "settings.general.sounds.agent.description": "Odtwórz dźwięk, gdy agent zakończy pracę lub wymaga uwagi",
   "settings.general.sounds.permissions.title": "Uprawnienia",
   "settings.general.sounds.permissions.description": "Odtwórz dźwięk, gdy wymagane jest uprawnienie",
   "settings.general.sounds.errors.title": "Błędy",
   "settings.general.sounds.errors.description": "Odtwórz dźwięk, gdy wystąpi błąd",
-
   "settings.shortcuts.title": "Skróty klawiszowe",
   "settings.shortcuts.reset.button": "Przywróć domyślne",
   "settings.shortcuts.reset.toast.title": "Zresetowano skróty",
@@ -627,14 +614,12 @@ export const dict = {
   "settings.shortcuts.pressKeys": "Naciśnij klawisze",
   "settings.shortcuts.search.placeholder": "Szukaj skrótów",
   "settings.shortcuts.search.empty": "Nie znaleziono skrótów",
-
   "settings.shortcuts.group.general": "Ogólne",
   "settings.shortcuts.group.session": "Sesja",
   "settings.shortcuts.group.navigation": "Nawigacja",
   "settings.shortcuts.group.modelAndAgent": "Model i agent",
   "settings.shortcuts.group.terminal": "Terminal",
   "settings.shortcuts.group.prompt": "Prompt",
-
   "settings.providers.title": "Dostawcy",
   "settings.providers.description": "Ustawienia dostawców będą tutaj konfigurowalne.",
   "settings.providers.section.connected": "Połączeni dostawcy",
@@ -652,16 +637,13 @@ export const dict = {
   "settings.commands.description": "Ustawienia poleceń będą tutaj konfigurowalne.",
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "Ustawienia MCP będą tutaj konfigurowalne.",
-
   "settings.permissions.title": "Uprawnienia",
   "settings.permissions.description": "Kontroluj, jakich narzędzi serwer może używać domyślnie.",
   "settings.permissions.section.tools": "Narzędzia",
   "settings.permissions.toast.updateFailed.title": "Nie udało się zaktualizować uprawnień",
-
   "settings.permissions.action.allow": "Zezwól",
   "settings.permissions.action.ask": "Pytaj",
   "settings.permissions.action.deny": "Odmów",
-
   "settings.permissions.tool.read.title": "Odczyt",
   "settings.permissions.tool.read.description": "Odczyt pliku (pasuje do ścieżki pliku)",
   "settings.permissions.tool.edit.title": "Edycja",
@@ -694,12 +676,10 @@ export const dict = {
   "settings.permissions.tool.external_directory.description": "Dostęp do plików poza katalogiem projektu",
   "settings.permissions.tool.doom_loop.title": "Zapętlenie",
   "settings.permissions.tool.doom_loop.description": "Wykrywanie powtarzających się wywołań narzędzi (doom loop)",
-
   "session.delete.failed.title": "Nie udało się usunąć sesji",
   "session.delete.title": "Usuń sesję",
   "session.delete.confirm": 'Usunąć sesję "{{name}}"?',
   "session.delete.button": "Usuń sesję",
-
   "workspace.new": "Nowa przestrzeń robocza",
   "workspace.type.local": "lokalna",
   "workspace.type.sandbox": "piaskownica",

+ 78 - 5
packages/app/src/i18n/ru.ts

@@ -72,6 +72,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "Авто-принятие изменений",
   "command.permissions.autoaccept.disable": "Прекратить авто-принятие изменений",
   "command.workspace.toggle": "Переключить рабочие пространства",
+  "command.workspace.toggle.description": "Включить или отключить несколько рабочих пространств в боковой панели",
   "command.session.undo": "Отменить",
   "command.session.undo.description": "Отменить последнее сообщение",
   "command.session.redo": "Повторить",
@@ -95,9 +96,13 @@ export const dict = {
   "dialog.provider.group.popular": "Популярные",
   "dialog.provider.group.other": "Другие",
   "dialog.provider.tag.recommended": "Рекомендуемые",
-  "dialog.provider.anthropic.note": "Подключитесь с помощью Claude Pro/Max или API ключа",
-  "dialog.provider.openai.note": "Подключитесь с помощью ChatGPT Pro/Plus или API ключа",
-  "dialog.provider.copilot.note": "Подключитесь с помощью Copilot или API ключа",
+  "dialog.provider.opencode.note": "Отобранные модели, включая Claude, GPT, Gemini и другие",
+  "dialog.provider.anthropic.note": "Прямой доступ к моделям Claude, включая Pro и Max",
+  "dialog.provider.copilot.note": "Модели Claude для помощи в кодировании",
+  "dialog.provider.openai.note": "Модели GPT для быстрых и мощных задач общего ИИ",
+  "dialog.provider.google.note": "Модели Gemini для быстрых и структурированных ответов",
+  "dialog.provider.openrouter.note": "Доступ ко всем поддерживаемым моделям через одного провайдера",
+  "dialog.provider.vercel.note": "Единый доступ к ИИ-моделям с умной маршрутизацией",
 
   "dialog.model.select.title": "Выбрать модель",
   "dialog.model.search.placeholder": "Поиск моделей",
@@ -145,6 +150,44 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} подключён",
   "provider.connect.toast.connected.description": "Модели {{provider}} теперь доступны.",
 
+  "provider.custom.title": "Пользовательский провайдер",
+  "provider.custom.description.prefix": "Настройте OpenAI-совместимого провайдера. См. ",
+  "provider.custom.description.link": "документацию по настройке провайдера",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "ID провайдера",
+  "provider.custom.field.providerID.placeholder": "myprovider",
+  "provider.custom.field.providerID.description": "Строчные буквы, цифры, дефисы или подчёркивания",
+  "provider.custom.field.name.label": "Отображаемое имя",
+  "provider.custom.field.name.placeholder": "Мой AI провайдер",
+  "provider.custom.field.baseURL.label": "Базовый URL",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "API ключ",
+  "provider.custom.field.apiKey.placeholder": "API ключ",
+  "provider.custom.field.apiKey.description":
+    "Необязательно. Оставьте пустым, если управляете авторизацией через заголовки.",
+  "provider.custom.models.label": "Модели",
+  "provider.custom.models.id.label": "ID",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "Имя",
+  "provider.custom.models.name.placeholder": "Отображаемое имя",
+  "provider.custom.models.remove": "Удалить модель",
+  "provider.custom.models.add": "Добавить модель",
+  "provider.custom.headers.label": "Заголовки (необязательно)",
+  "provider.custom.headers.key.label": "Заголовок",
+  "provider.custom.headers.key.placeholder": "Header-Name",
+  "provider.custom.headers.value.label": "Значение",
+  "provider.custom.headers.value.placeholder": "значение",
+  "provider.custom.headers.remove": "Удалить заголовок",
+  "provider.custom.headers.add": "Добавить заголовок",
+  "provider.custom.error.providerID.required": "Требуется ID провайдера",
+  "provider.custom.error.providerID.format": "Используйте строчные буквы, цифры, дефисы или подчёркивания",
+  "provider.custom.error.providerID.exists": "Такой ID провайдера уже существует",
+  "provider.custom.error.name.required": "Требуется отображаемое имя",
+  "provider.custom.error.baseURL.required": "Требуется базовый URL",
+  "provider.custom.error.baseURL.format": "Должен начинаться с http:// или https://",
+  "provider.custom.error.required": "Обязательно",
+  "provider.custom.error.duplicate": "Дубликат",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} отключён",
   "provider.disconnect.toast.disconnected.description": "Модели {{provider}} больше недоступны.",
   "model.tag.free": "Бесплатно",
@@ -166,6 +209,7 @@ export const dict = {
 
   "common.search.placeholder": "Поиск",
   "common.goBack": "Назад",
+  "common.goForward": "Вперёд",
   "common.loading": "Загрузка",
   "common.loading.ellipsis": "...",
   "common.cancel": "Отмена",
@@ -327,6 +371,23 @@ export const dict = {
   "context.usage.clickToView": "Нажмите для просмотра контекста",
   "context.usage.view": "Показать использование контекста",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "Язык",
   "toast.language.description": "Переключено на {{language}}",
 
@@ -384,6 +445,7 @@ export const dict = {
     "Корневой элемент не найден. Вы забыли добавить его в index.html? Или, может быть, атрибут id был написан неправильно?",
 
   "error.globalSync.connectFailed": "Не удалось подключиться к серверу. Запущен ли сервер по адресу `{{url}}`?",
+  "directory.error.invalidUrl": "Недопустимая директория в URL.",
 
   "error.chain.unknown": "Неизвестная ошибка",
   "error.chain.causedBy": "Причина:",
@@ -450,6 +512,11 @@ export const dict = {
 
   "session.header.search.placeholder": "Поиск {{project}}",
   "session.header.searchFiles": "Поиск файлов",
+  "session.header.openIn": "Открыть в",
+  "session.header.open.action": "Открыть {{app}}",
+  "session.header.open.ariaLabel": "Открыть в {{app}}",
+  "session.header.open.menu": "Варианты открытия",
+  "session.header.open.copyPath": "Копировать путь",
 
   "status.popover.trigger": "Статус",
   "status.popover.ariaLabel": "Настройки серверов",
@@ -518,13 +585,14 @@ export const dict = {
   "settings.tab.general": "Основные",
   "settings.tab.shortcuts": "Горячие клавиши",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "Интеграция с WSL",
+  "settings.desktop.wsl.description": "Запускать сервер OpenCode внутри WSL на Windows.",
 
   "settings.general.section.appearance": "Внешний вид",
   "settings.general.section.notifications": "Системные уведомления",
   "settings.general.section.updates": "Обновления",
   "settings.general.section.sounds": "Звуковые эффекты",
+  "settings.general.section.display": "Дисплей",
 
   "settings.general.row.language.title": "Язык",
   "settings.general.row.language.description": "Изменить язык отображения OpenCode",
@@ -535,6 +603,11 @@ export const dict = {
   "settings.general.row.font.title": "Шрифт",
   "settings.general.row.font.description": "Настройте моноширинный шрифт для блоков кода",
 
+  "settings.general.row.wayland.title": "Использовать нативный Wayland",
+  "settings.general.row.wayland.description": "Отключить X11 fallback на Wayland. Требуется перезапуск.",
+  "settings.general.row.wayland.tooltip":
+    "На Linux с мониторами разной частоты обновления нативный Wayland может быть стабильнее.",
+
   "settings.general.row.releaseNotes.title": "Примечания к выпуску",
   "settings.general.row.releaseNotes.description": 'Показывать всплывающие окна "Что нового" после обновлений',
 

+ 87 - 10
packages/app/src/i18n/th.ts

@@ -72,6 +72,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "ยอมรับการแก้ไขโดยอัตโนมัติ",
   "command.permissions.autoaccept.disable": "หยุดยอมรับการแก้ไขโดยอัตโนมัติ",
   "command.workspace.toggle": "สลับพื้นที่ทำงาน",
+  "command.workspace.toggle.description": "เปิดหรือปิดใช้งานพื้นที่ทำงานหลายรายการในแถบด้านข้าง",
   "command.session.undo": "ยกเลิก",
   "command.session.undo.description": "ยกเลิกข้อความล่าสุด",
   "command.session.redo": "ทำซ้ำ",
@@ -149,6 +150,43 @@ export const dict = {
   "provider.connect.toast.connected.title": "{{provider}} ที่เชื่อมต่อแล้ว",
   "provider.connect.toast.connected.description": "โมเดล {{provider}} พร้อมใช้งานแล้ว",
 
+  "provider.custom.title": "ผู้ให้บริการที่กำหนดเอง",
+  "provider.custom.description.prefix": "กำหนดค่าผู้ให้บริการที่เข้ากันได้กับ OpenAI ดู ",
+  "provider.custom.description.link": "เอกสารการกำหนดค่าผู้ให้บริการ",
+  "provider.custom.description.suffix": ".",
+  "provider.custom.field.providerID.label": "รหัสผู้ให้บริการ",
+  "provider.custom.field.providerID.placeholder": "myprovider",
+  "provider.custom.field.providerID.description": "ตัวอักษรพิมพ์เล็ก ตัวเลข ยัติภังค์ หรือขีดล่าง",
+  "provider.custom.field.name.label": "ชื่อที่แสดง",
+  "provider.custom.field.name.placeholder": "My AI Provider",
+  "provider.custom.field.baseURL.label": "URL พื้นฐาน",
+  "provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
+  "provider.custom.field.apiKey.label": "คีย์ API",
+  "provider.custom.field.apiKey.placeholder": "คีย์ API",
+  "provider.custom.field.apiKey.description": "ไม่บังคับ เว้นว่างไว้หากคุณจัดการการยืนยันตัวตนผ่านส่วนหัว",
+  "provider.custom.models.label": "โมเดล",
+  "provider.custom.models.id.label": "รหัส",
+  "provider.custom.models.id.placeholder": "model-id",
+  "provider.custom.models.name.label": "ชื่อ",
+  "provider.custom.models.name.placeholder": "ชื่อที่แสดง",
+  "provider.custom.models.remove": "ลบโมเดล",
+  "provider.custom.models.add": "เพิ่มโมเดล",
+  "provider.custom.headers.label": "ส่วนหัว (ไม่บังคับ)",
+  "provider.custom.headers.key.label": "ส่วนหัว",
+  "provider.custom.headers.key.placeholder": "Header-Name",
+  "provider.custom.headers.value.label": "ค่า",
+  "provider.custom.headers.value.placeholder": "ค่า",
+  "provider.custom.headers.remove": "ลบส่วนหัว",
+  "provider.custom.headers.add": "เพิ่มส่วนหัว",
+  "provider.custom.error.providerID.required": "ต้องระบุรหัสผู้ให้บริการ",
+  "provider.custom.error.providerID.format": "ใช้ตัวอักษรพิมพ์เล็ก ตัวเลข ยัติภังค์ หรือขีดล่าง",
+  "provider.custom.error.providerID.exists": "รหัสผู้ให้บริการนั้นมีอยู่แล้ว",
+  "provider.custom.error.name.required": "ต้องระบุชื่อที่แสดง",
+  "provider.custom.error.baseURL.required": "ต้องระบุ URL พื้นฐาน",
+  "provider.custom.error.baseURL.format": "ต้องขึ้นต้นด้วย http:// หรือ https://",
+  "provider.custom.error.required": "จำเป็น",
+  "provider.custom.error.duplicate": "ซ้ำ",
+
   "provider.disconnect.toast.disconnected.title": "{{provider}} ที่ยกเลิกการเชื่อมต่อแล้ว",
   "provider.disconnect.toast.disconnected.description": "โมเดล {{provider}} ไม่พร้อมใช้งานอีกต่อไป",
 
@@ -163,7 +201,7 @@ export const dict = {
   "model.input.image": "รูปภาพ",
   "model.input.audio": "เสียง",
   "model.input.video": "วิดีโอ",
-  "model.input.pdf": "pdf",
+  "model.input.pdf": "PDF",
   "model.tooltip.allows": "อนุญาต: {{inputs}}",
   "model.tooltip.reasoning.allowed": "อนุญาตการใช้เหตุผล",
   "model.tooltip.reasoning.none": "ไม่มีการใช้เหตุผล",
@@ -171,6 +209,7 @@ export const dict = {
 
   "common.search.placeholder": "ค้นหา",
   "common.goBack": "ย้อนกลับ",
+  "common.goForward": "นำทางไปข้างหน้า",
   "common.loading": "กำลังโหลด",
   "common.loading.ellipsis": "...",
   "common.cancel": "ยกเลิก",
@@ -220,8 +259,8 @@ export const dict = {
   "prompt.dropzone.label": "วางรูปภาพหรือ PDF ที่นี่",
   "prompt.dropzone.file.label": "วางเพื่อ @กล่าวถึงไฟล์",
   "prompt.slash.badge.custom": "กำหนดเอง",
-  "prompt.slash.badge.skill": "skill",
-  "prompt.slash.badge.mcp": "mcp",
+  "prompt.slash.badge.skill": "ทักษะ",
+  "prompt.slash.badge.mcp": "MCP",
   "prompt.context.active": "ใช้งานอยู่",
   "prompt.context.includeActiveFile": "รวมไฟล์ที่ใช้งานอยู่",
   "prompt.context.removeActiveFile": "เอาไฟล์ที่ใช้งานอยู่ออกจากบริบท",
@@ -330,22 +369,39 @@ export const dict = {
   "context.usage.clickToView": "คลิกเพื่อดูบริบท",
   "context.usage.view": "ดูการใช้บริบท",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "ภาษา",
   "toast.language.description": "สลับไปที่ {{language}}",
 
   "toast.theme.title": "สลับธีมแล้ว",
   "toast.scheme.title": "โทนสี",
 
-  "toast.permissions.autoaccept.on.title": "กำลังยอมรับการแก้ไขโดยอัตโนมัติ",
-  "toast.permissions.autoaccept.on.description": "สิทธิ์การแก้ไขและจะได้รับเขียนการอนุมัติโดยอัตโนมัติ",
-  "toast.permissions.autoaccept.off.title": "หยุดยอมรับการแก้ไขโดยอัตโนมัติ",
-  "toast.permissions.autoaccept.off.description": "สิทธิ์การแก้ไขและเขียนจะต้องได้รับการอนุมัติ",
-
   "toast.workspace.enabled.title": "เปิดใช้งานพื้นที่ทำงานแล้ว",
   "toast.workspace.enabled.description": "ตอนนี้จะแสดง worktree หลายรายการในแถบด้านข้าง",
   "toast.workspace.disabled.title": "ปิดใช้งานพื้นที่ทำงานแล้ว",
   "toast.workspace.disabled.description": "จะแสดงเฉพาะ worktree หลักในแถบด้านข้าง",
 
+  "toast.permissions.autoaccept.on.title": "กำลังยอมรับการแก้ไขโดยอัตโนมัติ",
+  "toast.permissions.autoaccept.on.description": "สิทธิ์การแก้ไขและจะได้รับเขียนการอนุมัติโดยอัตโนมัติ",
+  "toast.permissions.autoaccept.off.title": "หยุดยอมรับการแก้ไขโดยอัตโนมัติ",
+  "toast.permissions.autoaccept.off.description": "สิทธิ์การแก้ไขและเขียนจะต้องได้รับการอนุมัติ",
+
   "toast.model.none.title": "ไม่ได้เลือกโมเดล",
   "toast.model.none.description": "เชื่อมต่อผู้ให้บริการเพื่อสรุปเซสชันนี้",
 
@@ -387,6 +443,7 @@ export const dict = {
   "error.dev.rootNotFound": "ไม่พบองค์ประกอบรูท คุณลืมเพิ่มใน index.html หรือบางทีแอตทริบิวต์ id อาจสะกดผิด?",
 
   "error.globalSync.connectFailed": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ มีเซิร์ฟเวอร์ทำงานอยู่ที่ `{{url}}` หรือไม่?",
+  "directory.error.invalidUrl": "ไดเรกทอรีใน URL ไม่ถูกต้อง",
 
   "error.chain.unknown": "ข้อผิดพลาดที่ไม่รู้จัก",
   "error.chain.causedBy": "สาเหตุ:",
@@ -452,6 +509,11 @@ export const dict = {
 
   "session.header.search.placeholder": "ค้นหา {{project}}",
   "session.header.searchFiles": "ค้นหาไฟล์",
+  "session.header.openIn": "เปิดใน",
+  "session.header.open.action": "เปิด {{app}}",
+  "session.header.open.ariaLabel": "เปิดใน {{app}}",
+  "session.header.open.menu": "ตัวเลือกการเปิด",
+  "session.header.open.copyPath": "คัดลอกเส้นทาง",
 
   "status.popover.trigger": "สถานะ",
   "status.popover.ariaLabel": "การกำหนดค่าเซิร์ฟเวอร์",
@@ -517,13 +579,14 @@ export const dict = {
   "settings.tab.general": "ทั่วไป",
   "settings.tab.shortcuts": "ทางลัด",
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "การรวม WSL",
+  "settings.desktop.wsl.description": "เรียกใช้เซิร์ฟเวอร์ OpenCode ภายใน WSL บน Windows",
 
   "settings.general.section.appearance": "รูปลักษณ์",
   "settings.general.section.notifications": "การแจ้งเตือนระบบ",
   "settings.general.section.updates": "การอัปเดต",
   "settings.general.section.sounds": "เสียงเอฟเฟกต์",
+  "settings.general.section.display": "การแสดงผล",
 
   "settings.general.row.language.title": "ภาษา",
   "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ OpenCode",
@@ -534,8 +597,22 @@ export const dict = {
   "settings.general.row.font.title": "ฟอนต์",
   "settings.general.row.font.description": "ปรับแต่งฟอนต์โมโนที่ใช้ในบล็อกโค้ด",
 
+  "settings.general.row.wayland.title": "ใช้ Wayland แบบเนทีฟ",
+  "settings.general.row.wayland.description": "ปิดใช้งาน X11 fallback บน Wayland ต้องรีสตาร์ท",
+  "settings.general.row.wayland.tooltip": "บน Linux ที่มีจอภาพรีเฟรชเรตแบบผสม Wayland แบบเนทีฟอาจเสถียรกว่า",
+
   "settings.general.row.releaseNotes.title": "บันทึกการอัปเดต",
   "settings.general.row.releaseNotes.description": "แสดงป๊อปอัพ What's New หลังจากอัปเดต",
+
+  "settings.updates.row.startup.title": "ตรวจสอบการอัปเดตเมื่อเริ่มต้น",
+  "settings.updates.row.startup.description": "ตรวจสอบการอัปเดตโดยอัตโนมัติเมื่อ OpenCode เปิดใช้งาน",
+  "settings.updates.row.check.title": "ตรวจสอบการอัปเดต",
+  "settings.updates.row.check.description": "ตรวจสอบการอัปเดตด้วยตนเองและติดตั้งหากมี",
+  "settings.updates.action.checkNow": "ตรวจสอบทันที",
+  "settings.updates.action.checking": "กำลังตรวจสอบ...",
+  "settings.updates.toast.latest.title": "คุณเป็นเวอร์ชันล่าสุดแล้ว",
+  "settings.updates.toast.latest.description": "คุณกำลังใช้งาน OpenCode เวอร์ชันล่าสุด",
+
   "font.option.ibmPlexMono": "IBM Plex Mono",
   "font.option.cascadiaCode": "Cascadia Code",
   "font.option.firaCode": "Fira Code",

+ 86 - 53
packages/app/src/i18n/zh.ts

@@ -19,17 +19,22 @@ export const dict = {
   "command.category.agent": "智能体",
   "command.category.permissions": "权限",
   "command.category.workspace": "工作区",
-
   "command.category.settings": "设置",
+
   "theme.scheme.system": "系统",
   "theme.scheme.light": "浅色",
   "theme.scheme.dark": "深色",
 
   "command.sidebar.toggle": "切换侧边栏",
+
   "command.project.open": "打开项目",
+
   "command.provider.connect": "连接提供商",
+
   "command.server.switch": "切换服务器",
+
   "command.settings.open": "打开设置",
+
   "command.session.previous": "上一个会话",
   "command.session.next": "下一个会话",
   "command.session.previous.unseen": "上一个未读会话",
@@ -47,35 +52,53 @@ export const dict = {
   "command.language.set": "使用语言:{{language}}",
 
   "command.session.new": "新建会话",
+
   "command.file.open": "打开文件",
+
   "command.tab.close": "关闭标签页",
+
   "command.context.addSelection": "将所选内容添加到上下文",
   "command.context.addSelection.description": "添加当前文件中选中的行",
+
   "command.input.focus": "聚焦输入框",
+
   "command.terminal.toggle": "切换终端",
+
   "command.fileTree.toggle": "切换文件树",
+
   "command.review.toggle": "切换审查",
+
   "command.terminal.new": "新建终端",
   "command.terminal.new.description": "创建新的终端标签页",
+
   "command.steps.toggle": "切换步骤",
   "command.steps.toggle.description": "显示或隐藏当前消息的步骤",
+
   "command.message.previous": "上一条消息",
   "command.message.previous.description": "跳转到上一条用户消息",
   "command.message.next": "下一条消息",
   "command.message.next.description": "跳转到下一条用户消息",
+
   "command.model.choose": "选择模型",
   "command.model.choose.description": "选择不同的模型",
+
   "command.mcp.toggle": "切换 MCPs",
   "command.mcp.toggle.description": "切换 MCPs",
+
   "command.agent.cycle": "切换智能体",
   "command.agent.cycle.description": "切换到下一个智能体",
   "command.agent.cycle.reverse": "反向切换智能体",
   "command.agent.cycle.reverse.description": "切换到上一个智能体",
+
   "command.model.variant.cycle": "切换思考强度",
   "command.model.variant.cycle.description": "切换到下一个强度等级",
+
   "command.permissions.autoaccept.enable": "自动接受编辑",
   "command.permissions.autoaccept.disable": "停止自动接受编辑",
+
   "command.workspace.toggle": "切换工作区",
+  "command.workspace.toggle.description": "在侧边栏启用或禁用多个工作区",
+
   "command.session.undo": "撤销",
   "command.session.undo.description": "撤销上一条消息",
   "command.session.redo": "重做",
@@ -99,10 +122,10 @@ export const dict = {
   "dialog.provider.group.popular": "热门",
   "dialog.provider.group.other": "其他",
   "dialog.provider.tag.recommended": "推荐",
+  "dialog.provider.opencode.note": "使用 OpenCode Zen 或 API 密钥连接",
   "dialog.provider.anthropic.note": "使用 Claude Pro/Max 或 API 密钥连接",
-  "dialog.provider.openai.note": "使用 ChatGPT Pro/Plus 或 API 密钥连接",
   "dialog.provider.copilot.note": "使用 Copilot 或 API 密钥连接",
-  "dialog.provider.opencode.note": "使用 OpenCode Zen 或 API 密钥连接",
+  "dialog.provider.openai.note": "使用 ChatGPT Pro/Plus 或 API 密钥连接",
   "dialog.provider.google.note": "使用 Google 账号或 API 密钥连接",
   "dialog.provider.openrouter.note": "使用 OpenRouter 账号或 API 密钥连接",
   "dialog.provider.vercel.note": "使用 Vercel 账号或 API 密钥连接",
@@ -112,7 +135,6 @@ export const dict = {
   "dialog.model.empty": "未找到模型",
   "dialog.model.manage": "管理模型",
   "dialog.model.manage.description": "自定义模型选择器中显示的模型。",
-
   "dialog.model.unpaid.freeModels.title": "OpenCode 提供的免费模型",
   "dialog.model.unpaid.addMore.title": "从热门提供商添加更多模型",
 
@@ -125,8 +147,7 @@ export const dict = {
   "provider.connect.status.inProgress": "正在授权...",
   "provider.connect.status.waiting": "等待授权...",
   "provider.connect.status.failed": "授权失败:{{error}}",
-  "provider.connect.apiKey.description":
-    "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。",
+  "provider.connect.apiKey.description": "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。",
   "provider.connect.apiKey.label": "{{provider}} API 密钥",
   "provider.connect.apiKey.placeholder": "API 密钥",
   "provider.connect.apiKey.required": "API 密钥为必填项",
@@ -188,9 +209,9 @@ export const dict = {
 
   "provider.disconnect.toast.disconnected.title": "{{provider}} 已断开连接",
   "provider.disconnect.toast.disconnected.description": "{{provider}} 模型已不再可用。",
+
   "model.tag.free": "免费",
   "model.tag.latest": "最新",
-
   "model.provider.anthropic": "Anthropic",
   "model.provider.openai": "OpenAI",
   "model.provider.google": "Google",
@@ -205,8 +226,10 @@ export const dict = {
   "model.tooltip.reasoning.allowed": "支持推理",
   "model.tooltip.reasoning.none": "不支持推理",
   "model.tooltip.context": "上下文上限 {{limit}}",
+
   "common.search.placeholder": "搜索",
   "common.goBack": "返回",
+  "common.goForward": "前进",
   "common.loading": "加载中",
   "common.loading.ellipsis": "...",
   "common.cancel": "取消",
@@ -219,12 +242,11 @@ export const dict = {
   "common.attachment": "附件",
 
   "prompt.placeholder.shell": "输入 shell 命令...",
-  "prompt.placeholder.normal": '随便问点什么... "{{example}}"',
+  "prompt.placeholder.normal": "随便问点什么... \"{{example}}\"",
   "prompt.placeholder.summarizeComments": "总结评论…",
   "prompt.placeholder.summarizeComment": "总结该评论…",
   "prompt.mode.shell": "Shell",
   "prompt.mode.shell.exit": "按 esc 退出",
-
   "prompt.example.1": "修复代码库中的一个 TODO",
   "prompt.example.2": "这个项目的技术栈是什么?",
   "prompt.example.3": "修复失败的测试",
@@ -250,7 +272,6 @@ export const dict = {
   "prompt.example.23": "给这个列表添加分页",
   "prompt.example.24": "创建一个 CLI 命令用于...",
   "prompt.example.25": "这里的环境变量是怎么工作的?",
-
   "prompt.popover.emptyResults": "没有匹配的结果",
   "prompt.popover.emptyCommands": "没有匹配的命令",
   "prompt.dropzone.label": "将图片或 PDF 拖到这里",
@@ -266,7 +287,6 @@ export const dict = {
   "prompt.attachment.remove": "移除附件",
   "prompt.action.send": "发送",
   "prompt.action.stop": "停止",
-
   "prompt.toast.pasteUnsupported.title": "不支持的粘贴",
   "prompt.toast.pasteUnsupported.description": "这里只能粘贴图片或 PDF 文件。",
   "prompt.toast.modelAgentRequired.title": "请选择智能体和模型",
@@ -283,6 +303,7 @@ export const dict = {
   "dialog.mcp.empty": "未配置 MCPs",
 
   "dialog.lsp.empty": "已从文件类型自动检测到 LSPs",
+
   "dialog.plugins.empty": "在 opencode.json 中配置的插件",
 
   "mcp.status.connected": "已连接",
@@ -311,7 +332,6 @@ export const dict = {
   "dialog.server.default.set": "将当前服务器设为默认",
   "dialog.server.default.clear": "清除",
   "dialog.server.action.remove": "移除服务器",
-
   "dialog.server.menu.edit": "编辑",
   "dialog.server.menu.default": "设为默认",
   "dialog.server.menu.defaultRemove": "取消默认",
@@ -327,10 +347,10 @@ export const dict = {
   "dialog.project.edit.icon.recommended": "建议:128x128px",
   "dialog.project.edit.color": "颜色",
   "dialog.project.edit.color.select": "选择{{color}}颜色",
-
   "dialog.project.edit.worktree.startup": "工作区启动脚本",
   "dialog.project.edit.worktree.startup.description": "在创建新的工作区 (worktree) 后运行。",
   "dialog.project.edit.worktree.startup.placeholder": "例如 bun install",
+
   "context.breakdown.title": "上下文拆分",
   "context.breakdown.note": "输入 token 的大致拆分。“其他”包含工具定义和开销。",
   "context.breakdown.system": "系统",
@@ -338,10 +358,8 @@ export const dict = {
   "context.breakdown.assistant": "助手",
   "context.breakdown.tool": "工具调用",
   "context.breakdown.other": "其他",
-
   "context.systemPrompt.title": "系统提示词",
   "context.rawMessages.title": "原始消息",
-
   "context.stats.session": "会话",
   "context.stats.messages": "消息数",
   "context.stats.provider": "提供商",
@@ -358,34 +376,44 @@ export const dict = {
   "context.stats.totalCost": "总成本",
   "context.stats.sessionCreated": "创建时间",
   "context.stats.lastActivity": "最后活动",
-
   "context.usage.tokens": "Token",
   "context.usage.usage": "使用率",
   "context.usage.cost": "成本",
   "context.usage.clickToView": "点击查看上下文",
   "context.usage.view": "查看上下文用量",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "语言",
   "toast.language.description": "已切换到{{language}}",
-
   "toast.theme.title": "主题已切换",
   "toast.scheme.title": "颜色方案",
-
   "toast.workspace.enabled.title": "工作区已启用",
   "toast.workspace.enabled.description": "侧边栏现在显示多个工作树",
   "toast.workspace.disabled.title": "工作区已禁用",
   "toast.workspace.disabled.description": "侧边栏只显示主工作树",
-
   "toast.permissions.autoaccept.on.title": "自动接受编辑",
   "toast.permissions.autoaccept.on.description": "编辑和写入权限将自动获批",
   "toast.permissions.autoaccept.off.title": "已停止自动接受编辑",
   "toast.permissions.autoaccept.off.description": "编辑和写入权限将需要手动批准",
-
   "toast.model.none.title": "未选择模型",
   "toast.model.none.description": "请先连接提供商以总结此会话",
-
   "toast.file.loadFailed.title": "加载文件失败",
-
   "toast.file.listFailed.title": "列出文件失败",
   "toast.context.noLineSelection.title": "未选择行",
   "toast.context.noLineSelection.description": "请先在文件标签中选择行范围。",
@@ -394,14 +422,11 @@ export const dict = {
   "toast.session.share.success.description": "分享链接已复制到剪贴板",
   "toast.session.share.failed.title": "分享会话失败",
   "toast.session.share.failed.description": "分享会话时发生错误",
-
   "toast.session.unshare.success.title": "已取消分享会话",
   "toast.session.unshare.success.description": "会话已成功取消分享",
   "toast.session.unshare.failed.title": "取消分享失败",
   "toast.session.unshare.failed.description": "取消分享会话时发生错误",
-
   "toast.session.listFailed.title": "无法加载 {{project}} 的会话",
-
   "toast.update.title": "有可用更新",
   "toast.update.description": "OpenCode 有新版本 ({{version}}) 可安装。",
   "toast.update.action.installRestart": "安装并重启",
@@ -417,10 +442,9 @@ export const dict = {
   "error.page.report.prefix": "请将此错误报告给 OpenCode 团队",
   "error.page.report.discord": "在 Discord 上",
   "error.page.version": "版本:{{version}}",
-
   "error.dev.rootNotFound": "未找到根元素。你是不是忘了把它添加到 index.html?或者 id 属性拼写错了?",
-
   "error.globalSync.connectFailed": "无法连接到服务器。是否有服务器正在 `{{url}}` 运行?",
+
   "directory.error.invalidUrl": "URL 中的目录无效。",
 
   "error.chain.unknown": "未知错误",
@@ -432,13 +456,12 @@ export const dict = {
   "error.chain.didYouMean": "你是不是想输入:{{suggestions}}",
   "error.chain.modelNotFound": "未找到模型:{{provider}}/{{model}}",
   "error.chain.checkConfig": "请检查你的配置 (opencode.json) 中的 provider/model 名称",
-  "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: OpenCode 暂不支持 MCP 认证。',
+  "error.chain.mcpFailed": "MCP 服务器 \"{{name}}\" 启动失败。注意: OpenCode 暂不支持 MCP 认证。",
   "error.chain.providerAuthFailed": "提供商认证失败({{provider}}):{{message}}",
-  "error.chain.providerInitFailed": '无法初始化提供商 "{{provider}}"。请检查凭据和配置。',
+  "error.chain.providerInitFailed": "无法初始化提供商 \"{{provider}}\"。请检查凭据和配置。",
   "error.chain.configJsonInvalid": "配置文件 {{path}} 不是有效的 JSON(C)",
   "error.chain.configJsonInvalidWithMessage": "配置文件 {{path}} 不是有效的 JSON(C):{{message}}",
-  "error.chain.configDirectoryTypo":
-    '{{path}} 中的目录 "{{dir}}" 无效。请将目录重命名为 "{{suggestion}}" 或移除它。这是一个常见拼写错误。',
+  "error.chain.configDirectoryTypo": "{{path}} 中的目录 \"{{dir}}\" 无效。请将目录重命名为 \"{{suggestion}}\" 或移除它。这是一个常见拼写错误。",
   "error.chain.configFrontmatterError": "无法解析 {{path}} 中的 frontmatter:\n{{message}}",
   "error.chain.configInvalid": "配置文件 {{path}} 无效",
   "error.chain.configInvalidWithMessage": "配置文件 {{path}} 无效:{{message}}",
@@ -448,7 +471,6 @@ export const dict = {
   "notification.question.title": "问题",
   "notification.question.description": "{{sessionTitle}}({{projectName}})有一个问题",
   "notification.action.goToSession": "前往会话",
-
   "notification.session.responseReady.title": "回复已就绪",
   "notification.session.error.title": "会话错误",
   "notification.session.error.fallbackDescription": "发生错误",
@@ -474,17 +496,19 @@ export const dict = {
   "session.messages.loadingEarlier": "正在加载更早的消息...",
   "session.messages.loadEarlier": "加载更早的消息",
   "session.messages.loading": "正在加载消息...",
-
   "session.messages.jumpToLatest": "跳转到最新",
   "session.context.addToContext": "将 {{selection}} 添加到上下文",
-
   "session.new.worktree.main": "主分支",
   "session.new.worktree.mainWithBranch": "主分支({{branch}})",
   "session.new.worktree.create": "创建新的 worktree",
   "session.new.lastModified": "最后修改",
-
   "session.header.search.placeholder": "搜索 {{project}}",
   "session.header.searchFiles": "搜索文件",
+  "session.header.openIn": "打开方式",
+  "session.header.open.action": "打开 {{app}}",
+  "session.header.open.ariaLabel": "在 {{app}} 中打开",
+  "session.header.open.menu": "打开选项",
+  "session.header.open.copyPath": "复制路径",
 
   "status.popover.trigger": "状态",
   "status.popover.ariaLabel": "服务器配置",
@@ -510,13 +534,14 @@ export const dict = {
   "lsp.label.connected": "{{count}} LSP",
 
   "prompt.loading": "正在加载提示...",
+
   "terminal.loading": "正在加载终端...",
   "terminal.title": "终端",
   "terminal.title.numbered": "终端 {{number}}",
   "terminal.close": "关闭终端",
-
   "terminal.connectionLost.title": "连接已丢失",
   "terminal.connectionLost.description": "终端连接已中断。这可能发生在服务器重启时。",
+
   "common.closeTab": "关闭标签页",
   "common.dismiss": "忽略",
   "common.requestFailed": "请求失败",
@@ -529,8 +554,8 @@ export const dict = {
   "common.close": "关闭",
   "common.edit": "编辑",
   "common.loadMore": "加载更多",
-
   "common.key.esc": "ESC",
+
   "sidebar.menu.toggle": "切换菜单",
   "sidebar.nav.projectsAndSessions": "项目和会话",
   "sidebar.settings": "设置",
@@ -544,19 +569,22 @@ export const dict = {
   "sidebar.project.viewAllSessions": "查看全部会话",
 
   "app.name.desktop": "OpenCode Desktop",
+
   "settings.section.desktop": "桌面",
   "settings.section.server": "服务器",
+
   "settings.tab.general": "通用",
   "settings.tab.shortcuts": "快捷键",
+
   "settings.desktop.section.wsl": "WSL",
-  "settings.desktop.wsl.title": "WSL integration",
-  "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
+  "settings.desktop.wsl.title": "WSL 集成",
+  "settings.desktop.wsl.description": "在 Windows 的 WSL 环境中运行 OpenCode 服务器。",
 
   "settings.general.section.appearance": "外观",
   "settings.general.section.notifications": "系统通知",
   "settings.general.section.updates": "更新",
   "settings.general.section.sounds": "音效",
-
+  "settings.general.section.display": "显示",
   "settings.general.row.language.title": "语言",
   "settings.general.row.language.description": "更改 OpenCode 的显示语言",
   "settings.general.row.appearance.title": "外观",
@@ -565,6 +593,9 @@ export const dict = {
   "settings.general.row.theme.description": "自定义 OpenCode 的主题。",
   "settings.general.row.font.title": "字体",
   "settings.general.row.font.description": "自定义代码块使用的等宽字体",
+  "settings.general.row.wayland.title": "使用原生 Wayland",
+  "settings.general.row.wayland.description": "在 Wayland 上禁用 X11 回退。需要重启。",
+  "settings.general.row.wayland.tooltip": "在混合刷新率显示器的 Linux 系统上,原生 Wayland 可能更稳定。",
   "settings.general.row.releaseNotes.title": "发行说明",
   "settings.general.row.releaseNotes.description": "更新后显示“新功能”弹窗",
 
@@ -589,6 +620,7 @@ export const dict = {
   "font.option.robotoMono": "Roboto Mono",
   "font.option.sourceCodePro": "Source Code Pro",
   "font.option.ubuntuMono": "Ubuntu Mono",
+
   "sound.option.alert01": "警报 01",
   "sound.option.alert02": "警报 02",
   "sound.option.alert03": "警报 03",
@@ -634,13 +666,13 @@ export const dict = {
   "sound.option.yup04": "是 04",
   "sound.option.yup05": "是 05",
   "sound.option.yup06": "是 06",
+
   "settings.general.notifications.agent.title": "智能体",
   "settings.general.notifications.agent.description": "当智能体完成或需要注意时显示系统通知",
   "settings.general.notifications.permissions.title": "权限",
   "settings.general.notifications.permissions.description": "当需要权限时显示系统通知",
   "settings.general.notifications.errors.title": "错误",
   "settings.general.notifications.errors.description": "发生错误时显示系统通知",
-
   "settings.general.sounds.agent.title": "智能体",
   "settings.general.sounds.agent.description": "当智能体完成或需要注意时播放声音",
   "settings.general.sounds.permissions.title": "权限",
@@ -658,7 +690,6 @@ export const dict = {
   "settings.shortcuts.pressKeys": "按下按键",
   "settings.shortcuts.search.placeholder": "搜索快捷键",
   "settings.shortcuts.search.empty": "未找到快捷键",
-
   "settings.shortcuts.group.general": "通用",
   "settings.shortcuts.group.session": "会话",
   "settings.shortcuts.group.navigation": "导航",
@@ -675,12 +706,16 @@ export const dict = {
   "settings.providers.tag.config": "配置",
   "settings.providers.tag.custom": "自定义",
   "settings.providers.tag.other": "其他",
+
   "settings.models.title": "模型",
   "settings.models.description": "模型设置将在此处可配置。",
+
   "settings.agents.title": "智能体",
   "settings.agents.description": "智能体设置将在此处可配置。",
+
   "settings.commands.title": "命令",
   "settings.commands.description": "命令设置将在此处可配置。",
+
   "settings.mcp.title": "MCP",
   "settings.mcp.description": "MCP 设置将在此处可配置。",
 
@@ -688,11 +723,9 @@ export const dict = {
   "settings.permissions.description": "控制服务器默认可以使用哪些工具。",
   "settings.permissions.section.tools": "工具",
   "settings.permissions.toast.updateFailed.title": "更新权限失败",
-
   "settings.permissions.action.allow": "允许",
   "settings.permissions.action.ask": "询问",
   "settings.permissions.action.deny": "拒绝",
-
   "settings.permissions.tool.read.title": "读取",
   "settings.permissions.tool.read.description": "读取文件(匹配文件路径)",
   "settings.permissions.tool.edit.title": "编辑",
@@ -705,9 +738,9 @@ export const dict = {
   "settings.permissions.tool.list.description": "列出目录中的文件",
   "settings.permissions.tool.bash.title": "Bash",
   "settings.permissions.tool.bash.description": "运行 shell 命令",
-  "settings.permissions.tool.task.title": "Task",
+  "settings.permissions.tool.task.title": "任务",
   "settings.permissions.tool.task.description": "启动子智能体",
-  "settings.permissions.tool.skill.title": "Skill",
+  "settings.permissions.tool.skill.title": "技能",
   "settings.permissions.tool.skill.description": "按名称加载技能",
   "settings.permissions.tool.lsp.title": "LSP",
   "settings.permissions.tool.lsp.description": "运行语言服务器查询",
@@ -715,20 +748,20 @@ export const dict = {
   "settings.permissions.tool.todoread.description": "读取待办列表",
   "settings.permissions.tool.todowrite.title": "更新待办",
   "settings.permissions.tool.todowrite.description": "更新待办列表",
-  "settings.permissions.tool.webfetch.title": "Web Fetch",
+  "settings.permissions.tool.webfetch.title": "网页获取",
   "settings.permissions.tool.webfetch.description": "从 URL 获取内容",
-  "settings.permissions.tool.websearch.title": "Web Search",
+  "settings.permissions.tool.websearch.title": "网页搜索",
   "settings.permissions.tool.websearch.description": "搜索网页",
-  "settings.permissions.tool.codesearch.title": "Code Search",
+  "settings.permissions.tool.codesearch.title": "代码搜索",
   "settings.permissions.tool.codesearch.description": "在网上搜索代码",
   "settings.permissions.tool.external_directory.title": "外部目录",
   "settings.permissions.tool.external_directory.description": "访问项目目录之外的文件",
-  "settings.permissions.tool.doom_loop.title": "Doom Loop",
+  "settings.permissions.tool.doom_loop.title": "死循环",
   "settings.permissions.tool.doom_loop.description": "检测具有相同输入的重复工具调用",
 
   "session.delete.failed.title": "删除会话失败",
   "session.delete.title": "删除会话",
-  "session.delete.confirm": '删除会话 "{{name}}"?',
+  "session.delete.confirm": "删除会话 \"{{name}}\"?",
   "session.delete.button": "删除会话",
 
   "workspace.new": "新建工作区",
@@ -747,10 +780,10 @@ export const dict = {
   "workspace.status.clean": "未检测到未合并的更改。",
   "workspace.status.dirty": "检测到未合并的更改。",
   "workspace.delete.title": "删除工作区",
-  "workspace.delete.confirm": '删除工作区 "{{name}}"?',
+  "workspace.delete.confirm": "删除工作区 \"{{name}}\"?",
   "workspace.delete.button": "删除工作区",
   "workspace.reset.title": "重置工作区",
-  "workspace.reset.confirm": '重置工作区 "{{name}}"?',
+  "workspace.reset.confirm": "重置工作区 \"{{name}}\"?",
   "workspace.reset.button": "重置工作区",
   "workspace.reset.archived.none": "不会归档任何活跃会话。",
   "workspace.reset.archived.one": "将归档 1 个会话。",

+ 33 - 0
packages/app/src/i18n/zht.ts

@@ -76,6 +76,7 @@ export const dict = {
   "command.permissions.autoaccept.enable": "自動接受編輯",
   "command.permissions.autoaccept.disable": "停止自動接受編輯",
   "command.workspace.toggle": "切換工作區",
+  "command.workspace.toggle.description": "在側邊欄啟用或停用多個工作區",
   "command.session.undo": "復原",
   "command.session.undo.description": "復原上一則訊息",
   "command.session.redo": "重做",
@@ -99,9 +100,13 @@ export const dict = {
   "dialog.provider.group.popular": "熱門",
   "dialog.provider.group.other": "其他",
   "dialog.provider.tag.recommended": "推薦",
+  "dialog.provider.opencode.note": "精選模型,包含 Claude、GPT、Gemini 等等",
   "dialog.provider.anthropic.note": "使用 Claude Pro/Max 或 API 金鑰連線",
   "dialog.provider.openai.note": "使用 ChatGPT Pro/Plus 或 API 金鑰連線",
   "dialog.provider.copilot.note": "使用 Copilot 或 API 金鑰連線",
+  "dialog.provider.google.note": "Gemini 模型,提供快速且結構化的回應",
+  "dialog.provider.openrouter.note": "從單一提供者存取所有支援的模型",
+  "dialog.provider.vercel.note": "透過智慧路由統一存取 AI 模型",
 
   "dialog.model.select.title": "選擇模型",
   "dialog.model.search.placeholder": "搜尋模型",
@@ -204,6 +209,7 @@ export const dict = {
   "model.tooltip.context": "上下文上限 {{limit}}",
   "common.search.placeholder": "搜尋",
   "common.goBack": "返回",
+  "common.goForward": "前進",
   "common.loading": "載入中",
   "common.loading.ellipsis": "...",
   "common.cancel": "取消",
@@ -362,6 +368,23 @@ export const dict = {
   "context.usage.clickToView": "點擊查看上下文",
   "context.usage.view": "檢視上下文用量",
 
+  "language.en": "English",
+  "language.zh": "简体中文",
+  "language.zht": "繁體中文",
+  "language.ko": "한국어",
+  "language.de": "Deutsch",
+  "language.es": "Español",
+  "language.fr": "Français",
+  "language.da": "Dansk",
+  "language.ja": "日本語",
+  "language.pl": "Polski",
+  "language.ru": "Русский",
+  "language.ar": "العربية",
+  "language.no": "Norsk",
+  "language.br": "Português (Brasil)",
+  "language.bs": "Bosanski",
+  "language.th": "ไทย",
+
   "toast.language.title": "語言",
   "toast.language.description": "已切換到 {{language}}",
 
@@ -482,6 +505,11 @@ export const dict = {
 
   "session.header.search.placeholder": "搜尋 {{project}}",
   "session.header.searchFiles": "搜尋檔案",
+  "session.header.openIn": "開啟於",
+  "session.header.open.action": "開啟 {{app}}",
+  "session.header.open.ariaLabel": "在 {{app}} 中開啟",
+  "session.header.open.menu": "開啟選項",
+  "session.header.open.copyPath": "複製路徑",
 
   "status.popover.trigger": "狀態",
   "status.popover.ariaLabel": "伺服器設定",
@@ -553,6 +581,7 @@ export const dict = {
   "settings.general.section.notifications": "系統通知",
   "settings.general.section.updates": "更新",
   "settings.general.section.sounds": "音效",
+  "settings.general.section.display": "顯示",
 
   "settings.general.row.language.title": "語言",
   "settings.general.row.language.description": "變更 OpenCode 的顯示語言",
@@ -563,6 +592,10 @@ export const dict = {
   "settings.general.row.font.title": "字型",
   "settings.general.row.font.description": "自訂程式碼區塊使用的等寬字型",
 
+  "settings.general.row.wayland.title": "使用原生 Wayland",
+  "settings.general.row.wayland.description": "在 Wayland 上停用 X11 後備模式。需要重新啟動。",
+  "settings.general.row.wayland.tooltip": "在混合更新率螢幕的 Linux 系統上,原生 Wayland 可能更穩定。",
+
   "settings.general.row.releaseNotes.title": "發行說明",
   "settings.general.row.releaseNotes.description": "更新後顯示「新功能」彈出視窗",