@the-i18n-kit/cli 5.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -58
  3. package/dist/bin.js +1 -6
  4. package/dist/bin.js.map +1 -1
  5. package/dist/{_shared-DFyy3sh8.js → cli-waEjbUM1.js} +157 -27
  6. package/dist/cli-waEjbUM1.js.map +1 -0
  7. package/dist/config/framework/stubs/{next-intl-routing-Cwaa3f4R.d.ts → next-intl-routing-i6Mlxwdt.d.ts} +1 -1
  8. package/dist/config/framework/stubs/{next-intl-routing-Cwaa3f4R.d.ts.map → next-intl-routing-i6Mlxwdt.d.ts.map} +1 -1
  9. package/dist/{define-config-BaZ1dZph.d.ts → define-config-ChY3jk6K.d.ts} +26 -4
  10. package/dist/define-config-ChY3jk6K.d.ts.map +1 -0
  11. package/dist/{define-config-CLgKN-7N.d.ts → define-config-e0B0VHq7.d.ts} +1 -1
  12. package/dist/define-config.d.ts +1 -1
  13. package/dist/descriptors-10sgyqEs.js +1225 -0
  14. package/dist/descriptors-10sgyqEs.js.map +1 -0
  15. package/dist/detector-BJTkyhQ0.js +5 -0
  16. package/dist/detector-DtFY4qm3.js +2189 -0
  17. package/dist/detector-DtFY4qm3.js.map +1 -0
  18. package/dist/{index-DCG3dOdC.d.ts → index-CdjJ71Ag.d.ts} +665 -250
  19. package/dist/index-CdjJ71Ag.d.ts.map +1 -0
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +8 -5
  22. package/dist/json-writer-D0b6vEax.js +2 -0
  23. package/dist/json-writer-ek8yEI5R.js +342 -0
  24. package/dist/json-writer-ek8yEI5R.js.map +1 -0
  25. package/dist/{operations-CTo44gPu.js → operations-CNqEBD__.js} +1505 -3285
  26. package/dist/operations-CNqEBD__.js.map +1 -0
  27. package/dist/operations-D7IMu_xY.js +8 -0
  28. package/dist/php-reader-BGx6Ii2d.js +2 -0
  29. package/dist/{php-reader-3Fgw80zK.js → php-reader-DRpcRVzv.js} +6 -3
  30. package/dist/{php-reader-3Fgw80zK.js.map → php-reader-DRpcRVzv.js.map} +1 -1
  31. package/dist/{providers-CHE2ffi6.js → project-config-C3ao4Uii.js} +24 -214
  32. package/dist/project-config-C3ao4Uii.js.map +1 -0
  33. package/dist/providers-BbVPelvp.js +406 -0
  34. package/dist/providers-BbVPelvp.js.map +1 -0
  35. package/dist/report-By1-5JtO.js +37 -0
  36. package/dist/report-By1-5JtO.js.map +1 -0
  37. package/dist/report-CHZgH9Wy.js +2 -0
  38. package/package.json +11 -23
  39. package/dist/_shared-DFyy3sh8.js.map +0 -1
  40. package/dist/add-C-qs8iBa.js +0 -40
  41. package/dist/add-C-qs8iBa.js.map +0 -1
  42. package/dist/check-BI1orjXb.js +0 -41
  43. package/dist/check-BI1orjXb.js.map +0 -1
  44. package/dist/cli-DsFuVJNP.js +0 -74
  45. package/dist/cli-DsFuVJNP.js.map +0 -1
  46. package/dist/config/framework/stubs/unplugin-vue-i18n-1ud7-Ly8.d.ts +0 -25
  47. package/dist/config/framework/stubs/unplugin-vue-i18n-1ud7-Ly8.d.ts.map +0 -1
  48. package/dist/config/framework/stubs/unplugin-vue-i18n.js +0 -26
  49. package/dist/config/framework/stubs/unplugin-vue-i18n.js.map +0 -1
  50. package/dist/define-config-BaZ1dZph.d.ts.map +0 -1
  51. package/dist/detect-7cVfsNJP.js +0 -17
  52. package/dist/detect-7cVfsNJP.js.map +0 -1
  53. package/dist/empty-DB8Hl_8u.js +0 -36
  54. package/dist/empty-DB8Hl_8u.js.map +0 -1
  55. package/dist/find-duplicates-CmEqBfby.js +0 -42
  56. package/dist/find-duplicates-CmEqBfby.js.map +0 -1
  57. package/dist/get-BE21Iy6N.js +0 -41
  58. package/dist/get-BE21Iy6N.js.map +0 -1
  59. package/dist/index-DCG3dOdC.d.ts.map +0 -1
  60. package/dist/init-BtzmhsOM.js +0 -33
  61. package/dist/init-BtzmhsOM.js.map +0 -1
  62. package/dist/list-dirs-DUQbwvlE.js +0 -17
  63. package/dist/list-dirs-DUQbwvlE.js.map +0 -1
  64. package/dist/missing-CcYrgd54.js +0 -51
  65. package/dist/missing-CcYrgd54.js.map +0 -1
  66. package/dist/move-B2px6Ck-.js +0 -50
  67. package/dist/move-B2px6Ck-.js.map +0 -1
  68. package/dist/operations-CTo44gPu.js.map +0 -1
  69. package/dist/php-reader-CpnaPSpZ.js +0 -2
  70. package/dist/providers-CHE2ffi6.js.map +0 -1
  71. package/dist/remove-DTbqM4bR.js +0 -41
  72. package/dist/remove-DTbqM4bR.js.map +0 -1
  73. package/dist/remove-orphans-Dfzu7hRz.js +0 -57
  74. package/dist/remove-orphans-Dfzu7hRz.js.map +0 -1
  75. package/dist/rename-C_rFKkU4.js +0 -45
  76. package/dist/rename-C_rFKkU4.js.map +0 -1
  77. package/dist/rename-notice-BV8HNX3O.js +0 -25
  78. package/dist/rename-notice-BV8HNX3O.js.map +0 -1
  79. package/dist/rename-notice-Cx1vuTRz.js +0 -2
  80. package/dist/scaffold-CUimlNqR.js +0 -39
  81. package/dist/scaffold-CUimlNqR.js.map +0 -1
  82. package/dist/scan-BkOIYhjZ.js +0 -31
  83. package/dist/scan-BkOIYhjZ.js.map +0 -1
  84. package/dist/search-0io1BcsY.js +0 -49
  85. package/dist/search-0io1BcsY.js.map +0 -1
  86. package/dist/status-Bp-SzjTN.js +0 -45
  87. package/dist/status-Bp-SzjTN.js.map +0 -1
  88. package/dist/translate-cCb2Z57w.js +0 -92
  89. package/dist/translate-cCb2Z57w.js.map +0 -1
  90. package/dist/translate-key-DHLWEmrA.js +0 -73
  91. package/dist/translate-key-DHLWEmrA.js.map +0 -1
  92. package/dist/update-DV4ijRVB.js +0 -40
  93. package/dist/update-DV4ijRVB.js.map +0 -1
  94. package/dist/write-Czzm_Nb0.js +0 -47
  95. package/dist/write-Czzm_Nb0.js.map +0 -1
  96. /package/dist/{bin-DrKRgnr9.d.ts → bin-NyzIHE2F.d.ts} +0 -0
@@ -1,7 +1,127 @@
1
- import { a as LocaleDir, i as LocaleDefinition, n as defineI18nKitConfig, o as ProjectConfig, r as I18nConfig, s as LocaleFileFormat, t as I18nKitConfig } from "./define-config-BaZ1dZph.js";
1
+ import { a as LocaleDir, i as LocaleDefinition, n as defineI18nKitConfig, o as ProjectConfig, r as I18nConfig, s as LocaleFileFormat, t as I18nKitConfig } from "./define-config-ChY3jk6K.js";
2
2
 
3
- //#region src/core/types.d.ts
3
+ //#region src/config/layer-graph.d.ts
4
4
 
