fix(i18n): localize sidebar, settings tabs, and settings section titles

Three connected bugs where the Label/SettingsSection APIs took a `String`,
which routes through the StringProtocol overloads and bypasses localization
entirely. Identified by the user after testing zh-Hans / de / fr — the
sidebar menu items, Settings tab bar, and Settings section headers all
remained English under any App Language override.

- SidebarSection now exposes displayName: LocalizedStringResource; SidebarView
  builds Label via the Text/Image builders so the catalog key is actually
  used.
- SettingsTab gets the same displayName treatment; the .tabItem Label builds
  through the Text/Image builder too.
- SettingsSection.title changes from String → LocalizedStringKey so literal
  call sites (all ~20 of them) now extract into the catalog. Two call sites
  that were passing String variables (PlatformsView, CredentialPoolsView) are
  wrapped via LocalizedStringKey(...) — brand/provider names fall through to
  English as before. AuxiliaryTab's static task list gets a LocalizedStringKey
  column so its section titles extract too.

This change newly extracts 65 previously-invisible section-title keys into
the catalog; translations added for all six locales. Catalog: 575 → 644
source keys, each locale translated for 583 of them (brand names / protocol
names / format-only keys intentionally fall through).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-04-21 03:32:32 +02:00
parent 1726a613a5
commit f47034d4ad
14 changed files with 3078 additions and 17 deletions
+65
View File
@@ -20,11 +20,14 @@
"%lld tools": "%lld ferramentas",
"30 Days": "30 dias",
"7 Days": "7 dias",
"90 Days": "90 dias",
"A QR code will appear below. Scan it with WhatsApp on your phone. The session is saved to ~/.hermes/platforms/whatsapp/ so you won't need to scan again after restarts.": "Um QR code aparecerá abaixo. Escaneie com o WhatsApp do seu celular. A sessão é salva em ~/.hermes/platforms/whatsapp/ para não precisar escanear de novo após reinícios.",
"API Key": "Chave de API",
"API keys are never displayed in full. Scarf only shows the last 4 characters for identification. Full key values are stored by hermes in ~/.hermes/auth.json.": "Chaves de API nunca são exibidas por completo. O Scarf mostra apenas os últimos 4 caracteres para identificação. Os valores completos são armazenados pelo hermes em ~/.hermes/auth.json.",
"Access Control": "Controle de acesso",
"Actions": "Ações",
"Active": "Ativa",
"Active Personality": "Personalidade ativa",
"Active profile": "Perfil ativo",
"Activity": "Atividade",
"Activity Patterns": "Padrões de atividade",
@@ -42,6 +45,7 @@
"Add from Preset": "Adicionar a partir de predefinição",
"Add rotation credentials so hermes can failover between keys when one hits rate limits.": "Adicione credenciais de rotação para que o hermes possa alternar entre chaves quando uma atingir o limite de taxa.",
"Add your first command": "Adicione seu primeiro comando",
"Advanced": "Avançado",
"After approving in your browser, the provider shows a code. Paste it below and submit.": "Após aprovar no navegador, o provedor mostra um código. Cole abaixo e envie.",
"Agent": "Agent",
"All": "Todos",
@@ -49,25 +53,34 @@
"All Sessions": "Todas as sessões",
"All Time": "Todo o período",
"All installed hub skills are up to date.": "Todas as habilidades instaladas do hub estão atualizadas.",
"App Credentials": "Credenciais do app",
"Approval": "Aprovação",
"Approvals": "Aprovações",
"Approve": "Aprovar",
"Archive": "Arquivar",
"Args (one per line)": "Argumentos (um por linha)",
"Arguments": "Argumentos",
"Assistant Message": "Mensagem do assistente",
"Auth": "Auth",
"Authentication": "Autenticação",
"Authentication uses ssh-agent": "A autenticação usa ssh-agent",
"Authorization Code": "Código de autorização",
"Authorization URL": "URL de autorização",
"Aux Models": "Modelos auxiliares",
"Auxiliary tasks use separate, typically cheaper models. Leave Provider as `auto` to inherit the main provider.": "Tarefas auxiliares usam modelos separados, geralmente mais baratos. Deixe Provedor em `auto` para herdar o provedor principal.",
"Back": "Voltar",
"Back to Catalog": "Voltar ao catálogo",
"Backend": "Backend",
"Backup & Restore": "Backup e restauração",
"Backup Now": "Fazer backup agora",
"Becomes the key under mcp_servers: in config.yaml.": "Vira a chave sob mcp_servers: em config.yaml.",
"Behavior": "Comportamento",
"Browse": "Explorar",
"Browse Hub": "Explorar hub",
"Browse the Hub": "Explorar o hub",
"Browse...": "Explorar...",
"Browser": "Navegador",
"Built-in Memory": "Memória integrada",
"By Day": "Por dia",
"By Hour": "Por hora",
"Call timeout": "Tempo limite da chamada",
@@ -81,6 +94,7 @@
"Check for Updates": "Verificar atualizações",
"Check for Updates…": "Verificar atualizações…",
"Checking…": "Verificando…",
"Checkpoints": "Checkpoints",
"Choose a cron job from the list": "Escolha uma tarefa cron na lista",
"Choose a profile to inspect.": "Escolha um perfil para inspecionar.",
"Choose a project from the sidebar to view its dashboard.": "Escolha um projeto na barra lateral para ver o painel.",
@@ -98,16 +112,21 @@
"Close Window": "Fechar janela",
"Code: %@": "Código: %@",
"Command": "Comando",
"Command Allowlist": "Lista de comandos permitidos",
"Command looks destructive. Double-check before saving.": "O comando parece destrutivo. Revise antes de salvar.",
"Component": "Componente",
"Compress": "Compactar",
"Compress Conversation": "Compactar conversa",
"Compress conversation (/compress)": "Compactar conversa (/compress)",
"Compression": "Compactação",
"Config Diagnostics": "Diagnóstico de configuração",
"Configure": "Configurar",
"Connect timeout": "Tempo limite de conexão",
"Connected": "Conectado",
"Connected — can't read Hermes state": "Conectado — não é possível ler o estado do Hermes",
"Connection": "Conexão",
"Container Limits": "Limites do contêiner",
"Context & Compression": "Contexto e compactação",
"Continue Last Session": "Continuar última sessão",
"Copied": "Copiado",
"Copy": "Copiar",
@@ -132,21 +151,26 @@
"Cron Jobs": "Tarefas cron",
"Current: %@": "Atual: %@",
"Custom…": "Personalizado…",
"Daemon Endpoint": "Endpoint do daemon",
"Daemon running": "Daemon em execução",
"Dashboard": "Painel",
"Default": "Padrão",
"Default: ~/.hermes": "Padrão: ~/.hermes",
"Defaults to ~/.ssh/config or current user": "Padrão é ~/.ssh/config ou usuário atual",
"Defined Personalities": "Personalidades definidas",
"Delegation": "Delegação",
"Delete": "Excluir",
"Delete %@?": "Excluir %@?",
"Delete Session?": "Excluir sessão?",
"Delete profile '%@'?": "Excluir perfil '%@'?",
"Delete...": "Excluir...",
"Deliver: %@": "Entregar: %@",
"Details": "Detalhes",
"Diagnostic Output": "Saída de diagnóstico",
"Diagnostics": "Diagnóstico",
"Disable": "Desativar",
"Disabled": "Desativado",
"Display": "Exibição",
"Docs": "Docs",
"Done": "Concluído",
"Edit": "Editar",
@@ -160,10 +184,13 @@
"Enable 2FA on your email account and generate an app password. Regular account passwords will fail. Always set allowed senders — otherwise anyone knowing the address can message the agent.": "Ative o 2FA na sua conta de e-mail e gere uma senha de aplicativo. Senhas normais da conta não funcionam. Sempre defina remetentes permitidos — caso contrário, qualquer um que saiba o endereço pode enviar mensagens para o agente.",
"Enable the webhook platform to accept event-driven agent triggers. The HMAC secret is used as a fallback when individual routes don't provide their own.": "Ative a plataforma de webhook para aceitar gatilhos de agente orientados a eventos. O segredo HMAC é usado como fallback quando rotas individuais não fornecem o próprio.",
"Enabled": "Ativado",
"End-to-End Encryption (experimental)": "Criptografia ponta a ponta (experimental)",
"Entity Filters (config.yaml only)": "Filtros de entidade (somente config.yaml)",
"Env vars, headers, and tool filters can be edited after the server is added.": "Variáveis de ambiente, cabeçalhos e filtros de ferramentas podem ser editados após o servidor ser adicionado.",
"Environment Variables": "Variáveis de ambiente",
"Error": "Erro",
"Errors": "Erros",
"Event Filters": "Filtros de eventos",
"Exclude": "Excluir",
"Execute": "Executar",
"Expected at %@": "Esperado em %@",
@@ -172,18 +199,23 @@
"Export…": "Exportar…",
"Expose prompts": "Expor prompts",
"Expose resources": "Expor recursos",
"External Provider": "Provedor externo",
"Feedback": "Feedback",
"Fetch": "Buscar",
"Files": "Arquivos",
"Filter logs...": "Filtrar logs...",
"Filter servers...": "Filtrar servidores...",
"Filter skills...": "Filtrar habilidades...",
"Filter to session %@": "Filtrar para a sessão %@",
"Flush Memories": "Limpar memórias",
"Focus topic (optional)": "Tópico de foco (opcional)",
"Full copy of active profile (all state)": "Cópia completa do perfil ativo (todo o estado)",
"Gateway": "Gateway",
"Gateway Running": "Gateway em execução",
"Gateway Stopped": "Gateway parado",
"Gateway restart required": "Reinicialização do gateway necessária",
"General": "Geral",
"Global Settings": "Configurações globais",
"Header": "Cabeçalho",
"Headers": "Cabeçalhos",
"Health": "Saúde",
@@ -195,7 +227,10 @@
"Hide": "Ocultar",
"Hide Output": "Ocultar saída",
"Hide details": "Ocultar detalhes",
"Home Channel": "Canal principal",
"Homeserver": "Homeserver",
"Host key changed": "Chave do host alterada",
"Human Delay": "Atraso humano",
"ID: %@": "ID: %@",
"If this is the first connection, ensure your key is loaded with `ssh-add` and that the remote accepts it.": "Se esta for a primeira conexão, garanta que sua chave esteja carregada com `ssh-add` e que o remoto a aceite.",
"If you trust the change, remove the stale entry and reconnect:": "Se você confia na mudança, remova a entrada antiga e reconecte:",
@@ -217,6 +252,7 @@
"Last probe: %@": "Última verificação: %@",
"Last run: %@": "Última execução: %@",
"Last updated: %@": "Atualizado em: %@",
"Layout": "Layout",
"Leave blank to infer from the model ID's prefix (\"openai/...\" → openai).": "Deixe em branco para inferir pelo prefixo do ID do modelo (\"openai/...\" → openai).",
"Leave blank unless Hermes is installed at a non-default path (systemd services often live at /var/lib/hermes/.hermes; Docker sidecars vary). Test Connection auto-suggests a value when it detects one of the known alternates.": "Deixe em branco a menos que o Hermes esteja instalado em um caminho não padrão (serviços systemd geralmente ficam em /var/lib/hermes/.hermes; sidecars Docker variam). Testar conexão sugere automaticamente um valor ao detectar um dos caminhos alternativos conhecidos.",
"Level": "Nível",
@@ -227,7 +263,9 @@
"Loading session…": "Carregando sessão…",
"Local": "Local",
"Local (stdio)": "Local (stdio)",
"Locale": "Localidade",
"Log File": "Arquivo de log",
"Logging": "Registro",
"Logs": "Logs",
"MCP Servers": "Servidores MCP",
"MCP Servers (%lld)": "Servidores MCP (%lld)",
@@ -241,11 +279,14 @@
"Messages will appear here as the conversation progresses.": "As mensagens aparecerão aqui conforme a conversa progride.",
"Migrate": "Migrar",
"Missing required config:": "Configuração obrigatória ausente:",
"Modal": "Modal",
"Model": "Modelo",
"Model ID": "ID do modelo",
"Models": "Modelos",
"Monitor": "Monitor",
"Name": "Nome",
"Name (no leading slash)": "Nome (sem barra inicial)",
"Network": "Rede",
"New Session": "Nova sessão",
"New Webhook Subscription": "Nova assinatura de webhook",
"New name for '%@'": "Novo nome para '%@'",
@@ -283,6 +324,7 @@
"None": "Nenhum",
"Notable Sessions": "Sessões notáveis",
"OAuth login for %@": "Login OAuth para %@",
"OK": "OK",
"Open BotFather": "Abrir BotFather",
"Open Developer Portal": "Abrir Developer Portal",
"Open Local": "Abrir local",
@@ -294,6 +336,7 @@
"Open in Editor": "Abrir no editor",
"Open in new window": "Abrir em nova janela",
"Open session": "Abrir sessão",
"Optional": "Opcional",
"Optional — defaults to hostname": "Opcional — padrão é o nome do host",
"Optionally focus the summary on a specific topic. Leave blank to compress evenly.": "Opcionalmente, foque o resumo em um tópico específico. Deixe em branco para compactar uniformemente.",
"Other": "Outro",
@@ -304,11 +347,13 @@
"Pair Device": "Parear dispositivo",
"Paired Users": "Usuários pareados",
"Paste code here…": "Cole o código aqui…",
"Paths": "Caminhos",
"Pause": "Pausar",
"Pending Approvals": "Aprovações pendentes",
"Per-route subscriptions (events, prompt template, delivery target) are managed in the Webhooks sidebar — not here. This panel only controls whether the webhook platform is listening at all.": "As assinaturas por rota (eventos, template de prompt, alvo de entrega) são gerenciadas na barra lateral de Webhooks — não aqui. Este painel só controla se a plataforma de webhook está escutando.",
"Period": "Período",
"Personalities": "Personalidades",
"Personality": "Personalidade",
"Pick an MCP server to add.": "Escolha um servidor MCP para adicionar.",
"Pick one from the list, or add a new server from the toolbar.": "Escolha um da lista ou adicione um novo servidor pela barra de ferramentas.",
"Platforms": "Plataformas",
@@ -327,6 +372,7 @@
"Provider": "Provedor",
"Push to Talk": "Pressionar para falar",
"Push to talk (Ctrl+B)": "Pressionar para falar (Ctrl+B)",
"Push-to-Talk": "Pressionar para falar",
"Quick Commands": "Comandos rápidos",
"Quick commands are shell shortcuts hermes exposes in chat as `/command_name`. They live under `quick_commands:` in config.yaml.": "Comandos rápidos são atalhos de shell que o hermes expõe no chat como `/command_name`. Ficam em `quick_commands:` no config.yaml.",
"Quit Scarf": "Sair do Scarf",
@@ -338,6 +384,7 @@
"Recent Sessions": "Sessões recentes",
"Reconnect": "Reconectar",
"Recording…": "Gravando…",
"Redaction": "Redação",
"Refresh": "Atualizar",
"Reload": "Recarregar",
"Remote (HTTP)": "Remoto (HTTP)",
@@ -353,6 +400,8 @@
"Rename Profile": "Renomear perfil",
"Rename Session": "Renomear sessão",
"Rename...": "Renomear...",
"Required": "Obrigatório",
"Required Tokens": "Tokens obrigatórios",
"Requires: %@": "Requer: %@",
"Reset Cooldowns": "Redefinir cooldowns",
"Restart": "Reiniciar",
@@ -391,6 +440,7 @@
"Search or browse skills published to registries like skills.sh, GitHub, and the official hub.": "Pesquise ou navegue por habilidades publicadas em registros como skills.sh, GitHub e o hub oficial.",
"Search registries": "Pesquisar registros",
"Search…": "Pesquisar…",
"Security": "Segurança",
"Select": "Selecionar",
"Select Model": "Selecionar modelo",
"Select a Job": "Selecionar uma tarefa",
@@ -402,12 +452,14 @@
"Select an MCP Server": "Selecionar um servidor MCP",
"Send message (Enter)": "Enviar mensagem (Enter)",
"Series": "Série",
"Server": "Servidor",
"Server No Longer Exists": "Servidor não existe mais",
"Server name": "Nome do servidor",
"Servers": "Servidores",
"Service": "Serviço",
"Service definition stale": "Definição de serviço desatualizada",
"Session": "Sessão",
"Session Search": "Busca de sessões",
"Session title": "Título da sessão",
"Sessions": "Sessões",
"Settings": "Configurações",
@@ -424,7 +476,9 @@
"Site": "Site",
"Skills": "Habilidades",
"Skills (%lld)": "Habilidades (%lld)",
"Skills Hub": "Hub de habilidades",
"Source": "Origem",
"Speech-to-Text": "Voz para texto",
"Start": "Iniciar",
"Start Daemon": "Iniciar daemon",
"Start Hermes": "Iniciar Hermes",
@@ -449,6 +503,7 @@
"Test Connection": "Testar conexão",
"Test failed": "Teste falhou",
"Test passed": "Teste aprovado",
"Text-to-Speech": "Texto para voz",
"The agent hasn't advertised any slash commands yet. Keep typing to send as a message, or press Esc.": "O agente ainda não anunciou nenhum comando slash. Continue digitando para enviar como mensagem, ou pressione Esc.",
"The remote's SSH fingerprint no longer matches what your `~/.ssh/known_hosts` file expected. This usually means the remote was reinstalled — or, less commonly, that someone is intercepting the connection.": "A impressão SSH do remoto não corresponde mais ao que seu arquivo `~/.ssh/known_hosts` esperava. Normalmente isso significa que o remoto foi reinstalado — ou, mais raramente, que alguém está interceptando a conexão.",
"The server this window was opened with has been removed from your registry.": "O servidor com o qual esta janela foi aberta foi removido do seu registro.",
@@ -465,14 +520,17 @@
"This will permanently delete the session and all its messages.": "Isso excluirá permanentemente a sessão e todas as suas mensagens.",
"Timeout: %llds (%@)": "Tempo limite: %1$lld s (%2$@)",
"Timeouts": "Tempos limite",
"Tirith Sandbox": "Sandbox Tirith",
"To skip the passphrase prompt at every reboot, add `--apple-use-keychain` to cache it in macOS Keychain.": "Para pular a solicitação de frase secreta a cada reinicialização, adicione `--apple-use-keychain` para armazená-la no Keychain do macOS.",
"Toggle text-to-speech (/voice tts)": "Alternar texto-para-fala (/voice tts)",
"Toggle voice mode (/voice)": "Alternar modo de voz (/voice)",
"Token on disk. Clear to re-authenticate next time the gateway connects.": "Token no disco. Limpe para reautenticar na próxima vez que o gateway conectar.",
"Tool Approval Required": "Aprovação de ferramenta necessária",
"Tool Filters": "Filtros de ferramentas",
"Tool Progress": "Progresso da ferramenta",
"Tools": "Ferramentas",
"Top Tools": "Principais ferramentas",
"Turns & Reasoning": "Turnos e raciocínio",
"Uninstall": "Desinstalar",
"Unknown: %@": "Desconhecido: %@",
"Update": "Atualizar",
@@ -489,14 +547,21 @@
"Used as the YAML key. Lowercase, no spaces.": "Usado como chave YAML. Minúsculas, sem espaços.",
"View": "Ver",
"View All": "Ver tudo",
"Vision": "Visão",
"Voice": "Voz",
"Voice Off": "Voz desligada",
"Voice On": "Voz ligada",
"Waiting for authorization URL…": "Aguardando URL de autorização…",
"Waiting for first probe": "Aguardando primeira verificação",
"Waiting for hermes to prompt for the code…": "Aguardando o hermes solicitar o código…",
"Web Extract": "Extração da Web",
"Webhook (advanced)": "Webhook (avançado)",
"Webhook (hermes side)": "Webhook (lado hermes)",
"Webhook Security": "Segurança de webhook",
"Webhook platform not enabled": "Plataforma de webhook não ativada",
"Webhooks": "Webhooks",
"Webhooks let external services trigger agent responses. Each subscription gets its own URL endpoint.": "Webhooks permitem que serviços externos disparem respostas do agente. Cada assinatura tem seu próprio endpoint de URL.",
"Website Blocklist": "Lista de bloqueio de sites",
"WhatsApp uses the Baileys library to emulate a WhatsApp Web session. Pair this Mac as a linked device by running the pairing wizard and scanning the QR code with your phone (Settings → Linked Devices → Link a Device).": "O WhatsApp usa a biblioteca Baileys para emular uma sessão do WhatsApp Web. Pareie este Mac como dispositivo vinculado executando o assistente de pareamento e escaneando o QR code com seu telefone (Ajustes → Dispositivos vinculados → Vincular um dispositivo).",
"Working": "Trabalhando",
"e.g. anthropic": "ex: anthropic",