From 09a9556c70495eac0e7c8f105d69498583d9ec79 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Wed, 21 Jan 2026 05:22:51 -0600 Subject: [PATCH] feat(app): spanish translations --- packages/app/src/context/language.tsx | 10 +- packages/app/src/i18n/de.ts | 1 + packages/app/src/i18n/en.ts | 1 + packages/app/src/i18n/es.ts | 554 ++++++++++++++++++++++++++ packages/app/src/i18n/ko.ts | 1 + packages/app/src/i18n/zh.ts | 1 + packages/ui/src/i18n/es.ts | 90 +++++ 7 files changed, 656 insertions(+), 2 deletions(-) create mode 100644 packages/app/src/i18n/es.ts create mode 100644 packages/ui/src/i18n/es.ts diff --git a/packages/app/src/context/language.tsx b/packages/app/src/context/language.tsx index d2e8c077a..91b514de3 100644 --- a/packages/app/src/context/language.tsx +++ b/packages/app/src/context/language.tsx @@ -7,17 +7,19 @@ import { dict as en } from "@/i18n/en" import { dict as zh } from "@/i18n/zh" import { dict as ko } from "@/i18n/ko" import { dict as de } from "@/i18n/de" +import { dict as es } from "@/i18n/es" import { dict as uiEn } from "@opencode-ai/ui/i18n/en" import { dict as uiZh } from "@opencode-ai/ui/i18n/zh" import { dict as uiKo } from "@opencode-ai/ui/i18n/ko" import { dict as uiDe } from "@opencode-ai/ui/i18n/de" +import { dict as uiEs } from "@opencode-ai/ui/i18n/es" -export type Locale = "en" | "zh" | "ko" | "de" +export type Locale = "en" | "zh" | "ko" | "de" | "es" type RawDictionary = typeof en & typeof uiEn type Dictionary = i18n.Flatten -const LOCALES: readonly Locale[] = ["en", "zh", "ko", "de"] +const LOCALES: readonly Locale[] = ["en", "zh", "ko", "de", "es"] function detectLocale(): Locale { if (typeof navigator !== "object") return "en" @@ -28,6 +30,7 @@ function detectLocale(): Locale { if (language.toLowerCase().startsWith("zh")) return "zh" if (language.toLowerCase().startsWith("ko")) return "ko" if (language.toLowerCase().startsWith("de")) return "de" + if (language.toLowerCase().startsWith("es")) return "es" } return "en" @@ -47,6 +50,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont if (store.locale === "zh") return "zh" if (store.locale === "ko") return "ko" if (store.locale === "de") return "de" + if (store.locale === "es") return "es" return "en" }) @@ -61,6 +65,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont if (locale() === "en") return base if (locale() === "zh") return { ...base, ...i18n.flatten({ ...zh, ...uiZh }) } if (locale() === "de") return { ...base, ...i18n.flatten({ ...de, ...uiDe }) } + if (locale() === "es") return { ...base, ...i18n.flatten({ ...es, ...uiEs }) } return { ...base, ...i18n.flatten({ ...ko, ...uiKo }) } }) @@ -71,6 +76,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont zh: "language.zh", ko: "language.ko", de: "language.de", + es: "language.es", } const label = (value: Locale) => t(labelKey[value]) diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index dce6a3673..ebb45f967 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -276,6 +276,7 @@ export const dict = { "language.zh": "Chinesisch", "language.ko": "Koreanisch", "language.de": "Deutsch", + "language.es": "Spanisch", "toast.language.title": "Sprache", "toast.language.description": "Zu {{language}} gewechselt", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index e2635ca17..6a020eeab 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -270,6 +270,7 @@ export const dict = { "language.zh": "Chinese", "language.ko": "Korean", "language.de": "German", + "language.es": "Spanish", "toast.language.title": "Language", "toast.language.description": "Switched to {{language}}", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts new file mode 100644 index 000000000..d5fef0487 --- /dev/null +++ b/packages/app/src/i18n/es.ts @@ -0,0 +1,554 @@ +export const dict = { + "command.category.suggested": "Sugerido", + "command.category.view": "Ver", + "command.category.project": "Proyecto", + "command.category.provider": "Proveedor", + "command.category.server": "Servidor", + "command.category.session": "Sesión", + "command.category.theme": "Tema", + "command.category.language": "Idioma", + "command.category.file": "Archivo", + "command.category.terminal": "Terminal", + "command.category.model": "Modelo", + "command.category.mcp": "MCP", + "command.category.agent": "Agente", + "command.category.permissions": "Permisos", + + "theme.scheme.system": "Sistema", + "theme.scheme.light": "Claro", + "theme.scheme.dark": "Oscuro", + + "command.sidebar.toggle": "Alternar barra lateral", + "command.project.open": "Abrir proyecto", + "command.provider.connect": "Conectar proveedor", + "command.server.switch": "Cambiar servidor", + "command.session.previous": "Sesión anterior", + "command.session.next": "Siguiente sesión", + "command.session.archive": "Archivar sesión", + + "command.palette": "Paleta de comandos", + + "command.theme.cycle": "Alternar tema", + "command.theme.set": "Usar tema: {{theme}}", + "command.theme.scheme.cycle": "Alternar esquema de color", + "command.theme.scheme.set": "Usar esquema de color: {{scheme}}", + + "command.language.cycle": "Alternar idioma", + "command.language.set": "Usar idioma: {{language}}", + + "command.session.new": "Nueva sesión", + "command.file.open": "Abrir archivo", + "command.file.open.description": "Buscar archivos y comandos", + "command.terminal.toggle": "Alternar terminal", + "command.review.toggle": "Alternar revisión", + "command.terminal.new": "Nueva terminal", + "command.terminal.new.description": "Crear una nueva pestaña de terminal", + "command.steps.toggle": "Alternar pasos", + "command.steps.toggle.description": "Mostrar u ocultar pasos para el mensaje actual", + "command.message.previous": "Mensaje anterior", + "command.message.previous.description": "Ir al mensaje de usuario anterior", + "command.message.next": "Siguiente mensaje", + "command.message.next.description": "Ir al siguiente mensaje de usuario", + "command.model.choose": "Elegir modelo", + "command.model.choose.description": "Seleccionar un modelo diferente", + "command.mcp.toggle": "Alternar MCPs", + "command.mcp.toggle.description": "Alternar MCPs", + "command.agent.cycle": "Alternar agente", + "command.agent.cycle.description": "Cambiar al siguiente agente", + "command.agent.cycle.reverse": "Alternar agente hacia atrás", + "command.agent.cycle.reverse.description": "Cambiar al agente anterior", + "command.model.variant.cycle": "Alternar esfuerzo de pensamiento", + "command.model.variant.cycle.description": "Cambiar al siguiente nivel de esfuerzo", + "command.permissions.autoaccept.enable": "Aceptar ediciones automáticamente", + "command.permissions.autoaccept.disable": "Dejar de aceptar ediciones automáticamente", + "command.session.undo": "Deshacer", + "command.session.undo.description": "Deshacer el último mensaje", + "command.session.redo": "Rehacer", + "command.session.redo.description": "Rehacer el último mensaje deshecho", + "command.session.compact": "Compactar sesión", + "command.session.compact.description": "Resumir la sesión para reducir el tamaño del contexto", + "command.session.fork": "Bifurcar desde mensaje", + "command.session.fork.description": "Crear una nueva sesión desde un mensaje anterior", + "command.session.share": "Compartir sesión", + "command.session.share.description": "Compartir esta sesión y copiar la URL al portapapeles", + "command.session.unshare": "Dejar de compartir sesión", + "command.session.unshare.description": "Dejar de compartir esta sesión", + + "palette.search.placeholder": "Buscar archivos y comandos", + "palette.empty": "No se encontraron resultados", + "palette.group.commands": "Comandos", + "palette.group.files": "Archivos", + + "dialog.provider.search.placeholder": "Buscar proveedores", + "dialog.provider.empty": "No se encontraron proveedores", + "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.model.select.title": "Seleccionar modelo", + "dialog.model.search.placeholder": "Buscar modelos", + "dialog.model.empty": "Sin resultados de modelos", + "dialog.model.manage": "Gestionar modelos", + "dialog.model.manage.description": "Personalizar qué modelos aparecen en el selector de modelos.", + + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por OpenCode", + "dialog.model.unpaid.addMore.title": "Añadir más modelos de proveedores populares", + + "dialog.provider.viewAll": "Ver todos los proveedores", + + "provider.connect.title": "Conectar {{provider}}", + "provider.connect.title.anthropicProMax": "Iniciar sesión con Claude Pro/Max", + "provider.connect.selectMethod": "Seleccionar método de inicio de sesión para {{provider}}.", + "provider.connect.method.apiKey": "Clave API", + "provider.connect.status.inProgress": "Autorización en progreso...", + "provider.connect.status.waiting": "Esperando autorización...", + "provider.connect.status.failed": "Autorización fallida: {{error}}", + "provider.connect.apiKey.description": + "Introduce tu clave API de {{provider}} para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + "provider.connect.apiKey.label": "Clave API de {{provider}}", + "provider.connect.apiKey.placeholder": "Clave API", + "provider.connect.apiKey.required": "La clave API es obligatoria", + "provider.connect.opencodeZen.line1": + "OpenCode Zen te da acceso a un conjunto curado de modelos fiables optimizados para agentes de programación.", + "provider.connect.opencodeZen.line2": + "Con una sola clave API obtendrás acceso a modelos como Claude, GPT, Gemini, GLM y más.", + "provider.connect.opencodeZen.visit.prefix": "Visita ", + "provider.connect.opencodeZen.visit.suffix": " para obtener tu clave API.", + "provider.connect.oauth.code.visit.prefix": "Visita ", + "provider.connect.oauth.code.visit.link": "este enlace", + "provider.connect.oauth.code.visit.suffix": + " para obtener tu código de autorización para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + "provider.connect.oauth.code.label": "Código de autorización {{method}}", + "provider.connect.oauth.code.placeholder": "Código de autorización", + "provider.connect.oauth.code.required": "El código de autorización es obligatorio", + "provider.connect.oauth.code.invalid": "Código de autorización inválido", + "provider.connect.oauth.auto.visit.prefix": "Visita ", + "provider.connect.oauth.auto.visit.link": "este enlace", + "provider.connect.oauth.auto.visit.suffix": + " e introduce el código a continuación para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + "provider.connect.oauth.auto.confirmationCode": "Código de confirmación", + "provider.connect.toast.connected.title": "{{provider}} conectado", + "provider.connect.toast.connected.description": "Los modelos de {{provider}} ahora están disponibles para usar.", + + "model.tag.free": "Gratis", + "model.tag.latest": "Último", + + "common.search.placeholder": "Buscar", + "common.loading": "Cargando", + "common.cancel": "Cancelar", + "common.submit": "Enviar", + "common.save": "Guardar", + "common.saving": "Guardando...", + "common.default": "Predeterminado", + "common.attachment": "adjunto", + + "prompt.placeholder.shell": "Introduce comando de shell...", + "prompt.placeholder.normal": 'Pregunta cualquier cosa... "{{example}}"', + "prompt.mode.shell": "Shell", + "prompt.mode.shell.exit": "esc para salir", + + "prompt.example.1": "Arreglar un TODO en el código", + "prompt.example.2": "¿Cuál es el stack tecnológico de este proyecto?", + "prompt.example.3": "Arreglar pruebas rotas", + "prompt.example.4": "Explicar cómo funciona la autenticación", + "prompt.example.5": "Encontrar y arreglar vulnerabilidades de seguridad", + "prompt.example.6": "Añadir pruebas unitarias para el servicio de usuario", + "prompt.example.7": "Refactorizar esta función para que sea más legible", + "prompt.example.8": "¿Qué significa este error?", + "prompt.example.9": "Ayúdame a depurar este problema", + "prompt.example.10": "Generar documentación de API", + "prompt.example.11": "Optimizar consultas a la base de datos", + "prompt.example.12": "Añadir validación de entrada", + "prompt.example.13": "Crear un nuevo componente para...", + "prompt.example.14": "¿Cómo despliego este proyecto?", + "prompt.example.15": "Revisar mi código para mejores prácticas", + "prompt.example.16": "Añadir manejo de errores a esta función", + "prompt.example.17": "Explicar este patrón de regex", + "prompt.example.18": "Convertir esto a TypeScript", + "prompt.example.19": "Añadir logging en todo el código", + "prompt.example.20": "¿Qué dependencias están desactualizadas?", + "prompt.example.21": "Ayúdame a escribir un script de migración", + "prompt.example.22": "Implementar caché para este endpoint", + "prompt.example.23": "Añadir paginación a esta lista", + "prompt.example.24": "Crear un comando CLI para...", + "prompt.example.25": "¿Cómo funcionan las variables de entorno aquí?", + + "prompt.popover.emptyResults": "Sin resultados coincidentes", + "prompt.popover.emptyCommands": "Sin comandos coincidentes", + "prompt.dropzone.label": "Suelta imágenes o PDFs aquí", + "prompt.slash.badge.custom": "personalizado", + "prompt.context.active": "activo", + "prompt.context.includeActiveFile": "Incluir archivo activo", + "prompt.action.attachFile": "Adjuntar archivo", + "prompt.action.send": "Enviar", + "prompt.action.stop": "Detener", + + "prompt.toast.pasteUnsupported.title": "Pegado no soportado", + "prompt.toast.pasteUnsupported.description": "Solo se pueden pegar imágenes o PDFs aquí.", + "prompt.toast.modelAgentRequired.title": "Selecciona un agente y modelo", + "prompt.toast.modelAgentRequired.description": "Elige un agente y modelo antes de enviar un prompt.", + "prompt.toast.worktreeCreateFailed.title": "Fallo al crear el árbol de trabajo", + "prompt.toast.sessionCreateFailed.title": "Fallo al crear la sesión", + "prompt.toast.shellSendFailed.title": "Fallo al enviar comando de shell", + "prompt.toast.commandSendFailed.title": "Fallo al enviar comando", + "prompt.toast.promptSendFailed.title": "Fallo al enviar prompt", + + "dialog.mcp.title": "MCPs", + "dialog.mcp.description": "{{enabled}} de {{total}} habilitados", + "dialog.mcp.empty": "No hay MCPs configurados", + + "mcp.status.connected": "conectado", + "mcp.status.failed": "fallido", + "mcp.status.needs_auth": "necesita auth", + "mcp.status.disabled": "deshabilitado", + + "dialog.fork.empty": "No hay mensajes desde donde bifurcar", + + "dialog.directory.search.placeholder": "Buscar carpetas", + "dialog.directory.empty": "No se encontraron carpetas", + + "dialog.server.title": "Servidores", + "dialog.server.description": "Cambiar a qué servidor de OpenCode se conecta esta app.", + "dialog.server.search.placeholder": "Buscar servidores", + "dialog.server.empty": "No hay servidores aún", + "dialog.server.add.title": "Añadir un servidor", + "dialog.server.add.url": "URL del servidor", + "dialog.server.add.placeholder": "http://localhost:4096", + "dialog.server.add.error": "No se pudo conectar al servidor", + "dialog.server.add.checking": "Comprobando...", + "dialog.server.add.button": "Añadir", + "dialog.server.default.title": "Servidor predeterminado", + "dialog.server.default.description": + "Conectar a este servidor al iniciar la app en lugar de iniciar un servidor local. Requiere reinicio.", + "dialog.server.default.none": "Ningún servidor seleccionado", + "dialog.server.default.set": "Establecer servidor actual como predeterminado", + "dialog.server.default.clear": "Limpiar", + + "dialog.project.edit.title": "Editar proyecto", + "dialog.project.edit.name": "Nombre", + "dialog.project.edit.icon": "Icono", + "dialog.project.edit.icon.alt": "Icono del proyecto", + "dialog.project.edit.icon.hint": "Haz clic o arrastra una imagen", + "dialog.project.edit.icon.recommended": "Recomendado: 128x128px", + "dialog.project.edit.color": "Color", + + "context.breakdown.title": "Desglose de Contexto", + "context.breakdown.note": + 'Desglose aproximado de tokens de entrada. "Otro" incluye definiciones de herramientas y sobrecarga.', + "context.breakdown.system": "Sistema", + "context.breakdown.user": "Usuario", + "context.breakdown.assistant": "Asistente", + "context.breakdown.tool": "Llamadas a herramientas", + "context.breakdown.other": "Otro", + + "context.systemPrompt.title": "Prompt del Sistema", + "context.rawMessages.title": "Mensajes en bruto", + + "context.stats.session": "Sesión", + "context.stats.messages": "Mensajes", + "context.stats.provider": "Proveedor", + "context.stats.model": "Modelo", + "context.stats.limit": "Límite de Contexto", + "context.stats.totalTokens": "Tokens Totales", + "context.stats.usage": "Uso", + "context.stats.inputTokens": "Tokens de Entrada", + "context.stats.outputTokens": "Tokens de Salida", + "context.stats.reasoningTokens": "Tokens de Razonamiento", + "context.stats.cacheTokens": "Tokens de Caché (lectura/escritura)", + "context.stats.userMessages": "Mensajes de Usuario", + "context.stats.assistantMessages": "Mensajes de Asistente", + "context.stats.totalCost": "Costo Total", + "context.stats.sessionCreated": "Sesión Creada", + "context.stats.lastActivity": "Última Actividad", + + "context.usage.tokens": "Tokens", + "context.usage.usage": "Uso", + "context.usage.cost": "Costo", + "context.usage.clickToView": "Haz clic para ver contexto", + + "language.en": "Inglés", + "language.zh": "Chino", + "language.ko": "Coreano", + "language.de": "Alemán", + "language.es": "Español", + + "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.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.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!", + "toast.session.share.failed.title": "Fallo al compartir sesión", + "toast.session.share.failed.description": "Ocurrió un error al compartir la sesión", + + "toast.session.unshare.success.title": "Sesión dejó de compartirse", + "toast.session.unshare.success.description": "¡La sesión dejó de compartirse exitosamente!", + "toast.session.unshare.failed.title": "Fallo al dejar de compartir sesión", + "toast.session.unshare.failed.description": "Ocurrió un error al dejar de compartir la sesión", + + "toast.session.listFailed.title": "Fallo al cargar sesiones para {{project}}", + + "toast.update.title": "Actualización disponible", + "toast.update.description": "Una nueva versión de OpenCode ({{version}}) está disponible para instalar.", + "toast.update.action.installRestart": "Instalar y reiniciar", + "toast.update.action.notYet": "Todavía no", + + "error.page.title": "Algo salió mal", + "error.page.description": "Ocurrió un error al cargar la aplicación.", + "error.page.details.label": "Detalles del error", + "error.page.action.restart": "Reiniciar", + "error.page.action.checking": "Comprobando...", + "error.page.action.checkUpdates": "Buscar actualizaciones", + "error.page.action.updateTo": "Actualizar a {{version}}", + "error.page.report.prefix": "Por favor reporta este error al equipo de OpenCode", + "error.page.report.discord": "en Discord", + "error.page.version": "Versión: {{version}}", + + "error.dev.rootNotFound": + "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}}`?", + + "error.chain.unknown": "Error desconocido", + "error.chain.causedBy": "Causado por:", + "error.chain.apiError": "Error de API", + "error.chain.status": "Estado: {{status}}", + "error.chain.retryable": "Reintentable: {{retryable}}", + "error.chain.responseBody": "Cuerpo de la respuesta:\n{{body}}", + "error.chain.didYouMean": "¿Quisiste decir: {{suggestions}}", + "error.chain.modelNotFound": "Modelo no encontrado: {{provider}}/{{model}}", + "error.chain.checkConfig": "Comprueba los nombres de proveedor/modelo en tu configuración (opencode.json)", + "error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, OpenCode no soporta autenticación MCP todavía.', + "error.chain.providerAuthFailed": "Autenticación de proveedor fallida ({{provider}}): {{message}}", + "error.chain.providerInitFailed": + 'Fallo al inicializar proveedor "{{provider}}". Comprueba credenciales y configuración.', + "error.chain.configJsonInvalid": "El archivo de configuración en {{path}} no es un JSON(C) válido", + "error.chain.configJsonInvalidWithMessage": + "El archivo de configuración en {{path}} no es un JSON(C) válido: {{message}}", + "error.chain.configDirectoryTypo": + 'El directorio "{{dir}}" en {{path}} no es válido. Renombra el directorio a "{{suggestion}}" o elimínalo. Esto es un error tipográfico común.', + "error.chain.configFrontmatterError": "Fallo al analizar frontmatter en {{path}}:\n{{message}}", + "error.chain.configInvalid": "El archivo de configuración en {{path}} es inválido", + "error.chain.configInvalidWithMessage": "El archivo de configuración en {{path}} es inválido: {{message}}", + + "notification.permission.title": "Permiso requerido", + "notification.permission.description": "{{sessionTitle}} en {{projectName}} necesita permiso", + "notification.question.title": "Pregunta", + "notification.question.description": "{{sessionTitle}} en {{projectName}} tiene una pregunta", + "notification.action.goToSession": "Ir a sesión", + + "notification.session.responseReady.title": "Respuesta lista", + "notification.session.error.title": "Error de sesión", + "notification.session.error.fallbackDescription": "Ocurrió un error", + + "home.recentProjects": "Proyectos recientes", + "home.empty.title": "Sin proyectos recientes", + "home.empty.description": "Empieza abriendo un proyecto local", + + "session.tab.session": "Sesión", + "session.tab.review": "Revisión", + "session.tab.context": "Contexto", + "session.review.filesChanged": "{{count}} Archivos Cambiados", + "session.review.loadingChanges": "Cargando cambios...", + "session.review.empty": "No hay cambios en esta sesión aún", + "session.messages.renderEarlier": "Renderizar mensajes anteriores", + "session.messages.loadingEarlier": "Cargando mensajes anteriores...", + "session.messages.loadEarlier": "Cargar mensajes anteriores", + "session.messages.loading": "Cargando mensajes...", + + "session.context.addToContext": "Añadir {{selection}} al contexto", + + "session.new.worktree.main": "Rama principal", + "session.new.worktree.mainWithBranch": "Rama principal ({{branch}})", + "session.new.worktree.create": "Crear nuevo árbol de trabajo", + "session.new.lastModified": "Última modificación", + + "session.header.search.placeholder": "Buscar {{project}}", + + "session.share.popover.title": "Publicar en web", + "session.share.popover.description.shared": + "Esta sesión es pública en la web. Es accesible para cualquiera con el enlace.", + "session.share.popover.description.unshared": + "Compartir sesión públicamente en la web. Será accesible para cualquiera con el enlace.", + "session.share.action.share": "Compartir", + "session.share.action.publish": "Publicar", + "session.share.action.publishing": "Publicando...", + "session.share.action.unpublish": "Despublicar", + "session.share.action.unpublishing": "Despublicando...", + "session.share.action.view": "Ver", + "session.share.copy.copied": "Copiado", + "session.share.copy.copyLink": "Copiar enlace", + + "lsp.tooltip.none": "Sin servidores LSP", + "lsp.label.connected": "{{count}} LSP", + + "prompt.loading": "Cargando prompt...", + "terminal.loading": "Cargando terminal...", + "terminal.title": "Terminal", + "terminal.title.numbered": "Terminal {{number}}", + + "common.closeTab": "Cerrar pestaña", + "common.dismiss": "Descartar", + "common.requestFailed": "Solicitud fallida", + "common.moreOptions": "Más opciones", + "common.learnMore": "Saber más", + "common.rename": "Renombrar", + "common.reset": "Restablecer", + "common.delete": "Eliminar", + "common.close": "Cerrar", + "common.edit": "Editar", + "common.loadMore": "Cargar más", + + "sidebar.settings": "Ajustes", + "sidebar.help": "Ayuda", + "sidebar.workspaces.enable": "Habilitar espacios de trabajo", + "sidebar.workspaces.disable": "Deshabilitar espacios de trabajo", + "sidebar.gettingStarted.title": "Empezando", + "sidebar.gettingStarted.line1": "OpenCode incluye modelos gratuitos para que puedas empezar inmediatamente.", + "sidebar.gettingStarted.line2": "Conecta cualquier proveedor para usar modelos, inc. Claude, GPT, Gemini etc.", + "sidebar.project.recentSessions": "Sesiones recientes", + "sidebar.project.viewAllSessions": "Ver todas las sesiones", + + "settings.section.desktop": "Escritorio", + "settings.tab.general": "General", + "settings.tab.shortcuts": "Atajos", + + "settings.general.section.appearance": "Apariencia", + "settings.general.section.notifications": "Notificaciones del sistema", + "settings.general.section.sounds": "Efectos de sonido", + + "settings.general.row.language.title": "Idioma", + "settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode", + "settings.general.row.appearance.title": "Apariencia", + "settings.general.row.appearance.description": "Personaliza cómo se ve OpenCode en tu dispositivo", + "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.notifications.agent.title": "Agente", + "settings.general.notifications.agent.description": + "Mostrar notificación del sistema cuando el agente termine o necesite atención", + "settings.general.notifications.permissions.title": "Permisos", + "settings.general.notifications.permissions.description": + "Mostrar notificación del sistema cuando se requiera un permiso", + "settings.general.notifications.errors.title": "Errores", + "settings.general.notifications.errors.description": "Mostrar notificación del sistema cuando ocurra un error", + + "settings.general.sounds.agent.title": "Agente", + "settings.general.sounds.agent.description": "Reproducir sonido cuando el agente termine o necesite atención", + "settings.general.sounds.permissions.title": "Permisos", + "settings.general.sounds.permissions.description": "Reproducir sonido cuando se requiera un permiso", + "settings.general.sounds.errors.title": "Errores", + "settings.general.sounds.errors.description": "Reproducir sonido cuando ocurra un error", + + "settings.shortcuts.title": "Atajos de teclado", + "settings.shortcuts.reset.button": "Restablecer a valores predeterminados", + "settings.shortcuts.reset.toast.title": "Atajos restablecidos", + "settings.shortcuts.reset.toast.description": + "Los atajos de teclado han sido restablecidos a los valores predeterminados.", + "settings.shortcuts.conflict.title": "Atajo ya en uso", + "settings.shortcuts.conflict.description": "{{keybind}} ya está asignado a {{titles}}.", + "settings.shortcuts.unassigned": "Sin asignar", + "settings.shortcuts.pressKeys": "Presiona teclas", + + "settings.shortcuts.group.general": "General", + "settings.shortcuts.group.session": "Sesión", + "settings.shortcuts.group.navigation": "Navegación", + "settings.shortcuts.group.modelAndAgent": "Modelo y agente", + "settings.shortcuts.group.terminal": "Terminal", + "settings.shortcuts.group.prompt": "Prompt", + + "settings.providers.title": "Proveedores", + "settings.providers.description": "La configuración de proveedores estará disponible aquí.", + "settings.models.title": "Modelos", + "settings.models.description": "La configuración de modelos estará disponible aquí.", + "settings.agents.title": "Agentes", + "settings.agents.description": "La configuración de agentes estará disponible aquí.", + "settings.commands.title": "Comandos", + "settings.commands.description": "La configuración de comandos estará disponible aquí.", + "settings.mcp.title": "MCP", + "settings.mcp.description": "La configuración de MCP estará disponible aquí.", + + "settings.permissions.title": "Permisos", + "settings.permissions.description": "Controla qué herramientas puede usar el servidor por defecto.", + "settings.permissions.section.tools": "Herramientas", + "settings.permissions.toast.updateFailed.title": "Fallo al actualizar permisos", + + "settings.permissions.action.allow": "Permitir", + "settings.permissions.action.ask": "Preguntar", + "settings.permissions.action.deny": "Denegar", + + "settings.permissions.tool.read.title": "Leer", + "settings.permissions.tool.read.description": "Leer un archivo (coincide con la ruta del archivo)", + "settings.permissions.tool.edit.title": "Editar", + "settings.permissions.tool.edit.description": + "Modificar archivos, incluyendo ediciones, escrituras, parches y multi-ediciones", + "settings.permissions.tool.glob.title": "Glob", + "settings.permissions.tool.glob.description": "Coincidir archivos usando patrones glob", + "settings.permissions.tool.grep.title": "Grep", + "settings.permissions.tool.grep.description": "Buscar contenidos de archivo usando expresiones regulares", + "settings.permissions.tool.list.title": "Listar", + "settings.permissions.tool.list.description": "Listar archivos dentro de un directorio", + "settings.permissions.tool.bash.title": "Bash", + "settings.permissions.tool.bash.description": "Ejecutar comandos de shell", + "settings.permissions.tool.task.title": "Tarea", + "settings.permissions.tool.task.description": "Lanzar sub-agentes", + "settings.permissions.tool.skill.title": "Habilidad", + "settings.permissions.tool.skill.description": "Cargar una habilidad por nombre", + "settings.permissions.tool.lsp.title": "LSP", + "settings.permissions.tool.lsp.description": "Ejecutar consultas de servidor de lenguaje", + "settings.permissions.tool.todoread.title": "Leer Todo", + "settings.permissions.tool.todoread.description": "Leer la lista de tareas", + "settings.permissions.tool.todowrite.title": "Escribir Todo", + "settings.permissions.tool.todowrite.description": "Actualizar la lista de tareas", + "settings.permissions.tool.webfetch.title": "Web Fetch", + "settings.permissions.tool.webfetch.description": "Obtener contenido de una URL", + "settings.permissions.tool.websearch.title": "Búsqueda Web", + "settings.permissions.tool.websearch.description": "Buscar en la web", + "settings.permissions.tool.codesearch.title": "Búsqueda de Código", + "settings.permissions.tool.codesearch.description": "Buscar código en la web", + "settings.permissions.tool.external_directory.title": "Directorio Externo", + "settings.permissions.tool.external_directory.description": "Acceder a archivos fuera del directorio del proyecto", + "settings.permissions.tool.doom_loop.title": "Bucle Infinito", + "settings.permissions.tool.doom_loop.description": "Detectar llamadas a herramientas repetidas con entrada idéntica", + + "workspace.new": "Nuevo espacio de trabajo", + "workspace.type.local": "local", + "workspace.type.sandbox": "sandbox", + "workspace.create.failed.title": "Fallo al crear espacio de trabajo", + "workspace.delete.failed.title": "Fallo al eliminar espacio de trabajo", + "workspace.resetting.title": "Restableciendo espacio de trabajo", + "workspace.resetting.description": "Esto puede tomar un minuto.", + "workspace.reset.failed.title": "Fallo al restablecer espacio de trabajo", + "workspace.reset.success.title": "Espacio de trabajo restablecido", + "workspace.reset.success.description": "El espacio de trabajo ahora coincide con la rama predeterminada.", + "workspace.status.checking": "Comprobando cambios no fusionados...", + "workspace.status.error": "No se pudo verificar el estado de git.", + "workspace.status.clean": "No se detectaron cambios no fusionados.", + "workspace.status.dirty": "Cambios no fusionados detectados en este espacio de trabajo.", + "workspace.delete.title": "Eliminar espacio de trabajo", + "workspace.delete.confirm": '¿Eliminar espacio de trabajo "{{name}}"?', + "workspace.delete.button": "Eliminar espacio de trabajo", + "workspace.reset.title": "Restablecer espacio de trabajo", + "workspace.reset.confirm": '¿Restablecer espacio de trabajo "{{name}}"?', + "workspace.reset.button": "Restablecer espacio de trabajo", + "workspace.reset.archived.none": "No se archivarán sesiones activas.", + "workspace.reset.archived.one": "1 sesión será archivada.", + "workspace.reset.archived.many": "{{count}} sesiones serán archivadas.", + "workspace.reset.note": "Esto restablecerá el espacio de trabajo para coincidir con la rama predeterminada.", +} diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 65ebd7b35..87be2871f 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -273,6 +273,7 @@ export const dict = { "language.zh": "중국어", "language.ko": "한국어", "language.de": "독일어", + "language.es": "스페인어", "toast.language.title": "언어", "toast.language.description": "{{language}}(으)로 전환됨", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 0b1615ce1..3c557ae8e 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -269,6 +269,7 @@ export const dict = { "language.zh": "中文", "language.ko": "韩语", "language.de": "德语", + "language.es": "西班牙语", "toast.language.title": "语言", "toast.language.description": "已切换到{{language}}", diff --git a/packages/ui/src/i18n/es.ts b/packages/ui/src/i18n/es.ts new file mode 100644 index 000000000..4d80bc988 --- /dev/null +++ b/packages/ui/src/i18n/es.ts @@ -0,0 +1,90 @@ +export const dict = { + "ui.sessionReview.title": "Cambios de la sesión", + "ui.sessionReview.diffStyle.unified": "Unificado", + "ui.sessionReview.diffStyle.split": "Dividido", + "ui.sessionReview.expandAll": "Expandir todo", + "ui.sessionReview.collapseAll": "Colapsar todo", + + "ui.sessionTurn.steps.show": "Mostrar pasos", + "ui.sessionTurn.steps.hide": "Ocultar pasos", + "ui.sessionTurn.summary.response": "Respuesta", + "ui.sessionTurn.diff.showMore": "Mostrar más cambios ({{count}})", + + "ui.sessionTurn.retry.retrying": "reintentando", + "ui.sessionTurn.retry.inSeconds": "en {{seconds}}s", + + "ui.sessionTurn.status.delegating": "Delegando trabajo", + "ui.sessionTurn.status.planning": "Planificando siguientes pasos", + "ui.sessionTurn.status.gatheringContext": "Recopilando contexto", + "ui.sessionTurn.status.searchingCodebase": "Buscando en la base de código", + "ui.sessionTurn.status.searchingWeb": "Buscando en la web", + "ui.sessionTurn.status.makingEdits": "Realizando ediciones", + "ui.sessionTurn.status.runningCommands": "Ejecutando comandos", + "ui.sessionTurn.status.thinking": "Pensando", + "ui.sessionTurn.status.thinkingWithTopic": "Pensando - {{topic}}", + "ui.sessionTurn.status.gatheringThoughts": "Recopilando pensamientos", + "ui.sessionTurn.status.consideringNextSteps": "Considerando siguientes pasos", + + "ui.messagePart.diagnostic.error": "Error", + "ui.messagePart.title.edit": "Editar", + "ui.messagePart.title.write": "Escribir", + "ui.messagePart.option.typeOwnAnswer": "Escribe tu propia respuesta", + "ui.messagePart.review.title": "Revisa tus respuestas", + + "ui.list.loading": "Cargando", + "ui.list.empty": "Sin resultados", + "ui.list.emptyWithFilter.prefix": "Sin resultados para", + "ui.list.emptyWithFilter.suffix": "", + + "ui.messageNav.newMessage": "Nuevo mensaje", + + "ui.textField.copyToClipboard": "Copiar al portapapeles", + "ui.textField.copied": "Copiado", + + "ui.imagePreview.alt": "Vista previa de imagen", + + "ui.tool.read": "Leer", + "ui.tool.list": "Listar", + "ui.tool.glob": "Glob", + "ui.tool.grep": "Grep", + "ui.tool.webfetch": "Webfetch", + "ui.tool.shell": "Shell", + "ui.tool.patch": "Parche", + "ui.tool.todos": "Tareas", + "ui.tool.todos.read": "Leer tareas", + "ui.tool.questions": "Preguntas", + "ui.tool.agent": "Agente {{type}}", + + "ui.common.file.one": "archivo", + "ui.common.file.other": "archivos", + "ui.common.question.one": "pregunta", + "ui.common.question.other": "preguntas", + + "ui.common.add": "Añadir", + "ui.common.cancel": "Cancelar", + "ui.common.confirm": "Confirmar", + "ui.common.dismiss": "Descartar", + "ui.common.next": "Siguiente", + "ui.common.submit": "Enviar", + + "ui.permission.deny": "Denegar", + "ui.permission.allowAlways": "Permitir siempre", + "ui.permission.allowOnce": "Permitir una vez", + + "ui.message.expand": "Expandir mensaje", + "ui.message.collapse": "Colapsar mensaje", + "ui.message.copy": "Copiar", + "ui.message.copied": "¡Copiado!", + "ui.message.attachment.alt": "adjunto", + + "ui.patch.action.deleted": "Eliminado", + "ui.patch.action.created": "Creado", + "ui.patch.action.moved": "Movido", + "ui.patch.action.patched": "Parcheado", + + "ui.question.subtitle.answered": "{{count}} respondidas", + "ui.question.answer.none": "(sin respuesta)", + "ui.question.review.notAnswered": "(no respondida)", + "ui.question.multiHint": "(selecciona todas las que correspondan)", + "ui.question.custom.placeholder": "Escribe tu respuesta...", +}