-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 5 Localization de
🌎 Sprache: Deutsch — alle 33 Sprachen ansehen
Ziel: verstehen, wie LockedIn CLI 33 Sprachen spricht — und üben, einen Agenten dabei anzuleiten, noch eine hinzuzufügen. Lokalisierung ist eine hervorragende Aufgabe für einen Agenten: mechanisch genug zum Delegieren, aber mit echten Einschränkungen (Test-Gate, Layout-Regeln, Grammatik-Review), die dir beibringen zu reviewen.
← Zurück: Tutorial 4 Prompts formulieren und prüfen · Zurück zu Start
Starte die CLI auf Spanisch, Hindi, Japanisch, vereinfachtem Chinesisch oder einer anderen mitgelieferten Sprache, und alles ändert sich — der Splash, die Hilfetabelle, die Ausgabe jedes Commands, die Chat-Session, sogar das rechtliche Kleingedruckte. Nicht nur die Witze: die gesamte sichtbare Oberfläche.
lockedin --lang de post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh auraDie Sprache wird beim Start automatisch erkannt, in dieser Prioritätsreihenfolge:
- das Flag
--lang(--lang de,--lang=fr,-l ja) - die Umgebungsvariable
LOCKEDIN_LANG - dein Locale (
LC_ALL/LC_MESSAGES/LANG, dann das Locale von OS/Laufzeit) - Englisch als Fallback
normalizeLang() verwendet normalerweise den primären Subtag des Locale. Das bedeutet: de-DE wählt de, aber tlh wird nicht versehentlich zu tl; die echten Aliasse fil und tgl mappen absichtlich auf Tagalog (tl), das norwegische nb und nn mappen auf no, das historische indonesische in mappt auf id, und das historische hebräische iw mappt auf he. Zwei Region-Codes bleiben wortwörtlich erhalten, statt auf ihren primären Subtag zurückzufallen: pt-BR/pt_BR wählen den kanonischen regionalen Code, während generisches pt das rückwärtskompatible brasilianisch-portugiesische Bundle bleibt (beide sind brasilianisches Portugiesisch und teilen sich dieselben Pools/UI), und en-SG/en_SG behalten Singlish (generisches en bleibt Englisch). Traditionelles Hongkong-Chinesisch ist dieselbe Art Ausnahme: zh-HK, zh_HK.UTF-8 und zh-Hant-HK wählen zh-HK, während generisches zh und Mainland-Tags vereinfachtes Chinesisch (zh) wählen.
Mitten im Flug umschalten — das /language-Panel. Die CLI konnte schon immer in einer anderen Sprache starten (--lang, LOCKEDIN_LANG); jetzt kannst du mitten in der Session umschalten. Tippe /language (Aliasse /lang und /languages), um alle 33 Sprachen nach Code aufzulisten, jeweils in ihrer eigenen Schrift; /language el schaltet für den Rest der Session um. Der Sinn ist die Rettungsleine: Nach einem Wechsel zeichnet die CLI in der neuen Sprache neu und druckt dann, in der Sprache, die du gerade verlassen hast, den exakten Weg zurück — /language en jetzt, lockedin --lang en beim nächsten Mal —, damit dich ein versehentlicher Abstecher nach 日本語 oder ಕನ್ನಡ nie stranden lässt. (Wenn du zweimal wechselst, wird auch die Sprache angeboten, auf die dein LOCKEDIN_LANG zeigt.) --lang und LOCKEDIN_LANG bleiben unverändert. Wie /a11y ist das ein aufrichtig nützliches Werkzeug, nicht Teil der Satire.
Jeder übersetzbare Text lebt in Bundles, eines pro Sprache, jeweils in dieser Form:
{ meta: { lang: 'de', name: 'Deutsch', dir: 'ltr' },
pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
ui: { buzzwordDensity: 'Buzzword-Dichte: ', /* labels, headings */ } }-
poolssind die Inhalts-Arrays (die Witze), denen du in Kapitel 2 begegnet bist. -
uisind die Oberflächen-Strings: Labels, Überschriften und kleine Templates.
Englisch ist das Referenz-Bundle innerhalb von src/lockedin.js; die anderen 32 Bundle-Module leben in 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 und zh-HK (pt-BR verwendet die Pools/UI von pt wieder, wird aber separat registriert). Jedes davon ist in BUNDLES registriert; SUPPORTED_LANGS wird aus diesen Keys erzeugt, und renderHelp() gibt diese generierte Code-Liste aus. Kein UI-Bundle hartcodiert die Liste.
setLang('fr'); // richtet die aktive Sprache auf das französische Bundle
// L = aktive pools, U = aktive ui
pick(L.HOOKS) // ein französischer Hook
U.buzzwordDensity // "Densité de jargon : "Weil jeder Renderer L und U liest (niemals einen hartcodierten String), ändert setLang allein das gesamte Erlebnis. Das ist der ganze Trick.
Hier ist die Invariante, die das Hinzufügen einer Sprache sicher macht:
Jedes Bundle muss exakt dieselben
pools- undui-Keys bereitstellen wie Englisch.
Ein Test erzwingt das für alle 33 Bundles. Wenn du in Englisch einen neuen UI-String hinzufügst und vergisst, ihn ins Ukrainische zu übersetzen, springt npm test auf Rot und sagt dir, welcher Key fehlt. Du kannst eine halb übersetzte Sprache nicht lautlos ausliefern.
Sprachen belasten das Terminal-Layout auf unterschiedliche Weise:
-
Japanisch, vereinfachtes Chinesisch und traditionelles Hongkong-Chinesisch verwenden East-Asian-Wide-/Fullwidth-Zeichen.
vw()zählt diese als zwei Spalten, undwrap()trennt lange Zeichenfolgen ohne Leerzeichen hart um, damit CJK-Text in Karten und Boxen bleibt. -
Hindi und Kannada verwenden nichtabständige bzw. einschließende kombinierende Zeichen (
Mn/Me), etwa Matras und Viramas.vw()zählt diese als null Spalten, damit sie die gemessene Breite nicht aufblasen. -
box()umbrecht jede Body-Zeile vor dem Auffüllen, sodass ein langer übersetzter Banner den Rahmen nicht mehr durchschlagen kann. - Jedes Bundle setzt
sentenceEndundlistSep(zum Beispiel./。,,/、), damit von Generatoren zusammengesetzte Sätze natürlich klingen.
Wenn du eine Sprache hinzufügst, müssen Kartenkopf-Strings (cardSubtitle, cardMeta, cardFooter) trotzdem in ≤ 60 sichtbare Spalten passen. Arabisch, Persisch, Hebräisch und Urdu setzen meta.dir: 'rtl'. Die Ausgabe enthält standardmäßig keine bidi-Steuerzeichen, weil einige Terminals sie als gerahmte Labels darstellen. LOCKEDIN_BIDI=on aktiviert explizit ausgeglichene Isolate nach dem Umbruch für Terminals, von denen bekannt ist, dass sie sie unterstützen, und bewahrt ANSI, ASCII-Commands und die logische Copy/Paste-Reihenfolge. Screenreader-Ausgabe entfernt diese Steuerzeichen immer. Ohne dieses Opt-in kann die gemischte RTL/LTR-Reihenfolge weniger ausgefeilt sein; Unterstützung wird nie sondiert oder geraten.
Einige UI-Templates fügen rohe Nutzerklauseln mit Platzhaltern wie {cap} ein. Übersetze sie nicht Slot für Slot. Der Satz muss grammatisch bleiben, wenn der Platzhalter eine Phrase ist, die der Nutzer eingegeben hat, und kein hübsches Substantiv.
Ein echter Warn-Bug: Japanische Templates, die は direkt hinter {cap} setzen, können falsch klingen, wenn {cap} eine vollständige Klausel ist. Die Lösung ist nicht „härter übersetzen“, sondern das Template umzubauen (zum Beispiel einen Nominalisierer hinzuzufügen oder den Platzhalter zu verschieben), damit beliebige Nutzereingaben weiterhin passen.
Diese Übung funktioniert immer noch genau gleich. Such dir eine Sprache aus, die du grob gegenprüfen kannst (oder bitte den Agenten darum), und bring sie End-to-End ans Ziel. Schreib zuerst die Spezifikation:
Füge Dänisch (
da) hinzu. Erstellesrc/content/da.jsals{ meta, pools, ui }-Bundle mit den gleichen Keys wie Englisch und übersetze jeden Eintrag (Content-Pools mit jeweils ~25 Einträgen, alle UI-Strings). RegistrieredainBUNDLESinsrc/lockedin.js.--lang daund einda-*-Locale müssen es auswählen. Halte die Kartenkopf-Strings innerhalb der Breitenbegrenzung.npm testmuss grün bleiben, und füge dänische Invarianten- und Erkennungstests hinzu, die den vorhandenen lokalisierten Tests entsprechen.
Führe dann den Loop aus Kapitel 3–4 aus:
- Zuerst planen. „Bevor du Code schreibst, sag mir, welche Dateien du ändern wirst und wie du die Schlüsselparität mit Englisch beibehältst.“
-
Zuerst Tests. „Füge fehlschlagende Tests hinzu:
da-Erkennung, Schlüsselparität fürdaund eine dänische Reflect-/Connect-Invariante. Erstelle das Bundle noch nicht.“ -
Implementieren. „Erstelle jetzt
src/content/da.js, indem du ein vorhandenes Bundle Key für Key übersetzt, registriere es und lass die Tests bestehen. Für Zufälligkeit nurpick/shuffle.“ -
Gate + Review.
npm test, dannlockedin --lang da post— und lies den Diff: Wurde jeder Key übersetzt? Sind die Kartenrahmen noch ausgerichtet? Überleben Templates mit{cap}rohe Nutzerklauseln?
Kleinere Aufwärmübungen, falls dir eine ganze Sprache zu viel ist:
- „Füge allen 33 Sprach-Bundles ein weiteres
TAGLINEhinzu und halte die Anzahlen gleich.“ - „Prüfe, ob
cardFooterin Kannada ≤ 60 sichtbare Spalten hat, und erkläre, wie kombinierende Zeichen gemessen wurden.“ - „Zeig mir den Test, der fehlschlagen würde, wenn ich einen
ui-Key ausja.jslöschen würde.“
- Überflieg
src/content/es.js— es ist immer noch eine freundliche Vorlage für ein neues Bundle. - Lies
docs/HANDOFF.md→ „Adding a language“ noch einmal. - Genieße die mehrsprachigen Witze in der Befehlsreferenz.
Damit ist das Tutorial komplett. Du kannst jetzt einen KI-Agenten anleiten, Features zu bauen und hinter einem Test-Gate zu lokalisieren — in 33 Sprachen und bereit für noch mehr. Stimmst du zu? 👇
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.