---
title: "Config et glossaire"
description: "Les points d'entrée du SDK qui chargent et valident la config verbatra et modifient le glossaire, plus celui qui détecte si un dossier contient un projet."
type: "reference"
---
# Config et glossaire

Les points d'entrée du SDK qui chargent et valident la config verbatra et modifient le glossaire, plus celui qui détecte si un dossier contient un projet.

## Charger la config [#config]

### loadConfig [#loadconfig]

Trouve, charge et valide la config du projet, en renvoyant une `VerbatraConfig`. Par ordre de priorité : `configOverride` (valider un objet en mémoire), puis `configPath` (charger un fichier explicite), puis une recherche depuis `cwd` dans l'[ordre de découverte](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#ordre-de-découverte). Un `glossary` donné comme chemin de fichier est lu et validé ici, donc le code en aval voit toujours un glossaire en mémoire : une table de version 1 du terme source vers sa traduction, ou une définition de version 2.

```ts title="Signature"
function loadConfig(
  options?: LoadConfigOptions,
): Promise<VerbatraConfig>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory the search starts from, and the base a relative `configPath` resolves against. Defaults to the process working directory. A flow given the loaded config without a `cwd` resolves its paths against the project root resolveProjectRoot describes, except for a `configOverride` config, whose flows fall back to the process working directory. |
| `configOverride` | `unknown` | no | A config object to validate directly instead of reading any file. Takes precedence over `configPath` and over searching. Useful for embedding verbatra in a tool that already holds the configuration in memory. |
| `configPath` | `string` | no | An explicit config file to load, bypassing the search. A missing file is an error rather than a fallback to search. |
| `fs` | `SdkFs` | no | File-system port used to read the glossary file. Defaults to the real file system. |
| `fresh` | `boolean` | no | Re-evaluate a JavaScript or TypeScript config file instead of reusing what an earlier load in the same process evaluated. A `.ts` config is re-evaluated together with the modules it imports; a `.js` or `.cjs` config is re-evaluated alone, so a module it imports or requires keeps its first evaluation until the process restarts. Without it, a process that loads the config twice keeps the first result of a `verbatra.config.ts`, `.js`, or `.cjs` file even after the file changed. A long-running process that reloads the config after an edit sets it. JSON, YAML, and `package.json` configs are always read afresh. Defaults to `false`. |

**Renvoie :** `VerbatraConfig`

**Lève :** [`CONFIG_NOT_FOUND`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_not_found), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid)

**Exemple :** [Une config sans fichier](https://verbatra.kreitz-webdev.de/fr/docs/programmatic-api.md#une-config-sans-fichier)

Voir [Le fichier de configuration](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md) pour le schéma. `fs` est le port de système de fichiers par lequel un fichier de glossaire est lu, comme décrit dans [Le point d'injection de dépendances](https://verbatra.kreitz-webdev.de/fr/docs/sdk.md#le-point-dinjection-de-dépendances).

### loadConfigWithMeta [#loadconfigwithmeta]

<AvailableFrom version="0.5.0" />

Le même chargement, plus la provenance : renvoie `{ config, source, glossary }`, où `source` dit si la config vient d'une recherche, d'un chemin explicite ou d'une surcharge en mémoire (avec le `filepath` absolu quand il y en a un), et `glossary` note si le glossaire était absent, inline ou résolu depuis un fichier. Utilise-le quand tu dois afficher d'où vient la config.

```ts title="Signature"
function loadConfigWithMeta(
  options?: LoadConfigOptions,
): Promise<LoadedConfig>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory the search starts from, and the base a relative `configPath` resolves against. Defaults to the process working directory. A flow given the loaded config without a `cwd` resolves its paths against the project root resolveProjectRoot describes, except for a `configOverride` config, whose flows fall back to the process working directory. |
| `configOverride` | `unknown` | no | A config object to validate directly instead of reading any file. Takes precedence over `configPath` and over searching. Useful for embedding verbatra in a tool that already holds the configuration in memory. |
| `configPath` | `string` | no | An explicit config file to load, bypassing the search. A missing file is an error rather than a fallback to search. |
| `fs` | `SdkFs` | no | File-system port used to read the glossary file. Defaults to the real file system. |
| `fresh` | `boolean` | no | Re-evaluate a JavaScript or TypeScript config file instead of reusing what an earlier load in the same process evaluated. A `.ts` config is re-evaluated together with the modules it imports; a `.js` or `.cjs` config is re-evaluated alone, so a module it imports or requires keeps its first evaluation until the process restarts. Without it, a process that loads the config twice keeps the first result of a `verbatra.config.ts`, `.js`, or `.cjs` file even after the file changed. A long-running process that reloads the config after an edit sets it. JSON, YAML, and `package.json` configs are always read afresh. Defaults to `false`. |

