-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 5 Localization pt
Meta: entender como o LockedIn CLI fala 33 idiomas — e praticar direcionar um agente para adicionar mais um. Localização é uma tarefa fantástica para um agente: é mecânica o suficiente para delegar, mas tem restrições reais (uma barreira de testes, regras de layout, revisão gramatical) que te ensinam a revisar.
← Anterior: Tutorial 4 Prompts e Revisão · Voltar para Início
Execute a CLI em espanhol, hindi, japonês, chinês simplificado, ou qualquer idioma incluído, e tudo muda — o splash, a tabela de ajuda, a saída de cada comando, a sessão de chat, até a letra miúda legal. Não só as piadas: a superfície visível inteira.
lockedin --lang pt post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh auraO idioma é autodetectado na inicialização, resolvido em ordem de prioridade:
- a flag
--lang(--lang pt,--lang=fr,-l ja) - a variável de ambiente
LOCKEDIN_LANG - seu locale (
LC_ALL/LC_MESSAGES/LANG, depois o locale do sistema/runtime) - inglês, como reserva
normalizeLang() normalmente usa o subtag primário do locale. Isso significa
que de-DE seleciona de, mas tlh não se torna tl por acidente; os
aliases reais fil e tgl mapeiam intencionalmente para tagalo (tl), o
norueguês nb e nn mapeiam para no, o indonésio legado in mapeia para
id, e o hebraico legado iw mapeia para he. Dois códigos regionais são
preservados literalmente em vez de dobrados para seu subtag primário:
pt-BR/pt_BR selecionam o código regional canônico enquanto o pt
genérico continua sendo o bundle de português do Brasil compatível com
versões anteriores (ambos são português do Brasil e compartilham os mesmos
pools/UI), e en-SG/en_SG mantêm o singlish (o en genérico continua
sendo inglês). O chinês tradicional de Hong Kong é o mesmo tipo de exceção:
zh-HK, zh_HK.UTF-8 e zh-Hant-HK selecionam zh-HK, enquanto o zh
genérico e as tags continentais selecionam chinês simplificado (zh).
Trocando em pleno voo — o painel /language. A CLI sempre pôde
começar em outro idioma (--lang, LOCKEDIN_LANG); agora você pode
trocar no meio da sessão. Digite /language (aliases /lang e
/languages) para listar os 33 idiomas por código, cada um em sua própria
escrita; /language el troca pelo resto da sessão. O ponto é a rota de
fuga: depois de uma troca, ela redesenha no novo idioma e então, no idioma
que você acabou de deixar, imprime o caminho exato de volta —
/language en agora, lockedin --lang en da próxima vez — para que cair sem querer em
日本語 ou ಕನ್ನಡ nunca te deixe preso. (Troque duas vezes e o idioma que seu
LOCKEDIN_LANG nomeia também é oferecido.) --lang e LOCKEDIN_LANG
permanecem inalterados. Assim como o /a11y, é um utilitário sincero, não
parte da sátira.
Todo o texto traduzível vive em bundles, um por idioma, cada um com esta forma:
{ meta: { lang: 'pt', name: 'Português', dir: 'ltr' },
pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
ui: { buzzwordDensity: 'Densidade de buzzwords: ', /* labels, títulos */ } }-
poolssão os arrays de conteúdo (as piadas) que você viu no Capítulo 2. -
uisão os textos de interface: labels, títulos e pequenos templates.
Inglês é o bundle de referência dentro de src/lockedin.js; os outros 32
módulos de bundle vivem em src/content/*.js: ar, bn, bo, de, el,
en-SG, es, eu, fa, fi, fr, he, hi, id, is, it, ja,
kn, ms, nl, no, pl, pt, pt-BR, ru, sv, tl, tr, uk,
ur, zh, e zh-HK (pt-BR reutiliza os pools/UI do pt, mas é
registrado separadamente). Cada um é registrado em BUNDLES;
SUPPORTED_LANGS é gerado a partir dessas chaves, e renderHelp() imprime
essa lista gerada. Nenhum bundle de UI codifica a lista de forma fixa.
setLang('fr'); // aponta o idioma ativo para o bundle francês
// L = pools ativos, U = ui ativo
pick(L.HOOKS) // um gancho em francês
U.buzzwordDensity // "Densité de jargon : "Como todo renderizador lê L e U (nunca uma string fixa), setLang
sozinho muda toda a experiência. Esse é o truque inteiro.
Aqui está a invariante que torna seguro adicionar um idioma:
Todo bundle deve expor exatamente as mesmas chaves de
poolseuique o inglês.
Um teste impõe isso nos 33 bundles. Se você adicionar uma string de UI nova em
inglês e esquecer de traduzi-la em ucraniano, npm test fica vermelho e te
diz qual chave está faltando. Você não consegue publicar silenciosamente um
idioma meio traduzido.
Idiomas estressam o layout do terminal de formas diferentes:
-
Japonês, chinês simplificado e chinês tradicional de Hong Kong usam
caracteres East Asian Wide / Fullwidth.
vw()os conta como duas colunas, ewrap()quebra à força tokens longos sem espaço para que o texto CJK continue dentro dos cartões e caixas. -
Hindi e canarês usam marcas combinantes não espaçadas/envolventes (
Mn/Me), como matras e viramas.vw()as conta como zero colunas para que não inflem a largura medida. -
box()quebra cada linha do corpo antes de preenchê-la, então um banner traduzido longo não consegue mais furar a borda. - Cada bundle define
sentenceEndelistSep(por exemplo./。,,/、) para que frases compostas por geradores soem naturais.
Quando você adiciona um idioma, as strings de cabeçalho do cartão
(cardSubtitle, cardMeta, cardFooter) ainda precisam caber em ≤ 60
colunas visíveis. Árabe, persa, hebraico e urdu definem meta.dir: 'rtl'.
A saída não contém controles bidi por padrão, porque alguns terminais os
renderizam como labels em caixas. LOCKEDIN_BIDI=on ativa explicitamente
isolamentos equilibrados depois da quebra de linha para terminais conhecidos
por suportá-los, preservando ANSI, comandos ASCII e a ordem lógica de
copiar/colar. A saída acessível sempre remove esses controles. Sem essa opção
explícita, a ordenação RTL/LTR mista pode ser menos sofisticada; nunca sonde
ou infira suporte.
Alguns templates de UI inserem cláusulas brutas do usuário com placeholders
como {cap}. Não os traduza posição por posição. A frase precisa continuar
gramatical quando o placeholder for uma frase que o usuário digitou, não um
substantivo arrumadinho.
Um bug real de cautela: templates em japonês que colocam は logo depois de
{cap} podem soar errados quando {cap} é uma cláusula completa. O conserto
não é "traduzir com mais força"; é reestruturar o template (por exemplo,
adicionar um nominalizador ou mover o placeholder) para que a entrada
arbitrária do usuário ainda se encaixe.
Este exercício continua funcionando exatamente da mesma forma. Escolha um idioma que você consiga verificar (ou peça ao agente que verifique), e conduza-o de ponta a ponta. Escreva a especificação primeiro:
Adicione dinamarquês (
da). Criesrc/content/da.jscomo um bundle{ meta, pools, ui }com as mesmas chaves do inglês, traduzindo cada entrada (pools de conteúdo com ~25 cada, todas as strings de UI). RegistredaemBUNDLESemsrc/lockedin.js.--lang dae um localeda-*devem selecioná-lo. Mantenha as strings de cabeçalho do cartão dentro do limite de largura.npm testdeve continuar verde, e adicione invariantes
- testes de detecção em dinamarquês espelhando os já localizados.
Depois rode o ciclo dos Capítulos 3–4:
- Plano primeiro. "Antes de escrever código, me diga quais arquivos você vai mudar e como vai manter a paridade de chaves com o inglês."
-
Testes primeiro. "Adicione testes que falham: detecção de
da, paridade de chaves parada, e uma invariante de reflect/connect em dinamarquês. Não crie o bundle ainda." -
Implemente. "Agora crie
src/content/da.jstraduzindo um bundle existente chave por chave, registre-o, e faça os testes passarem. Apenaspick/shufflepara a aleatoriedade." -
Barreira + revisão.
npm test, depoislockedin --lang da post— e leia o diff: cada chave foi traduzida? As bordas do cartão continuam alinhadas? Os templates com{cap}sobrevivem a cláusulas brutas do usuário?
Exercícios de aquecimento menores se um idioma inteiro for demais:
- "Adicione mais um
TAGLINEa todos os 33 bundles de idioma, mantendo as contagens iguais." - "Verifique se o
cardFooterem canarês tem ≤ 60 colunas visíveis e explique como as marcas combinantes foram medidas." - "Me mostre o teste que falharia se eu apagasse uma chave
uideja.js."
- Passe os olhos por
src/content/es.js— ainda é um template amigável para um bundle novo. - Releia
docs/HANDOFF.md→ "Adding a language". - Aproveite as piadas multilíngues na Referência de Comandos.
Esse é o tutorial completo. Você já consegue direcionar um agente de IA para construir funcionalidades e localizá-las atrás de uma barreira de testes — em 33 idiomas e pronto para mais. Concorda? 👇
Tutorial
- 1 · Orientation
- 2 · How the Code Works
- 3 · Your First Agent Task
- 4 · Prompting & Reviewing
- 5 · Localization
Reference
Satire · Sátira · 風刺. Not affiliated with LinkedIn. GPL-3.0-or-later.