@cat-factory/app 0.46.11 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/app/components/auth/AuthGate.vue +3 -2
  2. package/app/components/auth/LoginScreen.vue +172 -32
  3. package/app/components/auth/ResetPasswordScreen.vue +16 -13
  4. package/app/components/auth/UserMenu.vue +3 -2
  5. package/app/components/layout/AccountDeploymentSettings.vue +307 -37
  6. package/app/components/layout/AccountFragmentSettings.vue +2 -3
  7. package/app/components/layout/AccountTeamSettings.vue +75 -45
  8. package/app/components/layout/AiProvidersBanner.vue +11 -11
  9. package/app/components/layout/BoardSwitcher.vue +63 -29
  10. package/app/components/layout/CommandBar.vue +68 -54
  11. package/app/components/layout/GitHubPatBanner.vue +13 -6
  12. package/app/components/layout/IntegrationBackTitle.vue +4 -1
  13. package/app/components/layout/IntegrationsHub.vue +67 -49
  14. package/app/components/layout/NotificationsInbox.vue +48 -19
  15. package/app/components/layout/PersonalSetupModal.vue +26 -16
  16. package/app/components/layout/ProviderConfigBanner.vue +14 -9
  17. package/app/components/layout/SideBar.vue +20 -18
  18. package/app/components/layout/SpendWarningBanner.vue +16 -16
  19. package/app/components/providers/ApiKeysSection.vue +27 -3
  20. package/app/components/providers/PersonalSubscriptionSection.vue +18 -4
  21. package/app/components/providers/SignInRequiredNotice.vue +19 -0
  22. package/app/components/settings/AccountSettingsPanel.vue +9 -6
  23. package/app/components/settings/IssueTrackerPanel.vue +114 -53
  24. package/app/components/settings/LocalModeSettingsPanel.vue +60 -28
  25. package/app/components/settings/LocalModelEndpointsPanel.vue +72 -27
  26. package/app/components/settings/MergeThresholdsPanel.vue +93 -45
  27. package/app/components/settings/ModelConfigurationPanel.vue +62 -36
  28. package/app/components/settings/ObservabilityConnectionPanel.vue +65 -35
  29. package/app/components/settings/OpenRouterCatalogPanel.vue +70 -40
  30. package/app/components/settings/ProviderConnectionPanel.vue +115 -61
  31. package/app/components/settings/ServiceFragmentDefaultsPanel.vue +9 -12
  32. package/app/components/settings/UserSecretsSection.vue +37 -18
  33. package/app/components/settings/WorkspaceSettingsPanel.vue +114 -62
  34. package/app/composables/api/auth.ts +7 -0
  35. package/app/stores/auth.ts +25 -1
  36. package/app/types/accountSettings.ts +4 -0
  37. package/i18n/locales/en.json +908 -0
  38. package/i18n/locales/es.json +899 -0
  39. package/i18n/locales/fr.json +899 -0
  40. package/i18n/locales/pl.json +899 -0
  41. package/i18n/locales/uk.json +899 -0
  42. package/package.json +2 -2
@@ -710,5 +710,904 @@
710
710
  "userPrompt": "Prompt del usuario",
711
711
  "details": "Detalles"
712
712
  }