**Renvoie :** `LoadedConfig`

**Lève :** [`CONFIG_NOT_FOUND`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_not_found), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid)

Les deux acceptent `fresh: true` pour réévaluer un fichier de config JavaScript ou TypeScript au lieu de réutiliser ce qu'un chargement précédent dans le même processus a évalué ; un processus de longue durée qui recharge la config après une modification l'active. Les configs JSON, YAML et `package.json` sont toujours relues. <AvailableFrom version="0.12.0" />

### configCandidatePaths [#configcandidatepaths]

<AvailableFrom version="0.12.0" />

Liste chaque fichier depuis lequel `loadConfigWithMeta` pourrait lire une config avec les mêmes `{ cwd?, configPath? }` : seulement le fichier explicite quand `configPath` est défini, sinon chaque emplacement de recherche dans chaque répertoire de la chaîne de recherche, le plus proche d'abord, qu'il existe ou non. Surveille-les, par exemple par date de modification, pour remarquer une config créée, modifiée ou supprimée sans la charger à chaque requête. Le fichier de glossaire n'en fait pas partie ; `loadConfigWithMeta` le nomme dans `glossary`.

```ts title="Signature"
function configCandidatePaths(
  options?: ConfigCandidateOptions,
): readonly string[];
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory the config search starts from. Defaults to the process working directory. |
| `configPath` | `string` | no | An explicit config file, resolved against `cwd`. When set, it is the only candidate. |

**Renvoie :** `readonly string[]`

### resolveProjectRoot [#resolveprojectroot]

<AvailableFrom version="0.12.0" />

Renvoie la racine du projet par rapport à laquelle les flux résolvent les chemins relatifs : le
répertoire du fichier de config trouvé, donc un processus lancé dans un sous-répertoire travaille
sur les fichiers de locale, le fichier de verrouillage et `.verbatra-local/` du projet, ou `cwd`
pour une config issue de `configPath`. Un flux qui reçoit la config renvoyée par `loadConfig` ou
`loadConfigWithMeta` prend déjà cette racine comme `cwd` par défaut. Passe `resolveProjectRoot(loaded.source, cwd)` comme `cwd`
quand tu copies ou reconstruis la config, et à `loadLockFile`, `loadProvenance` et `runStatus`, qui
ne prennent pas de config.

```ts title="Signature"
function resolveProjectRoot(
  source: ConfigSource,
  cwd: string,
): string;
```

**Renvoie :** `string`

## Glossaire [#glossaire]

### readGlossaryFile [#readglossaryfile]

<AvailableFrom version="0.9.0" />

Lit un glossaire stocké dans un fichier directement depuis le disque et le renvoie sous forme de `Glossary` normalisé : `{ version, terms, doNotTranslate }`, où `version` vaut `1` pour une table plate de termes et `2` pour un [glossaire par locale](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#glossary), et où chaque terme porte `source`, un `target` facultatif, `targets`, `forbidden`, `caseSensitive`, et en option `note` et `partOfSpeech`. Son entrée `glossary` est la `GlossaryProvenance` renvoyée par `loadConfigWithMeta`, si bien que le fichier lu est toujours celui que la config nomme ; il n'y a aucun argument de chemin. Utilise-le dans un outil de longue durée qui montre le glossaire tel qu'il est maintenant, pas tel qu'au chargement.

```ts title="Signature"
function readGlossaryFile(
  input: GlossaryFileInput,
  deps?: GlossaryFileDeps,
): Promise<Glossary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `glossary` | `GlossaryProvenance` | yes | Where the loaded config's glossary came from, as reported by loadConfigWithMeta. Only a `file` provenance is accepted; it also carries the path, which is why neither function takes one. |

**Renvoie :** `Glossary`

