Merge origin/main into deferred OpenCode restart branch.

Resolve ProvidersPage and lifecycle conflicts with custom providers and
AppImage ARGV0 stripping. Address review follow-ups: OAuth index helper +
tests, single auth-methods load trigger, shared Google env-alias module with
VS Code parity coverage, and deferred restart for custom provider upsert.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-08-03 13:57:05 +00:00
co-authored by Serhii Dziupin
94 changed files with 5949 additions and 372 deletions
@@ -698,9 +698,8 @@ export const settingsDict = {
"settings.skills.sidebar.toast.skillDeleted": "Habilidad \"{name}\" eliminada con éxito",
"settings.skills.sidebar.toast.deleteSkillFailed": "No se pudo eliminar la habilidad",
"settings.skills.sidebar.toast.duplicateLoadFailed": "No se pudo cargar la información de la habilidad para duplicarla",
"settings.skills.sidebar.toast.renameLoadFailed": "No se pudo cargar la información de la habilidad",
"settings.skills.sidebar.toast.removeOldAfterRenameFailed": "No se pudo eliminar la habilidad antigua después del cambio de nombre",
"settings.skills.sidebar.toast.renameFailed": "No se pudo cambiar el nombre de la habilidad",
"settings.skills.sidebar.toast.skillRenamed": "Habilidad renombrada a \"{name}\"",
"settings.skills.sidebar.deleteDialog.title": "Eliminar habilidad",
"settings.skills.sidebar.deleteDialog.description": "¿Estás seguro de que quieres eliminar la habilidad \"{name}\"?",
"settings.skills.sidebar.renameDialog.title": "Cambiar nombre habilidad",
@@ -1313,7 +1312,58 @@ export const settingsDict = {
"settings.providers.page.connect.selectProviderPlaceholder": "Seleccionar proveedor",
"settings.providers.page.connect.searchProvidersPlaceholder": "Buscar...",
"settings.providers.page.connect.noProvidersFound": "No se encontraron proveedores",
"settings.providers.page.connect.allProvidersConnected": "Todos los proveedores están conectados.",
"settings.providers.page.custom.optionLabel": "Otro / Personalizado",
"settings.providers.page.custom.title": "Proveedor personalizado",
"settings.providers.page.custom.editTitle": "Editar proveedor personalizado",
"settings.providers.page.custom.description": "Añade un proveedor compatible con OpenAI con URL base, credenciales y lista de modelos. Se guarda en la configuración de OpenCode para usarlo en el chat como cualquier otro proveedor.",
"settings.providers.page.custom.field.providerID.label": "ID del proveedor",
"settings.providers.page.custom.field.providerID.placeholder": "mi-proveedor",
"settings.providers.page.custom.field.providerID.info": "Minúsculas, números, guiones y guiones bajos. Se usa como ID de proveedor de OpenCode.",
"settings.providers.page.custom.field.name.label": "Nombre visible",
"settings.providers.page.custom.field.name.placeholder": "Mi proveedor",
"settings.providers.page.custom.field.name.info": "Se muestra en los selectores de proveedor y modelo.",
"settings.providers.page.custom.field.baseURL.label": "URL base",
"settings.providers.page.custom.field.baseURL.placeholder": "https://api.example.com/v1",
"settings.providers.page.custom.field.baseURL.info": "URL base de la API compatible con OpenAI. Debe empezar por http:// o https://.",
"settings.providers.page.custom.field.apiKey.label": "Clave API",
"settings.providers.page.custom.field.apiKey.placeholder": "sk-... o {env:VAR_NAME}",
"settings.providers.page.custom.field.apiKey.info": "Se guarda en la autenticación de OpenCode, no en OpenChamber. Usa {env:VAR_NAME} para leer una clave del entorno.",
"settings.providers.page.custom.field.apiKey.editInfo": "Déjalo en blanco para conservar la credencial existente, o introduce una clave nueva / {env:VAR_NAME}.",
"settings.providers.page.custom.field.apiKey.editPlaceholder": "Déjalo en blanco para conservar la clave existente",
"settings.providers.page.custom.models.title": "Modelos",
"settings.providers.page.custom.models.idLabel": "ID del modelo",
"settings.providers.page.custom.models.idPlaceholder": "gpt-4o",
"settings.providers.page.custom.models.nameLabel": "Nombre del modelo",
"settings.providers.page.custom.models.namePlaceholder": "GPT-4o",
"settings.providers.page.custom.models.add": "Añadir modelo",
"settings.providers.page.custom.models.remove": "Quitar modelo",
"settings.providers.page.custom.headers.title": "Encabezados",
"settings.providers.page.custom.headers.description": "Encabezados de solicitud opcionales enviados en cada llamada.",
"settings.providers.page.custom.headers.keyLabel": "Nombre del encabezado",
"settings.providers.page.custom.headers.keyPlaceholder": "X-Custom-Header",
"settings.providers.page.custom.headers.valueLabel": "Valor del encabezado",
"settings.providers.page.custom.headers.valuePlaceholder": "valor",
"settings.providers.page.custom.headers.add": "Añadir encabezado",
"settings.providers.page.custom.headers.remove": "Quitar encabezado",
"settings.providers.page.custom.actions.back": "Atrás",
"settings.providers.page.custom.actions.save": "Guardar proveedor",
"settings.providers.page.custom.actions.update": "Actualizar proveedor",
"settings.providers.page.custom.error.providerID.required": "El ID del proveedor es obligatorio",
"settings.providers.page.custom.error.providerID.format": "Usa minúsculas, números, guiones o guiones bajos",
"settings.providers.page.custom.error.providerID.exists": "Ya hay un proveedor conectado con este ID",
"settings.providers.page.custom.error.name.required": "El nombre visible es obligatorio",
"settings.providers.page.custom.error.baseURL.required": "La URL base es obligatoria",
"settings.providers.page.custom.error.baseURL.format": "La URL base debe empezar por http:// o https://",
"settings.providers.page.custom.error.required": "Obligatorio",
"settings.providers.page.custom.error.duplicate": "Duplicado",
"settings.providers.page.custom.error.apiKey.required": "Se requiere una clave API o {env:VAR_NAME}",
"settings.providers.page.custom.authFailure.configAfterAuth": "Las credenciales se guardaron, pero no la configuración del proveedor. Corrige el error e inténtalo de nuevo, o desconéctalo para eliminar el guardado parcial.",
"settings.providers.page.auth.title": "Autenticación",
"settings.providers.page.auth.loadingMethods": "Cargando métodos de autenticación...",
"settings.providers.page.auth.apiKeyLabel": "Clave API",
@@ -1322,6 +1372,10 @@ export const settingsDict = {
"settings.providers.page.auth.oauthMethodFallback": "Método OAuth {index}",
"settings.providers.page.auth.pasteAuthorizationCodePlaceholder": "Pegar código de autorización",
"settings.providers.page.auth.connected": "Conectado",
"settings.providers.page.auth.incomplete": "Faltan credenciales",
"settings.providers.page.auth.incompleteHint": "· Añade una clave API o {env:VAR} antes de usar este proveedor en el chat",
"settings.providers.page.auth.useReconnectHint": "· Usar Reconnect para actualizar credenciales",
"settings.providers.page.connectionDetails.title": "Detalles de conexión",
"settings.providers.page.connectionDetails.configuredIn": "Configurado en:",
@@ -1351,6 +1405,8 @@ export const settingsDict = {
"settings.providers.page.actions.complete": "Completar",
"settings.providers.page.actions.hide": "Ocultar",
"settings.providers.page.actions.reconnect": "Reconectar",
"settings.providers.page.actions.edit": "Editar",
"settings.providers.page.actions.disconnecting": "Desconectando...",
"settings.providers.page.actions.disconnect": "Desconectar",
"settings.providers.page.actions.hideAll": "Ocultar todo",
@@ -1371,6 +1427,8 @@ export const settingsDict = {
"settings.providers.page.toast.deviceCodeCopyFailed": "No se pudo copiar el código de dispositivo",
"settings.providers.page.toast.providerDisconnected": "Proveedor desconectado",
"settings.providers.page.toast.providerDisconnectFailed": "No se pudo desconectar el proveedor",
"settings.providers.page.toast.customProviderSaved": "{provider} conectado",
"settings.providers.page.toast.customProviderSaveFailed": "No se pudo guardar el proveedor personalizado",
"settings.mcp.page.empty.selectServer": "Selecciona un servidor MCP desde el panel lateral",
"settings.mcp.page.empty.addNewOne": "o añade uno nuevo",
"settings.mcp.page.header.newServer": "Nuevo servidor MCP",