Idiomas da interface (i18n)
A interface do Kabul (desktop, app do celular, popover e menu da barra, menus nativos e notificações) está em inglês e em português do Brasil.
Qual idioma aparece
- Preferência em Configurações › Geral › Idioma (no celular, Ajustes › Idioma): Sistema (padrão), English ou Português. Fica em
localStorage["kabul.lang"]; trocar recarrega a janela. - Sistema segue
navigator.languages: o primeiro idioma que começa comptvira pt-BR,envira inglês e qualquer outro idioma cai no inglês. No app desktop o WebView informa o idioma do macOS porque oInfo.plistdeclaraCFBundleLocalizations(en, pt-BR). - O idioma em uso também vai para o app desktop (
set_ui_lang), que refaz o menu nativo e o da barra, traduz as notificações de limite e os seletores de pasta/arquivo, e grava emui-lang(na pasta de dados do Kabul) para o menu já nascer no idioma certo. Na primeira abertura vale o idioma do sistema (AppleLanguages). - No celular, o app manda o idioma ao service worker, que escreve em inglês os avisos push que o
kabuldmanda comkind(waiting,done).
Onde ficam os textos
apps/web/src/i18n/locales/{en,pt-BR}/<área>.json:common,app,chat,code,settings,usage,mobile,errors. Toda chave começa pelo nome da área (settings.title) e existe nos dois idiomas.t("area.chave", { nome })troca{nome}. Plural: o valor é{ "one": "…", "other": "…" }e a forma sai deIntl.PluralRulescomcount. Texto com elementos no meio (links,<code>):tNode/<T>dei18n/react.tsx.- Datas, números, moeda (US$ em pt-BR, $ em inglês), porcentagens e durações ("2 min 21 s" / "2m 21s"; no rodapé do turno, igual nos dois idiomas: "2m, 21s · 23:36" e "45s"; árvore de subagentes e painel Agentes "2m 21s" —
fmtDurationShort):i18n/format.ts, sempre peloIntlno idioma da interface. - Atalhos:
i18n/shortcuts.json(pt e en em cada atalho). - Textos nativos do app desktop:
apps/desktop/src-tauri/src/i18n.rs(tr("pt", "en")).
Erros do backend
O núcleo (kabul-core, kabuld) devolve erros em português. Em vez de mudar cada bail!, o frontend reconhece as mensagens conhecidas (i18n/errors.ts: padrão → chave errors.*, com os trechos variáveis como grupos nomeados) e mostra a versão em inglês; o toast do desktop já passa tudo por trError. O que não casar com nenhum padrão aparece como veio. Os erros do próprio app desktop (apps/desktop) já saem traduzidos pelo tr. Os alertas de uso trazem campos estruturados (window, title, pct, resets_in_secs, spent_usd, budget_usd) e o texto é montado no idioma da interface.
Verificação
npm run i18n:check(emapps/web) falha com: chave faltando num idioma, chave fora do prefixo da área, plural semone/other, variáveis{x}diferentes entre os idiomas,t("chave")inexistente, texto fixo em JSX (entre tags, emtitle/placeholder/aria-label… e em{cond ? "a" : "b"}), texto fixo emonError/confirmDialog/toasts e qualquer string com cara de português fora de comentário. Escape:// i18n-ignorena linha (ou na anterior) ou/* i18n-ignore-file */(dados de mentira do mock). Marcas e termos técnicos que não se traduzem ficam na listaALLOWdo script. Com--unused, lista chaves sem uso.- Os E2E rodam fixos em pt-BR (
locale: "pt-BR"nosplaywright*.config.ts). Oe2e/idioma-en.spec.tsroda as telas principais do desktop e do celular (iPhone) em inglês e falha com[i18n]no console (chave sem texto),area.chavena tela ou texto do dicionário pt-BR vazando.
Carga
Só o dicionário do idioma em uso é baixado (um pedaço de JS por idioma, ~27 KB gzip): main.tsx espera o loadMessages() antes de desenhar a tela. Por isso t() não pode rodar na carga de um módulo (o i18n:check acusa); constantes de rótulo usam função ou lazyRecord(() => ({ … })).
Prompts e textos gravados
- Os prompts das ações de git (Configurações › Ações), a instrução do plan mode e o contexto de issue do Linear vão para o agente no idioma da interface. O prompt de handoff entre agentes continua em português (espelha
transcript::handoff_promptdo núcleo). - O que fica gravado (meta do turno, título "Nova conversa", nome do checkpoint, motivo das execuções de rotina) fica no idioma em que foi criado.
O que continua em português
- Mensagens de erro do backend que não estão em
i18n/errors.ts(detalhes técnicos, saída degit/gh/tmux, prefixos de contexto raros), a nota dochat_starte textos que vêm como dado: checagens do Diagnóstico (grupo, nome e detalhe), nomes de processo, status dos provedores (ProviderStatus.description), rótulos de conta e títulos de janela de limite desconhecidos (CodexBar). - A notação de tecla "Espaço" dos atalhos personalizados (é o valor guardado no
localStorage). - Avisos push do
kabuldsemkind(os dewaitingedonesaem no idioma do aparelho). public/manifest.webmanifest(descrição da PWA,lang: pt-BR) e o<html lang>inicial doindex.html(corrigido na carga).- Saídas geradas no núcleo para arquivos: CSV de uso (cabeçalho e nome
kabul-uso-*.csv). - O
kabulCLI e os logs (eprintln!) do app e dokabuld.