Skip to content

feat(i18n): add Brazilian Portuguese (pt-BR) locale - #195

Open
barrymac wants to merge 1 commit into
grinev:mainfrom
barrymac:feat/i18n-pt-br
Open

feat(i18n): add Brazilian Portuguese (pt-BR) locale#195
barrymac wants to merge 1 commit into
grinev:mainfrom
barrymac:feat/i18n-pt-br

Conversation

@barrymac

Copy link
Copy Markdown

Summary

Adds a complete Brazilian Portuguese (pt-BR) locale — all 509 keys, following the same shape as the existing locales: typed against I18nDictionary, registered in LOCALE_DEFINITIONS with dateLocale: "pt-BR", selectable via BOT_LOCALE=pt or the settings menu.

Portuguese is the sixth most-spoken language in the world and Brazil is a large Telegram market, so this felt like a worthwhile gap to close. Happy to adjust any wording if a native-speaker reviewer disagrees with a choice.

Translation approach

  • Translated from en.ts; used the existing es.ts as a reference for house tone and button phrasing rather than translating from Spanish.
  • Brazilian, not European, Portuguese throughout — usuário (not utilizador), arquivo (not ficheiro), tela (not ecrã), gerenciar (not gerir), baixar (not descarregar). Uses você, consistently.
  • Every {placeholder}, emoji and \n escape preserved exactly.
  • Button labels kept short so they still fit on mobile.
  • Terms Brazilian users normally keep in English are left untranslated: OpenCode, commit, worktree, token, prompt, MCP, log, bash, cron. Likewise Status: and detached HEAD, which are identical in practice.

Heads-up: two existing tests had to change

This is the only part of the diff that isn't purely additive, so flagging it explicitly.

Two tests used "pt" as their example of an unsupported locale, so adding Portuguese made them fail:

  • tests/i18n/index.test.tsexpect(normalizeLocale("pt", "en")).toBe("en")
  • tests/config.test.tsvi.stubEnv("BOT_LOCALE", "pt")

Both now use "xx", which is unassigned in ISO 639 and — unlike ko, tr or he, which all have open locale PRs — is unlikely to ever become a real locale here. The intent of both tests is unchanged.

I also added two positive assertions that "pt" and "pt-BR" resolve to "pt", mirroring the existing ru-RU / fr-FR / en-US cases in the same test.

Verification

Run locally against this branch:

Gate Result
vitest run 1189/1189 pass (125 files)
tsc -p tsconfig.test.json --noEmit clean
eslint src tests --max-warnings=0 clean
prettier --check clean
tsc (build) clean

The typecheck is the meaningful one for key parity: because pt is declared as I18nDictionary, any missing or extra key fails compilation. I additionally verified programmatically that the key list is byte-identical to en.ts in both content and order, and that every {placeholder} token matches its English counterpart one-for-one.

Adds a complete pt-BR translation of all 509 keys, following the same
shape as the existing locales (typed against I18nDictionary, registered
in LOCALE_DEFINITIONS with dateLocale pt-BR).

Translated from en.ts, using es.ts as a reference for house tone and
button phrasing. Brazilian rather than European Portuguese throughout
(usuario/arquivo/tela/gerenciar/baixar, "voce" not "tu"). Placeholders,
emoji and escape sequences preserved exactly; button labels kept short
so they still fit on mobile. Technical terms Brazilian users normally
keep in English are left alone (OpenCode, commit, worktree, token, MCP).

Two existing tests used "pt" as their example of an *unsupported*
locale, so adding Portuguese made them fail. Both now use "xx", which is
unassigned in ISO 639 and -- unlike ko/tr/he, which have open locale PRs
-- is unlikely to become real later. Test intent is unchanged. Also
added positive assertions that "pt" and "pt-BR" resolve to "pt",
mirroring the existing ru-RU/fr-FR cases.

Verified locally: vitest 1189/1189 pass, tsc typecheck clean (which is
what proves key parity against I18nDictionary), eslint --max-warnings=0
clean, prettier clean, build clean.
@grinev

grinev commented Jul 29, 2026

Copy link
Copy Markdown
Owner

@barrymac please update README.md and env.example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants