---
title: "verbatra init"
description: "Crée une config verbatra et un exemple de .env pour ce projet, détectés depuis tes fichiers de locale, en interactif ou entièrement sans surveillance."
type: "reference"
---
# verbatra init

Crée une config verbatra et un exemple de .env pour ce projet, détectés depuis tes fichiers de locale, en interactif ou entièrement sans surveillance.

Échafaude un projet : `init` écrit un `verbatra.config.ts`, un `.env.example` qui nomme la variable de clé d'API de ton fournisseur (jamais une valeur de clé), et les entrées de `.gitignore` pour `.env`, `.env.local`, `.verbatra-local/` et `verbatra.cache.json`. Il lit d'abord les fichiers de locale du projet, donc en général tu n'as qu'à lui indiquer le fournisseur.

## Synopsis [#synopsis]

```bash
verbatra init [flags]
```

## Exemples [#exemples]

```bash
# prompt for anything not passed or detected
verbatra init --provider gemini

# fully unattended, one JSON document on stdout
verbatra init --provider gemini --yes --json

# choose the format and pattern yourself
verbatra init --provider deepl --format yaml --path "config/locales/{locale}.yml" --yes

# a local server that needs no key
verbatra init --provider openai-compatible --base-url http://localhost:11434/v1 --model llama3.1 --yes

# a self-hosted LibreTranslate server, no language model
verbatra init --provider libretranslate --base-url http://localhost:5000 --yes

# human-only: no provider, no API key
verbatra init --provider none --yes

# also set the project up for coding agents
verbatra init --provider gemini --yes --agent

# wire Cursor and VS Code, and only show what would change
verbatra init --agent --client cursor,vscode --dry-run
```

## Options [#options]

| Option | Argument | Défaut | Effet |
| --- | --- | --- | --- |
| `--provider` | `<id>` | aucun (requis, sauf s'il est demandé) | fournisseur pour lequel générer la config : `anthropic`, `openai`, `gemini`, `deepl`, `google-translate`, `opencode`, `openai-compatible`, `libretranslate` ou `none` |
| `--format` | `<id>` | détecté, sinon `i18next-json` | le format des fichiers de locale, l'un des ids de [Formats](https://verbatra.kreitz-webdev.de/fr/docs/formats.md) |
| `--source` | `<locale>` | détectée, sinon `en` | la locale source dans laquelle tes chaînes sont écrites |
| `--targets` | `<locales>` | détectées, sinon `de` | locales cibles vers lesquelles traduire, séparées par des virgules |
| `--path` | `<pattern>` | détecté, sinon la structure habituelle du format ([Détection](#détection)) | motif des fichiers de locale ; doit contenir le jeton `{locale}` |
| `--model` | `<name>` | le défaut de l'échafaudage | le modèle ; requis pour `openai-compatible`, optionnel pour `anthropic`, `openai`, `gemini` et `opencode` |
| `--base-url` | `<url>` | aucun | l'URL du serveur ; `openai-compatible` et `libretranslate` uniquement, et requis dans ce cas |
| `--api-key-env-var` | `<name>` | `OPENAI_COMPATIBLE_API_KEY` | la variable dans laquelle `openai-compatible` lit sa clé |
| `--yes` | aucun | désactivé | ne pose jamais de question ; prend le défaut pour tout ce qui n'est ni passé ni détecté |
| `--force` | aucun | désactivé | écrase un `verbatra.config.ts` existant dont le contenu diffère |
| `--agent` | aucun | désactivé | écrit en plus la section pour les agents de code dans `AGENTS.md` ou `CLAUDE.md` et le serveur MCP verbatra dans la config de projet de chaque client détecté ([Préparer les agents de code](#préparer-les-agents-de-code)) |
| `--client` | `<ids>` | détectés | clients séparés par des virgules que `--agent` configure à la place des clients détectés : `claude`, `cursor`, `vscode`, `codex`, `gemini` ou `all` ; requiert `--agent` |
| `--dry-run` | aucun | désactivé | signale chaque fichier que `init` écrirait ou modifierait, et n'écrit rien ([Exécution à blanc](#exécution-à-blanc)) |

Accepte aussi les [options globales](https://verbatra.kreitz-webdev.de/fr/docs/cli.md#options-globales) `--cwd` et `--json`, mais pas `--config`. Ici `--cwd` est le répertoire à analyser et dans lequel écrire, et il doit déjà exister. `--json` ne pose jamais de question.

## Comportement [#comportement]

### Questions [#questions]

<AvailableFrom version="0.12.0" />

Une option l'emporte toujours. Ce que tu omets est détecté depuis le projet, puis demandé quand stdin est un terminal et que ni `--yes` ni `--json` n'est passé, et sinon pris à sa valeur par défaut uniquement avec `--yes`. Entrée accepte la valeur suggérée. Une option avec une valeur vide, comme `--targets ''`, est une erreur d'utilisation (`INVALID_OPTION`), jamais une demande de valeur par défaut. Si stdin se termine pendant une question (Ctrl-D), `init` sort avec `2` et `MISSING_OPTIONS`.

Chaque réponse est vérifiée dès que tu la donnes. Une réponse invalide est expliquée sur stderr et redemandée, jusqu'à trois fois, en gardant tes réponses précédentes ; une troisième réponse invalide arrête `init` avec le code d'erreur de cette réponse (comme `INVALID_LOCALE`), nomme l'option à passer à la place et n'écrit rien.

### Détection [#détection]

`init` cherche dans le répertoire les fichiers qu'un adaptateur de format revendique, en ignorant les répertoires cachés, `node_modules` et les sorties de build, et trouve la partie de chaque chemin qui écrit une locale, comme `de.json`, `messages_pt_BR.properties`, `de.lproj/` ou le `values-de/` d'Android. Le motif de fichiers qui couvre le plus de locales l'emporte, et il fournit :

- `format` : le seul format dont l'adaptateur lit chaque fichier trouvé. Tous les adaptateurs JSON lisent `.json`, donc pour des fichiers JSON c'est une seule dépendance correspondante dans `package.json` (`i18next`, `vue-i18n`, `next-intl` ou `@ngx-translate/core`) qui tranche.
- `files.pattern` et `files.localeStyle` : `posix` quand les fichiers écrivent `pt_BR`, `android` pour les répertoires `values-*`, `literal` sinon.
- `sourceLocale` : la langue source d'un catalogue `.xcstrings`, sinon `en` ou l'unique locale `en-*` trouvée, sinon la seule locale trouvée.
- `targetLocales` : toutes les autres locales trouvées.

Un fichier à côté des fichiers de locale qui contient des chaînes sous aucun nom de locale, comme `messages.properties`, `Strings.resx` ou un `app.pot` gettext, est signalé comme `unqualifiedSourceFile`. verbatra ne peut pas lire la source dans un tel fichier, donc `init` ne devine pas la locale source : passe `--source`, même avec `--yes`, et les étapes suivantes nomment le fichier vers lequel renommer ou copier le fichier de base.

Sans aucun fichier de locale, seules les dépendances décident du format, et le motif suit la structure habituelle du format, celle indiquée pour chaque format dans [Choisis ta stack](https://verbatra.kreitz-webdev.de/fr/docs/pick-your-stack.md).

Un catalogue `apple-xcstrings` est un seul fichier partagé par toutes les locales, et verbatra ne le crée jamais : crée-le d'abord dans Xcode. `--format`, `--path` et `--source` restreignent la détection au lieu d'être remplacés par elle, donc `--format yaml` ne regarde que les fichiers YAML.

`init` ne tranche jamais entre des égaux. Plusieurs formats qui lisent les fichiers (du JSON simple sans dépendance i18n) terminent avec `2` et `FORMAT_AMBIGUOUS`, et plusieurs motifs à égalité (un fichier par namespace) terminent avec `2` et `LAYOUT_AMBIGUOUS`. Les deux listent les candidats ; passe `--format` ou `--path` pour choisir. Dans un terminal, il pose la question à la place.

### Exécutions sans surveillance [#exécutions-sans-surveillance]

Sans terminal, ou avec `--json`, `init` ne pose jamais de question. Une valeur ni passée, ni détectée, ni remplie par `--yes` est une erreur : `init` termine avec `2` et `MISSING_OPTIONS` et nomme d'un coup toutes les options manquantes. Une ambiguïté ou une option invalide liste aussi les options encore manquantes, donc une seule exécution dit à un agent tout ce qu'il doit passer. `--provider` n'a pas de défaut, pas plus que `--base-url` et `--model` pour `openai-compatible` ou `--base-url` pour `libretranslate`. Voici la commande qu'un agent exécute :

```bash
npx @verbatra/cli init --provider gemini --yes --json
```

### Sortie JSON [#sortie-json]

Schéma : [`init-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/init-envelope.json) valide l'enveloppe entière ; [Schémas](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#schémas) liste les autres.

Avec `--json`, stdout porte exactement une [enveloppe](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#sortie-json). Son `result` :

```ts
interface InitResult {
  configPath: string;                  // absolute path of verbatra.config.ts, or of the config --agent kept
  files: { path: string; action: "created" | "overwritten" | "updated" | "unchanged" }[];
  dryRun: boolean;                     // true under --dry-run: files holds the planned actions
  config: {                            // the config that was validated and written
    sourceLocale: string;
    targetLocales: string[];
    format: string;
    files: { pattern: string; localeStyle?: "posix" | "android" };
    provider: { id: string; options?: Record<string, unknown> };
    sensitiveData?: { mode: "warn" };
  } | null;
  sources: {                           // where each value came from
    provider: "flag" | "prompt";
    format: "flag" | "prompt" | "files" | "dependencies" | "default";
    pattern: "flag" | "prompt" | "detected" | "default";
    sourceLocale: "flag" | "prompt" | "detected" | "default";
    targetLocales: "flag" | "prompt" | "detected" | "default";
  } | null;
  apiKeyEnvVar: string | null;         // the variable to set; null for provider none
  detection: {
    format: { id: string; from: "input" | "files" | "dependencies" } | null;
    layout: {
      pattern: string;
      localeStyle: "literal" | "posix" | "android";
      locales: string[];
      sourceLocale: string | null;
      unqualifiedSourceFile: string | null;
      files: string[];
    } | null;
    ambiguities: { subject: "format" | "layout"; candidates: string[] }[];
    confidence: "high" | "medium" | "low" | "none";
    reasons: string[];                 // one sentence per decision or doubt
  } | null;
  agent: {                             // null without --agent
    instructionsFile: "AGENTS.md" | "CLAUDE.md";
    mcpServer: "added" | "present" | "differs" | "skipped" | null; // Claude Code; null when not wired
    configKept: boolean;               // true when --agent kept an existing config
    clients: {
      id: "claude" | "cursor" | "vscode" | "codex" | "gemini";
      file: string;                    // the client's config file, such as .mcp.json
      server: "added" | "present" | "differs" | "skipped";
      reason: "plugin" | "symlink" | null; // why the client was skipped
      selectedBy: "flag" | "markers" | "default";
      markers: string[];               // the client's marker files found in the project
    }[];
  } | null;
  nextSteps: { description: string; command: string | null }[];
}
```

`confidence` vaut `high` quand les fichiers seuls ont tout décidé, `medium` quand une convention ou une dépendance a comblé un manque (comme prendre `en` comme source) ou qu'un manque est resté ouvert, `low` quand aucun fichier de locale n'a appuyé le format, et `none` quand rien n'a été détecté. Un `default` dans `sources` est la valeur à revérifier. `nextSteps` se termine par les commandes exactes à lancer ensuite.

Une enveloppe d'erreur pour `FORMAT_AMBIGUOUS`, `LAYOUT_AMBIGUOUS`, `INVALID_PROVIDER` ou `INVALID_FORMAT` porte aussi `candidates`, les valeurs parmi lesquelles choisir. Toute erreur d'utilisation qui laisse des options sans réponse porte `missing`, qui les nomme, comme `"--source <locale>"`.

### Fournisseurs [#fournisseurs]

<AvailableFrom version="0.12.0" />

- `--provider none` génère une config [100 % humaine](https://verbatra.kreitz-webdev.de/fr/docs/human-only-workflow.md) sans `options` et n'écrit aucun `.env.example`, puisqu'aucune clé d'API n'est jamais lue.
- `--provider openai-compatible` génère la config d'un serveur local ou auto-hébergé à partir de `--base-url` et `--model`, avec `maxOutputTokens: 4096`. Sa clé est facultative : un serveur qui n'en a pas besoin laisse `OPENAI_COMPATIBLE_API_KEY` vide, et `--api-key-env-var` nomme une autre variable, en majuscules comme `LLM_API_KEY`. Une valeur refusée n'est jamais répétée, au cas où ce serait la clé elle-même.
- `--provider libretranslate` génère la config d'un serveur [LibreTranslate](https://verbatra.kreitz-webdev.de/fr/docs/providers.md#libretranslate) auto-hébergé à partir de `--base-url` seul, par exemple `http://localhost:5000`, et refuse `--model` et `--api-key-env-var`. `.env.example` nomme `LIBRETRANSLATE_API_KEY` pour un serveur démarré avec `--api-keys`.

`init` écrit le nom d'une variable dans la config et dans `.env.example`, jamais une valeur, et refuse une URL de base avec identifiants, query string ou fragment (`https://user:key@host`, `https://host/v1?api-key=...`), par laquelle une clé pourrait finir dans la config versionnée.

### Fichiers existants [#fichiers-existants]

Relancer `init` avec les mêmes réponses ne change rien et réussit. Un `verbatra.config.ts` au contenu différent est refusé avec `CONFIG_EXISTS` sauf si tu passes `--force`, et ce refus passe avant toute question ou autre erreur. Une autre config verbatra dans le répertoire (un `.verbatrarc.json` ou une propriété `verbatra` dans `package.json`) est refusée même avec `--force`, car elle serait lue en premier. Quand `init` refuse, rien n'est écrit. Si une config d'un répertoire parent couvre aussi celui-ci, `init` avertit sur stderr (dry run compris) : le nouveau `verbatra.config.ts` la remplace ici.

Un répertoire où `init` ne peut pas écrire est refusé avec `INIT_UNWRITABLE`, qui nomme le fichier et ceux déjà écrits. Un `verbatra.config.ts`, `.env.example` ou `.gitignore` qui est un lien symbolique sortant du projet, ou ne menant nulle part, est refusé avec `INIT_UNWRITABLE` avant toute écriture. Un `.env.example` existant est conservé ; s'il ne nomme pas encore la variable de clé, cette ligne est ajoutée, et avec `--force` un en-tête écrit par `init` lui-même est réécrit pour le nouveau fournisseur. `.gitignore` ne reçoit que les entrées qui lui manquent.

### Exécution à blanc [#exécution-à-blanc]

<AvailableFrom version="0.12.0" />

`--dry-run` passe par chaque vérification et chaque refus d'une vraie exécution sauf une écriture qui échoue, comme dans un répertoire en lecture seule, affiche `would create`, `would update`, `would overwrite` ou `unchanged` pour chaque fichier et n'écrit rien. Le résultat JSON liste les actions prévues et met `dryRun` à `true`.

### Préparer les agents de code [#préparer-les-agents-de-code]

<AvailableFrom version="0.12.0" />

`--agent` prépare aussi le projet pour les agents de code. Il n'écrit aucune valeur de clé, n'écrit jamais à travers un lien hors du projet, et ajoute :

- **Le fichier d'instructions.** Une section verbatra entre les marqueurs `<!-- verbatra:start -->` et `<!-- verbatra:end -->`, mot pour mot l'extrait de [Parler de verbatra à ton agent](https://verbatra.kreitz-webdev.de/fr/docs/agent-recipes.md#parler-de-verbatra-à-ton-agent). Elle va dans `AGENTS.md`, ou dans `CLAUDE.md` quand c'est le seul fichier d'instructions ; si les deux existent, `AGENTS.md` l'emporte. Dans un fichier qui contient déjà la section, le texte entre les marqueurs est remplacé par le texte actuel et signalé `updated`, ou `unchanged` s'il correspond déjà.
- **La config MCP de chaque client.** L'entrée du serveur `verbatra` de [Connecter un client MCP](https://verbatra.kreitz-webdev.de/fr/docs/connect-an-mcp-client.md), `npx -y @verbatra/mcp` sans `--allow-spend` ni `VERBATRA_MCP_ALLOW_SPEND`, donc les outils qui dépensent restent masqués. `@verbatra/cli` exporte ces entrées sous le nom `AGENT_CLIENT_CONFIGS`.

| Client | `--client` | Fichier | Détecté par |
| --- | --- | --- | --- |
| Claude Code | `claude` | `.mcp.json` | `CLAUDE.md`, `.claude/`, `.mcp.json` |
| Cursor | `cursor` | `.cursor/mcp.json` | `.cursor/`, `.cursorrules` |
| VS Code | `vscode` | `.vscode/mcp.json`, sous `servers` | `.vscode/mcp.json` |
| Codex | `codex` | `.codex/config.toml`, en `[mcp_servers.verbatra]` | `.codex/` |
| Gemini CLI | `gemini` | `.gemini/settings.json` | `.gemini/`, `GEMINI.md` |

`init` configure chaque client qu'il détecte, et seulement Claude Code quand il ne trouve aucun marqueur. `AGENTS.md` choisit le fichier d'instructions, pas un client. Un dossier `.vscode` sans `mcp.json` n'est pas configuré : une étape suivante nomme la commande qui le fait. Gemini CLI lit `GEMINI.md` : si ses paramètres ou `GEMINI.md` ne chargent pas le fichier d'instructions, une étape suivante dit comment. Un client détecté dont le chemin de config passe par un lien symbolique est sauté avec la raison `symlink` et une étape suivante. `--client` remplace la détection ; un id inconnu, une liste vide ou `--client` sans `--agent` sort avec `2` et `INVALID_OPTION`, avec les candidats.

Rien n'est touché hors des marqueurs, et les autres serveurs et clés gardent leurs octets, leur indentation et leurs fins de ligne quand le fichier a une entrée par ligne ; sinon il est réécrit avec le même contenu. La table Codex est ajoutée à la fin. Un serveur `verbatra` existant n'est jamais touché : le fichier est signalé `unchanged`, et le `server` du client vaut `present` quand l'entrée correspond à l'échafaudage, ou `differs` sinon, ce qui ajoute aussi une note dans `nextSteps`.

Quand `.claude/settings.json` ou `.claude/settings.local.json` active le plugin verbatra pour Claude Code, `init` saute `.mcp.json` : Claude Code est signalé `skipped` avec la raison `plugin` et une étape suivante, et une entrée existante n'est jamais supprimée. Un fichier de réglages derrière un lien symbolique est ignoré.

Dans un projet qui a déjà une config, `init --agent` n'écrit que les fichiers d'agents, garde la config, affiche `kept verbatra.config.ts`, ne pose jamais de question et ne détecte rien. Le résultat JSON liste la config comme `unchanged`, met `agent.configKept` à `true` et porte `null` pour `config`, `sources`, `apiKeyEnvVar` et `detection`. Une option de config ou `--force` remet la config dans l'exécution, comme sans `--agent`.

`init` refuse avant d'écrire quoi que ce soit, avec `AGENT_FILE_INVALID`, quand un fichier de client n'est pas du JSON pur (il ne réécrit jamais des commentaires ni des virgules finales), n'est pas un objet, répète une clé ou a une valeur de serveurs qui n'est pas un objet ; quand `.codex/config.toml` définit `mcp_servers` ou le serveur verbatra en ligne, avec des clés pointées ou comme tableau de tables, répète cette table ou une clé dedans, ou a une chaîne, un tableau ou un en-tête non fermé ; quand un client que nomme `--client` a un lien symbolique sur son chemin de config, ou qu'un fichier d'instructions pointe hors du projet ; ou quand le fichier d'instructions a un marqueur sans paire, dans le mauvais ordre ou répété. Le message ne cite jamais le fichier.

## Codes de sortie [#codes-de-sortie]

| Code | Signification |
| --- | --- |
| `0` | fichiers écrits, ou déjà à jour |
| `2` | une erreur d'utilisation : `MISSING_OPTIONS`, `INVALID_PROVIDER`, `INVALID_FORMAT`, `INVALID_OPTION`, `INVALID_LOCALE`, `INVALID_LOCALES`, `FORMAT_AMBIGUOUS`, `LAYOUT_AMBIGUOUS`, `CONFIG_EXISTS`, `INIT_UNWRITABLE`, `AGENT_FILE_INVALID`, ou `CONFIG_INVALID` quand les réponses ne donneraient pas une config valide |

La façon dont chaque commande utilise ces codes est décrite dans le [contrat des codes de sortie](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#codes-de-sortie).

## Voir aussi [#voir-aussi]

- [Configure verbatra avec un agent IA](https://verbatra.kreitz-webdev.de/fr/docs/start-with-ai.md) est le prompt pour agent construit sur cette commande.
- [Démarrage rapide](https://verbatra.kreitz-webdev.de/fr/docs/quickstart.md) va de init jusqu'à la première exécution.
- [Le fichier de configuration](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md) documente chaque clé posée par l'échafaudage.
- [Fournisseurs](https://verbatra.kreitz-webdev.de/fr/docs/providers.md) couvre les options de fournisseur et les variables de clé d'API.