5
+ /**
6
+ * Queryable view over the layer topology a resolved {@link I18nConfig}
7
+ * already carries: which locale dirs are canonical (alias-free), which
8
+ * layer owns an aliased dir, and which apps consume which layers.
9
+ *
10
+ * This is a pure derivation — no filesystem access, no config-shape
11
+ * changes. Cross-layer tooling (duplicate detection, scope-aware orphan
12
+ * scanning) builds on these queries instead of name-matching heuristics.
13
+ *
14
+ * ## Degenerate-case semantics
15
+ *
16
+ * These are load-bearing for consumers (scope-aware scanning must never
17
+ * wrongly narrow its scan scope):
18
+ *
19
+ * - **No app info** (`config.apps` empty or absent, e.g. hand-built
20
+ * configs): consumption edges are unknowable. `appsUsingLayer` and
21
+ * `layersOfApp` return `[]`, and `sharedLayers` conservatively contains
22
+ * *every* canonical layer — with no ownership information, every
23
+ * layer's keys must be treated as globally visible.
24
+ * - **Single-app config** (generic/Laravel/React adapters, or a Nuxt
25
+ * project with one app): the strict definition applies, so
26
+ * `sharedLayers` is empty (no layer is consumed by more than one app)
27
+ * and `appsUsingLayer` returns that one app for the layers it consumes.
28
+ * Per-layer scope then equals the whole project, which is correct.
29
+ * - **Canonical layer consumed by no app** (in a multi-app config):
30
+ * `appsUsingLayer` returns `[]` and the layer is not in `sharedLayers`.
31
+ * Callers should treat such layers conservatively (global scope).
32
+ */
33
+ interface LayerGraph {
34
+ /**
35
+ * Alias-free locale dirs, in `config.localeDirs` order. Aliased entries
36
+ * (e.g. `app-outlook` pointing at `app-shop`'s dir) are excluded.
37
+ */
38
+ canonicalLayers: LocaleDir[];
39
+ /**
40
+ * Resolve a layer name to the canonical layer that owns its locale dir.
41
+ * Follows chained `aliasOf` links (an alias may point at a layer that
42
+ * was itself demoted to an alias). Identity for canonical names and for
43
+ * names unknown to `localeDirs` (e.g. layers without locale dirs).
44
+ */
45
+ ownerOf: (layer: string) => string;
46
+ /**
47
+ * Names of apps whose consumed layers include the given layer. The
48
+ * queried name and each app's layer list are alias-resolved via
49
+ * {@link ownerOf} first, so querying an alias name yields the owner's
50
+ * consumers. Returns `[]` when no app info exists.
51
+ */
52
+ appsUsingLayer: (layer: string) => string[];
53
+ /**
54
+ * Canonical layers consumed by more than one app — e.g. a shared root
55
+ * layer in a multi-app monorepo, identified purely from consumption
56
+ * edges (no name matching). When no app info exists, contains every
57
+ * canonical layer (see degenerate-case semantics above).
58
+ */
59
+ sharedLayers: LocaleDir[];
60
+ /**
61
+ * Canonical layers the given app consumes (alias entries in the app's
62
+ * layer list resolve to their owners; layers without locale dirs are
63
+ * omitted). Returns `[]` for unknown apps or when no app info exists.
64
+ */
65
+ layersOfApp: (app: string) => LocaleDir[];
66
+ }
67
+ /**
68
+ * Build a {@link LayerGraph} from a resolved config's `localeDirs`
69
+ * (with their `aliasOf` markers) and `apps` (app → consumed-layers edges).
70
+ */
71
+ declare function buildLayerGraph(config: I18nConfig): LayerGraph;
72
+ /**
73
+ * The graph as plain data, for surfaces that can only carry JSON.
74
+ *
75
+ * {@link LayerGraph} is function-valued, so it cannot be serialised directly.
76
+ * This answers the question an agent actually has — *which layer does this key
77
+ * belong in* — which the flat layer list `discover` returned could not: a key
78
+ * used by more than one app belongs in a layer those apps share, and `shared`
79
+ * names those layers outright (#342).
80
+ *
81
+ * The degenerate cases documented on {@link LayerGraph} survive the flattening,
82
+ * because they are what keeps a consumer from wrongly narrowing scope:
83
+ * a config with no app info reports *every* canonical layer as shared, and a
84
+ * layer no app consumes appears in `consumers` with an empty array rather than
85
+ * being left out. Absent and "none" must not look alike here.
86
+ */
87
+ interface SerializedLayerGraph {
88
+ /** Alias-free layer names, in `config.localeDirs` order. */
89
+ canonical: string[];
90
+ /** Canonical layers consumed by more than one app — where shared keys belong. */
91
+ shared: string[];
92
+ /** Alias layer name → the canonical layer whose locale dir it points at. */
93
+ aliases: Record<string, string>;
94
+ /** Canonical layer name → the apps consuming it. Every canonical layer is a key. */
95
+ consumers: Record<string, string[]>;
96
+ }
97
+ /** Flatten {@link buildLayerGraph}'s view of `config` into plain JSON. */
98
+ declare function serializeLayerGraph(config: I18nConfig): SerializedLayerGraph;
99
+ //# sourceMappingURL=layer-graph.d.ts.map
100
+ //#endregion
101
+ //#region src/core/types.d.ts
102
+ /**
103
+ * The whole resolved project in one answer: the config, the locale dirs behind
104
+ * it, the topology those dirs form, and which locales are maintained by hand.
105
+ *
106
+ * A superset of `I18nConfig` rather than a wrapper around it, because every
107
+ * caller of the old three-call sequence merged the parts anyway and a nested
108
+ * `config` key would break each of them for nothing.
109
+ */
110
+ interface DescribeProjectResult extends I18nConfig {
111
+ /**
112
+ * Canonical codes of the locales the translate operations leave alone. The
113
+ * raw refs stay visible under `projectConfig.protectedLocales`.
114
+ */
115
+ protectedLocales: string[];
116
+ /** One entry per locale directory, with file counts and key namespaces. */
117
+ layers: LocaleDirInfo[];
118
+ /**
119
+ * Which layers are shared, which apps consume which layer, and what each
120
+ * alias points at — the topology behind the flat `layers` list, and what
121
+ * answers where a new key belongs.
122
+ */
123
+ layerGraph: SerializedLayerGraph;
124
+ }
5
125
  interface LocaleDirInfo {
6
126
  layer: string;
7
127
  path: string;
@@ -62,27 +182,6 @@ interface MutationResult {
62
182
  /** Present only when a ref matched several locales and precedence picked one. */
63
183
  ambiguousLocales?: LocaleRefAmbiguity[];
64
184
  }
65
- interface AddTranslationsResult {
66
- /** Present when dryRun=true */
67
- dryRun?: boolean;
68
- wouldAdd?: MutationPreview[];
69
- /** Present when dryRun=false */
70
- added?: string[];
71
- skipped: string[];
72
- filesWritten?: number;
73
- warnings?: string[];
74
- /** Present only when a locale ref resolved to nothing — see UnresolvedLocaleRef. */
75
- unresolvedLocales?: UnresolvedLocaleRef[];
76
- /** Present only when a locale ref matched several locales. */
77
- ambiguousLocales?: LocaleRefAmbiguity[];
78
- placeholderValidation?: PlaceholderValidationResult;
79
- summary?: {
80
- keysToAdd: number;
81
- keysSkipped: number;
82
- message: string;
83
- };
84
- skippedKeys?: string[];
85
- }
86
185
  interface WriteTranslationsResult {
87
186
  /** Present when dryRun=true */
88
187
  dryRun?: boolean;
@@ -104,26 +203,6 @@ interface WriteTranslationsResult {
104
203
  };
105
204
  skippedKeys?: string[];
106
205
  }
107
- interface UpdateTranslationsResult {
108
- /** Present when dryRun=true */
109
- dryRun?: boolean;
110
- wouldUpdate?: MutationPreview[];
111
- /** Present when dryRun=false */
112
- updated?: string[];
113
- skipped: string[];
114
- filesWritten?: number;
115
- /** Present only when a locale ref resolved to nothing — see UnresolvedLocaleRef. */
116
- unresolvedLocales?: UnresolvedLocaleRef[];
117
- /** Present only when a locale ref matched several locales. */
118
- ambiguousLocales?: LocaleRefAmbiguity[];
119
- placeholderValidation?: PlaceholderValidationResult;
120
- summary?: {
121
- keysToUpdate: number;
122
- keysSkipped: number;
123
- message: string;
124
- };
125
- skippedKeys?: string[];
126
- }
127
206
  /**
128
207
  * The config `init` emits. Only fields the matched adapter cannot derive:
129
208
  * writing a copy of what the framework already states creates a second source
@@ -173,16 +252,13 @@ interface InitProjectConfigResult {
173
252
  overwritten: boolean;
174
253
  }
175
254
  interface MissingTranslationsResult {
176
- /** Absent when the full report went to `reportFile` instead. */
177
- missing?: Record<string, Record<string, string[]>>;
255
+ missing: Record<string, Record<string, string[]>>;
178
256
  summary: {
179
257
  referenceLocale: string | LocaleRefInfo;
180
258
  targetLocales: Array<string | LocaleRefInfo>;
181
259
  layersScanned: string[];
182
260
  totalMissingKeys: number;
183
261
  };
184
- /** Present when reportOutput is configured */
185
- reportFile?: string;
186
262
  }
