export default { // Login login: { title: 'Hermes Web UI', description: 'Introduce tu nombre de usuario y contrasena para continuar.', placeholder: 'Token de acceso', submit: 'Iniciar sesion', tokenRequired: 'Por favor, introduce tu token de acceso', invalidToken: 'Token invalido', connectionFailed: 'No se puede conectar al servidor', passwordLogin: 'Contrasena', tokenLogin: 'Token', usernamePlaceholder: 'Nombre de usuario', passwordPlaceholder: 'Contrasena', defaultCredentialsHint: 'Nombre de usuario predeterminado: admin. Contrasena predeterminada: 123456.', credentialsRequired: 'Por favor, introduzca nombre de usuario y contrasena', invalidCredentials: 'Nombre de usuario o contrasena incorrectos', tooManyAttempts: 'Demasiados intentos fallidos, por favor intente mas tarde', lockResetHint: 'Si este es su servidor, borre el bloqueo de inicio de sesion con:', defaultLoginResetHint: 'Para restablecer la contrasena admin predeterminada, ejecute:', sessionExpired: 'La sesion expiro. Inicia sesion de nuevo.', accessDenied: 'No tienes permiso para acceder a este recurso.', passwordMismatch: 'Las contrasenas no coinciden', passwordTooShort: 'La contrasena debe tener al menos 6 caracteres', setupSuccess: 'Login con contrasena configurado correctamente', passwordChanged: 'Contrasena cambiada correctamente', passwordRemoved: 'Login con contrasena eliminado', setupPassword: 'Configurar login con contrasena', changePassword: 'Cambiar contrasena', changeUsername: 'Cambiar nombre de usuario', removePasswordLogin: 'Eliminar', username: 'Nombre de usuario', currentPassword: 'Contrasena actual', newPassword: 'Nueva contrasena', confirmPassword: 'Confirmar contrasena', newUsername: 'Nuevo nombre de usuario', usernameChanged: 'Nombre de usuario cambiado correctamente', usernameTooShort: 'El nombre de usuario debe tener al menos 2 caracteres', setupDescription: 'Administra el nombre de usuario y la contrasena usados para iniciar sesion.', removeConfirm: 'El login con contrasena es obligatorio para las cuentas de usuario.', passwordLoginNotConfigured: 'Login con contrasena no configurado', passwordLoginConfigured: 'Cuenta actual: {username}', defaultCredentialTitle: 'Cambia la cuenta y contrasena predeterminadas', defaultCredentialMessage: 'La cuenta actual aun usa el nombre de usuario o la contrasena predeterminados. Para evitar accesos no autorizados, cambia cuanto antes el nombre de usuario y la contrasena de la cuenta actual.', defaultCredentialAction: 'Cambiar ahora', defaultCredentialLater: 'Recordar mas tarde', }, users: { title: 'Gestion de cuentas', description: 'Crea usuarios, asigna roles y controla que perfiles pueden usar los administradores normales.', create: 'Crear usuario', edit: 'Editar usuario', username: 'Nombre de usuario', role: 'Rol', statusLabel: 'Estado', profiles: 'Perfiles accesibles', profilesPlaceholder: 'Selecciona perfiles accesibles', allProfiles: 'Todos los perfiles', noProfiles: 'Sin perfiles asignados', lastLogin: 'Ultimo inicio', newPasswordOptional: 'Nueva contrasena (dejar vacio para conservar)', loadFailed: 'No se pudieron cargar los usuarios', deleteConfirm: 'Eliminar este usuario?', enable: 'Activar', disable: 'Desactivar', roles: { superAdmin: 'Super admin', admin: 'Admin', }, status: { active: 'Activo', disabled: 'Desactivado', }, }, // Common common: { loading: 'Cargando...', cancel: 'Cancelar', retry: 'Reintentar', delete: 'Eliminar', edit: 'Editar', save: 'Guardar', saved: 'Guardado', update: 'Actualizar', create: 'Crear', saveFailed: 'Error al guardar', deleteFailed: 'Error al eliminar', ok: 'OK', copied: 'Copiado', copy: 'Copiar', noData: 'Sin datos', fetch: 'Obtener', add: 'Anadir', enable: 'Activar', disable: 'Desactivar', configured: 'Configurado', notConfigured: 'No configurado', confirm: 'Confirmar', expand: 'Expandir', collapse: 'Contraer', stop: 'Detener', start: 'Iniciar', expired: 'Expirado', }, // Gestion de MCP mcp: { title: 'Servidores MCP', loadFailed: 'Error al cargar servidores MCP', reloadAll: 'Recargar todos', refresh: 'Actualizar', total: 'Total', connected: 'Conectado', disconnected: 'Desconectado', tools: 'herramientas', tool: 'Herramientas', searchPlaceholder: 'Buscar servidores...', addServer: '+ Agregar servidor', zeroTools: '0 herramientas', loading: 'Cargando...', empty: 'No hay servidores MCP configurados', reloaded: '{server} recargado', reloadedAll: 'Todos los servidores MCP recargados', reloadFailed: 'Error al recargar', serverAdded: 'Servidor "{name}" agregado', addFailed: 'Error al agregar servidor', serverUpdated: 'Servidor "{name}" actualizado', updateFailed: 'Error al actualizar servidor', saveFailed: 'Error al guardar', serverRemoved: '"{name}" eliminado', enabled: "Habilitado: {name}", disabled: "Deshabilitado: {name}", connectedStatus: 'Conectado', disconnectedStatus: 'Desconectado', disabledStatus: 'Deshabilitado', toolList: 'Lista de herramientas', count: ' ', more: 'más', removeFailed: 'Error al eliminar servidor', testOk: 'Prueba OK — {count} herramientas disponibles', testEmpty: 'La prueba no devolvio herramientas', testFailed: 'Error en la prueba', edit: 'Editar', test: 'Probar', reload: 'Recargar', remove: 'Eliminar', confirmRemove: '¿Eliminar servidor "{name}"?', cancel: 'Cancelar', add: 'Agregar', save: 'Guardar', addTitle: 'Agregar servidor MCP', editTitle: 'Editar servidor MCP', invalidJson: 'JSON inválido', invalidYaml: 'Formato YAML no válido', invalidConfig: 'Configuración no válida', invalidServerConfig: 'Configuración del servidor no válida', missingCommandOrUrl: 'Debe incluir command o url', }, // Sidebar sidebar: { chat: 'Chat', search: 'Buscar', apiRelay: 'API Relay', history: 'Historial', jobs: 'Tareas programadas', models: 'Modelos', profiles: 'Perfiles', plugins: 'Plugins', mcp: 'MCP', skills: 'Habilidades', memory: 'Memoria', logs: 'Registros', usage: 'Uso', performance: 'Rendimiento', skillsUsage: 'Uso de habilidades', channels: 'Canales', terminal: 'Terminal', files: 'Archivos', groupChat: 'Chat grupal', groupConversation: 'Conversación', groupConversationShort: 'Conv.', groupAgent: 'Agente', groupAgentShort: 'Ag.', groupSystem: 'Sistema', groupSystemShort: 'Sist', groupMonitoring: 'Monitoreo', groupMonitoringShort: 'Mon.', settings: 'Configuracion', connected: 'Conectado', disconnected: 'Desconectado', updateTip: 'Ejecuta "hermes-web-ui update" en la terminal para actualizar', updateVersion: 'Actualizar a v{version}', reloadClientVersion: 'Recargar para v{version}', updating: 'Actualizando...', updateSuccess: 'Actualizacion completada. Actualiza la pagina en breve. Si no se inicia despues de un tiempo, inicialo manualmente.', updateFailed: 'Error al actualizar', logout: 'Cerrar sesion', nodeVersionWarning: 'Se detecto Node.js v{version}. Actualiza a la version 23 o posterior.', changelog: 'Registro de cambios', noChangelog: 'No hay registro de cambios', kanban: 'Kanban', groupTools: 'Herramientas', groupToolsShort: "Herr.", codingAgents: "Agentes de código", versionPreview: "Vista previa de versión", groupPlatform: 'Plataforma', gateways: 'Puertas de enlace', expand: 'Expandir menú', collapse: 'Contraer menú', }, performance: { title: 'Rendimiento', subtitle: 'Supervisa recursos del sistema, Bridge Broker, Workers y sesiones activas', refresh: 'Actualizar', autoRefreshOn: 'Actualización automática', autoRefreshOff: 'Actualización manual', loadFailed: 'No se pudieron cargar las métricas de rendimiento', systemCpu: 'CPU del sistema', systemMemory: 'Memoria del sistema', activeSessions: 'Sesiones activas', runningSessions: 'En ejecución {count}', workers: 'Workers', totalWorkerMemory: 'Memoria total de Worker', processes: 'Procesos', uptime: 'Tiempo activo', running: 'En ejecución', stopped: 'Detenido', workerMemory: 'Memoria de Worker', lastUpdated: 'Actualizado', profile: 'Profile', memory: 'Memoria', sessions: 'Sesiones', runningActiveSessions: 'En ejecución / Activas', lastUsed: 'Último uso', status: 'Estado', noWorkers: 'Sin Workers', sessionsByProfile: 'Sesiones por Profile', noActiveSessions: 'No hay sesiones activas', }, // Drawer drawer: { terminal: 'Terminal', files: 'Espacio de trabajo', }, // Chat chat: { contextRemaining: 'restante', contextClickToEdit: 'Haz clic para editar la longitud del contexto', contextEditTitle: 'Editar longitud del contexto', contextEditDesc: 'Establecer el límite de longitud del contexto para el modelo actual (en tokens)', contextEditPlaceholder: 'Ingresa la longitud del contexto', contextEditHint: 'Valores comunes: 256k (Hermes predeterminado), 128k (GPT-4), 32k (GPT-3.5)', contextEditSave: 'Guardar', contextEditCancel: 'Cancelar', contextEditInvalid: 'Por favor ingresa una longitud de contexto válida', contextEditSuccess: 'Longitud del contexto actualizada', contextEditFailed: 'Error en la actualización', emptyState: 'Inicia una conversacion con Hermes Agent', outlineTitle: 'Esquema de la conversación', outlineEmpty: 'Sin contenido de conversación', outlineUserQuestion: 'Pregunta del usuario', inputPlaceholder: 'Escribe un mensaje... (Enter para enviar, Shift+Enter para nueva linea)', slashCommandArgs: { message: '', title: '', text: '', }, slashCommands: { usage: 'Calcular el uso de la sesión actual', status: 'Mostrar estado de sesión y cola', abort: 'Detener la ejecución activa de Bridge', queue: 'Poner un mensaje en cola tras la ejecución activa', plan: 'Escribir un plan de implementación en Markdown', goal: 'Set a standing goal that continues across turns', goalStatus: 'Show the active goal status', goalPause: 'Pause the active goal loop', goalResume: 'Resume the paused goal loop', goalDone: 'Complete and clear the active goal', goalClear: 'Clear the active goal', subgoal: 'Add a criterion to the active goal', clear: 'Limpiar la vista actual', clearHistory: 'Eliminar el historial de mensajes guardado de esta sesión', title: 'Renombrar esta sesión', compress: 'Ejecutar compresión de contexto cuando esté inactiva', steer: 'Enviar texto de guía a la ejecución activa de Bridge', destroy: 'Liberar el agente Bridge de esta sesión', reloadMcp: 'Recargar servidores MCP', }, attachFiles: 'Adjuntar archivos', showToolCalls: 'Mostrar llamadas de herramientas', hideToolCalls: 'Ocultar llamadas de herramientas', messageQueue: 'Cola de mensajes', removeQueuedMessage: 'Quitar mensaje de la cola', stop: 'Detener', send: 'Enviar', contextUsed: 'Contexto utilizado:', sessions: 'Sesiones', webUiSessions: 'Sesiones', allProfiles: 'Todos los perfiles', profileMissingModelsTip: 'El perfil "{profile}" no tiene proveedor ni modelo disponible para esta sesión', sessionScopeHint: 'Chat solo muestra sesiones de Web UI/API Server. Las sesiones de CLI, Telegram, Discord, Cron y otros canales son de solo lectura en Historial.', openHistory: 'Abrir historial', hermesHistory: 'Historial de Hermes', historyScopeHint: 'Sesiones del historial de Hermes del perfil actual, de solo lectura y agrupadas por origen.', noSessions: 'Sin sesiones', newChat: 'Nuevo chat', approvalKicker: 'Permiso de terminal', approvalTitle: 'Revisar comando antes de ejecutar', approvalAllowOnce: 'Permitir una vez', approvalAllowSession: 'Permitir sesión', approvalAlways: 'Siempre', approvalDeny: 'Denegar', clarifyKicker: 'El agente necesita aclaración', clarifyTitle: 'El agente tiene una pregunta para usted', clarifyPlaceholder: 'Escriba su respuesta...', clarifySubmit: 'Responder', clarifyDismiss: 'Descartar', deleteSession: 'Eliminar esta sesion?', toggleBatchMode: 'Selección por lotes', selectAll: 'Seleccionar todo', confirmBatchDelete: '¿Eliminar {count} sesiones seleccionadas?', batchDeleteSuccess: '{count} sesiones eliminadas', batchDeletePartial: '{failed} sesiones fallaron al eliminar', batchDeleteFailed: 'Error al eliminar por lotes', importToWebUi: 'Importar a Web UI', importSessionSuccess: 'Sesion importada a Web UI', importSessionAlreadyExists: 'La sesion ya existe en Web UI', importSessionFailed: 'Error al importar la sesion', sessionDeleted: 'Sesion eliminada', rename: 'Renombrar', pin: 'Fijar', unpin: 'Desfijar', pinned: 'Fijados', chatMode: 'Modo de chat', liveMode: 'En vivo', liveSessions: 'Sesiones en vivo', recentBadge: 'Reciente', linkedSessions: '{count} vinculadas', noVisibleMessages: 'No hay mensajes visibles para humanos.', monitorRoleUser: 'Usuario', monitorRoleAssistant: 'Asistente', copySessionLink: 'Copiar enlace de sesión', openSessionInNewTab: 'Abrir en una nueva pestaña', sessionLinkCopied: 'Session link copied', copySessionId: 'Copiar ID de sesión', export: 'Exportar', exportFull: 'Exportación completa (JSON)', exportCompressed: 'Exportación comprimida (TXT)', exportCompressing: 'Comprimiendo contexto, espere...', exportSuccess: 'Sesión exportada', exportFailed: 'Error al exportar', renamed: 'Renombrada', renameFailed: 'Error al renombrar', renameSession: 'Renombrar sesion', sessionNotFound: 'Sesion no encontrada', enterNewTitle: 'Introduce un nuevo titulo', other: 'Otro', runFailed: 'Error en la ejecucion', error: 'Error', tool: 'Herramienta', arguments: 'Argumentos', result: 'Resultado', truncated: '... (truncado)', executionDuration: 'Tiempo de ejecución', thinkingLabel: 'Pensamiento', thinkingInProgress: 'Pensando…', thinkingShow: 'Mostrar pensamiento', thinkingHide: 'Ocultar pensamiento', thinkingDuration: 'Observado {duration}', thinkingChars: '{count} caracteres', copyBubble: 'Copiar mensaje', copiedBubble: 'Mensaje copiado', copyFailed: 'Error al copiar', playSpeech: 'Reproducir voz', pauseSpeech: 'Pausa', resumeSpeech: 'Reanudar', stopSpeech: 'Detener', speechNotSupported: 'Reproducción de voz no soportada en este navegador', searchEnterHint: 'Enter para abrir · Esc para cerrar', searchHint: 'Cmd/Ctrl+K', searchScope: 'Alcance de búsqueda: solo base de datos local de sesiones de Web UI; no incluye sesiones históricas Hermes de solo lectura.', searchFailed: 'No se pudieron buscar sesiones', searchNoSnippet: 'No hay resumen disponible', searchNoResults: 'No hay sesiones que coincidan', searchRecent: 'Sesión reciente', searchEmpty: 'Sesiones recientes', searchPlaceholder: 'Buscar sesiones...', searchSubtitle: 'Buscar por título o contenido de mensajes', searchTitle: 'Buscar sesiones', stopGateway: 'Detener gateway', start: 'Iniciar', workspaceSetFailed: 'No se pudo definir el workspace', workspaceSet: 'Workspace definido', workspacePlaceholder: 'Introduce la ruta del proyecto, p. ej. /home/user/project', workspace: 'Espacio de trabajo', setWorkspaceTitle: 'Definir workspace de sesión', setWorkspace: 'Definir workspace', modelSetFailed: 'No se pudo definir el modelo', modelSet: 'Modelo definido', setModelTitle: 'Definir modelo de sesión', setModel: 'Definir modelo', newCliChat: 'Nuevo CLI', cliEmptyState: 'Iniciar chat CLI', autoPlaySpeech: 'Reproducir voz automáticamente', }, // Jobs jobs: { title: 'Tareas programadas', createJob: 'Crear tarea', editJob: 'Editar tarea', noJobs: 'No hay tareas programadas aun. Crea una para comenzar.', name: 'Nombre', namePlaceholder: 'Nombre de la tarea', schedule: 'Programacion (expresion Cron)', schedulePlaceholder: 'ej. 0 9 * * *', quickPresets: 'Presets rapidos', selectPreset: 'Seleccionar un preset...', presetEveryMinute: 'Cada minuto', presetEvery5Min: 'Cada 5 minutos', presetEveryHour: 'Cada hora', presetEveryDay: 'Todos los dias a las 00:00', presetEveryDay9: 'Todos los dias a las 09:00', presetEveryMonday: 'Cada lunes a las 09:00', presetEveryMonth: 'El dia 1 de cada mes a las 09:00', prompt: 'Prompt', promptPlaceholder: 'El prompt a ejecutar', deliverTarget: 'Destino de entrega', origin: 'Origen', local: 'Local', repeatCount: 'Repeticiones (opcional)', modelPlaceholder: 'Modelo por defecto', repeatPlaceholder: 'Dejar vacio para infinito', jobCreated: 'Tarea creada', jobUpdated: 'Tarea actualizada', nameRequired: 'El nombre es obligatorio', scheduleRequired: 'La programacion es obligatoria', loadFailed: 'Error al cargar la tarea', jobPaused: 'Tarea en pausa', jobResumed: 'Tarea reanudada', jobTriggered: 'Job ejecutado', modelUpdated: 'Modelo actualizado', jobDeleted: 'Tarea eliminada', status: { running: 'En ejecucion', paused: 'En pausa', disabled: 'Desactivada', scheduled: 'Programada', }, info: { model: 'Modelo', schedule: 'Programacion', lastRun: 'Ultima ejecucion', nextRun: 'Proxima ejecucion', deliver: 'Entrega', repeat: 'Repeticion', }, action: { pause: 'Pausar', pauseJob: 'Pausar tarea', resume: 'Reanudar', resumeJob: 'Reanudar tarea', runNow: 'Ejecutar ahora', triggerImmediately: 'Ejecutar inmediatamente', }, runHistory: { title: 'Historial', runs: 'ejecuciones', noRuns: 'No se encontró historial.', }, }, // Skills skills: { title: 'Habilidades', searchPlaceholder: 'Buscar habilidades...', noMatch: 'Ninguna habilidad coincide con tu busqueda', noSkills: 'No se encontraron habilidades', backTo: 'Volver a', attachedFiles: 'Archivos adjuntos', loadFailed: 'Error al cargar la habilidad', fileLoadFailed: 'Error al cargar el archivo', modified: 'Modificado por el usuario', archived: 'Archivado', pinned: 'Fijado', pin: 'Fijar habilidad', unpin: 'Desfijar habilidad', pinFailed: 'Error al cambiar estado de fijacion', toggleFailed: 'Error al activar/desactivar la habilidad', source: { builtin: 'Integrado', hub: 'Hub', local: 'Local', external: 'Externo', }, }, // Plugins plugins: { title: 'Plugins', refresh: 'Actualizar', notice: 'Inventario de solo lectura de manifests de plugins Hermes detectables. Los metadatos de descubrimiento se leen sin cargar código de plugins. En v1, la gestión permanece en CLI; los cambios se aplican en nuevas sesiones Hermes.', loadFailed: 'No se pudieron cargar los plugins', commandCopied: 'Comando copiado', searchPlaceholder: 'Buscar key, nombre, descripción, ruta...', source: 'Origen', kind: 'Tipo', statusTitle: 'Estado', configStatus: 'config: {status}', notAvailable: 'n/a', copyCommand: 'Copiar comando', managedElsewhere: 'gestionado en otro lugar', noMatch: 'Ningún plugin coincide con los filtros actuales', enabled: 'activado', disabled: 'desactivado', summary: { total: 'Total', active: 'Activado / auto', inactive: 'Inactivo', disabled: 'Desactivado', providerManaged: 'Gestionado por provider', }, status: { enabled: 'Activado', 'auto-active': 'Autoactivo', inactive: 'Inactivo', disabled: 'Desactivado', 'provider-managed': 'Gestionado por provider', }, statusLabel: { enabled: 'Activado por configuración', 'auto-active': 'Autoactivo', inactive: 'Inactivo', disabled: 'Desactivado', 'provider-managed': 'Gestionado por provider', }, configStatuses: { enabled: 'activado', disabled: 'desactivado', 'not-enabled': 'no activado', auto: 'auto', 'provider-managed': 'gestionado por provider', }, table: { plugin: 'Plugin', status: 'Estado', source: 'Origen', kind: 'Tipo', capabilities: 'Capacidades', path: 'Ruta / entrypoint', cli: 'CLI', }, capabilities: { tools: '{count} herramientas', hooks: '{count} hooks', env: '{count} env', }, metadata: { agentRoot: 'Raíz del agente', python: 'Python', scanCwd: 'Escanear cwd', projectPlugins: 'Plugins del proyecto', }, }, // Memory memory: { title: 'Memoria', refresh: 'Actualizar', loadFailed: 'Error al cargar la memoria', myNotes: 'Mis notas', noNotes: 'Sin notas aun.', notesPlaceholder: 'Escribe tus notas...', userProfile: 'Perfil de usuario', noProfile: 'Sin perfil aun.', profilePlaceholder: 'Escribe tu perfil...', soul: 'Alma', noSoul: 'Sin configuracion de alma aun.', soulPlaceholder: 'Escribe la configuracion del alma...', }, // Models models: { title: 'Modelos', addProvider: 'Anadir proveedor', providerType: 'Tipo de proveedor', preset: 'Preajuste', custom: 'Personalizado', selectProvider: 'Seleccionar proveedor', chooseProvider: 'Elige un proveedor...', name: 'Nombre', autoGeneratedName: 'Generado automaticamente desde la URL base', baseUrl: 'URL base', region: 'Región', regionIntl: 'Internacional', regionCn: 'China continental', baseUrlPlaceholder: 'ej. https://api.example.com/v1', apiKey: 'Clave API', apiKeyPlaceholder: 'sk-...', defaultModel: 'Modelo predeterminado', selectOrInput: 'Seleccionar o ingresar un modelo...', selectModel: 'Seleccionar un modelo...', providerAdded: 'Proveedor anadido', providerDeleted: 'Proveedor eliminado', deleteProvider: 'Eliminar proveedor', deleteConfirm: 'Estas seguro de que quieres eliminar "{name}"?', codexLoginTitle: 'Inicio de sesión de OpenAI Codex', codexWaiting: 'Ingrese este código en la página de autorización para iniciar sesión:', codexCopyCode: 'Código copiado', codexOpenLink: 'Abrir página de autorización', codexApproved: 'Inicio de sesión exitoso', codexExpired: 'La autorización ha expirado. Por favor, inténtelo de nuevo.', nousLoginTitle: 'Inicio de sesión de Nous Portal', nousWaiting: 'Ingrese este código en la página de autorización:', nousCopyCode: 'Código copiado', nousOpenLink: 'Abrir página de autorización', nousApproved: 'Inicio de sesión exitoso', nousDenied: 'Autorización denegada', nousExpired: 'Autorización expirada', copilotLoginTitle: 'Inicio de sesión de GitHub Copilot', copilotWaiting: 'Abra GitHub e introduzca el código de dispositivo a continuación para autorizar. La ventana se cerrará automáticamente tras la aprobación.', copilotCopyCode: 'Código copiado', copilotOpenLink: 'Abrir la página de autorización de GitHub', copilotApproved: '¡Inicio de sesión exitoso!', copilotDenied: 'Autorización denegada.', copilotExpired: 'El enlace de autorización ha caducado. Vuelva a intentarlo.', copilotAddDetectedTitle: 'GitHub Copilot detectado', copilotAddDetected: 'Se detectó un token OAuth de GitHub Copilot en este equipo. Haz clic en Agregar para habilitar Copilot en Hermes.', copilotAddSourceEnv: 'Origen: ~/.hermes/.env (COPILOT_GITHUB_TOKEN)', copilotAddSourceGhCli: 'Origen: gh CLI (gh auth token)', copilotAddSourceAppsJson: 'Origen: extensión Copilot de VS Code (apps.json)', copilotDeleteHintEnv: 'Esto borrará COPILOT_GITHUB_TOKEN en ~/.hermes/.env. Otras herramientas no se verán afectadas.', copilotDeleteHintGhCli: 'Copilot se ocultará de Hermes. Tu sesión de gh CLI no se verá afectada — `gh auth status` seguirá mostrando que estás conectado.', copilotDeleteHintAppsJson: 'Copilot se ocultará de Hermes. La extensión Copilot de VS Code seguirá conectada.', customBadge: 'PERSONALIZADO', previewBadge: 'VISTA PREVIA', disabledBadge: 'NO DISPONIBLE', disabledTooltip: "Este modelo no está disponible para tu cuenta.", customModelPlaceholder: 'ID de modelo no listado', customModelHint: 'Para modelos compatibles con el proveedor que la API no devuelve; no es un cambio de nombre visible. Enter para cargar.', noProviders: 'No se encontraron proveedores. Anade un proveedor personalizado para comenzar.', clearVisibleModels: 'Borrar selección', currentDefault: 'Predeterminado actual', defaultShort: 'Predeterminado', builtIn: 'Integrado', customType: 'Personalizado', provider: 'Proveedor', contextLength: 'Longitud del contexto', contextLengthPlaceholder: 'ej. 256000 (opcional)', local: 'Local ({host})', selectProviderRequired: 'Por favor, selecciona un proveedor', baseUrlRequired: 'La URL base es obligatoria', apiKeyRequired: 'La clave API es obligatoria', modelRequired: 'El modelo predeterminado es obligatorio', enterBaseUrl: 'Por favor, introduce primero la URL base', unexpectedFormat: 'Formato de respuesta inesperado', foundModels: '{count} modelos encontrados', fetchFailed: 'Error al obtener los modelos', xaiWaiting: 'Completa la autorización en la página de xAI abierta. La ventana se cerrará automáticamente al aprobarse.', xaiOpenLink: 'Abrir página de autorización de xAI', xaiLoginTitle: 'Inicio de sesión OAuth de xAI Grok', xaiExpired: 'El enlace de autorización expiró. Inténtalo de nuevo.', xaiCopyLink: 'Copiar enlace de autorización', xaiApproved: '¡Inicio de sesión correcto!', visibilitySelectOne: 'Mantén al menos un modelo visible', visibilitySaved: 'Modelos visibles guardados', visibilitySaveFailed: 'No se pudieron guardar los modelos visibles', visibilityHint: 'Solo afecta al selector de modelos y a la página de modelos de Web UI. No modifica la configuración provider/model de Hermes CLI; las llamadas siguen usando el ID original del modelo.', showAllModels: 'Mostrar todos los modelos', searchPlaceholder: 'Buscar modelos...', removeCustomModel: 'Eliminar este modelo no listado', more: 'más', models: 'Lista de modelos', manageVisibleModelsFor: 'Gestionar modelos visibles de {name}', manageVisibleModels: 'Gestionar modelos visibles', getApiKey: 'Obtener API Key', count: 'modelos', aliasUseOriginal: 'Restaurar ID original', aliasTitleFor: 'Nombre visible de {model}', aliasTitle: 'Nombre visible del modelo', aliasSaveFailed: 'No se pudo guardar el nombre visible', aliasPlaceholder: 'Dejar vacío para usar el ID original del modelo', aliasManageFor: 'Nombres visibles de {provider}', aliasManage: 'Nombres visibles', aliasHint: 'Solo cambia el nombre visible en Web UI. Hermes sigue recibiendo el ID original del modelo.', aliasEdit: 'Renombrar', aliasCanonical: 'ID original: {model}', }, // Profiles profiles: { title: 'Perfiles', create: 'Crear perfil', import: 'Importar', export: 'Exportar', rename: 'Renombrar', delete: 'Eliminar', switchTo: 'Cambiar Hermes Profile', switchConfirm: 'Esto ejecutara `hermes profile use {name}` y cambiara el active profile de Hermes CLI. Continuar?', switchSuccess: 'Hermes active profile cambiado a "{name}"', switchFailed: 'Error al cambiar Hermes Profile. Es posible que la pasarela necesite un reinicio manual.', createSuccess: 'Perfil "{name}" creado', createFailed: 'Error al crear el perfil', renameSuccess: 'Perfil renombrado', renameFailed: 'Error al renombrar el perfil', deleteConfirm: 'Estas seguro de que quieres eliminar el perfil "{name}"?', deleteSuccess: 'Perfil eliminado', deleteFailed: 'Error al eliminar el perfil', exportSuccess: 'Perfil exportado', exportFailed: 'Error al exportar el perfil', importSuccess: 'Perfil importado', importFailed: 'Error al importar el perfil', importSelectFile: 'Seleccionar archivo de archivo', importInvalidFile: 'Por favor, selecciona un archivo valido (.tar.gz, .tgz, .gz, .zip)', name: 'Nombre del perfil', namePlaceholder: 'Solo letras, numeros y guiones', nameValidation: 'El nombre del perfil solo puede contener letras minúsculas, números, guiones bajos y guiones', newName: 'Nuevo nombre', newNamePlaceholder: 'Introduce un nuevo nombre', cloneFromCurrent: 'Clonar desde el perfil actual', cloneCleanupNotice: 'Al clonar se omiten automáticamente las credenciales exclusivas de plataforma (Weixin / Telegram / Slack, etc.) para evitar conflictos con el perfil de origen', cloneStrippedCredentials: 'Se eliminaron {count} credenciales exclusivas: {list}', cloneDisabledPlatforms: 'Se deshabilitaron {count} plataforma(s): {list}', cloneStrippedConfigCredentials: 'Se eliminaron {count} credencial(es) integradas de config.yaml: {list}', archivePath: 'Ruta del archivo', archivePathPlaceholder: 'Ruta del servidor al archivo de archivo', importName: 'Nombre del perfil (opcional)', importNamePlaceholder: 'Dejar vacio para usar el nombre del archivo', active: 'Activo', model: 'Modelo', gateway: 'Pasarela', alias: 'Alias', provider: 'Proveedor', path: 'Ruta', skills: 'Habilidades', hasEnv: 'Tiene .env', hasSoulMd: 'Tiene soul.md', noProfiles: 'No se encontraron perfiles. Crea uno para comenzar.', avatar: { title: 'Avatar personalizado', customize: 'Personalizar avatar', upload: 'Subir imagen', random: 'Generar aleatorio', reset: 'Restaurar predeterminado', hint: 'PNG, JPEG o WebP, máximo 1 MB', invalidType: 'Elige una imagen PNG, JPEG o WebP', tooLarge: 'La imagen del avatar no puede superar 1 MB', saveSuccess: 'Avatar guardado', saveFailed: 'No se pudo guardar el avatar', resetSuccess: 'Avatar predeterminado restaurado', resetFailed: 'No se pudo restaurar el avatar predeterminado', }, runtime: { activeProfile: 'Actual: {name}', bridgeWorker: 'Estado del Bridge', gateway: 'Puerta de enlace', active: 'Activo', activeTag: 'Actual', idle: 'Inactivo', checking: 'Comprobando', running: 'En ejecución', stopped: 'Detenido', restartGateway: 'Reiniciar gateway', restartProfile: 'Reiniciar perfil', switchProfile: 'Cambiar perfil frontend', gatewayRestarted: 'Gateway reiniciado: {name}', gatewayRestartFailed: 'No se pudo reiniciar el gateway', profileRestarted: 'Perfil reiniciado: {name}', profileRestartFailed: 'No se pudo reiniciar el perfil', }, }, // Logs logs: { title: 'Registros', all: 'Todos', searchPlaceholder: 'Buscar...', refresh: 'Actualizar', noEntries: 'Sin entradas de registro', }, // Settings settings: { title: 'Configuracion', saved: 'Guardado', saveFailed: 'Error al guardar', tabs: { display: 'Pantalla', account: 'Cuenta actual', users: 'Gestion de cuentas', agent: 'Agente', memory: 'Memoria', compression: 'Compresion', session: 'Sesion', privacy: 'Privacidad', apiServer: 'Servidor API', models: 'Modelos', voice: 'Voz', }, display: { streaming: 'Respuestas en streaming', streamingHint: 'Mostrar respuestas de la IA en tiempo real', compact: 'Modo compacto', compactHint: 'Reducir el espaciado entre mensajes', showReasoning: 'Mostrar razonamiento', showReasoningHint: 'Mostrar el proceso de pensamiento del modelo', showCost: 'Mostrar costo', showCostHint: 'Mostrar uso de tokens en las respuestas', inlineDiffs: 'Diffs en linea', inlineDiffsHint: 'Mostrar cambios de codigo en linea', bellOnComplete: 'Sonido de finalizacion', bellOnCompleteHint: 'Reproducir un sonido cuando la IA termina', busyInputMode: 'Modo de entrada ocupada', busyInputModeHint: 'Permitir entrada mientras la IA procesa', theme: 'Tema', themeHint: 'Elige claro, oscuro o seguir la preferencia del sistema', themeLight: 'Claro', themeDark: 'Oscuro', themeSystem: 'Sistema', }, agent: { maxTurns: 'Turnos maximos', maxTurnsHint: 'Rondas maximas de interaccion por conversacion', gatewayTimeout: 'Tiempo de espera de la pasarela', gatewayTimeoutHint: 'Tiempo de espera de la peticion en segundos', restartDrainTimeout: 'Tiempo de drenado al reiniciar', restartDrainTimeoutHint: 'Tiempo de drenado antes de reiniciar en segundos', toolEnforcement: 'Aplicacion de herramientas', toolEnforcementHint: 'Controlar el modo de ejecucion de llamadas a herramientas', auto: 'Automatico', always: 'Siempre', never: 'Nunca', }, memory: { enabled: 'Activar memoria', enabledHint: 'Permitir que la IA recuerde el contexto de la conversacion', userProfile: 'Perfil de usuario', userProfileHint: 'Permitir que la IA recuerde las preferencias del usuario', charLimit: 'Limite de caracteres de memoria', charLimitHint: 'Maximo de caracteres para MEMORY.md', userCharLimit: 'Limite de caracteres del perfil de usuario', userCharLimitHint: 'Maximo de caracteres para USER.md', }, compression: { enabled: 'Activar compresion', enabledHint: 'Comprimir automaticamente el historial largo antes de superar el contexto del modelo', threshold: 'Umbral de compresion', thresholdHint: 'Iniciar compresion cuando los tokens estimados superen esta proporcion del contexto', targetRatio: 'Proporcion objetivo', targetRatioHint: 'Tamano objetivo del historial tras comprimir como proporcion del contexto', protectLastN: 'Proteger mensajes recientes', protectLastNHint: 'Mantener sin comprimir esta cantidad de mensajes recientes', protectFirstN: 'Proteger primeros mensajes', protectFirstNHint: 'Mantener sin comprimir esta cantidad de mensajes iniciales', }, session: { mode: 'Modo de reinicio', modeHint: 'Condicion de activacion del reinicio de sesion', modeBoth: 'Inactividad + Programado', modeIdle: 'Solo inactividad', modeDaily: 'Solo programado', modeNone: 'Nunca (solo manual)', idleMinutes: 'Tiempo de inactividad', idleMinutesHint: 'Tiempo de espera antes del reinicio automatico (minutos)', atHour: 'Hora de reinicio programado', humanOnly: 'Mostrar solo sesiones humanas', humanOnlyHint: 'Oculta por defecto el ruido de subagentes y del monitor de sesiones', liveMonitorHumanOnly: 'Monitor en vivo: mostrar solo sesiones humanas', liveMonitorHumanOnlyHint: 'Oculta por defecto el ruido de subagentes y del monitor de sesiones en el monitor en vivo', atHourHint: 'Reiniciar sesion a esta hora todos los dias', requireAuth: 'Autorización de sesión', requireAuthHint: 'Requiere autorización para operaciones de sesión', }, privacy: { redactPii: 'Ocultar informacion personal', redactPiiHint: 'Detectar y ocultar automaticamente informacion sensible (contrasenas, claves, etc.)', }, apiServer: { enable: 'Activar', enableHint: 'Activar servidor API', host: 'Host', hostHint: 'Direccion de escucha', port: 'Puerto', portHint: 'Puerto de escucha', key: 'Clave', keyHint: 'Clave de acceso API', cors: 'Origenes CORS', corsHint: 'Fuentes cross-origin permitidas', }, voice: { ttsProvider: 'Proveedor TTS', ttsProviderHint: 'Elija el motor de texto a voz para la reproduccion de mensajes', providerWebSpeech: 'WebSpeech API (Navegador)', providerOpenai: 'OpenAI TTS', providerCustom: 'Endpoint personalizado (compatible con OpenAI)', providerEdge: 'Edge TTS (Gratuito, sin clave API)', // WebSpeech webspeechVoice: 'Voz', webspeechVoiceHint: 'Seleccione una voz de su navegador o sistema operativo', webspeechVoicePlaceholder: 'Auto (voz predeterminada)', // OpenAI openaiKey: 'Clave API', openaiKeyHint: 'Su clave API de OpenAI con acceso TTS', openaiUrl: 'URL base de API', openaiUrlHint: 'ej. https://api.openai.com/v1/audio/speech', openaiModel: 'Modelo', openaiModelHint: 'tts-1 (mas rapido) / tts-1-hd (mayor calidad)', openaiVoice: 'Voz', openaiVoiceHint: 'Voz a utilizar para la sintesis', // Custom endpoint customHint: 'Utilice cualquier API TTS compatible con OpenAI — funciona con GPT-SoVITS, CosyVoice, etc.', customUrl: 'URL de API', customUrlHint: 'URL base de su servicio TTS', customUrlPlaceholder: 'Direccion configurada en el adaptador local, ej. http://127.0.0.1:9880', customApiKey: 'Clave API (opcional)', customApiKeyHint: 'Algunos endpoints personalizados requieren autenticacion', customApiKeyPlaceholder: 'Dejar en blanco si no es necesario', // Edge TTS edgeHint: 'Impulsado por Microsoft Edge TTS (node-edge-tts).', edgeUrl: 'URL del adaptador', edgeUrlHint: 'Direccion del adaptador Edge TTS, ej. http://127.0.0.1:9882', edgeUrlPlaceholder: 'http://127.0.0.1:9882', edgeVoice: 'Voz', edgeVoiceHint: 'Seleccione una voz para la sintesis de voz', edgeRate: 'Velocidad', edgeRateHint: 'Ajustar velocidad del habla (0.5x ~ 2.0x)', edgePitch: 'Tono', edgePitchHint: 'Ajustar tono del habla (-20 ~ +20 Hz)', // Test testTitle: 'Prueba de voz', testText: 'Texto de prueba', testTextPlaceholder: 'Ingrese texto para probar...', testTextDefault: 'Hola, esta es una prueba de voz.', testButton: 'Probar', testButtonPlaying: 'Reproduciendo...', testFailed: 'Prueba fallida: {error}', // MiMo TTS providerMimo: 'MiMo TTS', mimoHint: 'Xiaomi MiMo TTS — voces predefinidas, diseño de voz y clonación de voz', mimoApiKey: 'Clave API', mimoApiKeyHint: 'Obtenga su clave en platform.xiaomimimo.com', mimoApiKeyPlaceholder: 'Clave API MiMo', mimoBaseUrl: 'URL base', mimoBaseUrlHint: 'URL del endpoint de la API MiMo', mimoModel: 'Modelo', mimoModelHint: 'Seleccione el modelo de síntesis de voz', mimoModelPreset: 'Voces predefinidas', mimoModelVoiceDesign: 'Diseño de voz', mimoModelVoiceClone: 'Clonación de voz', mimoVoice: 'Voz', mimoVoiceHint: 'Seleccione una voz predefinida', mimoVoiceDesignPrompt: 'Descripción de voz', mimoVoiceDesignPromptHint: 'Describa las características de voz deseadas', mimoVoiceDesignPromptPlaceholder: 'Ej: Una voz femenina cálida y joven, algo lenta, con tono magnético', mimoCloneAudio: 'Subir audio', mimoCloneAudioHint: 'Suba una muestra de audio para clonación (mp3/wav, máx. 10 MB)', mimoCloneAudioUpload: 'Elegir archivo', mimoCloneAudioClear: 'Borrar', mimoStylePrompt: 'Indicador de estilo', mimoStylePromptHint: 'Opcional — describa el estilo de habla en lenguaje natural', mimoStylePromptPlaceholder: 'Ej: Tono brillante y animado, ritmo rápido', }, lockedIps: { title: 'IPs bloqueadas', count: '{count} bloqueadas', empty: 'Sin IPs bloqueadas', unlock: 'Desbloquear', unlockAll: 'Desbloquear todo', unlockAllConfirm: 'Desbloquear todas las IPs?', unlocked: 'IP desbloqueada', allUnlocked: '{count} IPs desbloqueadas', }, models: { apiKey: 'API Key', apiKeyPlaceholder: 'Introduce API Key', noProviders: 'No hay proveedores configurados', save: 'Guardar', saveFailed: 'Error al guardar', saved: 'Guardado', }, }, githubPreview: { title: "Vista previa de versión", description: "Clona el tag de GitHub seleccionado en el espacio de vista previa de Web UI, instala dependencias y lo ejecuta con los puertos de desarrollo.", refresh: "Actualizar", selectTag: "Selecciona un tag", prepare: "Preparar código", install: "Instalar dependencias", start: "Iniciar vista previa", stop: "Detener", note: "El código de vista previa se guarda bajo el directorio de datos de Web UI. Producción sigue en el puerto 8648; la vista previa usa frontend 8651 y backend 8650.", path: "Ruta de vista previa", webuiHome: "Datos de vista previa", currentTag: "Tag actual", repoReady: "Repositorio listo", dependencies: "Dependencias instaladas", running: "Estado", notRunning: "No ejecutándose", open: "Abrir vista previa", log: "Ruta del log de acciones", logOutput: "Salida de logs", actionLog: "Log de acciones", devLog: "Log del servidor dev", yes: "Sí", no: "No", actionFailed: "Acción fallida", nodeEnvironmentMissing: "No se detectó Node/npm. Instala Node.js y vuelve a intentarlo.", prepareSuccess: "Código de vista previa listo", installSuccess: "Dependencias instaladas", startSuccess: "Vista previa iniciada", stopSuccess: "Vista previa detenida", }, codingAgents: { title: "Agentes de código", notice: "No todos los proveedores y modelos son compatibles.", claudeDescription: "CLI de Anthropic para tareas únicas en print mode y sesiones interactivas de código.", codexDescription: "CLI de OpenAI y flujo del proveedor openai-codex de Hermes para tareas de repositorio.", copyCommand: "Copiar", commandCopied: "Comando copiado", commandCopyFailed: "Error al copiar", refresh: "Actualizar", checking: "Comprobando", installStatus: "Estado de instalación", installed: "Instalado", notInstalled: "No instalado", installNow: "Instalar", installing: "Instalando", installSuccess: "Instalado", installFailed: "Error de instalación", nodeEnvironmentMissing: "No se detectó Node/npm. Instala Node.js y vuelve a intentarlo.", deleteNow: "Eliminar", deleting: "Eliminando", deleteSuccess: "Eliminado", deleteFailed: "Error al eliminar", configFiles: "Archivos de configuración", profileScope: "Perfil", providerScope: "Proveedor", providerPlaceholder: "p. ej. custom:glm", modelScope: "Modelo", modelPlaceholder: "Selecciona modelo", launchModeScope: "Modo de inicio", launchModeGlobal: "Configuración global", launchModeScoped: "Proveedor y modelo", protocolScope: "Protocolo", protocolOpenAiChat: "OpenAI Chat Completions (/v1/chat/completions)", protocolOpenAiResponses: "OpenAI Responses (/v1/responses)", protocolAnthropicMessages: "Anthropic Messages (/v1/messages)", reloadConfig: "Recargar configuración", configFileNotCreated: "No creado", configLoadFailed: "No se pudo leer el archivo de configuración", loadFailed: "No se pudieron inspeccionar los agentes de código", launch: "Iniciar", launchTitle: "Iniciar agente de código", nativeTerminal: "Terminal nativa", builtInTerminal: "Terminal integrada", launchPrepared: "Configuración de inicio preparada", launchPrepareFailed: "No se pudo preparar la configuración de inicio", nativeLaunchStarted: "Terminal nativa abierta", nativeLaunchFailed: "No se pudo abrir la terminal nativa", terminalTitle: "Terminal del agente de código", loadProvidersFailed: "No se pudieron cargar proveedores del perfil actual", selectProviderModel: "Selecciona un proveedor y un modelo", launchConfigDir: "Directorio de configuración de inicio", launchCommand: "Comando de inicio", table: { tool: "Herramienta", kind: "Paso", command: "Comando", note: "Nota", action: "Acción", }, kinds: { install: "Instalar", auth: "Autenticación", health: "Salud", run: "Ejecutar", }, notes: { claudeInstall: "Instala la CLI de Claude Code globalmente.", codexInstall: "Instala la CLI de Codex globalmente.", claudeAuth: "Comprueba el inicio de sesión de Claude Code; ejecuta claude una vez si falta.", codexAuth: "Agrega credenciales OAuth de OpenAI Codex gestionadas por Hermes.", claudeHealth: "Comprueba el actualizador y el estado de la CLI local.", codexHealth: "Confirma que la CLI de Codex está disponible en PATH.", claudeRun: "Print mode es la ruta más limpia para tareas únicas impulsadas por API.", codexRun: "Las tareas únicas de Codex deben ejecutarse dentro de un repositorio git.", }, }, // Platform channel settings platform: { requireMention: "Requerir mencion {'@'}", requireMentionGroup: "Requerir mencion {'@'} en grupos para responder", requireMentionChannel: "Requerir mencion {'@'} en canales para responder", requireMentionRoom: "Requerir mencion {'@'} en salas para responder", reactions: 'Reacciones', reactionsHint: 'Reaccionar a mensajes con emoji', freeResponseChats: 'Chats de respuesta libre', freeResponseChatsHint: "IDs de chats que responden sin mencion {'@'} (separados por comas)", freeResponseChannels: 'Canales de respuesta libre', freeResponseChannelsHint: "IDs de canales que responden sin mencion {'@'} (separados por comas)", freeResponseRooms: 'Salas de respuesta libre', freeResponseRoomsHint: "IDs de salas que responden sin mencion {'@'} (separados por comas)", mentionPatterns: 'Patrones de mencion personalizados', mentionPatternsHint: 'Patrones de activacion adicionales', autoThread: 'Hilo automatico', autoThreadHint: "Crear automaticamente hilos de respuesta despues de mencion {'@'}", autoThreadHintRoom: 'Crear automaticamente hilos de respuesta en salas', dmMentionThreads: 'Hilos de mencion en MD', dmMentionThreadsHint: 'Usar hilos de respuesta para menciones en mensajes directos', allowBots: 'Permitir mensajes de bots', allowBotsHint: 'Responder a mensajes de otros bots', allowedChannels: 'Canales permitidos', allowedChannelsHint: 'Lista blanca de IDs de canales (separados por comas)', ignoredChannels: 'Canales ignorados', ignoredChannelsHint: 'Canales donde el bot nunca responde (separados por comas)', noThreadChannels: 'Canales sin hilo', noThreadChannelsHint: 'Canales donde el bot responde sin hilos (separados por comas)', exclusiveTokenWarning: 'Esta plataforma usa bloqueo exclusivo de token. Cada perfil debe usar un token de identidad distinto para evitar conflictos con otros perfiles.', botToken: 'Token del bot', botTokenHint: 'Token del bot del portal de desarrolladores', accessToken: 'Token de acceso', accessTokenHint: 'Token de acceso de Matrix', homeserver: 'URL del homeserver', homeserverHint: 'URL del homeserver de Matrix', appId: 'ID de aplicacion', appIdHint: 'ID de aplicacion de Feishu', appSecret: 'Secreto de aplicacion', appSecretHint: 'Secreto de aplicacion de Feishu', clientId: 'ID de cliente', clientIdHint: 'ID de cliente de DingTalk', clientSecret: 'Secreto de cliente', clientSecretHint: 'Secreto de cliente de DingTalk', cardTemplateId: 'ID de plantilla de tarjeta IA', cardTemplateIdHint: 'ID de plantilla de tarjeta IA de DingTalk; déjelo vacío para desactivar las tarjetas IA', botId: 'ID del bot', botIdHint: 'ID del bot de WeCom', wecomSecretHint: 'Secreto del bot de WeCom', waEnabled: 'Activar WhatsApp', waEnabledHint: 'Activar WhatsApp mediante emparejamiento por codigo QR', weixinToken: 'Token de Weixin', weixinTokenHint: 'Desde el inicio de sesion QR de la CLI de weixin (hermes weixin)', accountId: 'ID de cuenta', accountIdHint: 'ID de cuenta de Weixin', qrLogin: 'Inicio de sesion QR', qrRelogin: 'Volver a iniciar sesion', qrFetching: 'Obteniendo codigo QR...', qrScanHint: 'Escanea con WeChat para iniciar sesion', qrScanedHint: 'Escaneado, por favor confirma en el telefono...', qqSandboxHint: 'Habilitar entorno sandbox (para pruebas)', qqSandbox: 'Modo sandbox', qqQrScanHint: 'Escanea el código QR con QQ o abre el enlace en el teléfono para completar la vinculación', qqMarkdownHint: 'Habilitar mensajes con formato Markdown (algunos clientes pueden no soportarlo)', qqMarkdown: 'Soporte Markdown', qqAppSecretHint: 'App Secret del bot de QQ Open Platform', qqAppSecret: 'App Secret', qqAppIdHint: 'App ID del bot de QQ Open Platform', qqAppId: 'App ID', allowedUsersHint: 'Lista blanca de IDs de usuario u OpenID, separados por comas', allowedUsers: 'Usuarios permitidos', allowAllUsersHint: 'Permite mensajes de cualquier usuario; desactívalo para usar la lista blanca', allowAllUsers: 'Permitir todos los usuarios', }, // Language language: { label: 'Idioma', zh: '中文', en: 'English', es: 'Espanol', }, // Terminal terminal: { sessions: 'Sesiones', newTab: 'Nueva terminal', closeSession: 'Cerrar esta sesion?', sessionExited: 'Finalizada', processExited: 'Proceso finalizado con codigo {code}', noSessions: 'No hay sesiones de terminal', connectionFailed: 'No se pudo conectar al terminal', connectionError: 'Error de conexión', connectionClosed: 'Conexión cerrada', }, // Usage usage: { title: 'Estadisticas de uso', refresh: 'Actualizar', totalTokens: 'Total de tokens', inputTokens: 'Entrada', outputTokens: 'Salida', totalSessions: 'Total de sesiones', avgPerDay: '~{n}/dia de promedio', estimatedCost: 'Costo est.', cacheHitRate: 'Tasa de acierto de cache', modelBreakdown: 'Desglose por modelo', dailyTrend: 'Uso diario', date: 'Fecha', tokens: 'Tokens', cache: 'Caché', cacheRead: 'Lectura de caché', cacheWrite: 'Escritura de caché', sessions: 'Sesiones', cost: 'Costo', noData: 'Sin datos de uso', }, skillsUsage: { title: 'Uso de habilidades', subtitle: 'Sigue las cargas y ediciones de habilidades en sesiones de Hermes', refresh: 'Actualizar', periodSelector: 'Periodo de uso de habilidades', periodLabel: '{days} d', summary: 'Resumen', totalActions: 'Acciones', loads: 'Cargas', edits: 'Ed.', distinctSkills: 'Habs.', topSkills: 'Top habs.', dailyTrend: 'Tendencia diaria', periodSummary: 'Últimos {days} días', skill: 'Hab.', share: '%', lastUsed: 'Últ. uso', noData: 'No hay datos de uso de habilidades', loadFailed: 'No se pudo cargar el uso de habilidades', otherSkills: 'Otras habs.', }, // Registro de cambios changelog: { new_0_6_4_1: 'CI se refuerza con instalación npm fijada y cobertura Docker smoke para PRs', new_0_6_4_2: 'El chat ahora usa paginación virtualizada para que conversaciones largas se desplacen y carguen con más fiabilidad', new_0_6_4_3: 'La publicación de imágenes Docker ahora solo se ejecuta en releases, no en checks normales de PR', new_0_6_4_4: 'Version Preview está disponible para super admins, con selección main/tag, checkout de preview, instalación de dependencias, controles start/stop y logs', new_0_6_4_5: 'Las instancias preview aíslan puertos frontend/backend, Web UI home y agent bridge endpoint, con parches runtime para tags antiguos que cubren puertos, WebSocket, base URL y navegación preview anidada', new_0_6_4_6: 'Las tablas legacy session_usage sin created_at ahora migran de forma segura con un valor predeterminado', new_0_6_4_7: 'Los endpoints de bridge profile worker ahora se separan por broker endpoint, evitando que producción y preview con el mismo Profile se roben worker sockets y causen errores unknown run', new_0_6_5_1: 'Coding Agents añade un flujo completo de inicio para Claude Code y Codex, con configuración global, workspaces aislados por profile/provider y terminal integrada o nativa', new_0_6_5_2: 'El inicio de Codex soporta OpenAI Chat Completions, OpenAI Responses y Anthropic Messages, con proxy local para adaptar distintos proveedores', new_0_6_5_3: 'Coding Agents es más estable en Windows con detección de shims .cmd/.bat, correcciones de terminal y Claude Code custom model sin validación local de modelos', new_0_6_5_4: 'Listas de mensajes, paginación History, autenticación TTS, menciones de agentes en chat grupal, supresión de checks de actualización y bridge worker transport mejoran la estabilidad', new_0_6_3_1: 'El estado del spinner de Bridge ya no se guarda como reasoning del modelo, evitando que texto decorativo de thinking contamine el contexto futuro', new_0_6_3_2: 'History ahora incluye controles para importar sesiones de Hermes CLI al historial local de Web UI con normalizacion de mensajes mas segura', new_0_6_3_3: 'La configuracion de Provider admite base URLs integradas editables, LM Studio como provider integrado y descubrimiento en vivo desde LM Studio /models', new_0_6_3_4: 'Las solicitudes OpenRouter enviadas por el bridge de Web UI ahora incluyen headers de atribucion de la app Hermes Web UI', new_0_6_3_5: 'El endpoint publico de auth status ya no expone el primer nombre de usuario a solicitudes no autenticadas', new_0_6_3_6: 'La configuracion de DingTalk ahora incluye un campo AI Card Template ID persistido como DINGTALK_CARD_TEMPLATE_ID', new_0_6_3_7: 'La salida JSON del socket Bridge limpia caracteres Unicode surrogate aislados para evitar caidas de SSE durante el chat', new_0_6_2_1: 'Web Bridge ahora soporta comandos /plan con inicio correcto del run y estado visible del comando', new_0_6_2_2: 'El menú de comandos del input de chat ahora incluye /goal y /subgoal, con acciones de estado, pausa, reanudar, finalizar y limpiar', new_0_6_2_3: 'Los flujos de Goal y subgoal se integran con sesiones de chat, incluyendo continuaciones de objetivos y actualizaciones de estado', new_0_6_2_4: 'Se restauran las opciones de canal destino para jobs, permitiendo que los jobs programados elijan el destino previsto', new_0_6_2_5: 'El uso de tokens de contexto se reanuda con precisión tras reconexiones mediante cálculos conscientes del snapshot', new_0_6_2_6: 'La compresión de checkpoints de contexto es más fiable con resúmenes Codex lentos: Web UI espera 5 minutos y el Python bridge broker ya no corta requests de worker a los 2 minutos', new_0_6_2_7: 'La promoción de cola de chat está corregida para que los mensajes queued no salten antes de tiempo a la lista, incluso en ventanas sincronizadas', new_0_6_2_8: 'Los prompts Clarify ya no envían respuestas de texto libre con Enter y los prompts respondidos no se reabren al cambiar de sesión', new_0_6_2_9: 'El refresco de entorno del terminal Bridge y la limpieza de stale pid quedan mejor acotados, reduciendo estados runtime obsoletos en la UI', new_0_6_2_10: 'La longitud de contexto predeterminada ahora sigue el estándar Hermes de 256.000 tokens', new_0_5_35_1: 'Las sesiones Bridge ahora pueden ejecutarse en paralelo entre distintos sessions, mientras los runs del mismo session siguen serializados para conservar el orden', new_0_5_35_2: 'Añade la página Performance Monitor para CPU/memoria del sistema, Web UI, Bridge Broker, Workers y estado de sesiones activas', new_0_5_35_3: 'Añade métricas por worker con CPU, memoria, Profile, número de sesiones y estado de ejecución', new_0_5_35_4: 'Mejora la limpieza del ciclo de vida de Bridge workers para recuperar workers al cerrar el Broker o terminar el proceso padre y reducir procesos Python huérfanos', new_0_5_35_5: 'Refuerza la compatibilidad del monitoreo con fallbacks de recursos para macOS, Windows, Linux, Docker y Termux', new_0_5_35_6: 'Performance Monitor ya no se bloquea con requests a workers durante la inicialización de Agent, reduciendo request timeouts en Windows', new_0_5_35_7: 'Chat Markdown ahora soporta vista previa inline de contenido de texto, y los iconos de descarga bajan archivos directamente sin abrir el drawer', new_0_5_35_8: 'Mejora el drawer de contenido con cierre en móvil, ancho completo en móvil, 800px en escritorio y fondos consistentes para texto/Markdown', new_0_6_0_1: 'La gestión por cuenta y por Profile protege de forma coherente sesiones, modelos, uso, Kanban, jobs, subidas, medios y APIs Hermes relacionadas', new_0_6_0_2: 'Los Skills de medios integrados usan el token de servidor generado solo para endpoints de medios y resuelven credenciales fun-codex/xAI desde el Profile solicitado', new_0_6_0_3: 'El chat individual y el grupal inyectan el Hermes Profile actual en las instrucciones del run para que los Skills envíen X-Hermes-Profile', new_0_6_0_4: 'El progreso de subagents de delegate_task se muestra en la UI del chat con estados de inicio, herramienta, progreso y finalización', new_0_6_0_5: 'Al detener o abortar un run se limpian eventos temporales para que el estado abort anterior no pase al siguiente chat', new_0_6_0_6: 'Actualiza documentación y sitio web para gestión de cuentas, credenciales predeterminadas, gestión cuenta/Profile, subidas/descargas y Skills de medios', new_0_6_0_7: 'Añade comandos CLI de mantenimiento para limpiar bloqueos de IP de login y restablecer el login predeterminado admin / 123456', new_0_6_0_8: 'La versión 0.6.0 marca el límite entre la Web UI de usuario único y multiusuario. Si el modo multiusuario causa problemas, abre un issue y vuelve a la versión 0.5.35 de usuario único si es necesario', new_0_6_1_1: 'Las listas de sesiones muestran por defecto todos los perfiles disponibles para la cuenta; solo se filtran por perfil cuando se selecciona explícitamente, y CLI start/stop/status ya no imprimen la advertencia experimental de node:sqlite', new_0_6_1_2: 'Las respuestas de Clarify y confirmación ahora viajan por el socket de chat autenticado hasta Hermes bridge, con pruebas de la ruta de respuesta', new_0_6_1_3: 'Las entradas de navegación y filas de sesiones de chat usan enlaces nativos para abrir en nueva pestaña, copiar enlaces y conservar grupos laterales colapsados', new_0_6_1_4: 'Los enlaces de sesión ya no filtran la lista normal por el Profile de la ruta, y las etiquetas de abrir en nueva pestaña están localizadas', new_0_6_1_5: 'Skills lee skills.external_dirs desde la configuración del Profile activo, marca skills externas, mantiene prioridad local y resuelve archivos externos', new_0_6_1_6: 'El bloqueo de IP de inicio de sesión permite 10 intentos fallidos y la pantalla bloqueada muestra comandos de recuperación para limpiar bloqueos y restablecer el login predeterminado', new_0_6_1_7: 'Las desconexiones de chat en móvil o segundo plano se tratan como transitorias y la reconexión reanuda el estado del run desde el servidor', new_0_6_1_8: 'El flush de marcadores de herramientas en Bridge ahora persiste prefijos parciales en los límites de herramienta y de run', new_0_6_1_9: 'Las acciones de History sensibles a Profile eliminan sesiones con objetivos calificados por Profile y refrescan History al cambiar el Profile global', new_0_6_1_10: 'Se eliminó el bypass heredado AUTH_DISABLED para el modelo multiusuario, mientras AUTH_TOKEN sigue soportado', }, // Archivos files: { title: 'Archivos', tree: 'Arbol de directorios', list: 'Lista de archivos', breadcrumbRoot: 'Inicio', newFile: 'Nuevo archivo', newFolder: 'Nueva carpeta', upload: 'Subir', refresh: 'Actualizar', open: 'Abrir', edit: 'Editar', preview: 'Vista previa', download: 'Descargar', copyPath: 'Copiar ruta', rename: 'Renombrar', delete: 'Eliminar', name: 'Nombre', size: 'Tamano', modified: 'Modificado', actions: 'Acciones', emptyDir: 'Directorio vacio', loading: 'Cargando...', confirmDelete: '?Seguro que quiere eliminar "{name}"?', confirmDeleteDir: '?Seguro que quiere eliminar el directorio "{name}" y todo su contenido?', deleteFailed: 'Error al eliminar', deleted: 'Eliminado', renameTo: 'Renombrar a', newFileName: 'Nombre del archivo', newFolderName: 'Nombre de la carpeta', created: 'Creado', createFailed: 'Error al crear', renamed: 'Renombrado', renameFailed: 'Error al renombrar', uploadSuccess: '{count} archivo(s) subido(s)', uploadFailed: 'Error al subir', saveFailed: 'Error al guardar', saved: 'Guardado', unsavedChanges: 'Tiene cambios sin guardar. ?Descartar?', pathCopied: 'Ruta copiada', fileTooLarge: 'Archivo demasiado grande (max 10MB)', permissionDenied: 'No se puede modificar un archivo protegido', notFound: 'Archivo o directorio no encontrado', backendError: 'Error en la operacion de archivo', dragDropHint: 'Arrastra archivos aqui para subir', closeEditor: 'Cerrar editor', closePreview: 'Cerrar', saveFile: 'Guardar', fileTree: 'Árbol de archivos', }, // Chat grupal groupChat: { title: 'Chat grupal', createRoom: 'Crear sala', joinByCode: 'Unirse con codigo', roomName: 'Nombre de la sala', roomNamePlaceholder: 'Ingrese el nombre de la sala', inviteCode: 'Codigo de invitacion', autoGenerate: 'Generar automaticamente', noRooms: 'Aun no hay salas', selectOrCreate: 'Seleccione o cree una sala para comenzar a chatear', agents: 'Agentes', addAgent: 'Agregar agente', selectProfile: 'Seleccione un perfil', agentAdded: 'Agente agregado', agentAlreadyInRoom: 'El agente ya esta en esta sala', agentAddFailedCount: 'No se agregaron {count} agente(s): {details}', noAgents: 'No hay agentes en esta sala', members: 'Miembros', roomCreated: 'Sala creada', roomDeleted: 'Sala eliminada', roomCloned: 'Sala clonada', cloneRoom: 'Clonar sala', copyRoomLink: 'Copiar enlace de sala', deleteRoomConfirm: '¿Eliminar esta sala?', clearContext: 'Limpiar contexto', clearContextConfirm: '¿Limpiar el contexto de esta sala? Se eliminarán mensajes e instantáneas de compresión, pero se conservan agentes y miembros.', contextCleared: 'Contexto limpiado', you: 'Tú', joined: 'Se unio a la sala', joinFailed: 'Error al unirse a la sala', inputPlaceholder: 'Escriba un mensaje... (Enter para enviar)', enterCode: 'Ingrese el codigo de invitacion', yourName: 'Tu nombre', yourNamePlaceholder: 'Ingresa tu nombre para mostrar', yourDescription: 'Descripcion (opcional)', yourDescriptionPlaceholder: 'Cuentales a los demas quien eres...', agentName: 'Nombre del agente', agentNamePlaceholder: 'Nombre personalizado (vacío = nombre del perfil)', agentDesc: 'Descripción del agente', agentDescPlaceholder: 'Describe lo que hace este agente...', agentReplying: 'está respondiendo...', agentCompressing: 'está comprimiendo contexto...', compressionSettings: 'Configuración de compresión', triggerTokens: 'Tokens de activación', triggerTokensDesc: 'Umbral de tokens para activar la compresión', maxHistoryTokens: 'Tokens máximos de historial', maxHistoryTokensDesc: 'Máximo de tokens para el contexto comprimido', tailMessageCount: 'Mensajes recientes', tailMessageCountDesc: 'Número de mensajes recientes a conservar sin comprimir', compressionConfig: 'Config. de compresión', compressNow: 'Comprimir ahora', compressingInProgress: 'Compresión en progreso', compressionSaved: 'Configuración guardada', }, // Descarga download: { downloading: 'Descargando...', downloadFailed: 'Error en la descarga', fileNotFound: 'Archivo no encontrado o eliminado', fileTooLarge: 'Archivo demasiado grande (excede el limite)', backendError: 'Error al leer el archivo, el entorno remoto puede no estar disponible', backendTimeout: 'Tiempo de lectura del archivo agotado', unsupportedBackend: 'El backend del terminal actual no admite la descarga de archivos', invalidPath: 'Ruta de archivo invalida', contentDisplay: 'Contenido', download: 'Descargar', downloadFile: 'Descargar archivo', }, gateways: { title: 'Puertas de enlace', running: 'En ejecución', stopped: 'Detenido', started: 'Iniciado', startFailed: 'No se pudo iniciar el gateway', stopFailed: 'No se pudo detener el gateway', }, kanban: { title: 'Tablero Kanban', createTask: 'Nueva tarea', noTasks: 'Sin tareas', allStatuses: 'Todos los estados', allAssignees: 'Todos los responsables', columns: { triage: 'Clasificación', todo: 'Pendiente', ready: 'Listo', running: 'En curso', blocked: 'Bloqueado', done: 'Completado', archived: 'Archivado', }, card: { assigneeTooltip: 'Responsable', priority: { low: 'Baja', medium: 'Media', high: 'Alta', }, timeAgo: { justNow: 'ahora mismo', minutes: 'hace {count} min', hours: 'hace {count} h', days: 'hace {count} d', }, }, board: { create: 'Nuevo tablero', archive: 'Archivar tablero', archiveConfirm: '¿Archivar el tablero actual?', archived: 'Tablero archivado', created: 'Tablero creado', slugPlaceholder: 'Identificador del tablero, p. ej. project-a', namePlaceholder: 'Nombre visible (opcional)', slugRequired: 'El identificador del tablero es obligatorio', }, form: { title: 'Título', titlePlaceholder: 'Título de la tarea', titleRequired: 'El título es obligatorio', body: 'Descripción', bodyPlaceholder: 'Descripción de la tarea (opcional)', assignee: 'Responsable', selectAssignee: 'Seleccionar responsable...', priority: 'Prioridad', selectPriority: 'Seleccionar prioridad...', }, detail: { status: 'Estado', priority: 'Prioridad', assignee: 'Responsable', tenant: 'Inquilino', createdAt: 'Creada', startedAt: 'Iniciada', completedAt: 'Completada', comments: 'Comentarios', events: 'Eventos', runs: 'Ejecuciones', artifacts: 'Archivos generados', result: 'Resultado', highlights: 'Información clave', sources: 'Fuentes de datos', sessions: 'Sesiones relacionadas', sessionMessages: 'Mensajes de sesión', noSessions: 'No se encontraron sesiones relacionadas.', }, action: { title: 'Acciones', assign: 'Asignar', assignTo: 'Asignar a...', block: 'Bloquear', blockReason: 'Motivo del bloqueo', unblock: 'Desbloquear', complete: 'Completar', completeSummary: 'Resumen de finalización (opcional)', }, message: { loadFailed: 'No se pudo cargar la tarea', taskCreated: 'Tarea creada', taskAssigned: 'Tarea asignada', taskBlocked: 'Tarea bloqueada', taskUnblocked: 'Tarea desbloqueada', taskCompleted: 'Tarea completada', }, stats: { total: 'Total', tasks: 'Tareas', }, }, }