CLI Commands

CLI Commands

Every command @the-i18n-kit/cli registers is listed below and documented on its own page. Every one of them accepts the shared flags and sets one of the exit codes below, so the command pages carry only what is distinctive about each.

Commands

CommandWhat it does
initCreate a schema-valid .i18n-mcp.json from framework detection. Non-interactive; refuses to overwrite without force.
discoverDescribe the project: detected config, locale directories per layer with file counts and top-level namespaces, the layer graph, and the hand-maintained locales.
getGet translation values by key path or by key prefix, from one layer or from every layer that defines them. Use "*" as the locale to read from all locales.
writeWrite translation key-value pairs to a layer. Keys are inserted in alphabetical order.
missingFind translation keys that exist in the reference locale but are missing in other locales. Scans a specific layer or all layers.
statusTranslation coverage in one call: per-locale and per-layer counts of total, translated, missing and empty keys, plus an overall completion percentage.
searchSearch translation files by key path or value, one compact row per matching key rather than one per key and locale.
removeRemove one or more translation keys from ALL locale files in the given layer.
moveMove a translation key to another layer, to another key path, or both, carrying every locale that defines it.
translateFind the keys missing in the target locales and translate them. Without a translation backend nothing is written: the result carries per-locale fallback contexts to translate by hand instead.
translate-keyAdd or update one source translation key and translate it into the target locales.
checkFind keys referenced in source code but defined in NO locale layer the using app consumes — the direction that ships raw keys to production.
orphansReport translation keys that no source code references. Nothing is deleted unless remove is set.
find-duplicatesFind translation keys defined in BOTH a shared layer and an app layer that consumes it.
scaffoldCreate empty locale files for new languages, copying the key structure of the default locale with every value set to an empty string.

Shared Flags

FlagTypeRequiredDefaultDescription
--projectDir, -dstringno—Project directory (default: cwd)
--jsonbooleannofalseOutput as JSON (default for non-TTY)

Flag Name Forms

Flags are declared in camel case and print that way in the-i18n-cli <command> --help, which is the form used throughout this reference. citty registers the kebab-case form as an alias, so --dryRun and --dry-run are the same flag.

Exit Codes

CodeMeans
0The run succeeded and no gate tripped.
1The run itself failed — an unusable API key, an unreadable project, a translate call that produced nothing.
2The run succeeded and a gate tripped — one you requested, or one the command always evaluates. The findings are real; the tool worked.

A gate tripping is not a run failing. Exit 2 means the command did its job and found something you asked it to fail on — missing keys, orphans, coverage below a floor. Exit 1 means the run itself fell over, and its counters say nothing about your project. A failed run outranks a tripped gate: gates are not consulted at all when the run failed.

CI Gates

Gates are opt-in, with one exception. Without one of these flags a command reports its findings and exits 0, so failing a build on findings is something you ask for rather than something you discover. The exception is a gate marked "always on": its findings are a defect rather than a threshold, so there is nothing to opt into.

CommandFlagTrips when
missing--failOnMissingExit 2 when any key is missing (CI gate).
status--failUnderExit 2 when overall completion is below this percentage (CI gate).
translate--failOnFailedExit 2 when any key failed to translate (CI gate).
checkalways onsummary.undefinedCount is above 0
orphans--failOnOrphansExit 2 when any orphan key is found (CI gate).

When a gate trips, the result gains a gatesTripped array naming each gate, the counter it read, the threshold it was held to and the value it observed. A run where nothing tripped is byte-for-byte what it was before gates existed, so a consumer parsing the result needs no change to tolerate them.

A gate marked "always on" needs no flag: its findings are a defect rather than a threshold you opt into caring about. It still reports as a gate — exit 2 with a gatesTripped entry — so a finding stays distinguishable from the run itself failing with exit 1.
Copyright © 2026