← ClaudeAtlas

find-unused-locale-keyslisted

Find and (on confirmation) delete i18n message keys in control/messages/en.json that are no longer referenced anywhere in control/**. Uses deterministic, conservative static analysis of next-intl translator usage — zero false positives by design (never deletes a live key), at the cost of retaining a few dead keys that sit under dynamically-built key prefixes. Reports first; only deletes after you approve, and deletes from en.json ONLY — run /sync-locales afterward to propagate the removals to every other locale. Invoke as `/find-unused-locale-keys`.
zombico/mojulo · ★ 0 · AI & Automation · score 62
Install: claude install-skill zombico/mojulo
# /find-unused-locale-keys Identify message keys in `control/messages/en.json` that no code under `control/**` references, then — only after you confirm — delete them from `en.json`. Deletion touches **en.json only**; the operator runs `/sync-locales` afterward to sweep the removals across every other locale. Companion to `/sync-locales` (propagates en.json *edits*, including removals, to other locales) and `/translate-messages` (bootstraps a new locale). This skill is the *garbage collector* for the source catalog — it finds the dead keys and prunes the source; `/sync-locales` carries the deletions out to the translations. ## Why this needs more than grep ~16% of translator call sites in this repo build keys dynamically: `t(\`status.${x}\`)`, `t(\`preview.contexts.${ctx}.${k}\`)`, or `t(routeConfig.labelKey)`. A naïve "does the string `status.building` appear in source?" scan would delete those live keys. The helper script handles this by: - binding each translator to its namespace (`const t = useTranslations('apps')` → `t('actions.stop')` is `apps.actions.stop`); - treating a template literal's static prefix as a **protected subtree** (`t(\`status.${x}\`)` protects `<ns>.status.**` — the dynamic part is never resolved); - protecting the **whole namespace** of a bare `t(var)` call on a namespaced translator; - surfacing bare `t(var)` calls on a **root** translator (`useTranslations()`) as *blind spots* for human review, backed by a raw dotted-string-literal corpus that