- Home
- Skills
- Translation & Localization
- Translation Key Drift Auditor
Works with the AI Agents you already use
Translation Key Drift Auditor
Compares a project's locale catalogues against the code that looks keys up in them and returns a ranked drift report
$5
/moSubscription · cancel anytime
Secure checkout via Stripe
- Always the latest version
- Delivered live to your agent via MCP
- Cancel anytime, access ends at period end
Translation Key Drift Auditor
Example session with this skill installed
The Arabic build is showing odd plurals and I think our English file has fallen behind. Audit the l10n files against the app.
- Read your context and instructions
- Compiled the translation key drift
Translation drift - lib/l10n
Base fr, 8 keys - checked: en, ar
1 breaking, 1 missing, 3 never extracted, 1 plural gap, 1 unused, 1 not provable
Base locale is
fr, not en: l10n.yaml:2 sets template-arb-file: app_fr.arb, and README.md:3 says the same. French is the file everything else is measured against, so "the English file has fallen behind" is the right instinct - English is a translation here, and it is the one with a hole in it.
Lookup pattern in use: Flutter gen-l10n. Every call site binds final l10n = AppLocalizations.of(context); and then reads a generated member - l10n.appTitle, l10n.welcomeUser(crewName). Seven such lookups across three screens, all static member access. No template literals, no concatenation, no map indexing: there are
no dynamic key prefixes in this repo, so the unused list below is settled by search rather than guessed at.
Breaking - placeholder mismatch
welcomeUser- base expects {name} - lib/l10n/app_fr.arb:4 (declared@welcomeUser.placeholders.name, lib/l10n/app_fr.arb:5-11)
en: no placeholder at all - lib/l10n/app_en.arb:4"Welcome back"
ar: has {name} - lib/l10n/app_ar.arb:4 (correct)
Called with an argument at lib/screens/home_screen.dart:17 -Text(l10n.welcomeUser(crewName))
Effect: the generatedAppLocalizationsEn.welcomeUser(String name)still takes the crew name and never renders it. English readers get a bare "Welcome back" while French and Arabic readers get the name. It does not throw - it silently drops information, which is why nobody has reported it.
Fix:"welcomeUser": "Welcome back, {name}"
Missing in a shipping locale
settingsTitle- en - used at lib/screens/settings_screen.dart:13, base at lib/l10n/app_fr.arb:12
Shows
"Paramètres" - the French base string, not the raw key. gen-l10n backfills any message absent from a locale ARB with the template locale's message (it warns at build time and carries on), and l10n.yaml:4 nullable-getter: false means the call site never guards for it. So the English settings screen has a French title in the app bar.
Present in ar at lib/l10n/app_ar.arb:5, so this is an English-only hole.
Fix: "settingsTitle": "TODO(en) Paramètres" - the marker keeps the build green without shipping an invented string; an English writer replaces it with "Settings".
Never extracted
"Save changes"- lib/screens/home_screen.dart:19 - suggested keysaveChanges
Rendered as a bareconst Textinside the home column, between two translated widgets. French and Arabic readers see English."Clear offline cache"- lib/screens/settings_screen.dart:17 - suggested keyclearOfflineCache
ListTiletitle, directly beneath a translatedbatteryWarningtile."Close settings"- lib/screens/settings_screen.dart:19 - suggested keycloseSettings
ASemantics(label:)- it never appears on screen, but it is what TalkBack and VoiceOver read aloud. An Arabic screen-reader user hears an English phrase. Easy to miss precisely because it is invisible.
All three follow the camelCase convention already used across the catalogue. Each needs the key added to app_fr.arb (with the French source string), then TODO(en) / TODO(ar) stubs, and the call site changed to Text(l10n.saveChanges) and so on. The const on lines 19 and 17 has to go - a localized lookup is not a compile-time constant.
Plural gaps
syncPending- ar needs zero, one, two, few, many, other - has only one, other - lib/l10n/app_ar.arb:6
This is the odd Arabic plurals you are seeing, and it is invisible to a missing-key check: the key is present in every locale, so nothing flags it. Arabic is a six-category language under CLDR. With onlyoneandotherdefined, ICU falls through tootherfor every count that is not 1 - so 0, 2, and 3-10 reports all render theotherform. Theotherform here is{count} تقارير(the paucal/plural noun), which is wrong for 0 and for exactly 2, and grammatically the wrong number class for 11 and above. The count itself will also render in whichever digit set the locale resolves to, unrelated to this gap.
Fix: the categories are mechanical, the strings are not. The skeleton is
{count, plural, zero{TODO(ar)} one{...} two{TODO(ar)} few{TODO(ar)} many{TODO(ar)} other{...}}
keeping the existingoneandotherarms. The five new arms need an Arabic speaker - this audit does not write them.- en:
one/otherat lib/l10n/app_en.arb:5 - correct and complete for English.
Note, not counted as a finding: fr formally carries a many category in CLDR, but it fires only for compact notation (1M, 2M). syncPending is called with a plain int from lib/screens/home_screen.dart:18, so that category is unreachable here. Adding it would be noise.
Unused
deprecatedTooltip- lib/l10n/app_fr.arb:38, and translated in both locales (lib/l10n/app_en.arb:9, lib/l10n/app_ar.arb:10)
Zero references inlib/. No dynamic lookups exist in this repo, so nothing can be reaching it by a constructed key. The name suggests it was already known to be dead. Cleanup only, no urgency - and it is worth one grep across any code not in this repo before deleting three translated strings.
Not provable
- Which locales actually ship - no
MaterialApp/supportedLocalesdeclaration exists anywhere in this repo (the three files underlib/screens/are the whole of the Dart source). "en, ar, fr ship" is taken from the ARB files present inlib/l10n/plus README.md:4. If a locale is registered but has no ARB, this audit cannot see it.
Verdict
Not safe to ship in English or Arabic today: English silently drops the crew name from the welcome line and shows a French settings title, Arabic gets the wrong plural form for every count except one, and three user-facing strings - including a screen-reader label - were never extracted at all.
Subscription · always the latest version
- Secure checkout via Stripe
- Cancel anytime
- Delivered live via MCP (optional)
About this skill
Locale files drift away from the code that reads them, and nobody notices until a customer sees a raw key on screen. This skill checks your catalogues against the lookups in the code and returns a ranked report: placeholder mismatches that break at runtime first, then keys missing from a shipping locale, strings nobody ever extracted, plural categories that pl, ru and ar require but the catalogue never got, and dead keys last. Every finding cites the catalogue line and the code line.
What it does
Compares a project's locale catalogues against the code that looks keys up in them and returns a ranked drift report - placeholder mismatches first because those break at runtime, then keys missing from a shipping locale, user-facing strings that were never extracted, plural categories a language requires but the catalogue lacks, and dead keys last. Every finding carries the catalogue line and the code line that settle it.
Try it first
Open a repo that has a locales folder and say "check the translations against the code before we ship". You should get back a Translation drift report: the base locale it picked and why, six counts, then the ranked sections - breaking placeholder mismatches with the corrected string, keys missing per locale with what the reader sees instead, literals still sitting in the components, plural gaps named by CLDR category, unused keys, anything it could not settle, and a one-sentence verdict on whether the catalogue is safe to ship.
What it needs
An agent that can read and search the repo - Read, Grep, Glob and Bash. No API keys, no MCP servers, no network access. Framework-agnostic: it learns your lookup patterns from your own call sites instead of assuming i18next, react-intl, Vue I18n, gettext or ARB.
How to use
Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
Free forever
No account required to browse
Trust & safety
Security scanned
Verified clean 6 days ago