187
263
  interface LocaleStatus extends LocaleRefInfo {
188
264
  total: number;
@@ -203,10 +279,21 @@ interface LayerStatus {
203
279
  missing: number;
204
280
  empty: number;
205
281
  completion: number;
282
+ /**
283
+ * Apps whose declared layers include this one. Empty means either no app
284
+ * information exists (hand-built configs) or nothing consumes the layer.
285
+ */
286
+ consumedBy: string[];
206
287
  }
207
288
  interface TranslationStatusSummary {
208
289
  referenceLocale: LocaleRefInfo;
209
290
  layersScanned: string[];
291
+ /**
292
+ * Scanned layers no app consumes — keys nothing can render. Stays empty
293
+ * unless the project declares more than one app, since a single-app project
294
+ * has no consumption edges worth reporting on.
295
+ */
296
+ unconsumedLayers: string[];
210
297
  localesChecked: number;
211
298
  protectedLocales: string[];
212
299
  totalKeys: number;
@@ -217,22 +304,31 @@ interface TranslationStatusSummary {
217
304
  completionPercent: number;
218
305
  }
219
306
  interface TranslationStatusResult {
220
- locales?: LocaleStatus[];
221
- layers?: LayerStatus[];
307
+ locales: LocaleStatus[];
308
+ layers: LayerStatus[];
309
+ /**
310
+ * Locale → layer → the keys `summary.emptyKeys` counts: empty in that target
311
+ * locale while the reference locale has a value. Present only when the caller
312
+ * asked to list them. Added to the result rather than replacing it, so asking
313
+ * which keys are empty still answers the coverage question that prompted it.
314
+ */
315
+ empty?: Record<string, Record<string, string[]>>;
316
+ /**
317
+ * Layer → keys whose value is empty in the reference locale itself. Nothing
318
+ * to translate from, so excluded from every count; listed so a deliberate
319
+ * blank and a forgotten one can be told apart. Present only with `empty`,
320
+ * and only when there are any.
321
+ */
322
+ emptyInReference?: Record<string, string[]>;
222
323
  summary: TranslationStatusSummary;
223
- /** Present when the full breakdown went to a file instead. */
224
- reportFile?: string;
225
324
  }
226
325
  interface EmptyTranslationsResult {
227
- /** Absent when the full report went to `reportFile` instead. */
228
- emptyKeys?: Record<string, Record<string, string[]>>;
326
+ emptyKeys: Record<string, Record<string, string[]>>;
229
327
  summary: {
230
328
  totalEmpty: number;
231
329
  localesChecked: string[];
232
330
  layersChecked: string[];
233
331
  };
234
- /** Present when reportOutput is configured */
235
- reportFile?: string;
236
332
  }
237
333
  interface SearchMatch {
238
334
  layer: string;
@@ -297,6 +393,12 @@ interface MoveTranslationKeyPlanEntry {
297
393
  */
298
394
  action: 'move' | 'deduplicate';
299
395
  }
396
+ /**
397
+ * What a move returns: a rename result when the key stayed in its layer, a move
398
+ * result when it changed layers. A union rather than one merged shape, so
399
+ * neither half carries fields that can never be set for the other.
400
+ */
401
+ type MoveTranslationKeyOutcome = MoveTranslationKeyResult | RenameTranslationKeyResult;
300
402
  interface MoveTranslationKeyResult {
301
403
  /** Present when dryRun=true */
302
404
  dryRun?: boolean;
@@ -326,6 +428,29 @@ type TranslateMode = 'provider' | 'agent' | 'dry-run';
326
428
  type TranslateFailReason = 'provider-error' | 'omitted-by-model' | 'placeholder-mismatch' | 'plural-mismatch' | 'write-error' | 'truncated';
327
429
  /** Why a key or locale was intentionally not attempted. */
328
430
  type TranslateSkipReason = 'no-provider' | 'already-translated' | 'protected-locale';
431
+ /** What translate_missing accepts. `layer` omitted means every layer at once. */
432
+ interface TranslateMissingOptions {
433
+ layer?: string;
434
+ referenceLocale?: string;
435
+ targetLocales?: string[];
436
+ locales?: string[];
437
+ keys?: string[];
438
+ batchSize?: number;
439
+ dryRun?: boolean;
440
+ compact?: boolean;
441
+ projectDir?: string;
442
+ /**
443
+ * Also re-translate keys whose target was written from source text that has
444
+ * changed since (translation memory only). Off by default: without it the
445
+ * operation still never touches an existing value, it only reports the stale
446
+ * ones in `stale`.
447
+ */
448
+ overwriteStale?: boolean;
449
+ translateFn?: TranslateFn;
450
+ progressFn?: ProgressFn;
451
+ /** Called once after the pre-scan with the computed total number of progress steps. */
452
+ onProgressTotal?: (total: number) => void;
453
+ }
329
454
  interface TranslateMissingLocaleResult {
330
455
  mode: TranslateMode;
331
456
  /** Number of missing keys found for this locale. Always equals
@@ -342,6 +467,14 @@ interface TranslateMissingLocaleResult {
342
467
  key: string;
343
468
  reason: TranslateSkipReason;
344
469
  }>;
470
+ /**
471
+ * Translation-memory only: keys whose target value was written from source
472
+ * text that has changed since, and which this run left untouched. A bucket of
473
+ * its own, not part of `missing` — these keys are translated, just outdated —
474
+ * so the invariant above still holds. Re-translating them needs
475
+ * `overwriteStale`, which counts them into `missing` instead.
476
+ */
477
+ stale?: string[];
345
478
  batches?: number;
346
479
  model?: string;
347
480
  writeError?: string;
@@ -356,6 +489,7 @@ interface TranslateMissingCompactEntry {
356
489
  failed: number;
357
490
  skipped: number;
358
491
  wouldTranslate?: number;
492
+ stale?: number;
359
493
  batches?: number;
360
494
  model?: string;
361
495
  writeError?: string;
@@ -372,6 +506,8 @@ interface TranslateMissingResult {
372
506
  totalFailed: number;
373
507
  totalSkipped: number;
374
508
  totalWouldTranslate?: number;
509
+ /** Translation-memory only: stale keys left untouched, across all locales. */
510
+ staleCount?: number;
375
511
  layer: string;
376
512
  referenceLocale: string | LocaleRefInfo;
377
513
  targetLocales: Array<string | LocaleRefInfo>;
@@ -393,6 +529,8 @@ interface TranslateAllLayersSummary {
393
529
  totalFailed: number;
394
530
  totalSkipped: number;
395
531
  totalWouldTranslate?: number;
532
+ /** Translation-memory only: stale keys left untouched, across all layers and locales. */
533
+ staleCount?: number;
396
534
  /** Layer names that were translated. */
397
535
  layers: string[];
398
536
  byLayer: TranslateLayerTotals[];
@@ -425,6 +563,18 @@ interface TranslateKeyLocaleIssue {
425
563
  reason: TranslateFailReason | 'read-error';
426
564
  detail?: string;
427
565
  }
566
+ /**
567
+ * One locale translate_key deliberately left alone. `reason` is a closed set;
568
+ * `stale` refines 'already-translated' rather than extending it, so a caller
569
+ * can tell an existing translation that still matches its source from one the
570
+ * source has since outgrown.
571
+ */
572
+ interface TranslateKeySkip {
573
+ locale: string;
574
+ reason: TranslateSkipReason;
575
+ /** Translation-memory only: whether the existing value is out of date. */
576
+ stale?: boolean;
577
+ }
428
578
  interface TranslateKeyResult {
429
579
  key: string;
430
580
  sourceLocale: LocaleRefInfo;
@@ -433,10 +583,7 @@ interface TranslateKeyResult {
433
583
  translated: string[];
434
584
  /** Dry-run only: locales that would be translated. */
435
585
  wouldTranslate?: string[];
436
- skipped: Array<{
437
- locale: string;
438
- reason: TranslateSkipReason;
439
- }>;
586
+ skipped: TranslateKeySkip[];
440
587
  failed: TranslateKeyLocaleIssue[];
441
588
  filesWritten: number;
442
589
  dryRun: boolean;
@@ -469,8 +616,7 @@ interface UnresolvedKeyWarningRef {
469
616
  suggestedIgnorePattern?: string;
470
617
  }
471
618
  interface FindOrphanKeysResult {
472
- /** Absent when the full report went to `reportFile` instead. */
473
- orphanKeys?: Record<string, string[]>;
619
+ orphanKeys: Record<string, string[]>;
474
620
  uncertainKeys?: Record<string, string[]>;
475
621
  /**
476
622
  * Keys kept alive solely by the bare-candidate net — nothing a frontend
@@ -504,13 +650,10 @@ interface FindOrphanKeysResult {
504
650
  dynamicKeyWarning?: string;
505
651
  dynamicKeys?: DynamicKeyRef[];
506
652
  unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
507
- /** Present when reportOutput is configured */
508
- reportFile?: string;
509
653
  }
510
654
  /** Where each requested key is referenced in source. */
511
655
  interface CodeUsageResult {
512
- /** Absent when the full report went to `reportFile` instead. */
513
- usages?: Record<string, CodeUsageRef[]>;
656
+ usages: Record<string, CodeUsageRef[]>;
514
657
  /** Requested keys with no reference anywhere in the scanned source. */
515
658
  notFoundInCode?: string[];
516
659
  /** Dynamic expressions that could reach the requested keys. */
@@ -524,8 +667,6 @@ interface CodeUsageResult {
524
667
  dirsScanned?: string[];
525
668
  message?: string;
526
669
  };
527
- /** Present when the full report went to a file instead. */
528
- reportFile?: string;
529
670
  }
530
671
  interface CodeUsageRef {
531
672
  file: string;
@@ -544,8 +685,6 @@ interface ScanCodeUsageResult {
544
685
  };
545
686
  notFoundInCode?: string[];
546
687
  dynamicKeys?: DynamicKeyRef[];
547
- /** Present when reportOutput is configured */
548
- reportFile?: string;
549
688
  }
550
689
  interface RemoveOrphanKeysResult {
551
690
  orphanKeys?: Record<string, string[]>;
@@ -575,8 +714,6 @@ interface RemoveOrphanKeysResult {
575
714
  dynamicKeyWarning?: string;
576
715
  dynamicKeys?: DynamicKeyRef[];
577
716
  unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
578
- /** Present when reportOutput is configured */
579
- reportFile?: string;
580
717
  }
581
718
  interface ScaffoldLocaleFileInfo {
582
719
  locale: string;
@@ -625,7 +762,7 @@ declare function findLocaleImpl(config: I18nConfig, localeRef: string): LocaleDe
625
762
  * project default. Throws LOCALE_NOT_FOUND listing the available codes.
626
763
  */
627
764
  //#endregion
628
- //#region src/core/ops-translate.d.ts
765
+ //#region src/core/translate/targets.d.ts
629
766
  /**
630
767
  * Resolve the config's `protectedLocales` entries (any locale ref: code,
631
768
  * language tag, or file name) against the known locales. Entries that do not
@@ -633,6 +770,15 @@ declare function findLocaleImpl(config: I18nConfig, localeRef: string): LocaleDe
633
770
  * definitions, deduplicated by canonical code.
634
771
  */
635
772
  declare function resolveProtectedLocales(config: I18nConfig): LocaleDefinition[];
773
+ /**
774
+ * Resolve translate_missing target locales. Protected locales are excluded
775
+ * from the DEFAULT target set (returned separately so the caller can report
776
+ * them as skipped); naming one explicitly in targetLocales overrides the
777
+ * protection with a warning.
778
+ */
779
+
780
+ //#endregion
781
+ //#region src/core/translate/run.d.ts
636
782
  /**
637
783
  * Find keys missing in target locales and translate them.
638
784
  *
@@ -642,21 +788,7 @@ declare function resolveProtectedLocales(config: I18nConfig): LocaleDefinition[]
642
788
  * When `layer` is omitted, every canonical locale-backed layer is translated
643
789
  * in one run and the results are aggregated (see translateMissingAllLayers).
644
790
  */
645
- declare function translateMissing(opts: {
646
- layer?: string;
647
- referenceLocale?: string;
648
- targetLocales?: string[];
649
- locales?: string[];
650
- keys?: string[];
651
- batchSize?: number;
652
- dryRun?: boolean;
653
- compact?: boolean;
654
- projectDir?: string;
655
- translateFn?: TranslateFn;
656
- progressFn?: ProgressFn;
657
- /** Called once after the pre-scan with the computed total number of progress steps. */
658
- onProgressTotal?: (total: number) => void;
659
- }): Promise<TranslateMissingOutcome>;
791
+ declare function translateMissing(opts: TranslateMissingOptions): Promise<TranslateMissingOutcome>;
660
792
  /**
661
793
  * Translate one key from a source locale into target locales. Unlike
662
794
  * translate_missing, this can overwrite stale existing target values.
@@ -673,9 +805,23 @@ declare function translateKey(opts: {
673
805
  projectDir?: string;
674
806
  translateFn?: TranslateFn;
675
807
  }): Promise<TranslateKeyResult>;
676
- //# sourceMappingURL=ops-translate.d.ts.map
808
+ //# sourceMappingURL=run.d.ts.map
677
809
  //#endregion
678
810
  //#region src/core/ops-read.d.ts
811
+ /**
812
+ * Everything a caller needs to know about a project before touching it:
813
+ * resolved config, locale directories, the layer topology, and which locales
814
+ * are hand-maintained.
815
+ *
816
+ * This composition used to live in the MCP `discover` handler, so the terminal
817
+ * had no way to ask the question its own docs told people to ask — and the two
818
+ * surfaces would have had to be kept in step by hand once one of them grew a
819
+ * field. Callers add whatever is theirs alone (the MCP server adds the
820
+ * translation backend it resolved at startup); the project half is here.
821
+ */
822
+ declare function describeProject(opts?: {
823
+ projectDir?: string;
824
+ }): Promise<DescribeProjectResult>;
679
825
  /**
680
826
  * Detect the i18n configuration from the project, always bypassing the
681
827
  * config cache (clears it first).
@@ -704,7 +850,6 @@ declare function getMissingTranslations(opts: {
704
850
  targetLocales?: string[];
705
851
  locales?: string[];
706
852
  projectDir?: string;
707
- outputFile?: string;
708
853
  }): Promise<MissingTranslationsResult>;
709
854
  /**
710
855
  * Find translation keys that have empty string values in locale files.
@@ -713,8 +858,15 @@ declare function findEmptyTranslations(opts: {
713
858
  layer?: string;
714
859
  locale?: string;
715
860
  projectDir?: string;
716
- outputFile?: string;
717
861
  }): Promise<EmptyTranslationsResult>;
862
+ /**
863
+ * The scan behind {@link findEmptyTranslations}, against a config the caller
864
+ * already has.
865
+ *
866
+ * Separate so `getTranslationStatus` can embed the listing under its own
867
+ * `--list-empty` flag without detecting the project a second time.
868
+ */
869
+
718
870
  /**
719
871
  * Search translation files by key pattern or value substring.
720
872
  */
@@ -724,16 +876,7 @@ declare function searchTranslations(opts: {
724
876
  layer?: string;
725
877
  locale?: string;
726
878
  projectDir?: string;
727
- outputFile?: string;
728
- }): Promise<{
729
- matches: SearchMatch[];
730
- totalMatches: number;
731
- } | {
732
- reportFile: string;
733
- summary: {
734
- totalMatches: number;
735
- };
736
- }>;
879
+ }): Promise<SearchTranslationsResult>;
737
880
  interface NamespaceNode {
738
881
  keyCount: number;
739
882
  children?: Record<string, NamespaceNode>;
@@ -770,28 +913,6 @@ declare function writeTranslations(opts: {
770
913
  dryRun?: boolean;
771
914
  projectDir?: string;
772
915
  }): Promise<WriteTranslationsResult>;
773
- /**
774
- * Add new translation keys to the specified layer.
775
- *
776
- * @deprecated Use writeTranslations with mode: 'add' instead.
777
- */
778
- declare function addTranslations(opts: {
779
- layer: string;
780
- translations: Record<string, Record<string, string>>;
781
- dryRun?: boolean;
782
- projectDir?: string;
783
- }): Promise<AddTranslationsResult>;
784
- /**
785
- * Update existing translation keys in the specified layer.
786
- *
787
- * @deprecated Use writeTranslations with mode: 'update' instead.
788
- */
789
- declare function updateTranslations(opts: {
790
- layer: string;
791
- translations: Record<string, Record<string, string>>;
792
- dryRun?: boolean;
793
- projectDir?: string;
794
- }): Promise<UpdateTranslationsResult>;
795
916
  /**
796
917
  * Remove one or more translation keys from ALL locale files in the specified layer.
797
918
  */
@@ -802,7 +923,12 @@ declare function removeTranslations(opts: {
802
923
  projectDir?: string;
803
924
  }): Promise<RemoveTranslationsResult>;
804
925
  /**
805
- * Rename/move a translation key across ALL locale files in a layer.
926
+ * Rename a translation key across ALL locale files in one layer.
927
+ *
928
+ * Reachable on both surfaces through {@link moveTranslationKey}, which routes a
929
+ * same-layer request here. Kept exported because renaming within a layer is a
930
+ * complete operation on its own, and a programmatic caller that means exactly
931
+ * that should not have to express it as a move to nowhere.
806
932
  */
807
933
  declare function renameTranslationKey(opts: {
808
934
  layer: string;
@@ -821,7 +947,13 @@ declare function scaffoldLocaleFiles(opts: {
821
947
  projectDir?: string;
822
948
  }): Promise<ScaffoldLocaleResult>;
823
949
  /**
824
- * Move a key from one layer to another, carrying every locale that defines it.
950
+ * Move a key: to another layer, to another key path, or both.
951
+ *
952
+ * One entry point rather than two, because the caller's intent is "this key
953
+ * belongs somewhere else" and whether that somewhere else is a different layer
954
+ * is a detail of the project's shape, not a different operation. Omitting
955
+ * `toLayer` (or naming the layer the key already lives in) is a rename within
956
+ * the layer and routes to {@link renameTranslationKey}.
825
957
  *
826
958
  * Promoting an app-layer key to the shared layer once a second app needs it is
827
959
  * a first-class operation in a layered monorepo, and composing it out of
@@ -842,13 +974,15 @@ declare function scaffoldLocaleFiles(opts: {
842
974
  * silently.
843
975
  */
844
976
  declare function moveTranslationKey(opts: {
845
- fromLayer: string;
846
- toLayer: string;
977
+ /** Layer the key lives in today. */
978
+ layer: string;
847
979
  key: string;
980
+ /** Layer to move it to. Omitted, or equal to `layer`, means a rename in place. */
981
+ toLayer?: string;
848
982
  newKey?: string;
849
983
  dryRun?: boolean;
850
984
  projectDir?: string;
851
- }): Promise<MoveTranslationKeyResult>;
985
+ }): Promise<MoveTranslationKeyOutcome>;
852
986
  //# sourceMappingURL=ops-write.d.ts.map
853
987
  //#endregion
854
988
  //#region src/core/ops-status.d.ts
@@ -863,8 +997,13 @@ declare function moveTranslationKey(opts: {
863
997
  declare function getTranslationStatus(opts: {
864
998
  layer?: string;
865
999
  referenceLocale?: string;
1000
+ /**
1001
+ * Also list the keys behind `summary.emptyKeys`, under `empty`. Off by
1002
+ * default: the count is what a health check reads, and the list grows with
1003
+ * the project.
1004
+ */
1005
+ listEmpty?: boolean;
866
1006
  projectDir?: string;
867
- outputFile?: string;
868
1007
  }): Promise<TranslationStatusResult>;
869
1008
  //# sourceMappingURL=ops-status.d.ts.map
870
1009
  //#endregion
@@ -950,6 +1089,10 @@ interface ScanPatternSet {
950
1089
  * producing `${_}.header`-class candidates that suppress every key ending
951
1090
  * in those segments. Language-neutral shapes (dotted literals,
952
1091
  * trailing-dot prefixes) always run.
1092
+ *
1093
+ * Two-valued only because the two supported languages need two shape sets.
1094
+ * A third frontend makes this a language identifier rather than a family
1095
+ * flag — widen it then, and key it on the language the scanner is reading.
953
1096
  */
954
1097
  bareShapes?: 'js' | 'php';
955
1098
  }
@@ -957,7 +1100,15 @@ declare const VUE_NUXT_PATTERNS: ScanPatternSet;
957
1100
  /**
958
1101
  * Maps locale file format to the appropriate scan pattern set.
959
1102
  * 'php-array' → Laravel (PHP translation helpers in Blade/PHP files).
960
- * 'json' / undefined → Vue/Nuxt ($t / t calls in Vue/TS/JS files).
1103
+ * 'json' / 'yaml' / undefined → Vue/Nuxt ($t / t calls in Vue/TS/JS files).
1104
+ *
1105
+ * The locale-file format works as the key only while each format implies one
1106
+ * source language — 'json' and 'yaml' mean JS/TS/Vue here purely by
1107
+ * coincidence (a Rails project writes YAML and is not scanned by these
1108
+ * patterns at all), and a third language frontend writing JSON or YAML breaks
1109
+ * the mapping. Adding one means keying pattern sets on the language being
1110
+ * scanned and having callers pass that; the format would then select the IO
1111
+ * layer only.
961
1112
  */
962
1113
  declare function getPatternSet(format?: LocaleFileFormat): ScanPatternSet;
963
1114
  //# sourceMappingURL=patterns.d.ts.map
@@ -1005,7 +1156,18 @@ interface ScanResult {
1005
1156
  * frontend reports call sites, the rules decide what they mean.
1006
1157
  */
1007
1158
 
1008
- declare function scanSourceFiles(rootDir: string, excludeDirs?: string[], patterns?: ScanPatternSet, frontends?: LanguageFrontend[]): Promise<ScanResult>;
1159
+ /** What a caller can hand a scan beyond its inputs. */
1160
+ interface ScanSourceFilesHooks {
1161
+ /** Files to read, relative to `rootDir` — a {@link globSourceFiles} result, reused instead of walking the tree twice. */
1162
+ files?: string[];
1163
+ /**
1164
+ * Called once per file, right after it was read. `done` counts completions,
1165
+ * so it fires in completion order while the scan result itself stays in
1166
+ * input order — a counter is all that depends on the timing.
1167
+ */
1168
+ onFile?: (done: number, total: number, file: string) => void;
1169
+ }
1170
+ declare function scanSourceFiles(rootDir: string, excludeDirs?: string[], patterns?: ScanPatternSet, frontends?: LanguageFrontend[], hooks?: ScanSourceFilesHooks): Promise<ScanResult>;
1009
1171
  //#endregion
1010
1172
  //#region src/core/ops-orphans.d.ts
1011
1173
  /**
@@ -1024,7 +1186,10 @@ declare function findOrphanKeys(opts: {
1024
1186
  scanDirs?: string[];
1025
1187
  excludeDirs?: string[];
1026
1188
  projectDir?: string;
1027
- outputFile?: string;
1189
+ /** Scanning every source file of every app takes seconds — a caller that asked for progress hears about each stride of files. */
1190
+ progressFn?: ProgressFn;
1191
+ /** Called once with the number of progress steps, before the first `progressFn` call. */
1192
+ onProgressTotal?: (total: number) => void;
1028
1193
  }): Promise<FindOrphanKeysResult>;
1029
1194
  /**
1030
1195
  * Scan Vue/TS source files to find where translation keys are referenced.
@@ -1034,7 +1199,6 @@ declare function scanCodeUsage(opts: {
1034
1199
  scanDirs?: string[];
1035
1200
  excludeDirs?: string[];
1036
1201
  projectDir?: string;
1037
- outputFile?: string;
1038
1202
  }): Promise<CodeUsageResult>;
1039
1203
  /**
1040
1204
  * Find translation keys not referenced in source code and remove them.
@@ -1047,9 +1211,10 @@ declare function removeOrphanKeys(opts: {
1047
1211
  excludeDirs?: string[];
1048
1212
  dryRun?: boolean;
1049
1213
  projectDir?: string;
1050
- outputFile?: string;
1051
- /** Also write the orphan findings as a GitLab Code Quality JSON array to this path. */
1052
- codequalityOutput?: string;
1214
+ /** Same scan as {@link findOrphanKeys}, same reporting. */
1215
+ progressFn?: ProgressFn;
1216
+ /** Called once with the number of progress steps, before the first `progressFn` call. */
1217
+ onProgressTotal?: (total: number) => void;
1053
1218
  }): Promise<RemoveOrphanKeysResult>;
1054
1219
  //# sourceMappingURL=ops-orphans.d.ts.map
1055
1220
  //#endregion
@@ -1114,7 +1279,6 @@ interface FindDuplicateKeysResult {
1114
1279
  declare function findDuplicateKeys(opts?: {
1115
1280
  locale?: string;
1116
1281
  projectDir?: string;
1117
- outputFile?: string;
1118
1282
  /**
1119
1283
  * Also group keys by the value they carry. Off by default: it reads every
1120
1284
  * canonical layer rather than only the paired ones, and the existing result
@@ -1123,10 +1287,7 @@ declare function findDuplicateKeys(opts?: {
1123
1287
  byValue?: boolean;
1124
1288
  /** Shortest value worth grouping. Below it, repetition is usually legitimate. */
1125
1289
  minValueLength?: number;
1126
- }): Promise<FindDuplicateKeysResult | {
1127
- reportFile: string;
1128
- summary: FindDuplicateKeysSummary;
1129
- }>;
1290
+ }): Promise<FindDuplicateKeysResult>;
1130
1291
  //# sourceMappingURL=ops-duplicates.d.ts.map
1131
1292
  //#endregion
1132
1293
  //#region src/core/ops-check.d.ts
@@ -1155,10 +1316,26 @@ interface UncertainKeyFinding extends UndefinedKeyFinding {
1155
1316
  /** Why this is not a hard finding. */
1156
1317
  reason: string;
1157
1318
  }
1319
+ /** The locale file `write` extracted the undefined keys into. */
1320
+ interface ExtractedUndefinedKeys {
1321
+ layer: string;
1322
+ /** The project's default locale — the source every other locale is filled from. */
1323
+ locale: string;
1324
+ /** The keys that reached the file, in alphabetical order. */
1325
+ keys: string[];
1326
+ }
1158
1327
  interface CheckUndefinedKeysSummary {
1159
1328
  /** Distinct statically referenced keys across all scan units. */
1160
1329
  usedKeysChecked: number;
1330
+ /**
1331
+ * Keys that render raw at runtime, which is what the gate reads. After a
1332
+ * `write` run this counts the ones still undefined: an extracted key now has
1333
+ * a definition — an empty one — so it resolves, and `status` reports it as an
1334
+ * empty translation instead.
1335
+ */
1161
1336
  undefinedCount: number;
1337
+ /** Keys extracted into a locale file. Present only alongside `written`. */
1338
+ writtenCount?: number;
1162
1339
  uncertainCount: number;
1163
1340
  /** Unresolvable keys excluded by orphanScan ignorePatterns. */
1164
1341
  ignoredCount: number;
@@ -1171,9 +1348,19 @@ interface CheckUndefinedKeysSummary {
1171
1348
  message: string;
1172
1349
  }
1173
1350
  interface CheckUndefinedKeysResult {
1351
+ /**
1352
+ * The findings as the scan made them. A `write` run leaves them in place —
1353
+ * what was extracted is named in `written`, and the summary counts what is
1354
+ * left — because the call sites are what a reader has to visit either way.
1355
+ */
1174
1356
  undefinedKeys: UndefinedKeyFinding[];
1175
1357
  uncertainKeys: UncertainKeyFinding[];
1176
1358
  limitation: string;
1359
+ /**
1360
+ * Present only when `write` was asked for and the scan found something to
1361
+ * write. A clean scan reports nothing here, having written nothing.
1362
+ */
1363
+ written?: ExtractedUndefinedKeys;
1177
1364
  summary: CheckUndefinedKeysSummary;
1178
1365
  }
1179
1366
  /**
@@ -1186,6 +1373,9 @@ interface CheckUndefinedKeysResult {
1186
1373
  * scopeByLayer — a unit resolves exactly the layers it vouches for). The
1187
1374
  * graph's degenerate semantics carry over: with no app info every layer is
1188
1375
  * resolvable everywhere, so only keys defined in NO layer are flagged.
1376
+ *
1377
+ * With `write`, the findings are also extracted into a locale file as empty
1378
+ * translations, which is what turns a report into the first half of the fix.
1189
1379
  */
1190
1380
  declare function checkUndefinedKeys(opts?: {
1191
1381
  locale?: string;
@@ -1195,119 +1385,362 @@ declare function checkUndefinedKeys(opts?: {
1195
1385
  */
1196
1386
  scanDirs?: string[];
1197
1387
  excludeDirs?: string[];
1388
+ /** Extract the undefined keys into a locale file. See extractUndefinedKeys. */
1389
+ write?: boolean;
1390
+ /** The layer to extract into, where the findings alone do not decide. */
1391
+ layer?: string;
1198
1392
  projectDir?: string;
1199
- outputFile?: string;
1200
- /** Also write the findings as a GitLab Code Quality JSON array to this path. */
1201
- codequalityOutput?: string;
1202
- }): Promise<CheckUndefinedKeysResult | {
1203
- reportFile: string;
1204
- summary: CheckUndefinedKeysSummary;
1205
- }>;
1393
+ }): Promise<CheckUndefinedKeysResult>;
1206
1394
  //# sourceMappingURL=ops-check.d.ts.map
1207
1395
  //#endregion
1208
- //#region src/config/detector.d.ts
1209
- declare function detectI18nConfig(projectDir: string): Promise<I18nConfig>;
1210
- declare function clearConfigCache(): void;
1211
- declare function getCachedConfig(): I18nConfig | null;
1212
- //# sourceMappingURL=detector.d.ts.map
1213
-
1396
+ //#region src/core/codequality.d.ts
1397
+ interface CodeQualityIssue {
1398
+ description: string;
1399
+ check_name: string;
1400
+ fingerprint: string;
1401
+ severity: 'info' | 'minor' | 'major' | 'critical' | 'blocker';
1402
+ location: {
1403
+ path: string;
1404
+ lines: {
1405
+ begin: number;
1406
+ };
1407
+ };
1408
+ }
1409
+ /**
1410
+ * `check` findings → one issue per usage location. Uncertain findings are
1411
+ * not mapped: the widget has no "maybe" state, and a hard-looking finding
1412
+ * for an unverifiable key would train consumers to ignore the report.
1413
+ */
1214
1414
  //#endregion
1215
- //#region src/config/layer-graph.d.ts
1415
+ //#region src/surface/types.d.ts
1416
+ /** Which surface is invoking an operation. They differ only in the prose they own. */
1417
+ type Surface = 'cli' | 'mcp';
1216
1418
  /**
1217
- * Queryable view over the layer topology a resolved {@link I18nConfig}
1218
- * already carries: which locale dirs are canonical (alias-free), which
1219
- * layer owns an aliased dir, and which apps consume which layers.
1419
+ * What a parameter carries.
1220
1420
  *
1221
- * This is a pure derivation no filesystem access, no config-shape
1222
- * changes. Cross-layer tooling (duplicate detection, scope-aware orphan
1223
- * scanning) builds on these queries instead of name-matching heuristics.
1421
+ * `string[]` is a list on both surfaces: MCP passes a JSON array, the CLI a
1422
+ * comma-separated string it splits. `record` is the one nested shape on the
1423
+ * surface the key locale value map `write` takes — so the builders state
1424
+ * its inner levels once instead of every spec carrying a schema.
1425
+ */
1426
+ type ParamType = 'string' | 'boolean' | 'number' | 'string[]' | 'record';
1427
+ /** The value shape of a `record` parameter: dot-path key → locale ref → string. */
1428
+ type TranslationsRecord = Record<string, Record<string, string>>;
1429
+ interface CliParamOptions {
1430
+ /**
1431
+ * Additional spellings citty accepts for this flag. Single characters render
1432
+ * as `-d`; longer ones are the flag's previous name, kept working after the
1433
+ * descriptor took the name the MCP tool used.
1434
+ */
1435
+ alias?: string | readonly string[];
1436
+ /** Not exposed as a flag. Every use of this states why in a comment. */
1437
+ hidden?: boolean;
1438
+ }
1439
+ interface McpParamOptions {
1440
+ /** Not part of the tool's input schema. Every use of this states why in a comment. */
1441
+ hidden?: boolean;
1442
+ }
1443
+ /** One parameter of an operation, as both surfaces expose it. */
1444
+ interface ParamSpec {
1445
+ type: ParamType;
1446
+ /**
1447
+ * The one description. It reaches `--help`, the generated CLI page and the
1448
+ * JSON Schema an MCP host hands its model, so it is written for a reader who
1449
+ * knows neither surface: no `--flag` spellings, no "this tool".
1450
+ */
1451
+ description: string;
1452
+ required?: boolean;
1453
+ /**
1454
+ * Applied by the CLI so `--help` can state it. Deliberately not put into the
1455
+ * JSON Schema: the operations already apply their own defaults, and a schema
1456
+ * default would make a host send a value the caller never chose.
1457
+ */
1458
+ default?: unknown;
1459
+ /** The accepted values. The CLI validates against them and MCP emits an enum. */
1460
+ enum?: readonly string[];
1461
+ /** Numbers only: reject a fractional value. */
1462
+ integer?: boolean;
1463
+ /** Numbers only: reject anything below this. */
1464
+ min?: number;
1465
+ /** `string[]` parameters that also accept the literal "all". */
1466
+ allowAll?: boolean;
1467
+ cli?: CliParamOptions;
1468
+ mcp?: McpParamOptions;
1469
+ }
1470
+ type Params = Record<string, ParamSpec>;
1471
+ /**
1472
+ * A CI gate a command evaluates. `counter` is the field of `result.summary`
1473
+ * carrying the observed value.
1224
1474
  *
1225
- * ## Degenerate-case semantics
1475
+ * The two shapes are a union rather than one type with optional halves so the
1476
+ * invariants hold at compile time: a flagged gate always has a flag to read
1477
+ * its name and threshold from, and a flagless one always carries both itself.
1478
+ * Stated as options, `{ counter, threshold }` type-checks and then has no name
1479
+ * to report the gate under.
1480
+ */
1481
+ type GateSpec = FlaggedGateSpec | AlwaysOnGateSpec;
1482
+ interface GateSpecBase {
1483
+ counter: string;
1484
+ /** 'above' trips when observed > threshold (default); 'below' when observed < threshold. */
1485
+ direction?: 'above' | 'below';
1486
+ }
1487
+ /**
1488
+ * Requested by a flag, and evaluated only when that flag is passed. Omitting
1489
+ * `threshold` takes it from the flag's own value, so a boolean flag pairs with
1490
+ * `threshold: 0` and a numeric one (`--failUnder 90`) omits it.
1491
+ */
1492
+ interface FlaggedGateSpec extends GateSpecBase {
1493
+ flag: string;
1494
+ name?: never;
1495
+ threshold?: number;
1496
+ }
1497
+ /**
1498
+ * Always evaluated, for findings that are a defect rather than a threshold — a
1499
+ * key that renders raw in production is not something you opt into caring
1500
+ * about. It still reports as a gate: the run succeeded, and what it found is
1501
+ * what you are being told about.
1502
+ */
1503
+ interface AlwaysOnGateSpec extends GateSpecBase {
1504
+ flag?: never;
1505
+ name: string;
1506
+ threshold: number;
1507
+ }
1508
+ /**
1509
+ * What the surface hands a report builder beyond the result: the project the
1510
+ * operation ran against and the arguments it ran with.
1511
+ */
1512
+ interface ReportContext<A = Record<string, unknown>> {
1513
+ projectDir: string;
1514
+ /** The project's resolved i18n configuration, as the operation itself read it. */
1515
+ config: I18nConfig;
1516
+ /** The operation's arguments, as the surface resolved them. */
1517
+ args: A;
1518
+ }
1519
+ /**
1520
+ * How a result too large to hand back is diverted to a file.
1226
1521
  *
1227
- * These are load-bearing for consumers (scope-aware scanning must never
1228
- * wrongly narrow its scan scope):
1522
+ * An operation always returns its whole result. Whether that result is written
1523
+ * to disk and replaced by a compact stand-in is the surface's decision — it is
1524
+ * the surface that owns `outputFile`, the configured report directory and the
1525
+ * name the file is written under — so the operations know nothing about any of
1526
+ * it, and a descriptor declaring this is what gives an operation the parameters
1527
+ * that request it.
1528
+ */
1529
+ interface ReportSpec<R = unknown, A = Record<string, unknown>> {
1530
+ /**
1531
+ * The file's base name under the configured report directory, and the tool
1532
+ * name recorded inside the report. A function where one operation answers
1533
+ * different questions and writes each under its own name — pipelines archive
1534
+ * these paths, so they are part of the contract.
1535
+ */
1536
+ name: string | ((args: A) => string);
1537
+ /** The compact stand-in returned once the full result is on disk. */
1538
+ summary: (result: R) => unknown;
1539
+ /**
1540
+ * The `outputFile` parameter as this operation offers it. Declared here and
1541
+ * nowhere else, so an operation cannot advertise the parameter without the
1542
+ * plumbing behind it, nor grow the plumbing without the parameter.
1543
+ */
1544
+ outputFile: {
1545
+ /** The example path its description carries. */
1546
+ example: string;
1547
+ cli?: CliParamOptions;
1548
+ mcp?: McpParamOptions;
1549
+ };
1550
+ /** The same findings, as a GitLab Code Quality report the pipeline collects. */
1551
+ codequality?: {
1552
+ /** What the findings are called in the parameter's description. */
1553
+ findings: string;
1554
+ /**
1555
+ * Returning undefined writes nothing, which is not the same as writing an
1556
+ * empty array: the empty array is the baseline the merge-request widget
1557
+ * diffs against, so it is only right for a run that looked for these
1558
+ * findings and found none.
1559
+ */
1560
+ issues: (result: R, ctx: ReportContext<A>) => CodeQualityIssue[] | undefined;
1561
+ };
1562
+ }
1563
+ /**
1564
+ * A report spec with its result type erased, as the runner sees it.
1229
1565
  *
1230
- * - **No app info** (`config.apps` empty or absent, e.g. hand-built
1231
- * configs): consumption edges are unknowable. `appsUsingLayer` and
1232
- * `layersOfApp` return `[]`, and `sharedLayers` conservatively contains
1233
- * *every* canonical layer — with no ownership information, every
1234
- * layer's keys must be treated as globally visible.
1235
- * - **Single-app config** (generic/Laravel/Vue/React adapters, or a Nuxt
1236
- * project with one app): the strict definition applies, so
1237
- * `sharedLayers` is empty (no layer is consumed by more than one app)
1238
- * and `appsUsingLayer` returns that one app for the layers it consumes.
1239
- * Per-layer scope then equals the whole project, which is correct.
1240
- * - **Canonical layer consumed by no app** (in a multi-app config):
1241
- * `appsUsingLayer` returns `[]` and the layer is not in `sharedLayers`.
1242
- * Callers should treat such layers conservatively (global scope).
1566
+ * `any` rather than `unknown`: the runner holds a result whose type it cannot
1567
+ * know, while every declaration site is checked against its own operation's
1568
+ * result type.
1243
1569
  */
1244
- interface LayerGraph {
1570
+ type AnyReportSpec = ReportSpec<any>;
1571
+ /** How the MCP server advertises an operation as a tool. */
1572
+ interface McpToolSpec {
1573
+ name: string;
1574
+ /** The display title a host shows. */
1575
+ title: string;
1576
+ /** Behaviour hints a host reads. Only the translating tools declare any. */
1577
+ annotations?: {
1578
+ title?: string;
1579
+ readOnlyHint?: boolean;
1580
+ };
1581
+ }
1582
+ /** How the CLI exposes an operation as a command. */
1583
+ interface CliCommandSpec {
1584
+ name: string;
1585
+ }
1586
+ /**
1587
+ * What a surface hands an operation beyond its parameters.
1588
+ *
1589
+ * `surface` exists because the guidance an agent-mode result carries is the
1590
+ * caller's, not the operation's: a terminal is told to pass `--provider`, a
1591
+ * host is told to translate the fallback contexts inline. Keeping both strings
1592
+ * in one place is the point — they used to sit in two files and say different
1593
+ * things about the same state.
1594
+ */
1595
+ interface OperationContext {
1596
+ surface: Surface;
1597
+ /** Provider-backed translation, when the surface resolved one. */
1598
+ translateFn?: TranslateFn;
1245
1599
  /**
1246
- * Alias-free locale dirs, in `config.localeDirs` order. Aliased entries
1247
- * (e.g. `app-outlook` pointing at `app-shop`'s dir) are excluded.
1600
+ * Progress reporting, when the caller asked for it. Only MCP does — a
1601
+ * terminal is left with its exit code. The operations that take long enough
1602
+ * to report call it (translating, orphan scans); the rest never do.
1248
1603
  */
1249
- canonicalLayers: LocaleDir[];
1604
+ progressFn?: ProgressFn;
1250
1605
  /**
1251
- * Resolve a layer name to the canonical layer that owns its locale dir.
1252
- * Follows chained `aliasOf` links (an alias may point at a layer that
1253
- * was itself demoted to an alias). Identity for canonical names and for
1254
- * names unknown to `localeDirs` (e.g. layers without locale dirs).
1606
+ * The number of steps the operation is about to report, counted in whatever
1607
+ * unit it reports in. Called once, before the first `progressFn` call, so a
1608
+ * notification never goes out against an unknown total.
1255
1609
  */
1256
- ownerOf: (layer: string) => string;
1610
+ onProgressTotal?: (total: number) => void;
1611
+ }
1612
+ /**
1613
+ * The value of one parameter as the operation receives it: already split,
1614
+ * parsed and validated by whichever surface took it.
1615
+ */
1616
+ type ParamValue<S extends ParamSpec> = S extends {
1617
+ type: 'boolean';
1618
+ } ? boolean : S extends {
1619
+ type: 'number';
1620
+ } ? number : S extends {
1621
+ type: 'record';
1622
+ } ? TranslationsRecord : S extends {
1623
+ type: 'string[]';
1624
+ allowAll: true;
1625
+ } ? string[] | 'all' : S extends {
1626
+ type: 'string[]';
1627
+ } ? string[] : S extends {
1628
+ type: 'string';
1629
+ enum: readonly (infer E extends string)[];
1630
+ } ? E : S extends {
1631
+ type: 'string';
1632
+ } ? string : never;
1633
+ type RequiredParamNames<P extends Params> = { [K in keyof P]-?: P[K] extends {
1634
+ required: true;
1635
+ } ? K : never }[keyof P];
1636
+ /**
1637
+ * The arguments an operation's `run` receives. Required parameters are present,
1638
+ * the rest are optional, and `projectDir` is always available because both
1639
+ * surfaces resolve it themselves (the CLI from `--projectDir`, the server from
1640
+ * I18N_PROJECT_DIR) rather than making every operation declare it.
1641
+ */
1642
+ type OperationArgs<P extends Params = Params> = { [K in RequiredParamNames<P> & keyof P]: ParamValue<P[K]> } & { [K in Exclude<keyof P, RequiredParamNames<P>>]?: ParamValue<P[K]> } & {
1643
+ projectDir?: string;
1644
+ };
1645
+ /** One operation, as both surfaces read it. */
1646
+ interface OperationDescriptor<P extends Params = Params> {
1647
+ /** Stable identifier, independent of what either surface calls it. */
1648
+ id: string;
1649
+ /** Null for an operation the CLI does not expose. */
1650
+ cli: CliCommandSpec | null;
1651
+ /** Null for an operation the MCP server does not advertise. */
1652
+ mcp: McpToolSpec | null;
1653
+ /** One sentence, on both surfaces. */
1654
+ description: string;
1257
1655
  /**
1258
- * Names of apps whose consumed layers include the given layer. The
1259
- * queried name and each app's layer list are alias-resolved via
1260
- * {@link ownerOf} first, so querying an alias name yields the owner's
1261
- * consumers. Returns `[]` when no app info exists.
1656
+ * Further prose for a model deciding whether to call the tool: when to reach
1657
+ * for it, what the result carries, what it will not do. MCP only — a `--help`
1658
+ * line has to stay a line, and the generated CLI page says the same things in
1659
+ * its flag table.
1262
1660
  */
1263
- appsUsingLayer: (layer: string) => string[];
1661
+ longDescription?: string;
1662
+ params: P;
1663
+ /** CI gates the CLI evaluates. Exit codes are a CLI notion, so MCP ignores these. */
1664
+ gates?: GateSpec[];
1264
1665
  /**
1265
- * Canonical layers consumed by more than one app e.g. a shared root
1266
- * layer in a multi-app monorepo, identified purely from consumption
1267
- * edges (no name matching). When no app info exists, contains every
1268
- * canonical layer (see degenerate-case semantics above).
1666
+ * The operation translates, so the surface has to hand it a backend: the CLI
1667
+ * resolves one from the provider flags, the server from its startup
1668
+ * environment. Without one the operation returns contexts to translate by
1669
+ * hand rather than failing.
1269
1670
  */
1270
- sharedLayers: LocaleDir[];
1671
+ usesTranslateFn?: boolean;
1271
1672
  /**
1272
- * Canonical layers the given app consumes (alias entries in the app's
1273
- * layer list resolve to their owners; layers without locale dirs are
1274
- * omitted). Returns `[]` for unknown apps or when no app info exists.
1673
+ * The result is large enough to be worth writing to a file instead of
1674
+ * returning. Declaring this is what adds the parameters that request it and
1675
+ * what makes the configured report directory apply to the operation.
1676
+ *
1677
+ * The result type stays open: a `run` whose parameters are contextually typed
1678
+ * is not an inference site, so nothing here can see the operation's own
1679
+ * result type. Declaration sites annotate it on the builder instead, which is
1680
+ * what type-checks them.
1275
1681
  */
1276
- layersOfApp: (app: string) => LocaleDir[];
1682
+ report?: ReportSpec<any, OperationArgs<P>>;
1683
+ /**
1684
+ * Declared as a method so the table can hold descriptors with different
1685
+ * parameter maps: method parameters are compared bivariantly, which is what
1686
+ * lets `run` be typed against each operation's own arguments and still be
1687
+ * callable through the erased element type below.
1688
+ */
1689
+ run(args: OperationArgs<P>, ctx: OperationContext): Promise<unknown>;
1277
1690
  }
1278
1691
  /**
1279
- * Build a {@link LayerGraph} from a resolved config's `localeDirs`
1280
- * (with their `aliasOf` markers) and `apps` (app consumed-layers edges).
1692
+ * A descriptor as the registrars see it, with `run` erased to plain arguments.
1693
+ * They build those arguments from a schema at runtime and cannot know the
1694
+ * per-operation type, so the erasure happens once, in `defineOperation`,
1695
+ * instead of at every call site.
1281
1696
  */
1282
- declare function buildLayerGraph(config: I18nConfig): LayerGraph;
1697
+ type AnyOperationDescriptor = Omit<OperationDescriptor<Params>, 'run' | 'params' | 'report'> & {
1698
+ params: Params;
1699
+ report?: AnyReportSpec;
1700
+ run(args: Record<string, unknown>, ctx: OperationContext): Promise<unknown>;
1701
+ };
1283
1702
  /**
1284
- * The graph as plain data, for surfaces that can only carry JSON.
1703
+ * Declare one operation. The `const` type parameter is what keeps `required:
1704
+ * true` and `enum: [...]` literal, so `run` receives `layer: string` rather
1705
+ * than `string | undefined` for a parameter the surface guarantees.
1285
1706
  *
1286
- * {@link LayerGraph} is function-valued, so it cannot be serialised directly.
1287
- * This answers the question an agent actually has — *which layer does this key
1288
- * belong in* — which the flat layer list `discover` returned could not: a key
1289
- * used by more than one app belongs in a layer those apps share, and `shared`
1290
- * names those layers outright (#342).
1707
+ * An operation that declares a `report` gains the parameters that request one
1708
+ * here, so the two cannot drift apart.
1709
+ */
1710
+ //#endregion
1711
+ //#region src/surface/descriptors.d.ts
1712
+ /**
1713
+ * Registry order: it is the order `the-i18n-cli --help` lists commands in and
1714
+ * the order both generated reference overviews are written in.
1715
+ */
1716
+ declare const descriptors: readonly AnyOperationDescriptor[];
1717
+ /** The descriptors a surface exposes, in registry order. */
1718
+ declare function descriptorsFor(surface: 'cli' | 'mcp'): AnyOperationDescriptor[];
1719
+ /** The parameter names a surface exposes for one operation, in declaration order. */
1720
+ declare function visibleParams(descriptor: AnyOperationDescriptor, surface: 'cli' | 'mcp'): string[];
1721
+ //# sourceMappingURL=descriptors.d.ts.map
1722
+
1723
+ //#endregion
1724
+ //#region src/surface/report.d.ts
1725
+ /**
1726
+ * Write the result where the caller asked for it, and hand back the compact
1727
+ * stand-in — or hand back the result untouched when nothing asked for a file.
1291
1728
  *
1292
- * The degenerate cases documented on {@link LayerGraph} survive the flattening,
1293
- * because they are what keeps a consumer from wrongly narrowing scope:
1294
- * a config with no app info reports *every* canonical layer as shared, and a
1295
- * layer no app consumes appears in `consumers` with an empty array rather than
1296
- * being left out. Absent and "none" must not look alike here.
1729
+ * Called with the arguments the operation ran with, which is what lets an
1730
+ * operation answering several questions write each under its own report name.
1297
1731
  */
1298
- interface SerializedLayerGraph {
1299
- /** Alias-free layer names, in `config.localeDirs` order. */
1300
- canonical: string[];
1301
- /** Canonical layers consumed by more than one app — where shared keys belong. */
1302
- shared: string[];
1303
- /** Alias layer name the canonical layer whose locale dir it points at. */
1304
- aliases: Record<string, string>;
1305
- /** Canonical layer name → the apps consuming it. Every canonical layer is a key. */
1306
- consumers: Record<string, string[]>;
1307
- }
1308
- /** Flatten {@link buildLayerGraph}'s view of `config` into plain JSON. */
1309
- declare function serializeLayerGraph(config: I18nConfig): SerializedLayerGraph;
1310
- //# sourceMappingURL=layer-graph.d.ts.map
1732
+ declare function divertToReport(result: unknown, descriptor: AnyOperationDescriptor, args: Record<string, unknown>): Promise<unknown>;
1733
+ //# sourceMappingURL=report.d.ts.map
1734
+ //#endregion
1735
+ //#region src/config/cache.d.ts
1736
+ /** The most recently resolved config, or null when nothing has been resolved. */
1737
+ declare function getCachedConfig(): I18nConfig | null;
1738
+ declare function clearConfigCache(): void;
1739
+ //# sourceMappingURL=cache.d.ts.map
1740
+ //#endregion
1741
+ //#region src/config/detector.d.ts
1742
+ declare function detectI18nConfig(projectDir: string): Promise<I18nConfig>;
1743
+ //# sourceMappingURL=detector.d.ts.map
1311
1744
  //#endregion
1312
1745
  //#region src/scanner/frontends/oxc.d.ts
1313
1746
  declare function createOxcFrontend(): LanguageFrontend;
@@ -1382,25 +1815,6 @@ declare class ToolError extends Error {
1382
1815
  }
1383
1816
  //# sourceMappingURL=errors.d.ts.map
1384
1817
  //#endregion
1385
- //#region src/utils/rename-notice.d.ts
1386
- /**
1387
- * The kit is renaming to the `@the-i18n-kit` scope (#315). During the window
1388
- * both names publish from one source at matching versions, so nothing breaks —
1389
- * but a user on the old name has no way of learning that unless the package
1390
- * tells them.
1391
- *
1392
- * A package finds out it is the old one by reading its own `name` at runtime,
1393
- * which is why this takes the name rather than deciding for itself: the same
1394
- * code ships under both names, and only the manifest differs.
1395
- */
1396
- /**
1397
- * The notice for a package running under a legacy name, or null when it is
1398
- * already running under its new one — which is the case that must stay silent,
1399
- * since a notice there would be telling people to do what they have done.
1400
- */
1401
- declare function renameNotice(packageName: string): string | null;
1402
- //# sourceMappingURL=rename-notice.d.ts.map
1403
- //#endregion
1404
1818
  //#region src/llm/providers.d.ts
1405
1819
  type LlmProvider = 'openai' | 'anthropic' | 'google';
1406
1820
  /** How a provider failure should be handled by the caller. */
@@ -1419,7 +1833,7 @@ declare class TranslateProviderError extends Error {
1419
1833
  constructor(message: string, kind: TranslateProviderErrorKind, status?: number);
1420
1834
  }
1421
1835
  /**
1422
- * Classify an SDK error into a TranslateProviderError:
1836
+ * Classify a provider error into a TranslateProviderError:
1423
1837
  * 401/403 → auth, 429 → rate-limit, anything else → provider.
1424
1838
  * Already-classified errors pass through unchanged.
1425
1839
  */
@@ -1451,8 +1865,9 @@ declare function resolveProviderBaseUrl(sources: {
1451
1865
  config?: string;
1452
1866
  }): string | undefined;
1453
1867
  /**
1454
- * Create a TranslateFn from an LLM provider config.
1455
- * Throws if the provider SDK is not installed or API key is missing.
1868
+ * Create a TranslateFn from an LLM provider config. Every provider is called
1869
+ * over plain HTTP, so nothing beyond the CLI has to be installed.
1870
+ * Throws if the API key is missing.
1456
1871
  */
1457
1872
  declare function createTranslateFn(config: LlmProviderConfig): Promise<TranslateFn>;
1458
1873
  //# sourceMappingURL=providers.d.ts.map
@@ -1474,5 +1889,5 @@ declare function loadProjectConfig(projectDir: string): Promise<ProjectConfig |
1474
1889
  //# sourceMappingURL=project-config.d.ts.map
1475
1890
 
1476
1891
  //#endregion
1477
- export { AddTranslationsResult, BASE_URL_ENV, type CallArgument, type CallSite, type CheckUndefinedKeysResult, type CheckUndefinedKeysSummary, CodeUsageRef, CodeUsageResult, type DuplicateKeyCollision, DynamicKeyRef, EmptyTranslationsResult, type FileEvidence, type FindDuplicateKeysResult, type FindDuplicateKeysSummary, FindOrphanKeysResult, GeneratedProjectConfig, type I18nConfig, type I18nKitConfig, InitProjectConfigResult, type KeyUsageLocation, LARAVEL_PATTERNS, type LanguageFrontend, type LayerGraph, LayerStatus, type LlmProvider, type LlmProviderConfig, type LocaleDefinition, type LocaleDir, LocaleDirInfo, type LocaleRefAmbiguity, LocaleRefInfo, LocaleStatus, MisplacedUsageRef, MissingTranslationsResult, MoveTranslationKeyPlanEntry, MoveTranslationKeyResult, MutationPreview, MutationResult, PlaceholderValidationIssue, PlaceholderValidationResult, ProgressFn, type ProjectConfig, RemoveOrphanKeysResult, RemoveTranslationsPreview, RemoveTranslationsResult, RenameTranslationKeyPreview, RenameTranslationKeyResult, ScaffoldLocaleFileInfo, ScaffoldLocaleResult, ScanCodeUsageResult, type ScanResult, SearchMatch, SearchTranslationsResult, type SerializedLayerGraph, ToolError, TranslateAllLayersResult, TranslateAllLayersSummary, TranslateFailReason, TranslateFn, TranslateKeyLocaleIssue, TranslateKeyResult, TranslateLayerTotals, TranslateMissingCompactEntry, TranslateMissingLocaleResult, TranslateMissingOutcome, TranslateMissingResult, TranslateMode, TranslateProviderError, type TranslateProviderErrorKind, TranslateRequest, TranslateResponse, TranslateSkipReason, TranslationStatusResult, TranslationStatusSummary, type UncertainKeyFinding, type UndefinedKeyFinding, UnresolvedKeyWarningRef, UnresolvedLocaleRef, UpdateTranslationsResult, VUE_NUXT_PATTERNS, WriteTranslationsResult, addTranslations, buildLayerGraph, checkUndefinedKeys, classifyProviderError, clearConfigCache, createBladeFrontend, createOxcFrontend, createPatternsFrontend, createPhpFrontend, createTranslateFn, defineI18nKitConfig, detectConfig, detectI18nConfig, findDuplicateKeys, findEmptyTranslations, findLocaleImpl, findOrphanKeys, getCachedConfig, getMissingTranslations, getPatternSet, getTranslationStatus, getTranslations, listLocaleDirs, listNamespaces, loadProjectConfig, moveTranslationKey, readLocaleData, removeOrphanKeys, removeTranslations, renameNotice, renameTranslationKey, resolveProtectedLocales, resolveProviderBaseUrl, scaffoldLocaleFiles, scanCodeUsage, scanSourceFiles, searchTranslations, serializeLayerGraph, toErrorMessage, translateKey, translateMissing, updateTranslations, writeTranslations };
1478
- //# sourceMappingURL=index-DCG3dOdC.d.ts.map
1892
+ export { type AnyOperationDescriptor, type AnyReportSpec, BASE_URL_ENV, type CallArgument, type CallSite, type CheckUndefinedKeysResult, type CheckUndefinedKeysSummary, CodeUsageRef, CodeUsageResult, DescribeProjectResult, type DuplicateKeyCollision, DynamicKeyRef, EmptyTranslationsResult, type FileEvidence, type FindDuplicateKeysResult, type FindDuplicateKeysSummary, FindOrphanKeysResult, GeneratedProjectConfig, type I18nConfig, type I18nKitConfig, InitProjectConfigResult, type KeyUsageLocation, LARAVEL_PATTERNS, type LanguageFrontend, type LayerGraph, LayerStatus, type LlmProvider, type LlmProviderConfig, type LocaleDefinition, type LocaleDir, LocaleDirInfo, type LocaleRefAmbiguity, LocaleRefInfo, LocaleStatus, MisplacedUsageRef, MissingTranslationsResult, MoveTranslationKeyOutcome, MoveTranslationKeyPlanEntry, MoveTranslationKeyResult, MutationPreview, MutationResult, type OperationContext, type OperationDescriptor, type ParamSpec, type ParamType, type Params, PlaceholderValidationIssue, PlaceholderValidationResult, ProgressFn, type ProjectConfig, RemoveOrphanKeysResult, RemoveTranslationsPreview, RemoveTranslationsResult, RenameTranslationKeyPreview, RenameTranslationKeyResult, type ReportContext, type ReportSpec, ScaffoldLocaleFileInfo, ScaffoldLocaleResult, ScanCodeUsageResult, type ScanResult, SearchMatch, SearchTranslationsResult, type SerializedLayerGraph, type Surface, ToolError, TranslateAllLayersResult, TranslateAllLayersSummary, TranslateFailReason, TranslateFn, TranslateKeyLocaleIssue, TranslateKeyResult, TranslateKeySkip, TranslateLayerTotals, TranslateMissingCompactEntry, TranslateMissingLocaleResult, TranslateMissingOptions, TranslateMissingOutcome, TranslateMissingResult, TranslateMode, TranslateProviderError, type TranslateProviderErrorKind, TranslateRequest, TranslateResponse, TranslateSkipReason, TranslationStatusResult, TranslationStatusSummary, type TranslationsRecord, type UncertainKeyFinding, type UndefinedKeyFinding, UnresolvedKeyWarningRef, UnresolvedLocaleRef, VUE_NUXT_PATTERNS, WriteTranslationsResult, buildLayerGraph, checkUndefinedKeys, classifyProviderError, clearConfigCache, createBladeFrontend, createOxcFrontend, createPatternsFrontend, createPhpFrontend, createTranslateFn, defineI18nKitConfig, describeProject, descriptors, descriptorsFor, detectConfig, detectI18nConfig, divertToReport, findDuplicateKeys, findEmptyTranslations, findLocaleImpl, findOrphanKeys, getCachedConfig, getMissingTranslations, getPatternSet, getTranslationStatus, getTranslations, listLocaleDirs, listNamespaces, loadProjectConfig, moveTranslationKey, readLocaleData, removeOrphanKeys, removeTranslations, renameTranslationKey, resolveProtectedLocales, resolveProviderBaseUrl, scaffoldLocaleFiles, scanCodeUsage, scanSourceFiles, searchTranslations, serializeLayerGraph, toErrorMessage, translateKey, translateMissing, visibleParams, writeTranslations };
1893
+ //# sourceMappingURL=index-CdjJ71Ag.d.ts.map