-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 5 Localization uk
Мета: зрозуміти, як LockedIn CLI говорить 33 мовами — і потренуватися скеровувати агента додати ще одну. Локалізація — фантастичне завдання для агента: воно достатньо механічне, щоб делегувати, але має справжні обмеження (тестовий бар'єр, правила розкладки, граматичне рев'ю), що вчать вас перевіряти.
← Назад: Урок 4 Промптинг і рев'ю · Назад до Головна
Запустіть CLI іспанською, гінді, японською, спрощеною китайською чи будь-якою поставленою мовою, і все змінюється — заставка, таблиця довідки, вивід кожної команди, сесія чату, навіть юридичний дрібний шрифт. Не лише жарти: уся видима поверхня.
lockedin --lang uk post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh auraМова автовизначається під час запуску, розв'язується в порядку пріоритету:
- прапорець
--lang(--lang uk,--lang=fr,-l ja) - змінна оточення
LOCKEDIN_LANG - ваша локаль (
LC_ALL/LC_MESSAGES/LANG, потім локаль ОС/середовища виконання) - англійська, як запасний варіант
normalizeLang() зазвичай використовує основний subtag локалі. Це означає, що
de-DE обирає de, але tlh не стає випадково tl; справжні аліаси fil і
tgl навмисно відображаються в тагальську (tl), норвезькі nb і nn
відображаються в no, застаріла індонезійська in відображається в id, а
застарілий іврит iw відображається в he. Два регіональні коди зберігаються
дослівно, а не згортаються до основного subtag: pt-BR/pt_BR обирають
канонічний регіональний код, тоді як загальний pt лишається зворотно сумісним
бандлом бразильської португальської (обидва — бразильська португальська й
розділяють одні pools/UI), а en-SG/en_SG зберігають синглиш (загальний en
лишається англійською). Гонконгська традиційна китайська — те саме виключення:
zh-HK, zh_HK.UTF-8 і zh-Hant-HK обирають zh-HK, тоді як загальний zh і
материкові теги обирають спрощену китайську (zh).
Перемикання на льоту — панель /language. CLI завжди міг стартувати іншою
мовою (--lang, LOCKEDIN_LANG); тепер ви можете перемикатися посеред сесії.
Надрукуйте /language (аліаси /lang і /languages), щоб перелічити всі 33 мови
за кодом, кожну своїм письмом; /language uk перемикає на решту сесії. Сенс — в
аварійному виході: після перемикання він перемальовує новою мовою, а потім, мовою,
яку ви щойно покинули, друкує точний шлях назад — /language en зараз,
lockedin --lang en наступного разу — щоб випадкове приземлення в 日本語 чи ಕನ್ನಡ ніколи
вас не замкнуло. (Перемкніться двічі, і пропонується також мова, яку називає ваш
LOCKEDIN_LANG.) --lang і LOCKEDIN_LANG без змін. Як і /a11y, це щира
утиліта, а не частина сатири.
Увесь перекладний текст живе в бандлах, по одному на мову, кожен у формі:
{ meta: { lang: 'uk', name: 'Українська', dir: 'ltr' },
pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
ui: { buzzwordDensity: 'Щільність buzzwords: ', /* labels, headings */ } }-
pools— це масиви контенту (жарти), які ви зустріли в Розділі 2. -
ui— це рядки «обв'язки»: мітки, заголовки й невеликі шаблони.
Англійська — це еталонний бандл усередині src/lockedin.js; інші 32 модулі
бандлів живуть у 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 і zh-HK
(pt-BR перевикористовує pools/UI з pt, але реєструється окремо). Кожен
зареєстрований у BUNDLES; SUPPORTED_LANGS генерується з цих ключів, і
renderHelp() друкує цей згенерований список кодів. Жоден UI-бандл не хардкодить
список.
setLang('fr'); // вказати активну мову на французький бандл
// L = активні pools, U = активний ui
pick(L.HOOKS) // французький hook
U.buzzwordDensity // "Densité de jargon : "Оскільки кожен рендерер читає L і U (ніколи захардкожений рядок), один
setLang міняє весь досвід. У цьому весь фокус.
Ось інваріант, що робить додавання мови безпечним:
Кожен бандл має надавати точно ті самі ключі
poolsіui, що й англійський.
Тест забезпечує це по всіх 33 бандлах. Якщо ви додасте новий UI-рядок в
англійський і забудете перекласти його українською, npm test стане червоним і
скаже вам, який ключ відсутній. Ви не можете мовчки викотити наполовину
перекладену мову.
Мови навантажують розкладку терміналу по-різному:
-
Японська, спрощена китайська й гонконгська традиційна китайська
використовують символи East Asian Wide / Fullwidth.
vw()рахує їх за два стовпці, аwrap()жорстко переносить довгі токени без пробілів, щоб текст CJK лишався всередині карток і рамок. -
Гінді та каннада використовують непробільні/охопні комбіновані знаки
(
Mn/Me), такі як matra й virama.vw()рахує їх за нуль стовпців, щоб вони не роздували виміряну ширину. -
box()переносить кожен рядок тіла перед додаванням відступів, тож довгий перекладений банер більше не може пробити рамку. - Кожен бандл задає
sentenceEndіlistSep(наприклад./。,,/、), щоб складені генератором речення читалися природно.
Коли ви додаєте мову, рядки заголовка картки (cardSubtitle, cardMeta,
cardFooter) усе одно мають вміщатися в ≤ 60 видимих стовпців. Арабська,
перська, іврит та урду задають meta.dir: 'rtl'. Вивід не містить bidi-керівних
символів за замовчуванням, бо деякі термінали рендерять їх як мітки в рамках.
LOCKEDIN_BIDI=on явно вмикає збалансовані isolates після перенесення для
терміналів, про які відомо, що вони їх підтримують, зберігаючи ANSI, ASCII-команди
й логічний порядок копіювання/вставлення. Доступний вивід завжди прибирає ці
керівні символи. Без явного увімкнення змішаний порядок RTL/LTR може бути менш
витонченим; ніколи не зондуйте й не виводьте підтримку.
Деякі UI-шаблони вставляють сирі користувацькі фрази з плейсхолдерами на кшталт
{cap}. Не перекладайте їх слот-у-слот. Речення має лишатися граматичним, коли
плейсхолдер — це фраза, яку надрукував користувач, а не охайний іменник.
Реальний застережний баг: японські шаблони, що ставлять は одразу після {cap},
можуть звучати неправильно, коли {cap} — це повне речення. Виправлення не
«перекладати старанніше»; це перебудувати шаблон (наприклад, додати номіналізатор
чи перемістити плейсхолдер), щоб довільний користувацький ввід усе ще підходив.
Ця вправа все ще працює точно так само. Оберіть мову, яку ви можете перевірити на здоровий глузд (чи попросіть агента), і проведіть її від початку до кінця. Спершу напишіть специфікацію:
Додайте данську (
da). Створітьsrc/content/da.jsяк бандл{ meta, pools, ui }із тими самими ключами, що й англійський, переклавши кожен запис (пули контенту по ~25 кожен, усі UI-рядки). ЗареєструйтеdaвBUNDLESуsrc/lockedin.js.--lang daі локальda-*мають його обирати. Тримайте рядки заголовка картки в межах ліміту ширини.npm testмає лишатися зеленим, і додайте інваріанти для данської + тести виявлення, що віддзеркалюють наявні локалізовані.
Потім проженіть цикл із Розділів 3–4:
- Спершу план. «Перш ніж писати код, скажи мені файли, які ти зміниш, і як ти збережеш паритет ключів з англійською.»
-
Спершу тести. «Додай падаючі тести: виявлення
da, паритет ключів дляda, і данський інваріант reflect/connect. Поки не створюй бандл.» -
Реалізація. «Тепер створи
src/content/da.js, перекладаючи наявний бандл ключ за ключем, зареєструй його й зроби так, щоб тести пройшли. Лишеpick/shuffleдля випадковості.» -
Бар'єр + рев'ю.
npm test, потімlockedin --lang da post— і прочитайте diff: чи перекладено кожен ключ? Чи все ще вирівнюються рамки карток? Чи виживають шаблони з{cap}на сирих користувацьких фразах?
Менші розминочні вправи, якщо ціла мова — це забагато:
- «Додай ще один
TAGLINEв усі 33 мовні бандли, зберігаючи кількість рівною.» - «Перевір, чи
≤ 60видимих стовпців уcardFooterканнада, і поясни, як вимірювалися комбіновані знаки.» - «Покажи мені тест, що впав би, якби я видалив ключ
uiзja.js.»
- Пробіжіться
src/content/es.js— він усе ще дружній шаблон для нового бандла. - Перечитайте
docs/HANDOFF.md→ «Adding a language». - Насолодіться багатомовними жартами в Довіднику команд.
Це повний посібник. Ви тепер вмієте скеровувати ШІ-агента будувати функції і локалізувати їх за тестовим бар'єром — 33 мовами й готові до більшого. Погоджуєтеся? 👇
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.