**Lève :** [`GLOSSARY_NOT_FILE_BACKED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#glossary_not_file_backed), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid)

Lève `GLOSSARY_NOT_FILE_BACKED` quand le glossaire est inline ou absent, et `CONFIG_INVALID` quand le fichier enfreint les [règles du fichier de glossaire](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#glossary) ou déclare une autre version.

<AvailableFrom version="0.12.0" />

Jusqu'à la 0.11, il renvoyait la table plate de termes elle-même.

### updateGlossaryTerm [#updateglossaryterm]

<AvailableFrom version="0.9.0" />

Ajoute, modifie ou supprime exactement un terme d'un glossaire stocké dans un fichier et renvoie le glossaire normalisé tel qu'il est désormais. `translation` est le nouveau texte ou `null` pour supprimer le terme. Le reste du fichier garde son ordre de clés et son indentation, l'écriture est atomique, et tout le cycle lecture, modification, écriture se déroule sous un verrou de glossaire valable pour le projet entier : deux modifications simultanées sont donc sérialisées plutôt qu'entrelacées.

```ts title="Signature"
function updateGlossaryTerm(
  input: UpdateGlossaryTermInput,
  deps?: GlossaryFileDeps,
): Promise<Glossary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | Directory the write lock is taken under. Defaults to the process working directory. |
| `term` | `string` | yes | The source term to add, change, or remove. Must not be blank. |
| `translation` | `string \| null` | no | The translation to store for the term. Without `locale` it is the translation every target locale uses; with `locale` it is that locale's own translation. `null` removes that translation only, and the term goes with it once it has no translation and no forbidden rendering left. Must not be blank. |
| `locale` | `string` | no | The target locale `translation` and `forbidden` apply to. Omit it for every locale. |
| `forbidden` | `readonly string[] \| null` | no | Renderings `locale` must never use for the term, replacing any listed before. `null` or an empty list removes them. Requires `locale`. |
| `note` | `string \| null` | no | Free-text context for the term, or `null` to remove it. |
| `partOfSpeech` | `string \| null` | no | The term's part of speech, free text, or `null` to remove it. |
| `caseSensitive` | `boolean` | no | Whether the term is matched with case. |
| `doNotTranslate` | `boolean` | no | `true` adds the term to the terms kept untranslated in every locale, `false` removes it from them. Cannot be combined with any field but `caseSensitive`. |
| `lockAcquireTimeoutMs` | `number` | no | How long, in milliseconds, to wait for the project's glossary write lock before failing with `LOCK_CONTENDED`. Defaults to ten minutes. |
| `glossary` | `GlossaryProvenance` | yes | Where the loaded config's glossary came from, as reported by loadConfigWithMeta. Only a `file` provenance is accepted; it also carries the path, which is why neither function takes one. |

**Renvoie :** `Glossary`

**Lève :** [`GLOSSARY_NOT_FILE_BACKED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#glossary_not_file_backed), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid), [`LOCK_TIMEOUT_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#lock_timeout_invalid), [`LOCK_CONTENDED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#lock_contended), [`RUN_CANCELLED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#run_cancelled), [`GLOSSARY_UNWRITABLE`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#glossary_unwritable)

<AvailableFrom version="0.12.0" />

Il prend aussi `locale` (`translation` est alors la traduction propre à cette locale et `null` ne supprime qu'elle), `forbidden` (les traductions que `locale` ne doit jamais utiliser ; `null` ou `[]` les supprime), `note`, `partOfSpeech` (chacun `null` pour le supprimer), `caseSensitive` et `doNotTranslate` (`true` ajoute le terme aux termes à ne pas traduire, `false` l'en retire ; il ne se combine pas avec les champs du terme). Un fichier version 1 reste en version 1 tant qu'une modification ne fait que définir ou supprimer une traduction pour toutes les locales ; toute autre modification le réécrit en version 2, chaque terme existant gardant sa traduction comme `target`. `translation: null` sans `locale` ne supprime désormais que la traduction partagée ; le terme lui-même est supprimé dès qu'il n'a plus ni traduction ni traduction interdite, donc aussitôt pour un terme version 1.

Un glossaire inline est refusé avec `GLOSSARY_NOT_FILE_BACKED` plutôt que converti : il vit dans un module de config exécutable. Un champ vide, une modification qui ne fixe aucun champ ou qui mélange `doNotTranslate` avec les champs du terme, des traductions interdites sans locale, une locale invalide, une modification qui laisserait un glossaire invalide et une modification dont le résultat dépasserait la limite de 1 Mio du glossaire sont refusés avec `CONFIG_INVALID` ; une écriture en échec, y compris un verrou d'écriture du glossaire impossible à créer dans un projet en lecture seule ou à libérer après une modification enregistrée, donne `GLOSSARY_UNWRITABLE`, avec l'erreur du système de fichiers comme `cause`. Une modification qui laisse le glossaire tel qu'il est déjà réussit et n'écrit rien.

<AvailableFrom version="0.12.0" />

Il prend aussi `lockAcquireTimeoutMs`, qui borne l'attente du verrou du glossaire avant que l'appel échoue avec `LOCK_CONTENDED` (dix minutes par défaut) ; une borne invalide échoue avec `LOCK_TIMEOUT_INVALID` avant toute lecture.

### glossaryForLocale [#glossaryforlocale]

<AvailableFrom version="0.12.0" />

Résout la partie d'un glossaire qui s'applique à une locale cible : `glossaryForLocale(config.glossary, "de")` renvoie `{ terms, doNotTranslate }`, chaque terme avec le `target` de la locale (sa propre entrée, puis celle de sa langue de base, puis celle partagée), ses traductions `forbidden`, `caseSensitive`, ainsi que sa `note` et son `partOfSpeech`, ou `undefined` quand rien du glossaire ne s'y applique. C'est exactement ce qu'une requête de traduction vers cette locale porte comme [`TranslateRequest.glossary`](https://verbatra.kreitz-webdev.de/fr/docs/sdk/extend.md#fournisseurs-personnalisés), et ce que voient les contrôles de relecture et l'empreinte de cache de cette locale.

```ts title="Signature"
function glossaryForLocale(
  glossary: GlossaryInput | Glossary | undefined,
  locale: string,
): LocaleGlossary | undefined;
```

**Renvoie :** `LocaleGlossary | undefined`

### glossaryHits [#glossaryhits]

<AvailableFrom version="0.12.0" />

`glossaryHits({ glossary, locale, sourceLocale, source })` renvoie les entrées du glossaire qui s'appliquent à un texte source dans une locale cible, sous la forme `{ terms, doNotTranslate }` que renvoie `glossaryForLocale` : chaque terme dont la source apparaît dans `source` comme terme entier, avec la traduction et les rendus interdits auxquels cette locale est tenue, et chaque terme à garder non traduit qui y apparaît. Un terme correspond avec ou sans casse selon ce qu'il indique, la casse étant repliée pour `sourceLocale`. Il utilise la même correspondance qu'une exécution de traduction pour signaler un terme de glossaire manqué, et ne lit rien.

```ts title="Signature"
function glossaryHits(
  input: GlossaryHitsInput,
): LocaleGlossary;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `glossary` | `Glossary \| GlossaryInput \| undefined` | yes | The config's glossary, in either supported shape or already normalized, or `undefined`. |
| `locale` | `string` | yes | The target locale whose translations and forbidden renderings apply. |
| `sourceLocale` | `string` | yes | The locale the text is written in, used to fold case for a term matched without case. |
| `source` | `string` | yes | The source text to look for terms in. |

**Renvoie :** `LocaleGlossary`

### glossaryDraftCheck [#glossarydraftcheck]

<AvailableFrom version="0.12.0" />

`glossaryDraftCheck({ glossary, locale, sourceLocale, source, draft })` vérifie un brouillon de traduction par rapport aux entrées du glossaire que `glossaryHits` trouve dans le texte source, avant que tu l'écrives. Chaque terme revient avec `targetUsed` (si le brouillon contient la traduction imposée ; absent pour un terme qui ne fait qu'interdire des rendus) et `forbiddenUsed` (les rendus interdits que le brouillon utilise et que la source n'utilise pas), et chaque terme à garder non traduit avec `kept`. Ce sont les règles avec lesquelles une exécution de traduction signale `GLOSSARY_TERM_MISSED` et `GLOSSARY_FORBIDDEN_TERM`. Il ne lit rien.

```ts title="Signature"
function glossaryDraftCheck(
  input: GlossaryDraftCheckInput,
): GlossaryDraftCheck;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `glossary` | `Glossary \| GlossaryInput \| undefined` | yes | The config's glossary, in either supported shape or already normalized, or `undefined`. |
| `locale` | `string` | yes | The target locale the draft is written in. |
| `sourceLocale` | `string` | yes | The locale the source text is written in. |
| `source` | `string` | yes | The key's source text. |
| `draft` | `string` | yes | The draft translation to check. |

**Renvoie :** `GlossaryDraftCheck`

### normalizeGlossary [#normalizeglossary]

<AvailableFrom version="0.12.0" />

Convertit un glossaire sous l'une ou l'autre forme, une table plate version 1 ou une définition version 2, en `Glossary` normalisé tel que le renvoie `readGlossaryFile`, avec toutes les valeurs par défaut remplies. Utilise-le pour afficher un glossaire inline de la même façon qu'un glossaire stocké dans un fichier. Il ne revalide pas ; `loadConfig` l'a déjà fait.

```ts title="Signature"
function normalizeGlossary(
  glossary: GlossaryInput | Glossary,
): Glossary;
```

**Renvoie :** `Glossary`

### sharedGlossaryTranslations [#sharedglossarytranslations]

<AvailableFrom version="0.12.0" />

Projette un `Glossary` normalisé sur une table plate de chaque terme doté d'un `target` partagé vers cette traduction, dans l'ordre du glossaire. Les traductions par locale, les traductions interdites et les termes de `doNotTranslate` en sont exclus : utilise-le seulement là où un consommateur ne peut afficher qu'une table plate de termes. Un terme nommé `__proto__` reste une clé propre.

```ts title="Signature"
function sharedGlossaryTranslations(
  glossary: Glossary,
): Readonly<Record<string, string>>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `version` | `1 \| 2` | yes | The format the glossary was written in: `1` for a flat term map, `2` for a GlossaryDefinition. |
| `terms` | `readonly GlossaryTerm[]` | yes | Every term, in the order it was written. |
| `doNotTranslate` | `readonly DoNotTranslateTerm[]` | yes | Every term to keep untranslated, in the order it was written. |

**Renvoie :** `Readonly<Record<string, string>>`

### redactGlossary [#redactglossary]

<AvailableFrom version="0.12.0" />

Fait passer chaque terme source, traduction, traduction interdite, note, catégorie grammaticale et terme de `doNotTranslate` d'un `Glossary` normalisé par `redact` et renvoie `{ glossary, redactedTerms }`, où `redactedTerms` nomme chaque terme dont une valeur a été remplacée, un terme source masqué apparaissant lui-même comme `[REDACTED]`, pour que la liste ne répète jamais un secret. Le serveur MCP et Studio l'utilisent avant qu'un glossaire ne quitte le processus ; utilise-le de la même façon dans ton propre outil.

```ts title="Signature"
function redactGlossary(glossary: Glossary): RedactedGlossary;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `version` | `1 \| 2` | yes | The format the glossary was written in: `1` for a flat term map, `2` for a GlossaryDefinition. |
| `terms` | `readonly GlossaryTerm[]` | yes | Every term, in the order it was written. |
| `doNotTranslate` | `readonly DoNotTranslateTerm[]` | yes | Every term to keep untranslated, in the order it was written. |

**Renvoie :** `RedactedGlossary`

### readCurrentGlossary [#readcurrentglossary]

<AvailableFrom version="0.12.0" />

Lit le glossaire que nomme une configuration chargée tel qu'il est maintenant : `readCurrentGlossary({ loaded })`, où `loaded` est ce que renvoie `loadConfigWithMeta`. Un glossaire stocké dans un fichier est relu depuis le disque, un glossaire inline vient de la config, et dans les deux cas le résultat est le `Glossary` normalisé, ou `undefined` quand la config n'en déclare aucun. Pour voir à quoi une locale cible est tenue, passe le résultat à `glossaryForLocale`.

```ts title="Signature"
function readCurrentGlossary(
  input: ReadCurrentGlossaryInput,
  deps?: GlossaryFileDeps,
): Promise<Glossary | undefined>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `loaded` | `GlossaryConfig` | yes | The loaded config, as loadConfigWithMeta returns it. |

**Renvoie :** `Glossary | undefined`

**Lève :** [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid)

### editConfiguredGlossaryTerm [#editconfiguredglossaryterm]

<AvailableFrom version="0.12.0" />

`updateGlossaryTerm` pour un outil qui détient une configuration chargée : prend `loaded` à la place de `glossary` avec les mêmes champs de modification, traite un champ laissé à `undefined` comme absent et vérifie d'abord `locale` par rapport aux locales cibles configurées ; si ce n'en est pas une, il échoue avec `UNKNOWN_LOCALE` et n'écrit rien. Le serveur MCP et Studio écrivent le glossaire par son intermédiaire.

```ts title="Signature"
function editConfiguredGlossaryTerm(
  input: EditConfiguredGlossaryTermInput,
  deps?: GlossaryFileDeps,
): Promise<Glossary>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `loaded` | `GlossaryConfig` | yes | The loaded config, as loadConfigWithMeta returns it. |
| `term` | `string` | yes | The source term to add, change, or remove. Must not be blank. |
| `cwd` | `string` | no | Directory the write lock is taken under. Defaults to the process working directory. |
| `translation` | `string \| null` | no | The translation to store for the term. Without `locale` it is the translation every target locale uses; with `locale` it is that locale's own translation. `null` removes that translation only, and the term goes with it once it has no translation and no forbidden rendering left. Must not be blank. |
| `locale` | `string` | no | The target locale `translation` and `forbidden` apply to. Omit it for every locale. |
| `forbidden` | `readonly string[] \| null` | no | Renderings `locale` must never use for the term, replacing any listed before. `null` or an empty list removes them. Requires `locale`. |
| `note` | `string \| null` | no | Free-text context for the term, or `null` to remove it. |
| `partOfSpeech` | `string \| null` | no | The term's part of speech, free text, or `null` to remove it. |
| `caseSensitive` | `boolean` | no | Whether the term is matched with case. |
| `doNotTranslate` | `boolean` | no | `true` adds the term to the terms kept untranslated in every locale, `false` removes it from them. Cannot be combined with any field but `caseSensitive`. |
| `lockAcquireTimeoutMs` | `number` | no | How long, in milliseconds, to wait for the project's glossary write lock before failing with `LOCK_CONTENDED`. Defaults to ten minutes. |

**Renvoie :** `Glossary`

**Lève :** [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#unknown_locale), [`GLOSSARY_NOT_FILE_BACKED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#glossary_not_file_backed), [`CONFIG_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#config_invalid), [`LOCK_TIMEOUT_INVALID`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#lock_timeout_invalid), [`LOCK_CONTENDED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#lock_contended), [`RUN_CANCELLED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#run_cancelled), [`GLOSSARY_UNWRITABLE`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#glossary_unwritable)

## Écriture, détection et mode 100 % humain [#écriture-détection-et-mode-100--humain]

### defineConfig [#defineconfig]

Une fonction identité pour un `verbatra.config.ts` typé : elle renvoie son argument inchangé, pour l'inférence de types et l'autocomplétion de l'éditeur, y compris les IDs de modèles connus du fournisseur sélectionné (à l'écriture seulement ; à l'exécution, toute chaîne non vide passe). Chaque fournisseur sauf `opencode`, `openai-compatible`, `libretranslate` et `none` a aussi une surcharge qui prend `AuthoringConfigFor<"<id>">`, comme `AuthoringConfigFor<"anthropic">`, et restreint le bloc `provider` aux options de ce fournisseur ; ces quatre-là utilisent le repli avec `AuthoringConfig` ci-dessous.

```ts title="Signature"
function defineConfig(config: AuthoringConfigFor<"anthropic">): VerbatraConfigInput;
function defineConfig(config: AuthoringConfigFor<"openai">): VerbatraConfigInput;
function defineConfig(config: AuthoringConfigFor<"gemini">): VerbatraConfigInput;
function defineConfig(config: AuthoringConfigFor<"deepl">): VerbatraConfigInput;
function defineConfig(config: AuthoringConfigFor<"google-translate">): VerbatraConfigInput;
function defineConfig(config: AuthoringConfig): VerbatraConfigInput;
```

**Renvoie :** `VerbatraConfigInput`

**Exemple :** [Ajoute un fichier source et une config](https://verbatra.kreitz-webdev.de/fr/docs/sdk-quickstart.md#ajoute-un-fichier-source-et-une-config)

### verbatraConfigSchema [#verbatraconfigschema]

Le schéma zod avec lequel `loadConfig` valide, exporté pour que ton propre outillage puisse valider un objet de config de la même façon que le SDK. Les clés de premier niveau inconnues sont rejetées, donc un secret égaré ne peut pas se cacher dans la config, sauf `$schema` : une chaîne optionnelle, ignorée à l'exécution, avec laquelle une config JSON ou YAML pointe un éditeur vers le `@verbatra/sdk/config-schema.json` du paquet.

```ts title="Signature"
const verbatraConfigSchema: z.ZodObject<{ ... }, z.core.$strict>;
```

Son bloc `rates` est une `RateCard`, la liste de prix qui exprime une [estimation](https://verbatra.kreitz-webdev.de/fr/docs/estimating-cost.md) en argent :

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `asOf` | `string` | yes | The date the rates were read, written as `YYYY-MM-DD`; printed beside every priced estimate. |
| `currency` | `string` | yes | The three-letter uppercase currency code the rates are written in, such as `USD` or `EUR`. |
| `table` | `Record<string, union>` | yes | The rate entries by rate key: a token rate or a character rate, never both. |

### scaffoldingMetadata [#scaffoldingmetadata]

<AvailableFrom version="0.4.0" />

Métadonnées en lecture seule dont la commande `init` de la CLI dérive ses questions : `providerEnv` (id de fournisseur vers la variable d'environnement où sa clé est lue), `scaffoldModels` (un modèle d'échafaudage par défaut par fournisseur LLM), `providerTokenLimitKeys` (la clé d'option sous laquelle chaque fournisseur LLM reçoit sa limite de tokens de sortie) et `supportedFormats` (l'ensemble fermé des ids de format). Lis la clé de limite de tokens dans `providerTokenLimitKeys` plutôt que d'en supposer une, car les clés diffèrent ([fournisseurs](https://verbatra.kreitz-webdev.de/fr/docs/providers.md)) ; DeepL et Google Cloud Translation n'ont pas d'entrée car ils ne prennent aucune limite de tokens. Le type `ScaffoldableProviderId` vaut `Exclude<ProviderId, "openai-compatible" | "libretranslate" | "none">` : chaque fournisseur qui n'a besoin que de son id. `openai-compatible` et `libretranslate` ont chacun besoin d'une `baseUrl` que toi seul connais et n'ont pas de variable d'environnement requise, et `none` n'appelle aucun fournisseur.

```ts title="Signature"
const scaffoldingMetadata: {
  readonly providerEnv: { ... };
  readonly scaffoldModels: { ... };
  readonly providerTokenLimitKeys: { ... };
  readonly supportedFormats: readonly [...];
  readonly humanOnlyProviderId: "none";
  readonly openAiCompatibleKeyEnv: "OPENAI_COMPATIBLE_API_KEY";
  readonly libreTranslateKeyEnv: "LIBRETRANSLATE_API_KEY";
  readonly configSearchPlaces: readonly string[];
};
```

`scaffoldingMetadata.humanOnlyProviderId` vaut `"none"`, l'id qui désactive la traduction automatique. Il n'a pas d'entrée dans `providerEnv`, puisqu'il ne lit aucune clé.

<AvailableFrom version="0.12.0" />

`scaffoldingMetadata.libreTranslateKeyEnv` vaut `"LIBRETRANSLATE_API_KEY"`, la variable dans laquelle un fournisseur `libretranslate` lit sa clé. Elle est facultative : un serveur démarré sans `--api-keys` n'en demande aucune, donc un générateur devrait la laisser non définie.

`scaffoldingMetadata.openAiCompatibleKeyEnv` vaut `"OPENAI_COMPATIBLE_API_KEY"`, la variable que lit un fournisseur `openai-compatible` quand ses options ne nomment aucun `apiKeyEnvVar`. `scaffoldingMetadata.configSearchPlaces` liste chaque nom de fichier où `loadConfig` cherche une config, dans l'ordre où il les vérifie ; un générateur qui écrit `verbatra.config.ts` devrait refuser quand un autre d'entre eux existe déjà, puisque le premier trouvé l'emporte.

### detectProject [#detectproject]

<AvailableFrom version="0.12.0" />

Détecte le format et l'organisation des fichiers de locale d'un projet à partir de ses fichiers, comme le fait `verbatra init` avant d'écrire une config. Il n'écrit rien et n'appelle aucun fournisseur. Il parcourt le répertoire (en sautant les répertoires cachés, `node_modules` et les sorties de build, dans une profondeur et un nombre d'entrées bornés) à la recherche de fichiers revendiqués par un adaptateur enregistré, trouve dans chacun le segment de chemin qui écrit une locale, et garde le motif de fichier qui couvre le plus de locales. Le format est celui dont le `canHandle` de l'adaptateur revendique chaque fichier trouvé compte tenu de son contenu ; pour le JSON, où tous les adaptateurs JSON le font, une seule bibliothèque i18n correspondante dans `package.json` tranche.

```ts title="Signature"
function detectProject(
  input?: DetectProjectInput,
  deps?: DetectProjectDeps,
): Promise<ProjectDetection>;
```

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `cwd` | `string` | no | The directory to scan. Defaults to the process working directory. |
| `format` | `FormatId` | no | A format already chosen. Only files this format's adapter claims are considered. |
| `pattern` | `string` | no | A file pattern already chosen, containing the `{locale}` token. Only files matching it are considered, and no other layout is searched for. |
| `sourceLocale` | `string` | no | A source locale already chosen. It is reported as the layout's source locale unchanged. |

**Renvoie :** `ProjectDetection`

```ts title="Exemple"
import { detectProject } from "@verbatra/sdk";

const detection = await detectProject({ cwd: "/path/to/project" });
if (detection.ambiguities.length > 0) {
  // several formats or file patterns fit: choose one of detection.ambiguities[0].candidates
}
const format = detection.format?.id;          // for example "yaml"
const pattern = detection.layout?.pattern;    // for example "config/locales/{locale}.yml"
```

Le résultat porte `format` (avec `from` : `input`, `files` ou `dependencies`), `layout` (`pattern`, `localeStyle`, `locales`, `sourceLocale`, `files`, `unqualifiedSourceFile`), `ambiguities` (chacune avec un `subject` valant `format` ou `layout` et ses `candidates`), une `confidence` valant `high`, `medium`, `low` ou `none`, et `reasons`, une phrase par décision. Les égalités sont signalées comme ambiguïtés, jamais devinées. Les entrées optionnelles `format`, `pattern` et `sourceLocale` restreignent la recherche, et `deps.fs` et `deps.adapterRegistry` remplacent le système de fichiers et les adaptateurs : les fichiers d'un adaptateur tiers sont donc détectés aussi. Un fichier manquant, illisible ou malformé ne lève jamais d'erreur ; le rapport est seulement plus mince. `layout.unqualifiedSourceFile` nomme un fichier à côté du layout avec des chaînes sous aucun nom de locale, comme `messages.properties` ou un modèle gettext `.pot` ; la locale source reste alors ouverte, puisque la source est lue depuis le fichier que le motif nomme pour elle.

### isMachineTranslationEnabled [#ismachinetranslationenabled]

<AvailableFrom version="0.12.0" />

Renvoie `false` exactement quand la configuration fixe `provider: { id: "none" }`, le mode [100 % humain](https://verbatra.kreitz-webdev.de/fr/docs/human-only-workflow.md) dans lequel aucun fournisseur n'est jamais construit et aucune clé d'API n'est lue. Une interface qui propose des actions dépensant auprès du fournisseur le lit pour les omettre entièrement ; c'est ainsi que Studio et le serveur MCP refusent la dépense même avec `--allow-spend`.

```ts title="Signature"
function isMachineTranslationEnabled(
  config: Pick<VerbatraConfig, "provider">,
): boolean;
```

**Renvoie :** `boolean`

### assertMachineTranslationEnabled [#assertmachinetranslationenabled]

<AvailableFrom version="0.12.0" />

Prend la configuration et une courte phrase nommant l'action, et lève une `SdkError` `MACHINE_TRANSLATION_DISABLED` sous `provider: { id: "none" }`. Appelle-le avant d'envelopper `translate` dans une action explicite « traduire tout ce qui est en attente », pour que l'action échoue comme `retranslateEntry` au lieu de remplir en silence depuis la seule mémoire de traduction.

```ts title="Signature"
function assertMachineTranslationEnabled(
  config: Pick<VerbatraConfig, "provider">,
  action: string,
): void;
```

**Renvoie :** `void`

**Lève :** [`MACHINE_TRANSLATION_DISABLED`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#machine_translation_disabled)

### assertTargetLocale [#asserttargetlocale]

<AvailableFrom version="0.12.0" />

Prend la configuration et une locale, et lève une `SdkError` `UNKNOWN_LOCALE` quand la locale ne fait pas partie des `targetLocales` configurées, avec le même message que chaque fonction du SDK qui accepte un filtre `locales`. Appelle-le dans une surface qui prend elle-même une seule locale, comme le fait `glossary.get` du serveur MCP, pour qu'une mauvaise locale échoue exactement comme dans le SDK.

```ts title="Signature"
function assertTargetLocale(
  config: Pick<VerbatraConfig, "targetLocales">,
  locale: string,
): void;
```

**Renvoie :** `void`

**Lève :** [`UNKNOWN_LOCALE`](https://verbatra.kreitz-webdev.de/fr/docs/error-codes.md#unknown_locale)