713
+ },
714
+ "auth": {
715
+ "gate": {
716
+ "loading": "Cargando…"
717
+ },
718
+ "localMode": {
719
+ "continueWith": "Continuar con {provider}",
720
+ "enterPatTitle": "O inicia sesión con un token de acceso personal",
721
+ "tokenPlaceholder": "pega un token de {provider}",
722
+ "createToken": "Crear un token de {provider} ↗",
723
+ "submit": "Iniciar sesión",
724
+ "orDivider": "o",
725
+ "failed": "Error al iniciar sesión. Comprueba el token e inténtalo de nuevo."
726
+ },
727
+ "signInRequired": {
728
+ "personalSubscriptions": "Las suscripciones personales se guardan en tu cuenta, pero este despliegue se ejecuta sin inicio de sesión, así que no se pueden almacenar aquí. Usa el grupo del espacio de trabajo o una clave de API de proveedor.",
729
+ "userApiKeys": "Tus claves de API personales se guardan en tu cuenta, pero este despliegue se ejecuta sin inicio de sesión, así que no se pueden almacenar aquí. Cambia el ámbito a «Este espacio de trabajo» para añadir una clave compartida."
730
+ },
731
+ "login": {
732
+ "appTitle": "Architecture Board",
733
+ "subtitle": "Inicia sesión para continuar.",
734
+ "inviteSubtitle": "Acepta tu invitación para continuar.",
735
+ "forgotSubtitle": "Restablece tu contraseña.",
736
+ "continueWithGithub": "Continuar con GitHub",
737
+ "continueWithGoogle": "Continuar con Google",
738
+ "or": "o",
739
+ "namePlaceholder": "Nombre (opcional)",
740
+ "emailPlaceholder": "Correo electrónico",
741
+ "passwordPlaceholder": "Contraseña",
742
+ "createAccount": "Crear cuenta",
743
+ "signIn": "Iniciar sesión",
744
+ "signUp": "Registrarse",
745
+ "needAccount": "¿Necesitas una cuenta? {signUp}",
746
+ "haveAccount": "¿Ya tienes una cuenta? {signIn}",
747
+ "forgotPassword": "¿Olvidaste tu contraseña?",
748
+ "forgotSent": "Si existe una cuenta con ese correo, un enlace para restablecer la contraseña está en camino. Revisa tu bandeja de entrada.",
749
+ "sendResetLink": "Enviar enlace de restablecimiento",
750
+ "backToSignIn": "Volver al inicio de sesión",
751
+ "signInFailed": "Error al iniciar sesión. Revisa tus datos e inténtalo de nuevo.",
752
+ "genericError": "Algo salió mal. Inténtalo de nuevo."
753
+ },
754
+ "resetPassword": {
755
+ "title": "Restablecer contraseña",
756
+ "subtitle": "Elige una nueva contraseña para tu cuenta.",
757
+ "doneBody": "Tu contraseña se ha restablecido. Ya puedes iniciar sesión con tu nueva contraseña.",
758
+ "goToSignIn": "Ir al inicio de sesión",
759
+ "missingToken": "A este enlace de restablecimiento le falta el token. Solicita un nuevo enlace desde la pantalla de inicio de sesión.",
760
+ "backToSignIn": "Volver al inicio de sesión",
761
+ "newPasswordPlaceholder": "Nueva contraseña",
762
+ "confirmPasswordPlaceholder": "Confirmar nueva contraseña",
763
+ "submit": "Restablecer contraseña",
764
+ "errorTooShort": "La contraseña debe tener al menos 8 caracteres.",
765
+ "errorMismatch": "Las contraseñas no coinciden.",
766
+ "errorInvalidLink": "Este enlace para restablecer la contraseña no es válido o ha caducado."
767
+ },
768
+ "userMenu": {
769
+ "mySetup": "Mi configuración",
770
+ "signOut": "Cerrar sesión"
771
+ }
772
+ },
773
+ "layout": {
774
+ "accountDeployment": {
775
+ "title": "Integraciones del despliegue",
776
+ "intro": "Credenciales compartidas por todos los espacios de trabajo de esta cuenta, cifradas en reposo. Los valores nunca se muestran tras guardarlos; deja un campo en blanco para conservar el secreto almacenado.",
777
+ "configured": "Configurado",
778
+ "notSet": "Sin definir",
779
+ "clear": "Borrar",
780
+ "loadFailed": "No se pudo cargar la configuración del despliegue",
781
+ "slack": {
782
+ "title": "Aplicación de Slack (OAuth)",
783
+ "description": "Habilita el flujo OAuth \"Add to Slack\". Sin él, los espacios de trabajo aún pueden conectar Slack pegando un token de bot.",
784
+ "clientId": "ID de cliente",
785
+ "clientSecret": "Secreto de cliente",
786
+ "redirectUrl": "URL de redirección",
787
+ "validation": "Introduce el id de cliente, el secreto y la URL de redirección",
788
+ "saved": "OAuth de Slack guardado",
789
+ "saveFailed": "No se pudo guardar el OAuth de Slack",
790
+ "cleared": "OAuth de Slack borrado",
791
+ "clearFailed": "No se pudo borrar el OAuth de Slack"
792
+ },
793
+ "web": {
794
+ "title": "Búsqueda web del contenedor",
795
+ "description": "El proveedor de búsqueda al que los agentes del contenedor acceden a través del proxy del backend. Define una clave de Brave (recomendado) o una URL de SearXNG autoalojada (con una clave bearer opcional).",
796
+ "configured": "Configurado ({provider})",
797
+ "braveKey": "Clave de API de Brave",
798
+ "searxngUrl": "URL de SearXNG",
799
+ "searxngKey": "Clave de SearXNG (opcional)",
800
+ "validation": "Introduce una clave de Brave o una URL de SearXNG",
801
+ "saved": "Claves de búsqueda web guardadas",
802
+ "saveFailed": "No se pudieron guardar las claves de búsqueda web",
803
+ "cleared": "Claves de búsqueda web borradas",
804
+ "clearFailed": "No se pudieron borrar las claves de búsqueda web"
805
+ },
806
+ "contentStorage": {
807
+ "title": "Almacenamiento de contenido",
808
+ "description": "Dónde se almacenan las capturas del probador de UI y las imágenes de diseño de referencia de esta cuenta. Los metadatos siempre viven en la base de datos; solo los bytes de archivo van al backend elegido.",
809
+ "default": "Predeterminado ({backend})",
810
+ "backends": {
811
+ "off": "Desactivado (almacenamiento deshabilitado)",
812
+ "fs": "Sistema de archivos local",
813
+ "s3": "Amazon S3 / compatible con S3",
814
+ "r2": "Cloudflare R2",
815
+ "db": "Base de datos Postgres"
816
+ },
817
+ "basePath": "Ruta base (predeterminada: .file-storage)",
818
+ "region": "Región (p. ej. us-east-1)",
819
+ "bucket": "Bucket",
820
+ "prefix": "Prefijo de clave (opcional)",
821
+ "endpoint": "Endpoint (opcional, compatible con S3)",
822
+ "forcePathStyle": "Forzar direccionamiento de estilo de ruta (la mayoría de almacenes compatibles con S3)",
823
+ "accessKeys": "Claves de acceso",
824
+ "accessKeyId": "ID de clave de acceso",
825
+ "secretAccessKey": "Clave de acceso secreta",
826
+ "keysHint": "Las claves se sellan en reposo y nunca se muestran tras guardarlas; déjalas en blanco para conservar las almacenadas.",
827
+ "regionBucketValidation": "Introduce la región y el bucket de S3",
828
+ "bothKeysValidation": "Introduce tanto el id de clave de acceso como el secreto",
829
+ "keysValidation": "Introduce el id de clave de acceso y el secreto de S3",
830
+ "saved": "Almacenamiento de contenido guardado",
831
+ "saveFailed": "No se pudo guardar el almacenamiento de contenido"
832
+ }
833
+ },
834
+ "accountFragments": {
835
+ "intro": "Directrices de buenas prácticas compartidas por todos los tableros de esta cuenta. Cada tablero las hereda y puede anularlas o añadir las suyas. Los agentes que conocen el código (coder, reviewer, architect, fixers) incorporan las relevantes en su prompt."
836
+ },
837
+ "accountTeam": {
838
+ "roles": {
839
+ "admin": "Administrador",
840
+ "developer": "Desarrollador",
841
+ "product": "Producto"
842
+ },
843
+ "org": {
844
+ "ctaTitle": "Invita a compañeros y gestiona roles",
845
+ "ctaBody": "Los miembros, roles e invitaciones viven en una organización. Crea una para invitar a compañeros y gestionar sus roles; tus tableros personales se mantienen igual.",
846
+ "namePlaceholder": "Acme Inc.",
847
+ "create": "Crear organización",
848
+ "created": "Organización creada"
849
+ },
850
+ "members": {
851
+ "title": "Miembros",
852
+ "empty": "Todavía no hay miembros."
853
+ },
854
+ "invite": {
855
+ "title": "Invitar a un compañero",
856
+ "submit": "Invitar",
857
+ "revoke": "Revocar invitación",
858
+ "created": "Invitación creada",
859
+ "createdEmailed": "Se envió un correo (o copia el enlace de la lista de abajo).",
860
+ "createdShareLink": "Comparte el enlace de aceptación con tu compañero.",
861
+ "status": {
862
+ "pending": "Pendiente",
863
+ "accepted": "Aceptada",
864
+ "revoked": "Revocada"
865
+ }
866
+ },
867
+ "email": {
868
+ "title": "Remitente de correo",
869
+ "notEnabled": "El envío de correo no está habilitado en este despliegue. Las invitaciones aún generan un enlace de aceptación que se puede compartir.",
870
+ "connectedAs": "Conectado mediante {provider} como {from}",
871
+ "disconnect": "Desconectar",
872
+ "connect": "Conectar remitente de correo",
873
+ "connected": "Remitente de correo conectado",
874
+ "fromPlaceholder": "Dirección de remitente",
875
+ "apiKeyPlaceholder": "Clave de API del proveedor",
876
+ "providers": {
877
+ "resend": "Resend",
878
+ "sendgrid": "SendGrid"
879
+ }
880
+ },
881
+ "apiKeys": {
882
+ "title": "Claves de API de la cuenta"
883
+ },
884
+ "errors": {
885
+ "updateRoles": "No se pudieron actualizar los roles",
886
+ "loadSettings": "No se pudo cargar la configuración del equipo",
887
+ "createOrg": "No se pudo crear la organización",
888
+ "sendInvite": "No se pudo enviar la invitación",
889
+ "revokeInvite": "No se pudo revocar la invitación",
890
+ "connectEmail": "No se pudo conectar el remitente de correo",
891
+ "disconnectEmail": "No se pudo desconectar el remitente de correo"
892
+ }
893
+ },
894
+ "boardSwitcher": {
895
+ "accountFallback": "Cuenta",
896
+ "boardFallback": "Tablero",
897
+ "providers": {
898
+ "docker": "Docker (local)",
899
+ "custom": "Personalizado"
900
+ },
901
+ "account": {
902
+ "newOrg": "Nueva organización…",
903
+ "settings": "Configuración de la cuenta…",
904
+ "defaultProvider": "Proveedor de nube predeterminado"
905
+ },
906
+ "board": {
907
+ "new": "Nuevo tablero…",
908
+ "rename": "Cambiar nombre del tablero…",
909
+ "delete": "Eliminar tablero"
910
+ },
911
+ "prompt": {
912
+ "create": "Crear",
913
+ "nameLabel": "Nombre",
914
+ "descriptionLabel": "Descripción",
915
+ "descriptionHint": "Opcional",
916
+ "descriptionPlaceholder": "¿Para qué sirve este tablero?",
917
+ "account": {
918
+ "title": "Nueva organización",
919
+ "placeholder": "Acme Inc."
920
+ },
921
+ "board": {
922
+ "title": "Nuevo tablero",
923
+ "placeholder": "Tablero sin título"
924
+ },
925
+ "rename": {
926
+ "title": "Configuración del tablero",
927
+ "placeholder": "Nombre del tablero"
928
+ }
929
+ },
930
+ "toast": {
931
+ "updateProviderFailed": "No se pudo actualizar el proveedor predeterminado",
932
+ "switchAccountFailed": "No se pudo cambiar de cuenta",
933
+ "openBoardFailed": "No se pudo abrir el tablero",
934
+ "boardDeleted": "Tablero eliminado",
935
+ "deleteBoardFailed": "No se pudo eliminar el tablero"
936
+ }
937
+ },
938
+ "notifications": {
939
+ "heading": "Requiere tu atención",
940
+ "overdue": "Vencida",
941
+ "openPr": "Abrir PR",
942
+ "dismiss": "Descartar",
943
+ "action": {
944
+ "merge_review": "Fusionar",
945
+ "pipeline_complete": "Confirmar y fusionar",
946
+ "ci_failed": "Reintentar ejecución",
947
+ "test_failed": "Reintentar ejecución",
948
+ "requirement_review": "Marcar como leída",
949
+ "clarity_review": "Marcar como leída",
950
+ "release_regression": "Confirmar recepción",
951
+ "decision_required": "Marcar como leída",
952
+ "human_test_ready": "Marcar como leída",
953
+ "visual_confirmation_ready": "Marcar como leída",
954
+ "human_review": "Marcar como leída",
955
+ "followup_pending": "Marcar como leída",
956
+ "markRead": "Marcar como leída"
957
+ }
958
+ },
959
+ "aiProvidersBanner": {
960
+ "setup": {
961
+ "title": "No hay ningún modelo de IA configurado",
962
+ "body": "Los agentes necesitan un modelo para ejecutarse. La IA funciona de forma inmediata solo en un despliegue de Cloudflare con Workers AI habilitado. De lo contrario, conecta una clave de proveedor, una suscripción, un proxy o un ejecutor local para continuar.",
963
+ "action": "Configurar IA"
964
+ },
965
+ "preset": {
966
+ "title": "El preajuste de modelo predeterminado usa modelos no disponibles",
967
+ "body": "Las tareas que usan el preajuste predeterminado fallarían. Edita el preajuste o configura el proveedor que falta.",
968
+ "action": "Revisar preajuste"
969
+ }
970
+ },
971
+ "githubPatBanner": {
972
+ "title": "PAT de GitHub no configurado",
973
+ "body": "El modo local accede a GitHub con un token de acceso personal. Sin uno, los pasos de los agentes que clonan, hacen push, abren PR, validan CI o fusionan fallarán.",
974
+ "createToken": "Crear un token de GitHub (ámbitos preseleccionados)",
975
+ "thenSet": "Luego define {envVar} y reinicia."
976
+ },
977
+ "providerConfigBanner": {
978
+ "titleMany": "Los proveedores necesitan configuración",
979
+ "titleOne": {
980
+ "environment": "El proveedor de entorno necesita configuración",
981
+ "runner-pool": "El grupo de ejecutores necesita configuración"
982
+ },
983
+ "body": "Hay un proveedor conectado para esta instancia, pero le faltan ajustes obligatorios, así que aún no puede ejecutarse. Añade los campos obligatorios para terminar de conectarlo.",
984
+ "action": {
985
+ "environment": "Configurar proveedor de entorno",
986
+ "runner-pool": "Configurar grupo de ejecutores"
987
+ }
988
+ },
989
+ "spendWarningBanner": {
990
+ "title": "Límite de gasto alcanzado, ejecución de agentes en pausa",
991
+ "body": "El gasto de tokens de este mes ha alcanzado el presupuesto configurado, por lo que las canalizaciones en curso se pausaron para evitar más costes. La ejecución se reanuda automáticamente cuando el presupuesto se renueva el mes que viene, o una vez que se aumente el límite.",
992
+ "spent": "Gastado",
993
+ "budget": "Presupuesto",
994
+ "tokens": "Tokens",
995
+ "resume": "Reanudar de todos modos",
996
+ "resumeHint": "Reanudar sigue generando gasto; se pausará de nuevo si sigue por encima del presupuesto."
997
+ },
998
+ "personalSetup": {
999
+ "title": "Mi configuración",
1000
+ "intro": "Tus conexiones personales, usadas para las ejecuciones que inicias y visibles solo para ti.",
1001
+ "connected": "Conectado",
1002
+ "notConnected": "No conectado",
1003
+ "connectedCount": "ninguno conectado | {count} conectado | {count} conectados",
1004
+ "sourceControl": {
1005
+ "title": "Control de versiones"
1006
+ },
1007
+ "githubToken": {
1008
+ "label": "Mi token de GitHub",
1009
+ "description": "Un token de acceso personal usado para las ejecuciones que inicias (pushes, PR, CI, fusión)."
1010
+ },
1011
+ "models": {
1012
+ "title": "Modelos"
1013
+ },
1014
+ "localRunners": {
1015
+ "label": "Mis ejecutores locales",
1016
+ "description": "Tus ejecutores de modelos en tu propia máquina (Ollama, LM Studio, vLLM)."
1017
+ },
1018
+ "subscriptions": {
1019
+ "label": "Mis suscripciones",
1020
+ "description": "Planes de uso individual que desbloqueas con una contraseña personal (Claude, GLM, Codex)."
1021
+ }
1022
+ },
1023
+ "integrationBack": {
1024
+ "backToMySetup": "Volver a Mi configuración",
1025
+ "backToIntegrations": "Volver a Integraciones"
1026
+ },
1027
+ "commandBar": {
1028
+ "searchPlaceholder": "Busca o ejecuta un comando…",
1029
+ "noMatches": "No hay comandos que coincidan.",
1030
+ "groups": {
1031
+ "create": "Crear",
1032
+ "repositories": "Repositorios",
1033
+ "integrations": "Integraciones",
1034
+ "workspace": "Espacio de trabajo",
1035
+ "account": "Cuenta"
1036
+ },
1037
+ "cmd": {
1038
+ "newPipeline": "Crear una canalización",
1039
+ "addFromRepo": "Añadir servicio desde un repositorio existente",
1040
+ "bootstrapRepo": "Iniciar un repositorio nuevo",
1041
+ "githubManage": "Gestionar la conexión de GitHub",
1042
+ "githubConnect": "Conectar GitHub",
1043
+ "slackManage": "Gestionar las notificaciones de Slack",
1044
+ "slackConnect": "Conectar Slack",
1045
+ "sourceManage": "Gestionar {source}",
1046
+ "sourceConnect": "Conectar {source}",
1047
+ "documentImport": "Importar y generar desde documentos",
1048
+ "taskImport": "Importar incidencias",
1049
+ "fragments": "Biblioteca de fragmentos de contexto",
1050
+ "mergeThresholds": "Umbrales de fusión",
1051
+ "workspaceSettings": "Ajustes del espacio de trabajo",
1052
+ "modelConfiguration": "Configuración de modelos",
1053
+ "serviceFragmentDefaults": "Buenas prácticas del servicio por defecto",
1054
+ "accountSettings": "Ajustes de la cuenta",
1055
+ "localModels": "Mis ejecutores locales",
1056
+ "sandbox": "Abrir el entorno de pruebas"
1057
+ },
1058
+ "keywords": {
1059
+ "newPipeline": "canalización agentes cadena pipeline",
1060
+ "addFromRepo": "github importar existente",
1061
+ "bootstrapRepo": "andamiaje crear arquitectura de referencia",
1062
+ "github": "git repositorios pull requests incidencias",
1063
+ "slack": "slack notificaciones canal menciones",
1064
+ "documentSource": "documento fuente prd rfc",
1065
+ "documentImport": "documento importar generar",
1066
+ "taskSource": "tarea fuente rastreador incidencias",
1067
+ "taskImport": "tarea importar incidencias",
1068
+ "fragments": "prompt fragmentos buenas prácticas directrices contexto",
1069
+ "mergeThresholds": "fusión política preajuste auto-fusión ci",
1070
+ "workspaceSettings": "límite tareas en ejecución por servicio espera escalado retraso notificación tiempo de espera",
1071
+ "modelConfiguration": "modelo llm enrutamiento tipo de agente preajuste por defecto configuración",
1072
+ "serviceFragmentDefaults": "fragmento buenas prácticas directriz servicio por defecto consciente del código",
1073
+ "accountSettings": "cuenta equipo miembros roles invitaciones correo claves api fragmento buenas prácticas biblioteca contexto organización personal",
1074
+ "localModels": "modelo local ejecutor ollama lm studio llamacpp vllm endpoint",
1075
+ "sandbox": "entorno de pruebas prompt modelo prueba experimento juez fixture benchmark evaluar"
1076
+ }
1077
+ },
1078
+ "integrationsHub": {
1079
+ "title": "Integraciones",
1080
+ "intro": "Conecta y gestiona los sistemas externos que este espacio de trabajo puede vincular.",
1081
+ "searchPlaceholder": "Buscar integraciones…",
1082
+ "noMatches": "Ninguna integración coincide con \"{query}\".",
1083
+ "getStarted": {
1084
+ "title": "Primeros pasos",
1085
+ "body": "Conecta una fuente de código y un proveedor de modelos para ejecutar tu primera canalización."
1086
+ },
1087
+ "status": {
1088
+ "connected": "Conectado",
1089
+ "keyConnected": "Clave conectada",
1090
+ "notConnected": "Sin conectar",
1091
+ "needsAttention": "Requiere atención",
1092
+ "disabled": "Desactivado",
1093
+ "recommended": "Recomendado"
1094
+ },
1095
+ "groups": {
1096
+ "models": "Modelos y proveedores",
1097
+ "sourceControl": "Control de código fuente",
1098
+ "communication": "Comunicación",
1099
+ "documents": "Documentos",
1100
+ "taskTrackers": "Rastreadores de tareas",
1101
+ "observability": "Observabilidad",
1102
+ "infrastructure": "Infraestructura",
1103
+ "personal": "Personal (solo tú)"
1104
+ },
1105
+ "items": {
1106
+ "openrouter": {
1107
+ "description": "Una sola puerta de enlace a más de 300 modelos. Añade tu clave y activa modelos en un único lugar."
1108
+ },
1109
+ "vendors": {
1110
+ "label": "Proveedores y claves",
1111
+ "description": "Suscripciones de LLM del espacio de trabajo y claves API de proveedores."
1112
+ },
1113
+ "github": {
1114
+ "description": "Conecta la GitHub App del espacio de trabajo y explora repositorios, PR e incidencias."
1115
+ },
1116
+ "slack": {
1117
+ "description": "Envía las notificaciones al espacio de Slack de tu equipo."
1118
+ },
1119
+ "documentSource": {
1120
+ "description": "Vincula {source} como fuente de documentos para el contexto de requisitos."
1121
+ },
1122
+ "documentImport": {
1123
+ "label": "Importar y generar",
1124
+ "description": "Importa documentos de una fuente conectada y genera estructura."
1125
+ },
1126
+ "taskSource": {
1127
+ "description": "Vincula {source} para importar y consultar incidencias del rastreador."
1128
+ },
1129
+ "taskImport": {
1130
+ "label": "Importar incidencias",
1131
+ "description": "Importa incidencias de un rastreador conectado al tablero."
1132
+ },
1133
+ "trackerSettings": {
1134
+ "label": "Ajustes del rastreador de incidencias"
1135
+ },
1136
+ "observability": {
1137
+ "label": "Salud posterior al lanzamiento",
1138
+ "description": "Vigila los monitores y SLO después de publicar una versión (Datadog)."
1139
+ },
1140
+ "environment": {
1141
+ "label": "Entornos efímeros",
1142
+ "description": "Donde el agente Tester se ejecuta contra un entorno de vista previa en vivo."
1143
+ },
1144
+ "runnerPool": {
1145
+ "label": "Grupo de ejecutores autoalojado",
1146
+ "description": "Donde se ejecutan los agentes de código cuando no se usan los Cloudflare Containers."
1147
+ },
1148
+ "localMode": {
1149
+ "label": "Modo local",
1150
+ "description": "Grupo de contenedores en caliente y reutilización de checkout por repositorio para el ejecutor local."
1151
+ },
1152
+ "githubPat": {
1153
+ "label": "Mi token de GitHub",
1154
+ "description": "Un token de acceso personal usado para las ejecuciones que inicias (pushes, PR, CI, fusión)."
1155
+ },
1156
+ "localRunners": {
1157
+ "label": "Mis ejecutores locales",
1158
+ "description": "Tus ejecutores de modelos en tu propia máquina (Ollama, LM Studio, vLLM…)."
1159
+ }
1160
+ }
1161
+ }
1162
+ },
1163
+ "settings": {
1164
+ "modelConfiguration": {
1165
+ "title": "Configuración de modelos",
1166
+ "subtitle": "Ajustes preestablecidos que asignan un modelo a cada agente. Una tarea elige uno; las tareas usan por defecto el ajuste predeterminado del espacio de trabajo.",
1167
+ "back": "Atrás",
1168
+ "closeEsc": "Cerrar (Esc)",
1169
+ "quota": "cuota",
1170
+ "list": {
1171
+ "intro": "Cada ajuste establece un {baseModel} para cada agente, con anulaciones opcionales por agente. Un modelo fijado en una tarea individual sigue prevaleciendo sobre el ajuste.",
1172
+ "introBaseModel": "modelo base",
1173
+ "newPreset": "Nuevo ajuste",
1174
+ "loadingCatalog": "Cargando el catálogo de modelos…",
1175
+ "default": "Predeterminado",
1176
+ "setDefaultTitle": "Establecer como predeterminado del espacio de trabajo",
1177
+ "editTitle": "Editar ajuste",
1178
+ "deleteDisabledTitle": "El ajuste predeterminado no se puede eliminar",
1179
+ "deleteTitle": "Eliminar ajuste",
1180
+ "basePrefix": "Base:",
1181
+ "overrideCount": "{count} anulación | {count} anulaciones",
1182
+ "empty": "Aún no hay ajustes. Crea uno para asignar modelos a tus agentes."
1183
+ },
1184
+ "editor": {
1185
+ "useBaseModel": "Usar el modelo base",
1186
+ "baseModel": "Modelo base",
1187
+ "nameLabel": "Nombre",
1188
+ "namePlaceholder": "p. ej. Kimi K2.7",
1189
+ "baseModelLabel": "Modelo base (aplicado a cada agente)",
1190
+ "makeDefault": "Hacer que este sea el predeterminado del espacio de trabajo",
1191
+ "perAgentOverrides": "Anulaciones por agente",
1192
+ "filterPlaceholder": "Filtrar agentes…",
1193
+ "noAgentsMatch": "Ningún agente coincide con \"{filter}\".",
1194
+ "saveChanges": "Guardar cambios",
1195
+ "createPreset": "Crear ajuste"
1196
+ },
1197
+ "toast": {
1198
+ "setDefaultFailed": "No se pudo establecer el ajuste predeterminado",
1199
+ "deleteFailed": "No se pudo eliminar el ajuste",
1200
+ "nameRequiredTitle": "Nombre obligatorio",
1201
+ "nameRequiredBody": "Dale un nombre al ajuste.",
1202
+ "saveFailed": "No se pudo guardar el ajuste"
1203
+ }
1204
+ },
1205
+ "account": {
1206
+ "title": "Configuración de la cuenta",
1207
+ "noAccount": "Ninguna cuenta seleccionada.",
1208
+ "tabs": {
1209
+ "team": "Equipo y acceso",
1210
+ "fragments": "Fragmentos de contexto"
1211
+ }
1212
+ },
1213
+ "providerConnection": {
1214
+ "fallbackTitle": "Proveedor",
1215
+ "kind": {
1216
+ "environment": {
1217
+ "title": "Proveedor de entornos efímeros",
1218
+ "blurb": "Donde el agente Tester se ejecuta contra un entorno de vista previa en vivo. Configura los ajustes por espacio de trabajo y las credenciales que necesita tu proveedor."
1219
+ },
1220
+ "runner-pool": {
1221
+ "title": "Grupo de ejecutores autoalojado",
1222
+ "blurb": "Donde se ejecutan los agentes de codificación cuando no se usan los contenedores de Cloudflare. Configura el endpoint del planificador del grupo y las credenciales."
1223
+ }
1224
+ },
1225
+ "delegation": {
1226
+ "title": "Delegación local",
1227
+ "intro": "De forma predeterminada, esta máquina ejecuta todo localmente: los agentes de contenedor en Docker del host y la infraestructura del Tester mediante docker-compose dentro del contenedor. Activa las opciones de abajo para delegar cualquiera de estas tareas en un servicio externo. Solo se aplica en modo local.",
1228
+ "agentsToggle": "Ejecutar los agentes de contenedor en el grupo de ejecutores",
1229
+ "agentsHint": "Envía cada agente de contenedor (codificador, tester, fusionador, bootstrap, …) al grupo de ejecutores autoalojado de este espacio de trabajo en lugar de a Docker del host.",
1230
+ "registerPoolPrompt": "{link} primero para habilitar esto.",
1231
+ "registerPoolLink": "Registra un grupo de ejecutores",
1232
+ "envToggle": "Aprovisionar los entornos del Tester mediante el proveedor",
1233
+ "envHint": "Levanta el entorno de vista previa del Tester a través del proveedor de entornos configurado abajo en lugar de docker-compose dentro del contenedor. Conecta un proveedor primero para habilitar esto.",
1234
+ "updateFailed": "No se pudo actualizar la delegación"
1235
+ },
1236
+ "runnerPoolLocalHint": "Registra tu grupo aquí y luego activa \"Ejecutar los agentes de contenedor en el grupo de ejecutores\" en la pantalla {link} para enrutar los agentes de este espacio de trabajo hacia él.",
1237
+ "ephemeralEnvironments": "Entornos efímeros",
1238
+ "viewLogs": "Ver registros",
1239
+ "hideLogs": "Ocultar registros",
1240
+ "connectedAt": "Conectado · {baseUrl}",
1241
+ "missingConfig": "Falta configuración obligatoria: {fields}",
1242
+ "manifestEditorUnavailable": "Este proveedor se configura redactando un manifiesto. El editor de manifiestos integrado aún no está disponible; regístralo a través de la API por ahora.",
1243
+ "form": {
1244
+ "updateConfiguration": "Actualizar configuración",
1245
+ "connect": "Conectar",
1246
+ "reenterSecrets": "Vuelve a introducir el campo secreto para guardar los cambios: los secretos almacenados son de solo escritura y no se muestran. | Vuelve a introducir los campos secretos para guardar los cambios: los secretos almacenados son de solo escritura y no se muestran.",
1247
+ "optionalLabel": "{label} (opcional)"
1248
+ },
1249
+ "field": {
1250
+ "defaultsTo": "Por defecto: {value}"
1251
+ },
1252
+ "test": {
1253
+ "button": "Probar conexión",
1254
+ "ok": "Conexión correcta",
1255
+ "failed": "Falló la conexión"
1256
+ },
1257
+ "toast": {
1258
+ "saved": "{title} guardado",
1259
+ "saveFailed": "No se pudo guardar la conexión",
1260
+ "removed": "Conexión eliminada",
1261
+ "removeFailed": "No se pudo eliminar la conexión"
1262
+ }
1263
+ },
1264
+ "serviceFragmentDefaults": {
1265
+ "intro": "Elige los fragmentos de buenas prácticas con los que arranca cada servicio nuevo. Su orientación se integra en el prompt de cada agente que trabaja con código (codificador, revisor, arquitecto, correctores) en las tareas del servicio. Puedes ajustar el conjunto por servicio en su inspector; cambiar este valor predeterminado no afecta a los servicios que ya existen.",
1266
+ "defaultFragments": "Fragmentos predeterminados",
1267
+ "addFragment": "Añadir fragmento",
1268
+ "empty": "Ninguno: los servicios nuevos arrancan sin fragmentos a nivel de servicio.",
1269
+ "saveFailed": "No se pudieron guardar los fragmentos predeterminados",
1270
+ "footer": {
1271
+ "question": "¿Necesitas añadir o editar los fragmentos en sí (redactados a mano, documentos enlazados, repos)?",
1272
+ "manageBoard": "Gestionar la biblioteca de fragmentos de este tablero →",
1273
+ "manageAccount": "Gestionar los fragmentos de la cuenta →"
1274
+ }
1275
+ },
1276
+ "issueTracker": {
1277
+ "filing": {
1278
+ "heading": "Dónde se registran los tickets",
1279
+ "description": "La canalización recurrente de deuda técnica crea una incidencia antes de la implementación y la registra en este gestor. Elige {none} para omitir el registro.",
1280
+ "none": "Ninguno",
1281
+ "githubHint": "GitHub Issues usa tu GitHub App instalada, que aún no está conectada. Instálala en {link}: el registro permanece desactivado hasta entonces.",
1282
+ "githubHintLink": "Integraciones → GitHub",
1283
+ "jiraHint": "Jira aún no está conectado. {link} para registrar y vincular incidencias.",
1284
+ "linearHint": "Linear aún no está conectado. {link} para registrar y vincular incidencias.",
1285
+ "connectLink": "Conéctalo",
1286
+ "jiraProjectKey": "Clave de proyecto de Jira",
1287
+ "jiraProjectKeyHelp": "Los nuevos tickets se registran en este proyecto.",
1288
+ "linearTeamId": "Id de equipo de Linear",
1289
+ "linearTeamIdHelp": "Las nuevas incidencias se crean en este equipo (Linear requiere un equipo para crear una incidencia)."
1290
+ },
1291
+ "vendor": {
1292
+ "github": "GitHub Issues",
1293
+ "jira": "Jira",
1294
+ "linear": "Linear"
1295
+ },
1296
+ "linking": {
1297
+ "heading": "Vincular incidencias como contexto",
1298
+ "description": "Cuando se ofrece una fuente, puedes importar sus incidencias y adjuntarlas a una tarea, para que los agentes vean la descripción de la incidencia y los comentarios mientras implementan. Esto es independiente del gestor de registro de arriba.",
1299
+ "github": {
1300
+ "available": "Usa tu GitHub App instalada: no se necesitan credenciales.",
1301
+ "unavailable": "Instala la GitHub App (Integraciones → GitHub) para ofrecer esta fuente."
1302
+ },
1303
+ "checkSetup": "Comprobar configuración",
1304
+ "install": "Instalar",
1305
+ "connected": "Conectado.",
1306
+ "jira": {
1307
+ "connectHint": "Conecta con una cuenta de Jira y un token de API."
1308
+ },
1309
+ "linear": {
1310
+ "connectHint": "Conecta con una clave de API personal de Linear."
1311
+ },
1312
+ "connect": "Conectar"
1313
+ },
1314
+ "writeback": {
1315
+ "heading": "Escritura de vuelta",
1316
+ "description": "Escribe de vuelta en la incidencia o incidencias vinculadas a una tarea a medida que avanza su pull request. Cada opción es el valor predeterminado del espacio de trabajo y puede anularse por tarea en el inspector. Las incidencias de GitHub se cierran de forma nativa; las de Jira pasan al primer estado de su categoría {done}.",
1317
+ "done": "Hecho",
1318
+ "commentOnOpen": {
1319
+ "label": "Comentar cuando se abre un PR",
1320
+ "help": "Publica un comentario en la incidencia vinculada con el enlace del nuevo pull request."
1321
+ },
1322
+ "resolveOnMerge": {
1323
+ "label": "Cerrar como resuelta cuando se fusiona un PR",
1324
+ "help": "Comenta que el PR se fusionó y luego cierra / resuelve la incidencia vinculada."
1325
+ }
1326
+ },
1327
+ "probeFailure": {
1328
+ "title": "El seguimiento de incidencias no está disponible",
1329
+ "disabled": "La integración de fuentes de tareas está desactivada en este despliegue (su clave de cifrado no está configurada). Define ENCRYPTION_KEY en el backend para habilitar el seguimiento de incidencias.",
1330
+ "serverError": "El servicio de seguimiento de incidencias devolvió un error (HTTP {status}): {message}. Esto suele significar que el backend no está totalmente migrado/configurado.",
1331
+ "loadFailedStatus": "No se pudo cargar la configuración del gestor de incidencias (HTTP {status}): {message}",
1332
+ "loadFailed": "No se pudo cargar la configuración del gestor de incidencias: {message}"
1333
+ },
1334
+ "toast": {
1335
+ "saved": "Gestor de incidencias guardado",
1336
+ "saveFailed": "No se pudo guardar la configuración",
1337
+ "updateFailed": "No se pudo actualizar",
1338
+ "checkFailed": "La comprobación falló"
1339
+ }
1340
+ },
1341
+ "userSecrets": {
1342
+ "title": "Mi token de GitHub",
1343
+ "intro": "Almacena un token de acceso personal usado para las ejecuciones que {you} inicias: los pushes, los pull requests, la puerta de CI y las fusiones se atribuyen a tu acceso de GitHub. Almacenado {scope}; el token es de solo escritura y nunca se vuelve a mostrar.",
1344
+ "introYou": "tú",
1345
+ "introScope": "solo para ti",
1346
+ "connectedStored": "Conectado · token almacenado",
1347
+ "replaceToken": "Reemplazar token",
1348
+ "addToken": "Añadir token",
1349
+ "labelField": "Etiqueta (opcional)",
1350
+ "optionalField": "{label} (opcional)",
1351
+ "testConnection": "Probar conexión",
1352
+ "tokenValid": "Token válido",
1353
+ "tokenRejected": "Token rechazado",
1354
+ "secretFallback": "Secreto",
1355
+ "toast": {
1356
+ "saved": "{label} guardado",
1357
+ "saveFailed": "No se pudo guardar el secreto",
1358
+ "removed": "Secreto eliminado",
1359
+ "removeFailed": "No se pudo eliminar el secreto"
1360
+ }
1361
+ },
1362
+ "mergeThresholds": {
1363
+ "intro": "Políticas de fusión automática con nombre que una tarea puede elegir. Cuando CI pasa, el agente {merger} puntúa el PR en complejidad, riesgo e impacto (0-100%); el PR se fusiona automáticamente solo cuando cada puntuación está en o por debajo de los límites del ajuste, de lo contrario se genera una notificación de revisión. El ajuste predeterminado rige cualquier tarea que no elija ninguno.",
1364
+ "mergerAgent": "merger",
1365
+ "concern": {
1366
+ "none": "Ninguno (detener siempre)",
1367
+ "low": "Bajo",
1368
+ "medium": "Medio",
1369
+ "high": "Alto (nunca detener)"
1370
+ },
1371
+ "presetNamePlaceholder": "Nombre del ajuste",
1372
+ "default": "Predeterminado",
1373
+ "makeDefault": "Hacer predeterminado",
1374
+ "deleteDefaultBlocked": "El ajuste predeterminado no se puede eliminar",
1375
+ "deletePreset": "Eliminar ajuste",
1376
+ "field": {
1377
+ "maxComplexity": "Complejidad máx. %",
1378
+ "maxRisk": "Riesgo máx. %",
1379
+ "maxImpact": "Impacto máx. %",
1380
+ "ciMaxAttempts": "Intentos de corrección de CI",
1381
+ "maxRequirementIterations": "Iteraciones de requisitos",
1382
+ "maxRequirementConcernAllowed": "Aprobación automática de inquietudes hasta"
1383
+ },
1384
+ "newPreset": "Nuevo ajuste",
1385
+ "create": {
1386
+ "name": "Nombre",
1387
+ "namePlaceholder": "p. ej. Cauteloso",
1388
+ "complexity": "Cmplj%",
1389
+ "risk": "Riesgo%",
1390
+ "impact": "Impacto%",
1391
+ "ciFix": "Corr. CI",
1392
+ "reqIter": "Iter. req.",
1393
+ "autoPass": "Aprob. auto. hasta"
1394
+ },
1395
+ "add": "Añadir",
1396
+ "toast": {
1397
+ "saved": "Ajuste guardado",
1398
+ "saveFailed": "No se pudo guardar el ajuste",
1399
+ "created": "Ajuste creado",
1400
+ "createFailed": "No se pudo crear el ajuste",
1401
+ "defaultFailed": "No se pudo establecer el predeterminado",
1402
+ "deleteFailed": "No se pudo eliminar el ajuste"
1403
+ }
1404
+ },
1405
+ "observabilityConnection": {
1406
+ "title": "Salud posterior al lanzamiento",
1407
+ "intro": "Después de que se publica un lanzamiento, la puerta {gate} vigila los monitores/SLO de observabilidad configurados. Ante una regresión, genera un agente de guardia para investigar (una persona decide si revertir). Asigna qué monitores/SLO vigila un servicio desde el inspector de ese servicio.",
1408
+ "connection": {
1409
+ "heading": "Conexión",
1410
+ "provider": "Proveedor"
1411
+ },
1412
+ "datadog": {
1413
+ "site": "Sitio de Datadog",
1414
+ "apiKey": "Clave de API",
1415
+ "appKey": "Clave de aplicación"
1416
+ },
1417
+ "saveConnection": "Guardar conexión",
1418
+ "disconnect": "Desconectar",
1419
+ "incident": {
1420
+ "heading": "Enriquecimiento de incidentes",
1421
+ "configured": "Configurado",
1422
+ "notSet": "Sin establecer",
1423
+ "description": "Opcional. Ante una regresión, la investigación de guardia se publica en un incidente que estos sistemas YA abrieron a partir de las mismas señales (anotar, nunca volver a alertar). Los secretos son de solo escritura: dejarlos en blanco mantiene el valor almacenado sin cambios.",
1424
+ "pagerDutyToken": "Token de API de PagerDuty",
1425
+ "pagerDutyFromEmail": "Correo remitente de PagerDuty",
1426
+ "incidentIoKey": "Clave de API de incident.io",
1427
+ "clear": "Borrar"
1428
+ },
1429
+ "status": {
1430
+ "notConnected": "Sin conectar",
1431
+ "connected": "Conectado",
1432
+ "connectedWithSite": "Conectado ({site})"
1433
+ },
1434
+ "toast": {
1435
+ "loadFailed": "No se pudo cargar la configuración de observabilidad",
1436
+ "incidentCredsRequired": "Introduce las credenciales de PagerDuty o incident.io",
1437
+ "incidentSaved": "Enriquecimiento de incidentes guardado",
1438
+ "incidentSaveFailed": "No se pudo guardar el enriquecimiento de incidentes",
1439
+ "incidentDisconnectFailed": "No se pudo desconectar el enriquecimiento de incidentes",
1440
+ "connected": "Observabilidad conectada",
1441
+ "connectFailed": "No se pudo guardar la conexión",
1442
+ "disconnectFailed": "No se pudo desconectar"
1443
+ }
1444
+ },
1445
+ "localMode": {
1446
+ "title": "Modo local",
1447
+ "intro": "Ajustes del ejecutor de contenedores local, almacenados en el despliegue de esta máquina (reemplazó las variables de entorno {poolVars} / {harnessVars}). Guardar redimensiona el grupo en caliente en vivo, sin necesidad de reiniciar; las ejecuciones en curso conservan el contenedor que ya tienen.",
1448
+ "pool": {
1449
+ "heading": "Grupo de contenedores en caliente",
1450
+ "description": "Mantén contenedores de arnés inactivos listos y vuelve a asignar uno (prefiriendo un contenedor que ya tenga el repositorio de la ejecución) en lugar de iniciar en frío por ejecución. Tamaño de grupo 0 lo desactiva. Requiere un entorno de la familia Docker (Docker/Podman/OrbStack/Colima); se ignora en Apple {appleContainer}.",
1451
+ "size": {
1452
+ "label": "Tamaño del grupo",
1453
+ "help": "Máximo de contenedores en caliente inactivos. 0 = agrupación desactivada."
1454
+ },
1455
+ "minWarm": {
1456
+ "label": "Precalentar al arrancar",
1457
+ "help": "Contenedores iniciados cuando arranca el servicio."
1458
+ },
1459
+ "max": {
1460
+ "label": "Máx. de contenedores",
1461
+ "help": "Límite estricto (asignados + inactivos). En blanco = tamaño del grupo.",
1462
+ "placeholder": "(tamaño del grupo)"
1463
+ },
1464
+ "idleTimeout": {
1465
+ "label": "Tiempo de inactividad (minutos)",
1466
+ "help": "Expulsar un contenedor agrupado inactivo después de."
1467
+ }
1468
+ },
1469
+ "checkout": {
1470
+ "heading": "Reutilización de la copia de trabajo",
1471
+ "description": "Cuando un contenedor en caliente ya tiene el repositorio de la ejecución, el arnés reutiliza su copia de trabajo por repositorio (limpieza + obtención + cambio de rama) en lugar de clonar de nuevo.",
1472
+ "workspaceRoot": {
1473
+ "label": "Raíz del espacio de trabajo",
1474
+ "help": "Directorio absoluto dentro del contenedor donde vive la copia de trabajo reutilizada."
1475
+ },
1476
+ "cleanKeep": {
1477
+ "label": "Conservar al limpiar (separado por comas)",
1478
+ "help": "Directorios de caché de dependencias que la limpieza por ejecución conserva."
1479
+ }
1480
+ },
1481
+ "toast": {
1482
+ "saved": "Configuración local guardada",
1483
+ "saveFailed": "No se pudo guardar la configuración local"
1484
+ }
1485
+ },
1486
+ "openRouterCatalog": {
1487
+ "intro": "Accede a {models} a través de una única pasarela. Añade tu clave de OpenRouter abajo y luego habilita los modelos que quieras. Aparecen en el selector de modelos con su ventana de contexto y su precio, y se contabilizan en tu presupuesto de gasto.",
1488
+ "introModels": "más de 300 modelos",
1489
+ "connectHeading": "Conecta tu clave de OpenRouter",
1490
+ "step1": "Abre {link} y crea una clave de API.",
1491
+ "step1Link": "openrouter.ai → Claves ↗",
1492
+ "step2": "Copia la clave (empieza por {prefix}) y pégala abajo.",
1493
+ "scope": "Ámbito",
1494
+ "scopeWorkspace": "Este espacio de trabajo",
1495
+ "scopeUser": "Mis claves (solo yo)",
1496
+ "labelOptional": "Etiqueta (opcional)",
1497
+ "labelPlaceholder": "p. ej. clave del equipo",
1498
+ "apiKey": "Clave de API",
1499
+ "connectAndBrowse": "Conectar y explorar",
1500
+ "keyConnected": "Clave de OpenRouter conectada",
1501
+ "manageKeys": "Gestionar en Proveedores y claves",
1502
+ "refresh": "Actualizar catálogo",
1503
+ "enableRecommended": "Habilitar recomendados",
1504
+ "filterPlaceholder": "Filtrar por nombre o slug…",
1505
+ "empty": "Aún no hay modelos. Pulsa {action} para cargar la lista en vivo de OpenRouter.",
1506
+ "enabledCount": "ningún modelo habilitado | {count} habilitado | {count} habilitados",
1507
+ "context": "{value} ctx",
1508
+ "contextThousands": "{value}K ctx",
1509
+ "price": "{input}/{output} por Mtok",
1510
+ "toast": {
1511
+ "connected": "Clave de OpenRouter conectada",
1512
+ "connectFailed": "No se pudo conectar la clave",
1513
+ "rejected": "OpenRouter rechazó la clave.",
1514
+ "unreachable": "No se pudo contactar con OpenRouter",
1515
+ "connectFirst": "Conecta primero una clave de OpenRouter.",
1516
+ "saved": "Catálogo de OpenRouter guardado",
1517
+ "saveFailed": "No se pudo guardar el catálogo"
1518
+ }
1519
+ },
1520
+ "workspaceSettings": {
1521
+ "title": "Configuración del espacio de trabajo",
1522
+ "tabs": {
1523
+ "workspace": "Espacio de trabajo",
1524
+ "budget": "Presupuesto",
1525
+ "merge": "Umbrales de fusión",
1526
+ "tracker": "Gestor de incidencias",
1527
+ "fragments": "Buenas prácticas del servicio"
1528
+ },
1529
+ "waiting": {
1530
+ "heading": "Esperando a una persona",
1531
+ "body": "Una ejecución detenida a la espera de una decisión humana (una revisión, una aprobación, una fusión) espera todo lo que haga falta y nunca se cancela. Pasados estos minutos, su notificación se pone en rojo y se marca como {overdue} en la bandeja de entrada.",
1532
+ "overdue": "Vencida",
1533
+ "escalateAfter": "Escalar después de (minutos)"
1534
+ },
1535
+ "taskLimit": {
1536
+ "heading": "Tareas en ejecución por servicio",
1537
+ "body": "Limita cuántas tareas pueden ejecutarse a la vez bajo un servicio. Iniciar una tarea por encima del límite se rechaza con un mensaje claro hasta que termine una tarea en ejecución.",
1538
+ "mode": "Modo",
1539
+ "maxRunning": "Máximo de tareas en ejecución",
1540
+ "maxPerType": "Máximo de tareas de tipo {type}",
1541
+ "modes": {
1542
+ "off": "Sin límite",
1543
+ "shared": "Compartido entre todos los tipos",
1544
+ "per_type": "Por tipo de tarea"
1545
+ }
1546
+ },
1547
+ "taskTypes": {
1548
+ "feature": "función",
1549
+ "bug": "error",
1550
+ "document": "documento",
1551
+ "spike": "spike"
1552
+ },
1553
+ "observability": {
1554
+ "heading": "Observabilidad del agente",
1555
+ "body": "Almacena el contexto completo proporcionado a cada agente: los prompts compuestos, los fragmentos de buenas prácticas incorporados y el contenido íntegro de los archivos inyectados en su contenedor, para poder inspeccionarlo después en la vista de observabilidad. Los cuerpos se conservan durante la misma ventana que la telemetría de LLM por llamada. Desactívalo para dejar de almacenarlo (las instantáneas existentes se eliminan por retención).",
1556
+ "toggle": "Almacenar el contexto completo del agente"
1557
+ },
1558
+ "retention": {
1559
+ "heading": "Retención de capturas de pantalla",
1560
+ "body": "Cuánto tiempo conservar las capturas de pantalla del probador de UI y las imágenes de diseño de referencia con las que se comparan (la verificación visual). Un trabajo de limpieza diario elimina tanto los bytes de las imágenes como sus metadatos cuando superan esta ventana.",
1561
+ "days": "Retención (días)"
1562
+ },
1563
+ "kaizen": {
1564
+ "heading": "Agente Kaizen",
1565
+ "body": "Al completarse cada ejecución, el agente Kaizen evalúa cómo fue cada paso del agente, desde fluido y eficiente hasta confuso y caótico, y recomienda mejoras de prompt/modelo. Una combinación de prompt + agente + modelo que obtiene una buena nota sin recomendaciones cinco veces seguidas se marca como verificada y deja de evaluarse. La evaluación se ejecuta en segundo plano y se muestra en los detalles de la ejecución y en la pantalla de Kaizen. Configura el modelo del evaluador en Configuración de modelos (el agente \"Kaizen\").",
1566
+ "toggle": "Evaluar ejecuciones de agentes con Kaizen"
1567
+ },
1568
+ "budget": {
1569
+ "heading": "Presupuesto de gasto mensual",
1570
+ "body": "El uso de tokens se contabiliza por llamada al LLM, se valora y se limita con este presupuesto. Al alcanzarlo, las ejecuciones de este espacio de trabajo se pausan y el tablero muestra una advertencia. Déjalo en blanco para heredar el valor predeterminado integrado (unos 100 EUR/mes).",
1571
+ "monthlyLimit": "Límite mensual",
1572
+ "defaultPlaceholder": "Predeterminado",
1573
+ "currency": "Moneda (ISO 4217)",
1574
+ "save": "Guardar presupuesto"
1575
+ },
1576
+ "toast": {
1577
+ "saved": "Configuración guardada",
1578
+ "saveFailed": "No se pudo guardar la configuración",
1579
+ "budgetSaved": "Presupuesto guardado",
1580
+ "budgetSaveFailed": "No se pudo guardar el presupuesto"
1581
+ }
1582
+ },
1583
+ "localModelEndpoints": {
1584
+ "title": "Mis runners locales",
1585
+ "intro": "Apunta los agentes a un LLM que se ejecuta en {ownMachine} (Ollama, LM Studio, llama.cpp, vLLM o cualquier servidor compatible con OpenAI). Un runner se almacena {justForYou} (un runner vive en tu equipo), y los modelos que habilites aparecen automáticamente en el selector de modelos. La clave de API (la mayoría de los runners la ignoran) es de solo escritura y nunca se vuelve a mostrar.",
1586
+ "introOwnMachine": "tu propia máquina",
1587
+ "introJustForYou": "solo para ti",
1588
+ "modelCount": "ningún modelo | {count} modelo | {count} modelos",
1589
+ "keySet": "clave establecida",
1590
+ "edit": "Editar",
1591
+ "editRunner": "Editar runner",
1592
+ "addRunner": "Añadir un runner",
1593
+ "runnerType": "Tipo de runner",
1594
+ "labelOptional": "Etiqueta (opcional)",
1595
+ "labelPlaceholder": "Mi {name}",
1596
+ "baseUrl": "URL base",
1597
+ "apiKeyOptional": "Clave de API (opcional)",
1598
+ "apiKeyKeepPlaceholder": "déjalo en blanco para conservar la clave guardada",
1599
+ "apiKeyIgnorePlaceholder": "la mayoría de los runners la ignoran",
1600
+ "testConnection": "Probar conexión",
1601
+ "unreachable": "No se pudo contactar con el runner.",
1602
+ "reachable": "Accesible · ningún modelo | Accesible · {count} modelo | Accesible · {count} modelos",
1603
+ "noModels": "No se informó de ningún modelo.",
1604
+ "enableModels": "Habilitar modelos",
1605
+ "toast": {
1606
+ "saved": "{name} guardado",
1607
+ "saveFailed": "No se pudo guardar el runner",
1608
+ "removed": "Runner eliminado",
1609
+ "removeFailed": "No se pudo eliminar el runner"
1610
+ }
1611
+ }
713
1612
  }
714
1613
  }