Aller au contenu
Aller au contenu

Référence / CLI

Page traduite automatiquement

Cette page a été traduite automatiquement, elle peut donc contenir des erreurs ou se lire un peu bizarrement. La version anglaise fait foi. Lire l'original en anglais.

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

verbatra init [flags]

Exemples

# 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

OptionArgumentDéfautEffet
--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-jsonle format des fichiers de locale, l'un des ids de Formats
--source<locale>détectée, sinon enla locale source dans laquelle tes chaînes sont écrites
--targets<locales>détectées, sinon delocales cibles vers lesquelles traduire, séparées par des virgules
--path<pattern>détecté, sinon la structure habituelle du format (Détection)motif des fichiers de locale ; doit contenir le jeton {locale}
--model<name>le défaut de l'échafaudagele modèle ; requis pour openai-compatible, optionnel pour anthropic, openai, gemini et opencode
--base-url<url>aucunl'URL du serveur ; openai-compatible et libretranslate uniquement, et requis dans ce cas
--api-key-env-var<name>OPENAI_COMPATIBLE_API_KEYla variable dans laquelle openai-compatible lit sa clé
--yesaucundésactivéne pose jamais de question ; prend le défaut pour tout ce qui n'est ni passé ni détecté
--forceaucundésactivéécrase un verbatra.config.ts existant dont le contenu diffère
--agentaucundé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)
--client<ids>détectésclients 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-runaucundésactivésignale chaque fichier que init écrirait ou modifierait, et n'écrit rien (Exécution à blanc)

Accepte aussi les 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

Questions

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

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.

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

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 :

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

Sortie JSON

Schéma : init-envelope.json valide l'enveloppe entière ; Schémas liste les autres.

Avec --json, stdout porte exactement une enveloppe. Son result :

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

  • --provider none génère une config 100 % humaine 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 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

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

--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

--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. 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, 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--clientFichierDétecté par
Claude Codeclaude.mcp.jsonCLAUDE.md, .claude/, .mcp.json
Cursorcursor.cursor/mcp.json.cursor/, .cursorrules
VS Codevscode.vscode/mcp.json, sous servers.vscode/mcp.json
Codexcodex.codex/config.toml, en [mcp_servers.verbatra].codex/
Gemini CLIgemini.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

CodeSignification
0fichiers écrits, ou déjà à jour
2une 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.

Voir aussi

Modifier sur GitHub

Sur cette page