[{"data":1,"prerenderedAt":3040},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-cold-start":357,"-getting-started-cold-start-surround":3037},[4,22,40,53,78,107,132,153,167,176,347],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Introduction","\u002Fintroduction","1.introduction",[9,13,17],{"title":10,"path":11,"stem":12},"Why the-i18n-kit","\u002Fintroduction\u002Fwhy","1.introduction\u002F1.why",{"title":14,"path":15,"stem":16},"Architecture","\u002Fintroduction\u002Farchitecture","1.introduction\u002F2.architecture",{"title":18,"path":19,"stem":20},"Built for Agents","\u002Fintroduction\u002Fbuilt-for-agents","1.introduction\u002F3.built-for-agents",false,{"title":23,"icon":24,"path":25,"stem":26,"children":27,"page":21},"ESLint Plugin","i-lucide-shield-check","\u002Feslint-plugin","10.eslint-plugin",[28,32,36],{"title":29,"path":30,"stem":31},"Install and Presets","\u002Feslint-plugin\u002Finstall","10.eslint-plugin\u002F1.install",{"title":33,"path":34,"stem":35},"The Rules","\u002Feslint-plugin\u002Frules","10.eslint-plugin\u002F2.rules",{"title":37,"path":38,"stem":39},"Layer-Aware Missing Keys","\u002Feslint-plugin\u002Flayer-aware","10.eslint-plugin\u002F3.layer-aware",{"title":41,"path":42,"stem":43,"children":44,"page":21},"Getting Started","\u002Fgetting-started","2.getting-started",[45,49],{"title":46,"path":47,"stem":48},"Set Up the MCP Server","\u002Fgetting-started\u002Fagent-setup","2.getting-started\u002F1.agent-setup",{"title":50,"path":51,"stem":52},"From an Unconfigured Repository to a Gated CI Job","\u002Fgetting-started\u002Fcold-start","2.getting-started\u002F2.cold-start",{"title":54,"path":55,"stem":56,"children":57,"page":21},"Monorepos","\u002Fmonorepos","3.monorepos",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Layers","\u002Fmonorepos\u002Flayers","3.monorepos\u002F1.layers",{"title":63,"path":64,"stem":65},"The Consumer Graph","\u002Fmonorepos\u002Fconsumer-graph","3.monorepos\u002F2.consumer-graph",{"title":67,"path":68,"stem":69},"The Shared Library Scenario","\u002Fmonorepos\u002Fshared-libraries","3.monorepos\u002F3.shared-libraries",{"title":71,"path":72,"stem":73},"Duplicates and Divergence","\u002Fmonorepos\u002Fduplicates-and-divergence","3.monorepos\u002F4.duplicates-and-divergence",{"title":75,"path":76,"stem":77},"Misplaced Usages","\u002Fmonorepos\u002Fmisplaced-usages","3.monorepos\u002F5.misplaced-usages",{"title":79,"path":80,"stem":81,"children":82,"page":21},"Frameworks","\u002Fframeworks","4.frameworks",[83,87,91,95,99,103],{"title":84,"path":85,"stem":86},"Detection","\u002Fframeworks\u002Fdetection","4.frameworks\u002F1.detection",{"title":88,"path":89,"stem":90},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F2.nuxt",{"title":92,"path":93,"stem":94},"Laravel","\u002Fframeworks\u002Flaravel","4.frameworks\u002F3.laravel",{"title":96,"path":97,"stem":98},"Vue","\u002Fframeworks\u002Fvue","4.frameworks\u002F4.vue",{"title":100,"path":101,"stem":102},"React \u002F Next.js","\u002Fframeworks\u002Freact-next","4.frameworks\u002F5.react-next",{"title":104,"path":105,"stem":106},"Generic","\u002Fframeworks\u002Fgeneric","4.frameworks\u002F6.generic",{"title":108,"path":109,"stem":110,"children":111,"page":21},"Configuration","\u002Fconfiguration","5.configuration",[112,116,120,124,128],{"title":113,"path":114,"stem":115},"Where Configuration Lives","\u002Fconfiguration\u002Fwhere-config-lives","5.configuration\u002F1.where-config-lives",{"title":117,"path":118,"stem":119},"Precedence and Conflicts","\u002Fconfiguration\u002Fprecedence","5.configuration\u002F2.precedence",{"title":121,"path":122,"stem":123},"Declared vs. Derived Configuration","\u002Fconfiguration\u002Fdeclared-vs-derived","5.configuration\u002F3.declared-vs-derived",{"title":125,"path":126,"stem":127},"Configuration Fields","\u002Fconfiguration\u002Freference","5.configuration\u002F4.reference",{"title":129,"path":130,"stem":131},"Referring to Locales","\u002Fconfiguration\u002Flocale-refs","5.configuration\u002F5.locale-refs",{"title":133,"path":134,"stem":135,"children":136,"page":21},"Nuxt Module","\u002Fnuxt-module","6.nuxt-module",[137,141,145,149],{"title":138,"path":139,"stem":140},"Install and Setup","\u002Fnuxt-module\u002Finstall","6.nuxt-module\u002F1.install",{"title":142,"path":143,"stem":144},"What It Publishes","\u002Fnuxt-module\u002Fwhat-it-publishes","6.nuxt-module\u002F2.what-it-publishes",{"title":146,"path":147,"stem":148},"What It Validates","\u002Fnuxt-module\u002Fvalidation","6.nuxt-module\u002F3.validation",{"title":150,"path":151,"stem":152},"Options and Limits","\u002Fnuxt-module\u002Foptions-and-limits","6.nuxt-module\u002F4.options-and-limits",{"title":154,"icon":155,"path":156,"stem":157,"children":158,"page":21},"CI\u002FCD","i-lucide-git-pull-request","\u002Fci-cd","7.ci-cd",[159,163],{"title":160,"path":161,"stem":162},"GitHub Actions","\u002Fci-cd\u002Fgithub-actions","7.ci-cd\u002F1.github-actions",{"title":164,"path":165,"stem":166},"GitLab CI","\u002Fci-cd\u002Fgitlab-ci","7.ci-cd\u002F2.gitlab-ci",{"title":168,"path":169,"stem":170,"children":171,"page":21},"Concepts","\u002Fconcepts","8.concepts",[172],{"title":173,"path":174,"stem":175},"Translation Modes","\u002Fconcepts\u002Ftranslation-modes","8.concepts\u002F1.translation-modes",{"title":177,"path":178,"stem":179,"children":180,"page":-1},"Reference","\u002Freference","9.reference",[181,183,261,339,343],{"title":177,"path":178,"stem":182},"9.reference\u002Findex",{"title":184,"path":185,"stem":186,"children":187,"page":-1},"CLI Commands","\u002Freference\u002Fcli","9.reference\u002F1.cli\u002Findex",[188,189,193,197,201,205,209,213,217,221,225,229,233,237,241,245,249,253,257],{"title":184,"path":185,"stem":186},{"title":190,"path":191,"stem":192},"add","\u002Freference\u002Fcli\u002Fadd","9.reference\u002F1.cli\u002Fadd",{"title":194,"path":195,"stem":196},"check","\u002Freference\u002Fcli\u002Fcheck","9.reference\u002F1.cli\u002Fcheck",{"title":198,"path":199,"stem":200},"find-duplicates","\u002Freference\u002Fcli\u002Ffind-duplicates","9.reference\u002F1.cli\u002Ffind-duplicates",{"title":202,"path":203,"stem":204},"get","\u002Freference\u002Fcli\u002Fget","9.reference\u002F1.cli\u002Fget",{"title":206,"path":207,"stem":208},"init","\u002Freference\u002Fcli\u002Finit","9.reference\u002F1.cli\u002Finit",{"title":210,"path":211,"stem":212},"missing","\u002Freference\u002Fcli\u002Fmissing","9.reference\u002F1.cli\u002Fmissing",{"title":214,"path":215,"stem":216},"move","\u002Freference\u002Fcli\u002Fmove","9.reference\u002F1.cli\u002Fmove",{"title":218,"path":219,"stem":220},"remove","\u002Freference\u002Fcli\u002Fremove","9.reference\u002F1.cli\u002Fremove",{"title":222,"path":223,"stem":224},"remove-orphans","\u002Freference\u002Fcli\u002Fremove-orphans","9.reference\u002F1.cli\u002Fremove-orphans",{"title":226,"path":227,"stem":228},"rename","\u002Freference\u002Fcli\u002Frename","9.reference\u002F1.cli\u002Frename",{"title":230,"path":231,"stem":232},"scaffold","\u002Freference\u002Fcli\u002Fscaffold","9.reference\u002F1.cli\u002Fscaffold",{"title":234,"path":235,"stem":236},"scan","\u002Freference\u002Fcli\u002Fscan","9.reference\u002F1.cli\u002Fscan",{"title":238,"path":239,"stem":240},"search","\u002Freference\u002Fcli\u002Fsearch","9.reference\u002F1.cli\u002Fsearch",{"title":242,"path":243,"stem":244},"status","\u002Freference\u002Fcli\u002Fstatus","9.reference\u002F1.cli\u002Fstatus",{"title":246,"path":247,"stem":248},"translate","\u002Freference\u002Fcli\u002Ftranslate","9.reference\u002F1.cli\u002Ftranslate",{"title":250,"path":251,"stem":252},"translate-key","\u002Freference\u002Fcli\u002Ftranslate-key","9.reference\u002F1.cli\u002Ftranslate-key",{"title":254,"path":255,"stem":256},"update","\u002Freference\u002Fcli\u002Fupdate","9.reference\u002F1.cli\u002Fupdate",{"title":258,"path":259,"stem":260},"write","\u002Freference\u002Fcli\u002Fwrite","9.reference\u002F1.cli\u002Fwrite",{"title":262,"path":263,"stem":264,"children":265,"page":-1},"MCP Tools","\u002Freference\u002Fmcp","9.reference\u002F2.mcp\u002Findex",[266,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335],{"title":262,"path":263,"stem":264},{"title":268,"path":269,"stem":270},"discover","\u002Freference\u002Fmcp\u002Fdiscover","9.reference\u002F2.mcp\u002Fdiscover",{"title":272,"path":273,"stem":274},"find_duplicate_keys","\u002Freference\u002Fmcp\u002Ffind_duplicate_keys","9.reference\u002F2.mcp\u002Ffind_duplicate_keys",{"title":276,"path":277,"stem":278},"find_empty_translations","\u002Freference\u002Fmcp\u002Ffind_empty_translations","9.reference\u002F2.mcp\u002Ffind_empty_translations",{"title":280,"path":281,"stem":282},"find_orphan_keys","\u002Freference\u002Fmcp\u002Ffind_orphan_keys","9.reference\u002F2.mcp\u002Ffind_orphan_keys",{"title":284,"path":285,"stem":286},"find_undefined_keys","\u002Freference\u002Fmcp\u002Ffind_undefined_keys","9.reference\u002F2.mcp\u002Ffind_undefined_keys",{"title":288,"path":289,"stem":290},"get_missing_translations","\u002Freference\u002Fmcp\u002Fget_missing_translations","9.reference\u002F2.mcp\u002Fget_missing_translations",{"title":292,"path":293,"stem":294},"get_translation_status","\u002Freference\u002Fmcp\u002Fget_translation_status","9.reference\u002F2.mcp\u002Fget_translation_status",{"title":296,"path":297,"stem":298},"get_translations","\u002Freference\u002Fmcp\u002Fget_translations","9.reference\u002F2.mcp\u002Fget_translations",{"title":300,"path":301,"stem":302},"list_namespaces","\u002Freference\u002Fmcp\u002Flist_namespaces","9.reference\u002F2.mcp\u002Flist_namespaces",{"title":304,"path":305,"stem":306},"move_translation_key","\u002Freference\u002Fmcp\u002Fmove_translation_key","9.reference\u002F2.mcp\u002Fmove_translation_key",{"title":308,"path":309,"stem":310},"remove_orphan_keys","\u002Freference\u002Fmcp\u002Fremove_orphan_keys","9.reference\u002F2.mcp\u002Fremove_orphan_keys",{"title":312,"path":313,"stem":314},"remove_translations","\u002Freference\u002Fmcp\u002Fremove_translations","9.reference\u002F2.mcp\u002Fremove_translations",{"title":316,"path":317,"stem":318},"rename_translation_key","\u002Freference\u002Fmcp\u002Frename_translation_key","9.reference\u002F2.mcp\u002Frename_translation_key",{"title":320,"path":321,"stem":322},"scaffold_locale","\u002Freference\u002Fmcp\u002Fscaffold_locale","9.reference\u002F2.mcp\u002Fscaffold_locale",{"title":324,"path":325,"stem":326},"search_translations","\u002Freference\u002Fmcp\u002Fsearch_translations","9.reference\u002F2.mcp\u002Fsearch_translations",{"title":328,"path":329,"stem":330},"translate_key","\u002Freference\u002Fmcp\u002Ftranslate_key","9.reference\u002F2.mcp\u002Ftranslate_key",{"title":332,"path":333,"stem":334},"translate_missing","\u002Freference\u002Fmcp\u002Ftranslate_missing","9.reference\u002F2.mcp\u002Ftranslate_missing",{"title":336,"path":337,"stem":338},"write_translations","\u002Freference\u002Fmcp\u002Fwrite_translations","9.reference\u002F2.mcp\u002Fwrite_translations",{"title":340,"path":341,"stem":342},"GitHub Action","\u002Freference\u002Faction","9.reference\u002F3.action",{"title":344,"path":345,"stem":346},"Programmatic API","\u002Freference\u002Fprogrammatic-api","9.reference\u002F4.programmatic-api",{"title":348,"icon":349,"path":350,"stem":351,"children":352,"page":21},"Extra Topics","i-lucide-microscope","\u002Fextra-topics","91.extra-topics",[353],{"title":354,"path":355,"stem":356},"How Detection Scores Adapters","\u002Fextra-topics\u002Fdetection-scoring","91.extra-topics\u002F1.detection-scoring",{"id":358,"title":50,"body":359,"description":377,"extension":3031,"links":3032,"meta":3033,"navigation":2520,"path":51,"seo":3034,"stem":52,"__hash__":3036},"docs\u002F2.getting-started\u002F2.cold-start.md",{"type":360,"value":361,"toc":3017},"minimark",[362,366,371,400,411,421,425,435,450,710,724,748,751,763,771,788,801,805,817,829,1419,1430,1433,1454,1460,1530,1535,1547,1552,1560,1572,1948,1962,1967,1974,1978,1984,1998,2312,2321,2324,2376,2433,2451,2470,2478,2488,2492,2495,2498,2660,2666,2672,2827,2841,2844,2847,2940,2950,2953,2958,2962,2985,2989,3013],[363,364,365],"p",{},"The outputs below come from running the sequence against a Vue project with four\nlocales in one layer. Your numbers differ; the shapes do not.",[367,368,370],"h2",{"id":369},"install-the-cli","Install the CLI",[372,373,378],"pre",{"className":374,"code":375,"language":376,"meta":377,"style":377},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npm install -g @the-i18n-kit\u002Fcli\n","bash","",[379,380,381],"code",{"__ignoreMap":377},[382,383,386,390,394,397],"span",{"class":384,"line":385},"line",1,[382,387,389],{"class":388},"sBMFI","npm",[382,391,393],{"class":392},"sfazB"," install",[382,395,396],{"class":392}," -g",[382,398,399],{"class":392}," @the-i18n-kit\u002Fcli\n",[363,401,402,403,406,407,410],{},"Or skip the install and prefix every command with ",[379,404,405],{},"npx -y @the-i18n-kit\u002Fcli@latest","\n— the binary is named ",[379,408,409],{},"the-i18n-cli"," either way, and that is the name used\nthroughout this page.",[412,413,414,416,417,420],"note",{},[379,415,409],{}," is also published unscoped, under the name the binary has. Install\nthe scoped ",[379,418,419],{},"@the-i18n-kit\u002Fcli","; the unscoped package publishes from the same\nsource at the same versions but stops receiving updates.",[367,422,424],{"id":423},"_1-generate-a-config-from-detection","1. Generate a Config From Detection",[363,426,427,428,430,431,434],{},"Run ",[379,429,206],{}," with ",[379,432,433],{},"--dryRun"," first. It reports the config it would write and\ntouches no disk:",[372,436,438],{"className":374,"code":437,"language":376,"meta":377,"style":377},"the-i18n-cli init --dryRun\n",[379,439,440],{"__ignoreMap":377},[382,441,442,444,447],{"class":384,"line":385},[382,443,409],{"class":388},[382,445,446],{"class":392}," init",[382,448,449],{"class":392}," --dryRun\n",[372,451,455],{"className":452,"code":453,"language":454,"meta":377,"style":377},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"config\": {\n    \"$schema\": \"https:\u002F\u002Fraw.githubusercontent.com\u002Ffabkho\u002Fthe-i18n-kit\u002Fmain\u002Fpackages\u002Fmcp\u002Fschema.json\",\n    \"context\": \"\",\n    \"glossary\": {},\n    \"translationPrompt\": \"\",\n    \"localeNotes\": {}\n  },\n  \"detected\": {\n    \"adapter\": \"vue\",\n    \"label\": \"Vue\",\n    \"confidence\": 5,\n    \"derivesLocaleConfig\": true\n  },\n  \"configPath\": \".i18n-mcp.json\",\n  \"written\": false\n}\n","json",[379,456,457,463,482,506,523,538,554,569,575,589,610,630,648,663,668,689,704],{"__ignoreMap":377},[382,458,459],{"class":384,"line":385},[382,460,462],{"class":461},"sMK4o","{\n",[382,464,466,469,473,476,479],{"class":384,"line":465},2,[382,467,468],{"class":461},"  \"",[382,470,472],{"class":471},"spNyl","config",[382,474,475],{"class":461},"\"",[382,477,478],{"class":461},":",[382,480,481],{"class":461}," {\n",[382,483,485,488,491,493,495,498,501,503],{"class":384,"line":484},3,[382,486,487],{"class":461},"    \"",[382,489,490],{"class":388},"$schema",[382,492,475],{"class":461},[382,494,478],{"class":461},[382,496,497],{"class":461}," \"",[382,499,500],{"class":392},"https:\u002F\u002Fraw.githubusercontent.com\u002Ffabkho\u002Fthe-i18n-kit\u002Fmain\u002Fpackages\u002Fmcp\u002Fschema.json",[382,502,475],{"class":461},[382,504,505],{"class":461},",\n",[382,507,509,511,514,516,518,521],{"class":384,"line":508},4,[382,510,487],{"class":461},[382,512,513],{"class":388},"context",[382,515,475],{"class":461},[382,517,478],{"class":461},[382,519,520],{"class":461}," \"\"",[382,522,505],{"class":461},[382,524,526,528,531,533,535],{"class":384,"line":525},5,[382,527,487],{"class":461},[382,529,530],{"class":388},"glossary",[382,532,475],{"class":461},[382,534,478],{"class":461},[382,536,537],{"class":461}," {},\n",[382,539,541,543,546,548,550,552],{"class":384,"line":540},6,[382,542,487],{"class":461},[382,544,545],{"class":388},"translationPrompt",[382,547,475],{"class":461},[382,549,478],{"class":461},[382,551,520],{"class":461},[382,553,505],{"class":461},[382,555,557,559,562,564,566],{"class":384,"line":556},7,[382,558,487],{"class":461},[382,560,561],{"class":388},"localeNotes",[382,563,475],{"class":461},[382,565,478],{"class":461},[382,567,568],{"class":461}," {}\n",[382,570,572],{"class":384,"line":571},8,[382,573,574],{"class":461},"  },\n",[382,576,578,580,583,585,587],{"class":384,"line":577},9,[382,579,468],{"class":461},[382,581,582],{"class":471},"detected",[382,584,475],{"class":461},[382,586,478],{"class":461},[382,588,481],{"class":461},[382,590,592,594,597,599,601,603,606,608],{"class":384,"line":591},10,[382,593,487],{"class":461},[382,595,596],{"class":388},"adapter",[382,598,475],{"class":461},[382,600,478],{"class":461},[382,602,497],{"class":461},[382,604,605],{"class":392},"vue",[382,607,475],{"class":461},[382,609,505],{"class":461},[382,611,613,615,618,620,622,624,626,628],{"class":384,"line":612},11,[382,614,487],{"class":461},[382,616,617],{"class":388},"label",[382,619,475],{"class":461},[382,621,478],{"class":461},[382,623,497],{"class":461},[382,625,96],{"class":392},[382,627,475],{"class":461},[382,629,505],{"class":461},[382,631,633,635,638,640,642,646],{"class":384,"line":632},12,[382,634,487],{"class":461},[382,636,637],{"class":388},"confidence",[382,639,475],{"class":461},[382,641,478],{"class":461},[382,643,645],{"class":644},"sbssI"," 5",[382,647,505],{"class":461},[382,649,651,653,656,658,660],{"class":384,"line":650},13,[382,652,487],{"class":461},[382,654,655],{"class":388},"derivesLocaleConfig",[382,657,475],{"class":461},[382,659,478],{"class":461},[382,661,662],{"class":461}," true\n",[382,664,666],{"class":384,"line":665},14,[382,667,574],{"class":461},[382,669,671,673,676,678,680,682,685,687],{"class":384,"line":670},15,[382,672,468],{"class":461},[382,674,675],{"class":471},"configPath",[382,677,475],{"class":461},[382,679,478],{"class":461},[382,681,497],{"class":461},[382,683,684],{"class":392},".i18n-mcp.json",[382,686,475],{"class":461},[382,688,505],{"class":461},[382,690,692,694,697,699,701],{"class":384,"line":691},16,[382,693,468],{"class":461},[382,695,696],{"class":471},"written",[382,698,475],{"class":461},[382,700,478],{"class":461},[382,702,703],{"class":461}," false\n",[382,705,707],{"class":384,"line":706},17,[382,708,709],{"class":461},"}\n",[363,711,712,713,715,716,718,719,723],{},"Read ",[379,714,582],{}," before you write anything. If ",[379,717,596],{}," is not the framework you\nexpected, ",[720,721,722],"a",{"href":85},"detection"," explains how to pin one rather than\nworking around a bad guess for the rest of this page.",[363,725,726,729,730,732,733,736,737,740,741,743,744,747],{},[379,727,728],{},"derivesLocaleConfig: true"," is why the generated config names no locales and no\ndirectories: this adapter reads them out of the project's own files — a Vite\nplugin, a next-intl routing file, a Nuxt config — so restating them by hand\nwould create two answers that can disagree. When no framework adapter matches,\n",[379,731,206],{}," probes for locale directories itself and writes ",[379,734,735],{},"localeDirs"," and\n",[379,738,739],{},"defaultLocale"," into the file instead — that is the generic path, and\n",[379,742,655],{}," is ",[379,745,746],{},"false"," on it.",[363,749,750],{},"Then write it:",[372,752,754],{"className":374,"code":753,"language":376,"meta":377,"style":377},"the-i18n-cli init\n",[379,755,756],{"__ignoreMap":377},[382,757,758,760],{"class":384,"line":385},[382,759,409],{"class":388},[382,761,762],{"class":392}," init\n",[372,764,769],{"className":765,"code":767,"language":768},[766],"language-text","ℹ Wrote .i18n-mcp.json (Vue, confidence 5)\n","text",[379,770,767],{"__ignoreMap":377},[363,772,773,775,776,778,779,782,783,787],{},[379,774,206],{}," is non-interactive and refuses to overwrite an existing ",[379,777,684],{},"\nwithout ",[379,780,781],{},"--force",", so running it in a configured repository cannot cost you a\nglossary. Full flags: ",[720,784,785],{"href":207},[379,786,206],{},".",[363,789,790,794,795,797,798,800],{},[791,792,793],"strong",{},"Verify:"," ",[379,796,684],{}," exists at your project root and contains a\n",[379,799,490],{}," pointer.",[367,802,804],{"id":803},"_2-take-a-health-check","2. Take a Health Check",[363,806,807,809,810,813,814,787],{},[379,808,242],{}," reports coverage per locale and per ",[791,811,812],{},"layer"," — a layer being a scoped\nlocale directory: a Nuxt layer, a workspace package, a shared UI library, or one\napp in a monorepo. A single-app project has one layer, named ",[379,815,816],{},"root",[372,818,820],{"className":374,"code":819,"language":376,"meta":377,"style":377},"the-i18n-cli status\n",[379,821,822],{"__ignoreMap":377},[382,823,824,826],{"class":384,"line":385},[382,825,409],{"class":388},[382,827,828],{"class":392}," status\n",[372,830,832],{"className":452,"code":831,"language":454,"meta":377,"style":377},"{\n  \"locales\": [\n    { \"code\": \"en-US\", \"total\": 12, \"translated\": 12, \"missing\": 0, \"empty\": 0, \"completion\": 100 },\n    { \"code\": \"es-ES\", \"total\": 12, \"translated\": 9, \"missing\": 3, \"empty\": 0, \"completion\": 75 },\n    { \"code\": \"fr-FR\", \"total\": 12, \"translated\": 11, \"missing\": 1, \"empty\": 0, \"completion\": 91.7 }\n  ],\n  \"layers\": [\n    { \"layer\": \"root\", \"total\": 36, \"translated\": 32, \"missing\": 4, \"empty\": 0, \"completion\": 88.9 }\n  ],\n  \"summary\": {\n    \"referenceLocale\": { \"code\": \"en-US\", \"language\": \"en-US\", \"file\": \"en-US.json\" },\n    \"layersScanned\": [\"root\"],\n    \"protectedLocales\": [],\n    \"totalKeys\": 36,\n    \"translatedKeys\": 32,\n    \"missingKeys\": 4,\n    \"emptyKeys\": 0,\n    \"completionPercent\": 88.9\n  }\n}\n",[379,833,834,838,852,943,1027,1112,1117,1130,1214,1218,1231,1296,1319,1333,1348,1363,1378,1393,1408,1414],{"__ignoreMap":377},[382,835,836],{"class":384,"line":385},[382,837,462],{"class":461},[382,839,840,842,845,847,849],{"class":384,"line":465},[382,841,468],{"class":461},[382,843,844],{"class":471},"locales",[382,846,475],{"class":461},[382,848,478],{"class":461},[382,850,851],{"class":461}," [\n",[382,853,854,857,859,861,863,865,867,870,872,875,877,880,882,884,887,889,891,894,896,898,900,902,904,906,908,910,913,915,917,920,922,924,926,928,930,933,935,937,940],{"class":384,"line":484},[382,855,856],{"class":461},"    {",[382,858,497],{"class":461},[382,860,379],{"class":388},[382,862,475],{"class":461},[382,864,478],{"class":461},[382,866,497],{"class":461},[382,868,869],{"class":392},"en-US",[382,871,475],{"class":461},[382,873,874],{"class":461},",",[382,876,497],{"class":461},[382,878,879],{"class":388},"total",[382,881,475],{"class":461},[382,883,478],{"class":461},[382,885,886],{"class":644}," 12",[382,888,874],{"class":461},[382,890,497],{"class":461},[382,892,893],{"class":388},"translated",[382,895,475],{"class":461},[382,897,478],{"class":461},[382,899,886],{"class":644},[382,901,874],{"class":461},[382,903,497],{"class":461},[382,905,210],{"class":388},[382,907,475],{"class":461},[382,909,478],{"class":461},[382,911,912],{"class":644}," 0",[382,914,874],{"class":461},[382,916,497],{"class":461},[382,918,919],{"class":388},"empty",[382,921,475],{"class":461},[382,923,478],{"class":461},[382,925,912],{"class":644},[382,927,874],{"class":461},[382,929,497],{"class":461},[382,931,932],{"class":388},"completion",[382,934,475],{"class":461},[382,936,478],{"class":461},[382,938,939],{"class":644}," 100",[382,941,942],{"class":461}," },\n",[382,944,945,947,949,951,953,955,957,960,962,964,966,968,970,972,974,976,978,980,982,984,987,989,991,993,995,997,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1025],{"class":384,"line":508},[382,946,856],{"class":461},[382,948,497],{"class":461},[382,950,379],{"class":388},[382,952,475],{"class":461},[382,954,478],{"class":461},[382,956,497],{"class":461},[382,958,959],{"class":392},"es-ES",[382,961,475],{"class":461},[382,963,874],{"class":461},[382,965,497],{"class":461},[382,967,879],{"class":388},[382,969,475],{"class":461},[382,971,478],{"class":461},[382,973,886],{"class":644},[382,975,874],{"class":461},[382,977,497],{"class":461},[382,979,893],{"class":388},[382,981,475],{"class":461},[382,983,478],{"class":461},[382,985,986],{"class":644}," 9",[382,988,874],{"class":461},[382,990,497],{"class":461},[382,992,210],{"class":388},[382,994,475],{"class":461},[382,996,478],{"class":461},[382,998,999],{"class":644}," 3",[382,1001,874],{"class":461},[382,1003,497],{"class":461},[382,1005,919],{"class":388},[382,1007,475],{"class":461},[382,1009,478],{"class":461},[382,1011,912],{"class":644},[382,1013,874],{"class":461},[382,1015,497],{"class":461},[382,1017,932],{"class":388},[382,1019,475],{"class":461},[382,1021,478],{"class":461},[382,1023,1024],{"class":644}," 75",[382,1026,942],{"class":461},[382,1028,1029,1031,1033,1035,1037,1039,1041,1044,1046,1048,1050,1052,1054,1056,1058,1060,1062,1064,1066,1068,1071,1073,1075,1077,1079,1081,1084,1086,1088,1090,1092,1094,1096,1098,1100,1102,1104,1106,1109],{"class":384,"line":525},[382,1030,856],{"class":461},[382,1032,497],{"class":461},[382,1034,379],{"class":388},[382,1036,475],{"class":461},[382,1038,478],{"class":461},[382,1040,497],{"class":461},[382,1042,1043],{"class":392},"fr-FR",[382,1045,475],{"class":461},[382,1047,874],{"class":461},[382,1049,497],{"class":461},[382,1051,879],{"class":388},[382,1053,475],{"class":461},[382,1055,478],{"class":461},[382,1057,886],{"class":644},[382,1059,874],{"class":461},[382,1061,497],{"class":461},[382,1063,893],{"class":388},[382,1065,475],{"class":461},[382,1067,478],{"class":461},[382,1069,1070],{"class":644}," 11",[382,1072,874],{"class":461},[382,1074,497],{"class":461},[382,1076,210],{"class":388},[382,1078,475],{"class":461},[382,1080,478],{"class":461},[382,1082,1083],{"class":644}," 1",[382,1085,874],{"class":461},[382,1087,497],{"class":461},[382,1089,919],{"class":388},[382,1091,475],{"class":461},[382,1093,478],{"class":461},[382,1095,912],{"class":644},[382,1097,874],{"class":461},[382,1099,497],{"class":461},[382,1101,932],{"class":388},[382,1103,475],{"class":461},[382,1105,478],{"class":461},[382,1107,1108],{"class":644}," 91.7",[382,1110,1111],{"class":461}," }\n",[382,1113,1114],{"class":384,"line":540},[382,1115,1116],{"class":461},"  ],\n",[382,1118,1119,1121,1124,1126,1128],{"class":384,"line":556},[382,1120,468],{"class":461},[382,1122,1123],{"class":471},"layers",[382,1125,475],{"class":461},[382,1127,478],{"class":461},[382,1129,851],{"class":461},[382,1131,1132,1134,1136,1138,1140,1142,1144,1146,1148,1150,1152,1154,1156,1158,1161,1163,1165,1167,1169,1171,1174,1176,1178,1180,1182,1184,1187,1189,1191,1193,1195,1197,1199,1201,1203,1205,1207,1209,1212],{"class":384,"line":571},[382,1133,856],{"class":461},[382,1135,497],{"class":461},[382,1137,812],{"class":388},[382,1139,475],{"class":461},[382,1141,478],{"class":461},[382,1143,497],{"class":461},[382,1145,816],{"class":392},[382,1147,475],{"class":461},[382,1149,874],{"class":461},[382,1151,497],{"class":461},[382,1153,879],{"class":388},[382,1155,475],{"class":461},[382,1157,478],{"class":461},[382,1159,1160],{"class":644}," 36",[382,1162,874],{"class":461},[382,1164,497],{"class":461},[382,1166,893],{"class":388},[382,1168,475],{"class":461},[382,1170,478],{"class":461},[382,1172,1173],{"class":644}," 32",[382,1175,874],{"class":461},[382,1177,497],{"class":461},[382,1179,210],{"class":388},[382,1181,475],{"class":461},[382,1183,478],{"class":461},[382,1185,1186],{"class":644}," 4",[382,1188,874],{"class":461},[382,1190,497],{"class":461},[382,1192,919],{"class":388},[382,1194,475],{"class":461},[382,1196,478],{"class":461},[382,1198,912],{"class":644},[382,1200,874],{"class":461},[382,1202,497],{"class":461},[382,1204,932],{"class":388},[382,1206,475],{"class":461},[382,1208,478],{"class":461},[382,1210,1211],{"class":644}," 88.9",[382,1213,1111],{"class":461},[382,1215,1216],{"class":384,"line":577},[382,1217,1116],{"class":461},[382,1219,1220,1222,1225,1227,1229],{"class":384,"line":591},[382,1221,468],{"class":461},[382,1223,1224],{"class":471},"summary",[382,1226,475],{"class":461},[382,1228,478],{"class":461},[382,1230,481],{"class":461},[382,1232,1233,1235,1238,1240,1242,1245,1247,1249,1251,1253,1255,1257,1259,1261,1263,1266,1268,1270,1272,1274,1276,1278,1280,1283,1285,1287,1289,1292,1294],{"class":384,"line":612},[382,1234,487],{"class":461},[382,1236,1237],{"class":388},"referenceLocale",[382,1239,475],{"class":461},[382,1241,478],{"class":461},[382,1243,1244],{"class":461}," {",[382,1246,497],{"class":461},[382,1248,379],{"class":644},[382,1250,475],{"class":461},[382,1252,478],{"class":461},[382,1254,497],{"class":461},[382,1256,869],{"class":392},[382,1258,475],{"class":461},[382,1260,874],{"class":461},[382,1262,497],{"class":461},[382,1264,1265],{"class":644},"language",[382,1267,475],{"class":461},[382,1269,478],{"class":461},[382,1271,497],{"class":461},[382,1273,869],{"class":392},[382,1275,475],{"class":461},[382,1277,874],{"class":461},[382,1279,497],{"class":461},[382,1281,1282],{"class":644},"file",[382,1284,475],{"class":461},[382,1286,478],{"class":461},[382,1288,497],{"class":461},[382,1290,1291],{"class":392},"en-US.json",[382,1293,475],{"class":461},[382,1295,942],{"class":461},[382,1297,1298,1300,1303,1305,1307,1310,1312,1314,1316],{"class":384,"line":632},[382,1299,487],{"class":461},[382,1301,1302],{"class":388},"layersScanned",[382,1304,475],{"class":461},[382,1306,478],{"class":461},[382,1308,1309],{"class":461}," [",[382,1311,475],{"class":461},[382,1313,816],{"class":392},[382,1315,475],{"class":461},[382,1317,1318],{"class":461},"],\n",[382,1320,1321,1323,1326,1328,1330],{"class":384,"line":650},[382,1322,487],{"class":461},[382,1324,1325],{"class":388},"protectedLocales",[382,1327,475],{"class":461},[382,1329,478],{"class":461},[382,1331,1332],{"class":461}," [],\n",[382,1334,1335,1337,1340,1342,1344,1346],{"class":384,"line":665},[382,1336,487],{"class":461},[382,1338,1339],{"class":388},"totalKeys",[382,1341,475],{"class":461},[382,1343,478],{"class":461},[382,1345,1160],{"class":644},[382,1347,505],{"class":461},[382,1349,1350,1352,1355,1357,1359,1361],{"class":384,"line":670},[382,1351,487],{"class":461},[382,1353,1354],{"class":388},"translatedKeys",[382,1356,475],{"class":461},[382,1358,478],{"class":461},[382,1360,1173],{"class":644},[382,1362,505],{"class":461},[382,1364,1365,1367,1370,1372,1374,1376],{"class":384,"line":691},[382,1366,487],{"class":461},[382,1368,1369],{"class":388},"missingKeys",[382,1371,475],{"class":461},[382,1373,478],{"class":461},[382,1375,1186],{"class":644},[382,1377,505],{"class":461},[382,1379,1380,1382,1385,1387,1389,1391],{"class":384,"line":706},[382,1381,487],{"class":461},[382,1383,1384],{"class":388},"emptyKeys",[382,1386,475],{"class":461},[382,1388,478],{"class":461},[382,1390,912],{"class":644},[382,1392,505],{"class":461},[382,1394,1396,1398,1401,1403,1405],{"class":384,"line":1395},18,[382,1397,487],{"class":461},[382,1399,1400],{"class":388},"completionPercent",[382,1402,475],{"class":461},[382,1404,478],{"class":461},[382,1406,1407],{"class":644}," 88.9\n",[382,1409,1411],{"class":384,"line":1410},19,[382,1412,1413],{"class":461},"  }\n",[382,1415,1417],{"class":384,"line":1416},20,[382,1418,709],{"class":461},[363,1420,1421,1422,1425,1426,1429],{},"Output is JSON whenever stdout is not a terminal, so ",[379,1423,1424],{},"the-i18n-cli status | jq .summary"," works with no flag. Logs go to stderr, which is what keeps the pipe\nparseable. Pass ",[379,1427,1428],{},"--json"," to force it in a terminal too.",[363,1431,1432],{},"Check two fields:",[1434,1435,1436,1447],"ul",{},[1437,1438,1439,1443,1444,787],"li",{},[791,1440,1441],{},[379,1442,1237],{}," is the locale everything is compared against. Some\nadapters derive it and some cannot: the Vue and React adapters take the\nalphabetically first locale they find, which is how a project with English\nsource strings ends up measured against ",[379,1445,1446],{},"de-DE",[1437,1448,1449,1453],{},[791,1450,1451],{},[379,1452,1325],{}," is empty until you say otherwise, so every locale is a\ncandidate for machine translation.",[363,1455,1456,1457,1459],{},"Fix both in the file ",[379,1458,206],{}," wrote in step 1:",[372,1461,1463],{"className":452,"code":1462,"filename":684,"language":454,"meta":377,"style":377},"{\n  \"$schema\": \"https:\u002F\u002Fraw.githubusercontent.com\u002Ffabkho\u002Fthe-i18n-kit\u002Fmain\u002Fpackages\u002Fmcp\u002Fschema.json\",\n  \"defaultLocale\": \"en-US\",\n  \"protectedLocales\": [\"de-DE\"]\n}\n",[379,1464,1465,1469,1487,1505,1526],{"__ignoreMap":377},[382,1466,1467],{"class":384,"line":385},[382,1468,462],{"class":461},[382,1470,1471,1473,1475,1477,1479,1481,1483,1485],{"class":384,"line":465},[382,1472,468],{"class":461},[382,1474,490],{"class":471},[382,1476,475],{"class":461},[382,1478,478],{"class":461},[382,1480,497],{"class":461},[382,1482,500],{"class":392},[382,1484,475],{"class":461},[382,1486,505],{"class":461},[382,1488,1489,1491,1493,1495,1497,1499,1501,1503],{"class":384,"line":484},[382,1490,468],{"class":461},[382,1492,739],{"class":471},[382,1494,475],{"class":461},[382,1496,478],{"class":461},[382,1498,497],{"class":461},[382,1500,869],{"class":392},[382,1502,475],{"class":461},[382,1504,505],{"class":461},[382,1506,1507,1509,1511,1513,1515,1517,1519,1521,1523],{"class":384,"line":508},[382,1508,468],{"class":461},[382,1510,1325],{"class":471},[382,1512,475],{"class":461},[382,1514,478],{"class":461},[382,1516,1309],{"class":461},[382,1518,475],{"class":461},[382,1520,1446],{"class":392},[382,1522,475],{"class":461},[382,1524,1525],{"class":461},"]\n",[382,1527,1528],{"class":384,"line":525},[382,1529,709],{"class":461},[363,1531,427,1532,1534],{},[379,1533,242],{}," again and both fields follow. A protected locale drops out of the\ncounted set, so the completion percentage moves — that is the confirmation the\nfile was read.",[363,1536,1537,794,1539,1542,1543,1546],{},[791,1538,793],{},[379,1540,1541],{},"summary.referenceLocale.code"," is the locale your developers write\nstrings in, and ",[379,1544,1545],{},"summary.protectedLocales"," names every locale a human\nmaintains.",[1548,1549,1551],"h3",{"id":1550},"the-other-half-of-the-health-check","The Other Half of the Health Check",[363,1553,1554,1556,1557,1559],{},[379,1555,242],{}," measures locale files against each other. It cannot see a key your code\ncalls that no locale file defines — that key renders as a raw string in\nproduction, and it is the failure your users notice first. ",[379,1558,194],{}," finds those:",[372,1561,1563],{"className":374,"code":1562,"language":376,"meta":377,"style":377},"the-i18n-cli check\n",[379,1564,1565],{"__ignoreMap":377},[382,1566,1567,1569],{"class":384,"line":385},[382,1568,409],{"class":388},[382,1570,1571],{"class":392}," check\n",[372,1573,1575],{"className":452,"code":1574,"language":454,"meta":377,"style":377},"{\n  \"undefinedKeys\": [\n    {\n      \"key\": \"booking.cancelled\",\n      \"app\": \"default\",\n      \"searchedLayers\": [\"root\"],\n      \"usages\": [{ \"file\": \"src\u002FApp.vue\", \"line\": 17 }]\n    }\n  ],\n  \"uncertainKeys\": [],\n  \"summary\": {\n    \"usedKeysChecked\": 5,\n    \"undefinedCount\": 1,\n    \"uncertainCount\": 0,\n    \"filesScanned\": 2,\n    \"locale\": \"en-US\"\n  },\n  \"gatesTripped\": [\n    {\n      \"name\": \"undefined-keys\",\n      \"counter\": \"undefinedCount\",\n      \"direction\": \"above\",\n      \"threshold\": 0,\n      \"observed\": 1\n    }\n  ]\n}\n",[379,1576,1577,1581,1594,1599,1620,1640,1661,1706,1711,1715,1728,1740,1755,1770,1785,1801,1819,1823,1836,1840,1860,1880,1901,1917,1932,1937,1943],{"__ignoreMap":377},[382,1578,1579],{"class":384,"line":385},[382,1580,462],{"class":461},[382,1582,1583,1585,1588,1590,1592],{"class":384,"line":465},[382,1584,468],{"class":461},[382,1586,1587],{"class":471},"undefinedKeys",[382,1589,475],{"class":461},[382,1591,478],{"class":461},[382,1593,851],{"class":461},[382,1595,1596],{"class":384,"line":484},[382,1597,1598],{"class":461},"    {\n",[382,1600,1601,1604,1607,1609,1611,1613,1616,1618],{"class":384,"line":508},[382,1602,1603],{"class":461},"      \"",[382,1605,1606],{"class":388},"key",[382,1608,475],{"class":461},[382,1610,478],{"class":461},[382,1612,497],{"class":461},[382,1614,1615],{"class":392},"booking.cancelled",[382,1617,475],{"class":461},[382,1619,505],{"class":461},[382,1621,1622,1624,1627,1629,1631,1633,1636,1638],{"class":384,"line":525},[382,1623,1603],{"class":461},[382,1625,1626],{"class":388},"app",[382,1628,475],{"class":461},[382,1630,478],{"class":461},[382,1632,497],{"class":461},[382,1634,1635],{"class":392},"default",[382,1637,475],{"class":461},[382,1639,505],{"class":461},[382,1641,1642,1644,1647,1649,1651,1653,1655,1657,1659],{"class":384,"line":540},[382,1643,1603],{"class":461},[382,1645,1646],{"class":388},"searchedLayers",[382,1648,475],{"class":461},[382,1650,478],{"class":461},[382,1652,1309],{"class":461},[382,1654,475],{"class":461},[382,1656,816],{"class":392},[382,1658,475],{"class":461},[382,1660,1318],{"class":461},[382,1662,1663,1665,1668,1670,1672,1675,1677,1679,1681,1683,1685,1688,1690,1692,1694,1696,1698,1700,1703],{"class":384,"line":556},[382,1664,1603],{"class":461},[382,1666,1667],{"class":388},"usages",[382,1669,475],{"class":461},[382,1671,478],{"class":461},[382,1673,1674],{"class":461}," [{",[382,1676,497],{"class":461},[382,1678,1282],{"class":644},[382,1680,475],{"class":461},[382,1682,478],{"class":461},[382,1684,497],{"class":461},[382,1686,1687],{"class":392},"src\u002FApp.vue",[382,1689,475],{"class":461},[382,1691,874],{"class":461},[382,1693,497],{"class":461},[382,1695,384],{"class":644},[382,1697,475],{"class":461},[382,1699,478],{"class":461},[382,1701,1702],{"class":644}," 17",[382,1704,1705],{"class":461}," }]\n",[382,1707,1708],{"class":384,"line":571},[382,1709,1710],{"class":461},"    }\n",[382,1712,1713],{"class":384,"line":577},[382,1714,1116],{"class":461},[382,1716,1717,1719,1722,1724,1726],{"class":384,"line":591},[382,1718,468],{"class":461},[382,1720,1721],{"class":471},"uncertainKeys",[382,1723,475],{"class":461},[382,1725,478],{"class":461},[382,1727,1332],{"class":461},[382,1729,1730,1732,1734,1736,1738],{"class":384,"line":612},[382,1731,468],{"class":461},[382,1733,1224],{"class":471},[382,1735,475],{"class":461},[382,1737,478],{"class":461},[382,1739,481],{"class":461},[382,1741,1742,1744,1747,1749,1751,1753],{"class":384,"line":632},[382,1743,487],{"class":461},[382,1745,1746],{"class":388},"usedKeysChecked",[382,1748,475],{"class":461},[382,1750,478],{"class":461},[382,1752,645],{"class":644},[382,1754,505],{"class":461},[382,1756,1757,1759,1762,1764,1766,1768],{"class":384,"line":650},[382,1758,487],{"class":461},[382,1760,1761],{"class":388},"undefinedCount",[382,1763,475],{"class":461},[382,1765,478],{"class":461},[382,1767,1083],{"class":644},[382,1769,505],{"class":461},[382,1771,1772,1774,1777,1779,1781,1783],{"class":384,"line":665},[382,1773,487],{"class":461},[382,1775,1776],{"class":388},"uncertainCount",[382,1778,475],{"class":461},[382,1780,478],{"class":461},[382,1782,912],{"class":644},[382,1784,505],{"class":461},[382,1786,1787,1789,1792,1794,1796,1799],{"class":384,"line":670},[382,1788,487],{"class":461},[382,1790,1791],{"class":388},"filesScanned",[382,1793,475],{"class":461},[382,1795,478],{"class":461},[382,1797,1798],{"class":644}," 2",[382,1800,505],{"class":461},[382,1802,1803,1805,1808,1810,1812,1814,1816],{"class":384,"line":691},[382,1804,487],{"class":461},[382,1806,1807],{"class":388},"locale",[382,1809,475],{"class":461},[382,1811,478],{"class":461},[382,1813,497],{"class":461},[382,1815,869],{"class":392},[382,1817,1818],{"class":461},"\"\n",[382,1820,1821],{"class":384,"line":706},[382,1822,574],{"class":461},[382,1824,1825,1827,1830,1832,1834],{"class":384,"line":1395},[382,1826,468],{"class":461},[382,1828,1829],{"class":471},"gatesTripped",[382,1831,475],{"class":461},[382,1833,478],{"class":461},[382,1835,851],{"class":461},[382,1837,1838],{"class":384,"line":1410},[382,1839,1598],{"class":461},[382,1841,1842,1844,1847,1849,1851,1853,1856,1858],{"class":384,"line":1416},[382,1843,1603],{"class":461},[382,1845,1846],{"class":388},"name",[382,1848,475],{"class":461},[382,1850,478],{"class":461},[382,1852,497],{"class":461},[382,1854,1855],{"class":392},"undefined-keys",[382,1857,475],{"class":461},[382,1859,505],{"class":461},[382,1861,1863,1865,1868,1870,1872,1874,1876,1878],{"class":384,"line":1862},21,[382,1864,1603],{"class":461},[382,1866,1867],{"class":388},"counter",[382,1869,475],{"class":461},[382,1871,478],{"class":461},[382,1873,497],{"class":461},[382,1875,1761],{"class":392},[382,1877,475],{"class":461},[382,1879,505],{"class":461},[382,1881,1883,1885,1888,1890,1892,1894,1897,1899],{"class":384,"line":1882},22,[382,1884,1603],{"class":461},[382,1886,1887],{"class":388},"direction",[382,1889,475],{"class":461},[382,1891,478],{"class":461},[382,1893,497],{"class":461},[382,1895,1896],{"class":392},"above",[382,1898,475],{"class":461},[382,1900,505],{"class":461},[382,1902,1904,1906,1909,1911,1913,1915],{"class":384,"line":1903},23,[382,1905,1603],{"class":461},[382,1907,1908],{"class":388},"threshold",[382,1910,475],{"class":461},[382,1912,478],{"class":461},[382,1914,912],{"class":644},[382,1916,505],{"class":461},[382,1918,1920,1922,1925,1927,1929],{"class":384,"line":1919},24,[382,1921,1603],{"class":461},[382,1923,1924],{"class":388},"observed",[382,1926,475],{"class":461},[382,1928,478],{"class":461},[382,1930,1931],{"class":644}," 1\n",[382,1933,1935],{"class":384,"line":1934},25,[382,1936,1710],{"class":461},[382,1938,1940],{"class":384,"line":1939},26,[382,1941,1942],{"class":461},"  ]\n",[382,1944,1946],{"class":384,"line":1945},27,[382,1947,709],{"class":461},[363,1949,1950,1951,1954,1955,1957,1958,787],{},"That run exits ",[791,1952,1953],{},"2",", not 1. Exit 2 means a gate tripped: the command worked and\nfound what you asked it to fail on. Exit 1 would mean the run itself fell over\nand its counters say nothing about your project. ",[379,1956,194],{}," is the one command whose\ngate is always on and needs no flag, because a key that renders raw is a defect\nrather than a threshold you opt into caring about. The full table is on the\n",[720,1959,1961],{"href":1960},"\u002Freference\u002Fcli#exit-codes","CLI reference",[363,1963,1964,1966],{},[379,1965,1721],{}," holds references the static scanner could not resolve —\ntemplate literals and other dynamically built keys. They are reported and never\ncounted as findings, so a dynamic key cannot fail your build on a guess.",[363,1968,1969,794,1971,1973],{},[791,1970,793],{},[379,1972,194],{}," exits 0 on a clean project, and exits 2 listing file and\nline when you delete a key that is still called.",[367,1975,1977],{"id":1976},"_3-translate-the-missing-keys","3. Translate the Missing Keys",[363,1979,1980,1981,1983],{},"Preview before spending anything. ",[379,1982,433],{}," reports what would be translated\nand calls no provider at all:",[372,1985,1987],{"className":374,"code":1986,"language":376,"meta":377,"style":377},"the-i18n-cli translate --dryRun\n",[379,1988,1989],{"__ignoreMap":377},[382,1990,1991,1993,1996],{"class":384,"line":385},[382,1992,409],{"class":388},[382,1994,1995],{"class":392}," translate",[382,1997,449],{"class":392},[372,1999,2001],{"className":452,"code":2000,"language":454,"meta":377,"style":377},"{\n  \"summary\": {\n    \"mode\": \"dry-run\",\n    \"totalTranslated\": 0,\n    \"totalFailed\": 0,\n    \"totalSkipped\": 0,\n    \"totalWouldTranslate\": 4,\n    \"layers\": [\"root\"],\n    \"referenceLocale\": { \"code\": \"en-US\", \"language\": \"en-US\", \"file\": \"en-US.json\" },\n    \"targetLocales\": [\n      { \"code\": \"es-ES\", \"language\": \"es-ES\", \"file\": \"es-ES.json\" },\n      { \"code\": \"fr-FR\", \"language\": \"fr-FR\", \"file\": \"fr-FR.json\" }\n    ]\n  }\n}\n",[379,2002,2003,2007,2019,2039,2054,2069,2084,2099,2119,2179,2192,2246,2299,2304,2308],{"__ignoreMap":377},[382,2004,2005],{"class":384,"line":385},[382,2006,462],{"class":461},[382,2008,2009,2011,2013,2015,2017],{"class":384,"line":465},[382,2010,468],{"class":461},[382,2012,1224],{"class":471},[382,2014,475],{"class":461},[382,2016,478],{"class":461},[382,2018,481],{"class":461},[382,2020,2021,2023,2026,2028,2030,2032,2035,2037],{"class":384,"line":484},[382,2022,487],{"class":461},[382,2024,2025],{"class":388},"mode",[382,2027,475],{"class":461},[382,2029,478],{"class":461},[382,2031,497],{"class":461},[382,2033,2034],{"class":392},"dry-run",[382,2036,475],{"class":461},[382,2038,505],{"class":461},[382,2040,2041,2043,2046,2048,2050,2052],{"class":384,"line":508},[382,2042,487],{"class":461},[382,2044,2045],{"class":388},"totalTranslated",[382,2047,475],{"class":461},[382,2049,478],{"class":461},[382,2051,912],{"class":644},[382,2053,505],{"class":461},[382,2055,2056,2058,2061,2063,2065,2067],{"class":384,"line":525},[382,2057,487],{"class":461},[382,2059,2060],{"class":388},"totalFailed",[382,2062,475],{"class":461},[382,2064,478],{"class":461},[382,2066,912],{"class":644},[382,2068,505],{"class":461},[382,2070,2071,2073,2076,2078,2080,2082],{"class":384,"line":540},[382,2072,487],{"class":461},[382,2074,2075],{"class":388},"totalSkipped",[382,2077,475],{"class":461},[382,2079,478],{"class":461},[382,2081,912],{"class":644},[382,2083,505],{"class":461},[382,2085,2086,2088,2091,2093,2095,2097],{"class":384,"line":556},[382,2087,487],{"class":461},[382,2089,2090],{"class":388},"totalWouldTranslate",[382,2092,475],{"class":461},[382,2094,478],{"class":461},[382,2096,1186],{"class":644},[382,2098,505],{"class":461},[382,2100,2101,2103,2105,2107,2109,2111,2113,2115,2117],{"class":384,"line":571},[382,2102,487],{"class":461},[382,2104,1123],{"class":388},[382,2106,475],{"class":461},[382,2108,478],{"class":461},[382,2110,1309],{"class":461},[382,2112,475],{"class":461},[382,2114,816],{"class":392},[382,2116,475],{"class":461},[382,2118,1318],{"class":461},[382,2120,2121,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2143,2145,2147,2149,2151,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173,2175,2177],{"class":384,"line":577},[382,2122,487],{"class":461},[382,2124,1237],{"class":388},[382,2126,475],{"class":461},[382,2128,478],{"class":461},[382,2130,1244],{"class":461},[382,2132,497],{"class":461},[382,2134,379],{"class":644},[382,2136,475],{"class":461},[382,2138,478],{"class":461},[382,2140,497],{"class":461},[382,2142,869],{"class":392},[382,2144,475],{"class":461},[382,2146,874],{"class":461},[382,2148,497],{"class":461},[382,2150,1265],{"class":644},[382,2152,475],{"class":461},[382,2154,478],{"class":461},[382,2156,497],{"class":461},[382,2158,869],{"class":392},[382,2160,475],{"class":461},[382,2162,874],{"class":461},[382,2164,497],{"class":461},[382,2166,1282],{"class":644},[382,2168,475],{"class":461},[382,2170,478],{"class":461},[382,2172,497],{"class":461},[382,2174,1291],{"class":392},[382,2176,475],{"class":461},[382,2178,942],{"class":461},[382,2180,2181,2183,2186,2188,2190],{"class":384,"line":591},[382,2182,487],{"class":461},[382,2184,2185],{"class":388},"targetLocales",[382,2187,475],{"class":461},[382,2189,478],{"class":461},[382,2191,851],{"class":461},[382,2193,2194,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221,2223,2225,2227,2229,2231,2233,2235,2237,2239,2242,2244],{"class":384,"line":612},[382,2195,2196],{"class":461},"      {",[382,2198,497],{"class":461},[382,2200,379],{"class":644},[382,2202,475],{"class":461},[382,2204,478],{"class":461},[382,2206,497],{"class":461},[382,2208,959],{"class":392},[382,2210,475],{"class":461},[382,2212,874],{"class":461},[382,2214,497],{"class":461},[382,2216,1265],{"class":644},[382,2218,475],{"class":461},[382,2220,478],{"class":461},[382,2222,497],{"class":461},[382,2224,959],{"class":392},[382,2226,475],{"class":461},[382,2228,874],{"class":461},[382,2230,497],{"class":461},[382,2232,1282],{"class":644},[382,2234,475],{"class":461},[382,2236,478],{"class":461},[382,2238,497],{"class":461},[382,2240,2241],{"class":392},"es-ES.json",[382,2243,475],{"class":461},[382,2245,942],{"class":461},[382,2247,2248,2250,2252,2254,2256,2258,2260,2262,2264,2266,2268,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290,2292,2295,2297],{"class":384,"line":632},[382,2249,2196],{"class":461},[382,2251,497],{"class":461},[382,2253,379],{"class":644},[382,2255,475],{"class":461},[382,2257,478],{"class":461},[382,2259,497],{"class":461},[382,2261,1043],{"class":392},[382,2263,475],{"class":461},[382,2265,874],{"class":461},[382,2267,497],{"class":461},[382,2269,1265],{"class":644},[382,2271,475],{"class":461},[382,2273,478],{"class":461},[382,2275,497],{"class":461},[382,2277,1043],{"class":392},[382,2279,475],{"class":461},[382,2281,874],{"class":461},[382,2283,497],{"class":461},[382,2285,1282],{"class":644},[382,2287,475],{"class":461},[382,2289,478],{"class":461},[382,2291,497],{"class":461},[382,2293,2294],{"class":392},"fr-FR.json",[382,2296,475],{"class":461},[382,2298,1111],{"class":461},[382,2300,2301],{"class":384,"line":650},[382,2302,2303],{"class":461},"    ]\n",[382,2305,2306],{"class":384,"line":665},[382,2307,1413],{"class":461},[382,2309,2310],{"class":384,"line":670},[382,2311,709],{"class":461},[363,2313,2314,2316,2317,2320],{},[379,2315,2185],{}," is the check that step 2 landed: the locale you protected is not\nin it. Without ",[379,2318,2319],{},"--layer",", every locale-backed layer is translated in one run and\nthe totals are aggregated across them.",[363,2322,2323],{},"Now the real run. Name a provider, a model and a key:",[372,2325,2327],{"className":374,"code":2326,"language":376,"meta":377,"style":377},"the-i18n-cli translate \\\n  --provider google \\\n  --model gemini-2.5-flash \\\n  --apiKey \u003Cyour-api-key>\n",[379,2328,2329,2339,2349,2359],{"__ignoreMap":377},[382,2330,2331,2333,2335],{"class":384,"line":385},[382,2332,409],{"class":388},[382,2334,1995],{"class":392},[382,2336,2338],{"class":2337},"sTEyZ"," \\\n",[382,2340,2341,2344,2347],{"class":384,"line":465},[382,2342,2343],{"class":392},"  --provider",[382,2345,2346],{"class":392}," google",[382,2348,2338],{"class":2337},[382,2350,2351,2354,2357],{"class":384,"line":484},[382,2352,2353],{"class":392},"  --model",[382,2355,2356],{"class":392}," gemini-2.5-flash",[382,2358,2338],{"class":2337},[382,2360,2361,2364,2367,2370,2373],{"class":384,"line":508},[382,2362,2363],{"class":392},"  --apiKey",[382,2365,2366],{"class":461}," \u003C",[382,2368,2369],{"class":392},"your-api-ke",[382,2371,2372],{"class":2337},"y",[382,2374,2375],{"class":461},">\n",[363,2377,2378,2379,2382,2383,2386,2387,2390,2391,2394,2395,2398,2399,2402,2403,2390,2406,2409,2410,2413,2414,2417,2418,2420,2421,2424,2425,2428,2429,2432],{},"Substitute your own key for ",[379,2380,2381],{},"\u003Cyour-api-key>",", or leave ",[379,2384,2385],{},"--apiKey"," off and export\n",[379,2388,2389],{},"OPENAI_API_KEY",", ",[379,2392,2393],{},"ANTHROPIC_API_KEY"," or ",[379,2396,2397],{},"GEMINI_API_KEY"," to match your\nprovider. ",[379,2400,2401],{},"--provider"," accepts ",[379,2404,2405],{},"openai",[379,2407,2408],{},"anthropic"," and ",[379,2411,2412],{},"google","; ",[379,2415,2416],{},"--model"," is\nrequired whenever ",[379,2419,2401],{}," is set. For a gateway, a proxy or a self-hosted\nmodel speaking one of those protocols, add ",[379,2422,2423],{},"--baseUrl"," — it falls back to\n",[379,2426,2427],{},"I18N_BASE_URL"," and then to ",[379,2430,2431],{},"providerBaseUrl"," in your config file.",[363,2434,2435,2436,2438,2439,2442,2443,2446,2447,2450],{},"Leave ",[379,2437,2401],{}," off entirely and nothing is translated: the run reports the\nkeys as ",[379,2440,2441],{},"skipped"," with the reason ",[379,2444,2445],{},"no-provider",". That is the mode an agent\ndrives through the ",[720,2448,2449],{"href":47},"MCP server",", where the agent's\nown model does the translating.",[363,2452,2453,2454,2390,2456,2459,2460,2462,2463,2465,2466,787],{},"Every key is accounted for in the result — ",[379,2455,893],{},[379,2457,2458],{},"failed"," with a reason\nfrom a fixed set, ",[379,2461,2441],{}," with a reason — and provider output is validated\nbefore it is written: placeholder parity per plural variant, and plural\nvariant-count parity with the source. A value that fails validation lands in\n",[379,2464,2458],{}," rather than in your locale file. Flags:\n",[720,2467,2468],{"href":247},[379,2469,246],{},[2471,2472,2473,2474,2477],"warning",{},"A partly failed run still writes what succeeded and exits 0. That is deliberate\n— the keys that failed stay missing and the next run retries them — but it means\na green run is not proof of a complete run. Add ",[379,2475,2476],{},"--failOnFailed"," to exit 2 when\nany key failed.",[363,2479,2480,794,2482,2484,2485,2487],{},[791,2481,793],{},[379,2483,242],{}," reports a higher ",[379,2486,1400],{}," than it did in step 2,\nand your protected locale is untouched.",[367,2489,2491],{"id":2490},"_4-gate-a-pipeline-on-it","4. Gate a Pipeline on It",[363,2493,2494],{},"The commands above carry their own pass\u002Ffail decision in their exit code,\nso a CI job runs one command and needs no JSON parsing to decide an outcome.",[1548,2496,160],{"id":2497},"github-actions",[372,2499,2504],{"className":2500,"code":2501,"filename":2502,"language":2503,"meta":377,"style":377},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: i18n\n\non: pull_request\n\njobs:\n  gate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: 22\n\n      - name: Fail on keys that would render raw\n        run: npx -y @the-i18n-kit\u002Fcli@latest check\n\n      - name: Fail when coverage drops below 90%\n        run: npx -y @the-i18n-kit\u002Fcli@latest status --failUnder 90\n",".github\u002Fworkflows\u002Fi18n.yml","yaml",[379,2505,2506,2516,2522,2533,2537,2545,2552,2562,2569,2582,2593,2600,2610,2614,2626,2636,2640,2651],{"__ignoreMap":377},[382,2507,2508,2511,2513],{"class":384,"line":385},[382,2509,1846],{"class":2510},"swJcz",[382,2512,478],{"class":461},[382,2514,2515],{"class":392}," i18n\n",[382,2517,2518],{"class":384,"line":465},[382,2519,2521],{"emptyLinePlaceholder":2520},true,"\n",[382,2523,2524,2528,2530],{"class":384,"line":484},[382,2525,2527],{"class":2526},"sfNiH","on",[382,2529,478],{"class":461},[382,2531,2532],{"class":392}," pull_request\n",[382,2534,2535],{"class":384,"line":508},[382,2536,2521],{"emptyLinePlaceholder":2520},[382,2538,2539,2542],{"class":384,"line":525},[382,2540,2541],{"class":2510},"jobs",[382,2543,2544],{"class":461},":\n",[382,2546,2547,2550],{"class":384,"line":540},[382,2548,2549],{"class":2510},"  gate",[382,2551,2544],{"class":461},[382,2553,2554,2557,2559],{"class":384,"line":556},[382,2555,2556],{"class":2510},"    runs-on",[382,2558,478],{"class":461},[382,2560,2561],{"class":392}," ubuntu-latest\n",[382,2563,2564,2567],{"class":384,"line":571},[382,2565,2566],{"class":2510},"    steps",[382,2568,2544],{"class":461},[382,2570,2571,2574,2577,2579],{"class":384,"line":577},[382,2572,2573],{"class":461},"      -",[382,2575,2576],{"class":2510}," uses",[382,2578,478],{"class":461},[382,2580,2581],{"class":392}," actions\u002Fcheckout@v4\n",[382,2583,2584,2586,2588,2590],{"class":384,"line":591},[382,2585,2573],{"class":461},[382,2587,2576],{"class":2510},[382,2589,478],{"class":461},[382,2591,2592],{"class":392}," actions\u002Fsetup-node@v4\n",[382,2594,2595,2598],{"class":384,"line":612},[382,2596,2597],{"class":2510},"        with",[382,2599,2544],{"class":461},[382,2601,2602,2605,2607],{"class":384,"line":632},[382,2603,2604],{"class":2510},"          node-version",[382,2606,478],{"class":461},[382,2608,2609],{"class":644}," 22\n",[382,2611,2612],{"class":384,"line":650},[382,2613,2521],{"emptyLinePlaceholder":2520},[382,2615,2616,2618,2621,2623],{"class":384,"line":665},[382,2617,2573],{"class":461},[382,2619,2620],{"class":2510}," name",[382,2622,478],{"class":461},[382,2624,2625],{"class":392}," Fail on keys that would render raw\n",[382,2627,2628,2631,2633],{"class":384,"line":670},[382,2629,2630],{"class":2510},"        run",[382,2632,478],{"class":461},[382,2634,2635],{"class":392}," npx -y @the-i18n-kit\u002Fcli@latest check\n",[382,2637,2638],{"class":384,"line":691},[382,2639,2521],{"emptyLinePlaceholder":2520},[382,2641,2642,2644,2646,2648],{"class":384,"line":706},[382,2643,2573],{"class":461},[382,2645,2620],{"class":2510},[382,2647,478],{"class":461},[382,2649,2650],{"class":392}," Fail when coverage drops below 90%\n",[382,2652,2653,2655,2657],{"class":384,"line":1395},[382,2654,2630],{"class":2510},[382,2656,478],{"class":461},[382,2658,2659],{"class":392}," npx -y @the-i18n-kit\u002Fcli@latest status --failUnder 90\n",[363,2661,2662,2663,2665],{},"Both steps fail the job with exit 2 on findings. Drop the second step if you do\nnot want a coverage floor yet — ",[379,2664,194],{}," alone is the one gate worth having on\nday one, and it costs no API key.",[363,2667,2668,2669,2671],{},"To have the pipeline fix what it finds, add the action that ships with the kit.\nIt installs the CLI and the SDK for your provider, runs ",[379,2670,246],{},", and opens a\npull request with what it wrote:",[372,2673,2676],{"className":2500,"code":2674,"filename":2675,"language":2503,"meta":377,"style":377},"name: i18n translate\n\non: pull_request\n\njobs:\n  translate:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - uses: fabkho\u002Fthe-i18n-kit@main\n        with:\n          provider: google\n          model: gemini-2.5-flash\n          api_key: ${{ secrets.GEMINI_API_KEY }}\n          layer: root\n",".github\u002Fworkflows\u002Fi18n-translate.yml",[379,2677,2678,2687,2691,2699,2703,2709,2716,2724,2731,2741,2750,2756,2766,2770,2781,2787,2797,2807,2817],{"__ignoreMap":377},[382,2679,2680,2682,2684],{"class":384,"line":385},[382,2681,1846],{"class":2510},[382,2683,478],{"class":461},[382,2685,2686],{"class":392}," i18n translate\n",[382,2688,2689],{"class":384,"line":465},[382,2690,2521],{"emptyLinePlaceholder":2520},[382,2692,2693,2695,2697],{"class":384,"line":484},[382,2694,2527],{"class":2526},[382,2696,478],{"class":461},[382,2698,2532],{"class":392},[382,2700,2701],{"class":384,"line":508},[382,2702,2521],{"emptyLinePlaceholder":2520},[382,2704,2705,2707],{"class":384,"line":525},[382,2706,2541],{"class":2510},[382,2708,2544],{"class":461},[382,2710,2711,2714],{"class":384,"line":540},[382,2712,2713],{"class":2510},"  translate",[382,2715,2544],{"class":461},[382,2717,2718,2720,2722],{"class":384,"line":556},[382,2719,2556],{"class":2510},[382,2721,478],{"class":461},[382,2723,2561],{"class":392},[382,2725,2726,2729],{"class":384,"line":571},[382,2727,2728],{"class":2510},"    permissions",[382,2730,2544],{"class":461},[382,2732,2733,2736,2738],{"class":384,"line":577},[382,2734,2735],{"class":2510},"      contents",[382,2737,478],{"class":461},[382,2739,2740],{"class":392}," write\n",[382,2742,2743,2746,2748],{"class":384,"line":591},[382,2744,2745],{"class":2510},"      pull-requests",[382,2747,478],{"class":461},[382,2749,2740],{"class":392},[382,2751,2752,2754],{"class":384,"line":612},[382,2753,2566],{"class":2510},[382,2755,2544],{"class":461},[382,2757,2758,2760,2762,2764],{"class":384,"line":632},[382,2759,2573],{"class":461},[382,2761,2576],{"class":2510},[382,2763,478],{"class":461},[382,2765,2581],{"class":392},[382,2767,2768],{"class":384,"line":650},[382,2769,2521],{"emptyLinePlaceholder":2520},[382,2771,2772,2774,2776,2778],{"class":384,"line":665},[382,2773,2573],{"class":461},[382,2775,2576],{"class":2510},[382,2777,478],{"class":461},[382,2779,2780],{"class":392}," fabkho\u002Fthe-i18n-kit@main\n",[382,2782,2783,2785],{"class":384,"line":670},[382,2784,2597],{"class":2510},[382,2786,2544],{"class":461},[382,2788,2789,2792,2794],{"class":384,"line":691},[382,2790,2791],{"class":2510},"          provider",[382,2793,478],{"class":461},[382,2795,2796],{"class":392}," google\n",[382,2798,2799,2802,2804],{"class":384,"line":706},[382,2800,2801],{"class":2510},"          model",[382,2803,478],{"class":461},[382,2805,2806],{"class":392}," gemini-2.5-flash\n",[382,2808,2809,2812,2814],{"class":384,"line":1395},[382,2810,2811],{"class":2510},"          api_key",[382,2813,478],{"class":461},[382,2815,2816],{"class":392}," ${{ secrets.GEMINI_API_KEY }}\n",[382,2818,2819,2822,2824],{"class":384,"line":1410},[382,2820,2821],{"class":2510},"          layer",[382,2823,478],{"class":461},[382,2825,2826],{"class":392}," root\n",[363,2828,2829,2831,2832,2834,2835,2837,2838,787],{},[379,2830,812],{}," is required — pass the layer name ",[379,2833,242],{}," reported under\n",[379,2836,1302],{},". Every input, with its default and whether it is required, is on\nthe ",[720,2839,2840],{"href":341},"action reference",[1548,2842,164],{"id":2843},"gitlab-ci",[363,2845,2846],{},"The kit ships a template with three reusable jobs. Include it and extend the one\nyou want:",[372,2848,2851],{"className":2500,"code":2849,"filename":2850,"language":2503,"meta":377,"style":377},"include:\n  - remote: 'https:\u002F\u002Fraw.githubusercontent.com\u002Ffabkho\u002Fthe-i18n-kit\u002Fmain\u002Fgitlab-ci.yml'\n\ni18n-check:\n  extends: .i18n-check\n  allow_failure: false\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n",".gitlab-ci.yml",[379,2852,2853,2860,2879,2883,2890,2900,2909,2916,2929],{"__ignoreMap":377},[382,2854,2855,2858],{"class":384,"line":385},[382,2856,2857],{"class":2510},"include",[382,2859,2544],{"class":461},[382,2861,2862,2865,2868,2870,2873,2876],{"class":384,"line":465},[382,2863,2864],{"class":461},"  -",[382,2866,2867],{"class":2510}," remote",[382,2869,478],{"class":461},[382,2871,2872],{"class":461}," '",[382,2874,2875],{"class":392},"https:\u002F\u002Fraw.githubusercontent.com\u002Ffabkho\u002Fthe-i18n-kit\u002Fmain\u002Fgitlab-ci.yml",[382,2877,2878],{"class":461},"'\n",[382,2880,2881],{"class":384,"line":484},[382,2882,2521],{"emptyLinePlaceholder":2520},[382,2884,2885,2888],{"class":384,"line":508},[382,2886,2887],{"class":2510},"i18n-check",[382,2889,2544],{"class":461},[382,2891,2892,2895,2897],{"class":384,"line":525},[382,2893,2894],{"class":2510},"  extends",[382,2896,478],{"class":461},[382,2898,2899],{"class":392}," .i18n-check\n",[382,2901,2902,2905,2907],{"class":384,"line":540},[382,2903,2904],{"class":2510},"  allow_failure",[382,2906,478],{"class":461},[382,2908,703],{"class":2526},[382,2910,2911,2914],{"class":384,"line":556},[382,2912,2913],{"class":2510},"  rules",[382,2915,2544],{"class":461},[382,2917,2918,2921,2924,2926],{"class":384,"line":571},[382,2919,2920],{"class":461},"    -",[382,2922,2923],{"class":2510}," if",[382,2925,478],{"class":461},[382,2927,2928],{"class":392}," $CI_PIPELINE_SOURCE == \"merge_request_event\"\n",[382,2930,2931,2933,2935,2937],{"class":384,"line":577},[382,2932,2920],{"class":461},[382,2934,2923],{"class":2510},[382,2936,478],{"class":461},[382,2938,2939],{"class":392}," $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n",[363,2941,2942,2945,2946,2949],{},[379,2943,2944],{},".i18n-check"," allows exit code 2 by default, which keeps findings informational\n— yellow, not red — while a scan that genuinely fell over still fails the job.\nSetting ",[379,2947,2948],{},"allow_failure: false",", as above, turns findings into a hard gate.",[363,2951,2952],{},"The job writes a GitLab Code Quality report, which puts each finding on the\nmerge request diff. The widget shows the difference between the merge request's\nreport and the newest one from the default branch, so the second rule above is\nrequired: with no default-branch baseline to compare against, the widget stays\nblank.",[363,2954,2955,2957],{},[791,2956,793],{}," open a merge request that calls a key you have not defined. The job\nfails, and the finding appears on the diff at the line that calls it.",[367,2959,2961],{"id":2960},"where-to-go-next","Where to Go Next",[1434,2963,2964,2969,2974,2980],{},[1437,2965,2966,2968],{},[720,2967,108],{"href":114}," — the two files kit policy\ncan be declared in, and how each is found. A glossary and tone notes are what\nmake provider translations sound like your product.",[1437,2970,2971,2973],{},[720,2972,54],{"href":60}," — what changes when locales live in several\nlayers and several apps consume them, and why usage is counted per consuming\napp.",[1437,2975,2976,2979],{},[720,2977,2978],{"href":47},"Set up the MCP server"," — the same operations,\ndriven by your agent instead of your terminal.",[1437,2981,2982,2984],{},[720,2983,1961],{"href":185}," — every command, generated from its own\ndefinition.",[367,2986,2988],{"id":2987},"limits","Limits",[1434,2990,2991,2998,3004],{},[1437,2992,2993,2409,2995,2997],{},[379,2994,194],{},[379,2996,222],{}," read your source statically and line by line.\nKeys built at runtime cannot be verified, so they are reported as uncertain and\nnever treated as findings. That is a floor on what these commands can prove,\nnot a bug to be configured away.",[1437,2999,3000,3001,3003],{},"Coverage is measured against a reference locale. If that locale is itself\nmissing a key, nothing here reports the key as missing anywhere — ",[379,3002,194],{}," is\nwhat catches it, from the calling side.",[1437,3005,3006,3007,3009,3010,3012],{},"The ",[379,3008,246],{}," gate is opt-in for a reason worth knowing before you turn it\non: ",[379,3011,2476],{}," fails a job that already committed the keys that\nsucceeded.",[3014,3015,3016],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":377,"searchDepth":484,"depth":484,"links":3018},[3019,3020,3021,3024,3025,3029,3030],{"id":369,"depth":465,"text":370},{"id":423,"depth":465,"text":424},{"id":803,"depth":465,"text":804,"children":3022},[3023],{"id":1550,"depth":484,"text":1551},{"id":1976,"depth":465,"text":1977},{"id":2490,"depth":465,"text":2491,"children":3026},[3027,3028],{"id":2497,"depth":484,"text":160},{"id":2843,"depth":484,"text":164},{"id":2960,"depth":465,"text":2961},{"id":2987,"depth":465,"text":2988},"md",null,{},{"description":3035,"title":50},"One sequence — init, a health check, a translate run against your provider, and a pipeline that blocks a merge on findings.","E_orygzX0e0L9LszXE-ZYPq5hHVkMQWImCYLTdmCY68",[3038,3039],{"title":46,"path":47,"stem":48,"description":377,"children":-1},{"title":59,"path":60,"stem":61,"description":377,"children":-1},1787604647515]