Référence / CLI
Page traduite automatiquement
Codes de sortie et sortie JSON
Le contrat des codes de sortie, l'enveloppe JSON de chaque commande avec --json, les codes propres à la CLI et la façon dont verbatra écrit sur stderr.
Tout ce sur quoi un script ou une étape CI peut compter pour toutes les commandes. Chaque page de commande n'ajoute que ce qui est propre à cette commande.
Codes de sortie
Le code de sortie est le contrat sur lequel ton étape CI se branche :
| Code | Signification |
|---|---|
0 | succès, par commande comme indiqué sous le tableau |
1 | l'exécution est allée au bout, mais le résultat n'est pas propre : translate ou import a terminé avec au moins une locale en échec ou partielle, check a trouvé une locale désynchronisée (ou, avec --qa, une traduction commitée avec une erreur d'intégrité ou, avec --strict, un avertissement de relecture ou un pluriel incomplet, ou, avec --require-reviewed, une traduction écrite par une machine que personne n'a approuvée, ou, avec --sensitive, un contenu qui semble sensible dans le fichier source ou le glossaire), check --file a trouvé une erreur de syntaxe ou d'intégrité dans le fichier (ou, avec --strict, un avertissement de relecture ou un pluriel incomplet), diff a trouvé une clé absente ou modifiée (ou, avec --unused, une analyse complète a trouvé une clé source inutilisée), report provenance a trouvé verbatra.provenance.json corrompu ou écrit par un verbatra plus récent, doctor a trouvé au moins une vérification en échec, types --check a trouvé la déclaration commitée obsolète, ou studio ou mcp a échoué en arrêtant son serveur |
2 | impossible de s'exécuter : une erreur globale (config invalide, source illisible, fichier de verrouillage corrompu, locale que le fournisseur ne prend pas en charge), une erreur d'utilisation (une liste --locales vide, INVALID_, ou un --debounce ou --port invalide), une valeur --locales non configurée (UNKNOWN_), init à qui il manque une option nécessaire, qui trouve plusieurs formats ou motifs de fichiers qui conviennent, qui refuse d'écraser une config existante, ou qui est incapable de générer une config valide, un démarrage ou un arrêt de watch en échec, studio incapable de charger la config, d'importer @verbatra/studio ou de démarrer son serveur, ou mcp dont --config nomme un chemin inexistant, ou incapable d'importer @verbatra/mcp, de démarrer son serveur ou d'appliquer --redact-values avec le @verbatra/mcp installé (une config absente ou invalide trouvée par la recherche le démarre sans configuration) |
3 | translate (exécution à blanc et --estimate compris) dans un projet 100 % humain (provider: { id: "none" }) s'est terminé proprement, mais a laissé des clés pour une traduction humaine ; une locale en échec ou partielle sort toujours avec 1 |
130 | translate ou import a été interrompu avec Ctrl-C (SIGINT) après avoir libéré ses verrous d'écriture, ou watch, studio ou mcp a été arrêté de force par une seconde interruption |
143 | translate ou import a été arrêté avec SIGTERM après avoir libéré ses verrous d'écriture |
Le code 0 signifie, par commande :
translateouimport: toutes les locales sont complètescheck: toutes les locales sont synchroniséesdiff: aucun changement en attentereport: le rapport a été affichédoctor: aucun problème de configuration du projetextract: l'analyse est terminéepseudo: la pseudolocale a été généréetypes: la déclaration a été généréeexport: le classeur a été écrittmx: la mémoire de traduction a été importée ou exportéeinit: le projet a été généré ou était déjà à jourwatch,studiooumcp: arrêt propre--helpou--version: l'aide ou la version a été affichée
Avec 130 et 143, stderr se termine par verbatra: interrupted (SIGINT), released locks (ou SIGTERM), ou, avec --json, par l'enregistrement {"type":"interrupted","signal":"SIGINT","locksReleased":true}. Si la libération des verrous échoue ou ne se termine pas en 5 secondes, la ligne le dit à la place (could not release locks: <reason> ou lock release did not finish within 5s), et l'enregistrement JSON porte "locksReleased":false avec "reason":"failed" (plus message) ou "reason":"timed-out" (plus deadlineMs).
Quelques cas limites à connaître :
Disponible à partir de 0.9.0- Une locale partielle compte comme un échec. Cela veut dire que le fichier a été écrit mais qu'il manque encore des clés, en général parce qu'un sous-lot du fournisseur a échoué ou que la barrière d'intégrité a refusé une traduction. Elle sort avec
1exactement comme une locale échouée. Lispartialsur le résumé pour distinguer les deux. Un sous-lot échoué laisse sur la locale un avisSUB_qui nomme le code d'erreur du fournisseur, ouBATCH_ FAILED PROVIDER_quand l'échec n'était pas une erreur structurée du fournisseur.CALL_ FAILED - Une locale que le fournisseur ne prend pas en charge est elle aussi une erreur globale, jamais une seule locale en échec.
translate(exécution à blanc et--estimatecompris),watchau démarrage et une retraduction d'une seule clé la refusent avecLOCALE_et sortent avecUNSUPPORTED_ BY_ PROVIDER 2avant qu'aucun fournisseur ne soit construit ni que quoi que ce soit ne soit dépensé : aucune locale de l'exécution n'a démarré et rien n'a été écrit. Elle est jugée d'après la table de langues que verbatra embarque pour DeepL et Google Cloud Translation ; un fournisseur LLM accepte toutes les locales. Laisse la locale de côté avec--localespour traduire les autres, et lanceverbatra doctor --localespour savoir pourquoi. Voir Prise en charge des langues. - Un fichier de verrouillage corrompu est une erreur globale pour
translatecomme pourimport, jamais une seule locale en échec. C'est un fichier unique et partagé : s'il se corrompt en cours d'exécution, celle-ci s'arrête avec2au lieu de poursuivre avec les locales restantes. Ce qui a été écrit avant l'interruption reste sur le disque : répare le fichier de verrouillage puis relance la commande. - Une interruption unique est un arrêt propre, et les trois commandes de longue durée (
watch,studioetmcp) sortent avec0dans ce cas. Au-delà, ne suppose pas qu'elles se comportent pareil : si l'arrêt lui-même échoue,watchsort avec2tandis questudioetmcpsortent avec1. - Une exécution échouée pendant
watchapparaît comme un enregistrement sur le flux de sortie, jamais comme un code de sortie non nul. exportn'a pas de mode d'échec par locale : il sort avec0ou2, jamais1.doctorlit une config cassée différemment de toutes les autres commandes : une config que la recherche ne trouve pas, ou une config qui ne passe pas la validation, est une vérification en échec et un code de sortie1, parce que signaler exactement cela est le travail de la commande. Il sort avec2seulement quand il ne peut pas s'exécuter du tout, par exemple avec un chemin--configexplicite qui n'existe pas.- Un mode d'échec sort du contrat : une erreur d'analyse qui n'est pas une erreur d'utilisation est relancée, et le binaire ne l'attrape pas, donc le comportement par défaut de Node face à un rejet non géré s'applique au lieu de l'un des six codes.
- Une clé protégée (une valeur obsolète écrite, importée ou modifiée hors de verbatra par une personne, ou une clé épinglée) ne change pas le code de sortie de
translatedans un projet avec fournisseur : il sort avec0et indique sur stderr combien de clés il a laissées (les clés épinglées ne comptent pas).checksort quand même avec1pour elle, car la clé reste obsolète jusqu'à ce qu'une personne la résolve. Dans un projet 100 % humain, elle compte pour la sortie3.
Sortie JSON
Toutes les commandes sauf studio et mcp acceptent --json pour une sortie lisible par machine sur stdout : translate, watch, check, diff, report, export, import, tmx, doctor, pseudo, types, extract et init. Chaque enregistrement tient sur une ligne, et chaque enregistrement est entouré de la même enveloppe : tu te branches sur un seul champ et tu n'as jamais à deviner de quelle commande viennent les données que tu tiens :
type Envelope<TResult> =
| { ok: true; version: 1; command: string; result: TResult }
| {
ok: false;
version: 1;
command: string | null;
code: string;
message: string;
causeCode?: string; // the code of the error this one wraps, when it has one
candidates?: string[]; // the values to choose from, on an error that has them
missing?: string[]; // the flags still to pass, on an init usage error
hint?: string; // the next step that resolves the error, when there is one
};version est la version de cette forme d'enveloppe, pas la version du paquet. C'est un entier, tu le compares donc avec === plutôt que d'analyser une plage, et il ne change que lorsqu'un champ existant change de sens ou disparaît. De nouveaux champs peuvent apparaître sans changement de version, ignore donc ceux que tu ne reconnais pas.
Une exécution qui échoue dans son ensemble écrit exactement un enregistrement ok: false sur stdout et sort avec 2. Son code est le même code d'erreur stable que porte la ligne stderr, c'est donc sur lui que tu te branches :
{ "ok": false, "version": 1, "command": "translate", "code": "CONFIG_INVALID", "message": "..." }command vaut null uniquement quand l'échec s'est produit avant qu'une sous-commande soit résolue. candidates n'apparaît que sur une erreur qui te demande de choisir, comme FORMAT_ d'init, et liste les valeurs parmi lesquelles choisir. missing apparaît sur une erreur d'utilisation d'init qui laisse des options sans réponse, et nomme chaque option encore à passer. causeCode apparaît quand l'erreur en enveloppe une autre dotée d'un code, comme un PROVIDER_ causé par MISSING_ ; la ligne stderr se termine alors par (cause: MISSING_.
hint apparaît quand l'erreur a une prochaine étape : une phrase courte à l'impératif qui la résout, comme "Set GEMINI_ pour une clé manquante ou "Run `verbatra check --help` to see the options and arguments it accepts." pour un USAGE_. Agis en fonction de lui plutôt que d'analyser message. Il nomme des variables, des options et des chemins, jamais la valeur d'une clé. Chaque code du SDK, d'un fournisseur et d'un adaptateur de format en a un (le SDK exporte le même texte sous le nom errorHint), tout comme chaque code d'erreur de la CLI sauf CLI_. Sans --json, le même texte suit la ligne d'erreur sur stderr sous la forme next: ..., sauf avec --quiet. mcp --json est l'exception : il est refusé avec une seule ligne USAGE_ sur stderr, sans enveloppe et sans next:. Les erreurs de démarrage de studio et mcp n'ont pas non plus de ligne next:.
Le result d'une enveloppe réussie diffère selon la commande et il est décrit sur sa page, sous Sortie JSON : extract, translate, watch, check, diff, report, doctor, pseudo, types, export, import, tmx, init.
Schémas Disponible à partir de 0.12.0
Chaque enregistrement que --json affiche a un JSON Schema (draft 2020-12). Les schémas sont livrés dans les paquets npm et servis à des URL stables, pour qu'un script, un agent ou un éditeur puisse valider la sortie au lieu de lire de la prose. Chaque schéma de sortie accepte les propriétés qu'il ne liste pas, comme le promet le contrat de l'enveloppe ci-dessus ; garde-le ainsi si tu en copies un. Le schéma de configuration est l'exception voulue : il décrit ce que tu écris, donc il refuse une clé inconnue pour repérer une faute de frappe.
| Document | URL | Fichier dans le paquet |
|---|---|---|
| N'importe quelle enveloppe, de succès ou d'erreur | envelope.json | @verbatra/cli/schemas/envelope.json |
L'enveloppe d'une commande, avec son result | https://verbatra.kreitz-webdev.de/schema/v1/<command>-envelope.json | @verbatra/cli/schemas/<command>-envelope.json |
| L'enveloppe d'erreur | error-envelope.json | @verbatra/cli/schemas/error-envelope.json |
Le résultat de init seul, sans enveloppe | init-result.json | @verbatra/cli/schemas/init-result.json |
| Une ligne JSON sur stderr : progression, attente d'un verrou, interruption | stderr-record.json | @verbatra/cli/schemas/stderr-record.json |
| Le fichier de configuration | config.json | @verbatra/sdk/schemas/config.json ou @verbatra/sdk/config-schema.json : le même schéma sans $id ni title |
Chaque page de commande lie son enveloppe sous Sortie JSON, et https://verbatra.kreitz-webdev.de/schema/v1 liste chaque document avec son titre. L'enveloppe d'une commande pointe vers le schéma de son result par URL dans $ref : un validateur le charge donc par le réseau, ou depuis node_ si tu enregistres ces fichiers d'abord.
v1 suit la version: 1 de l'enveloppe et sert toujours la dernière version publiée. Un champ ajouté reste dans v1 ; un changement qui casse une charge utile augmente la version de l'enveloppe et ajoute /schema/v2/. Le schéma de configuration utilise le même schéma d'URL, mais suit les changements de la configuration elle-même. L'URL sert toujours la dernière version publiée, alors qu'une copie venant de npm reste à sa version : une copie plus ancienne peut donc refuser un enregistrement d'une CLI plus récente là où un schéma liste des valeurs fermées, comme le type d'un enregistrement stderr ou la command d'une enveloppe.
Codes d'erreur de la CLI Disponible à partir de 0.12.0
La CLI lève ces codes elle-même. La même liste est publiée sous le nom CLI_ (avec le type CliErrorCode) par @verbatra/cli, pour qu'un script puisse vérifier un code avec elle. Tout autre code vient du SDK, d'un fournisseur ou d'un adaptateur de format. Ce que signifie chaque code, quelles commandes le lèvent et quelle est l'étape suivante se trouvent dans Codes d'erreur.
Erreurs sur stderr
Toute erreur va sur stderr sous forme d'une ligne structurée (verbatra: error [CODE] message) dans les deux modes. Depuis la 0.12.0, cela inclut une erreur d'analyse des arguments (une option ou une commande inconnue, un argument manquant) : elle affiche verbatra: error [USAGE_ et sort avec 2, là où elle affichait avant le error: unknown option '--nope' propre à commander, sans code. init suit la même grammaire depuis la 0.12.0 ; avant, un fournisseur absent affichait verbatra: --provider is required (...) sans code. Depuis la 0.12.0, sans --json une indication suit la ligne sous la forme next: ..., et avec --json une erreur d'analyse écrit sur stdout l'enveloppe USAGE_ avec son hint ; mcp réserve stdout au protocole, donc il refuse --json sur stderr uniquement. Le démarrage de studio et mcp fait exception à la ligne structurée : quand @verbatra/studio ou @verbatra/mcp n'est pas installé, stderr ne porte que l'instruction d'installation, sans le préfixe verbatra:. Avec --json, le message d'une erreur d'analyse est le texte propre à commander, préfixe error: compris. Sans --json, une exécution échouée n'écrit toujours strictement rien sur stdout. Les enregistrements de progression et d'attente de verrouillage vont toujours sur stderr, donc stdout ne porte que des enveloppes.
Sortie dans le terminal Disponible à partir de 0.12.0
Les résultats vont sur stdout. La progression, les avis, les suggestions, les avertissements et les erreurs vont sur stderr, et verbatra les adapte selon la destination de stderr :
- Dans un terminal interactif, les libellés fixes comme
error,[ok]etnext:sont colorés, et une étape qui dure plus de 300 ms affiche un spinner ASCII (| / - \). - Quand stderr est redirigé ou envoyé dans un pipe, que
CIa une valeur autre que vide,0oufalse, ou queTERMvautdumb, la sortie se compose de lignes simples, uniquement ajoutées, sans couleur ni animation. - Les étiquettes de statut du rapport de
doctorsur stdout ([ok ],[warn],[fail],[skip]) sont colorées quand stdout est lui-même un terminal interactif ; un rapport redirigé reste brut, sauf siFORCE_active la couleur.COLOR --jsonn'ajoute jamais de couleur ni d'animation, et stdout ne porte que des enveloppes. De simples lignes d'avertissementverbatra:peuvent quand même arriver sur stderr : un consommateur n'analyse donc que les lignes de stderr qui commencent par{. Voir Sortie JSON.
| Flag ou variable | Effet |
|---|---|
-q, --quiet | n'affiche que les résultats, les avertissements et les erreurs : supprime les lignes de progression, les suggestions next: et les lignes informatives sur stderr, tandis que le résumé du résultat, avis compris, reste. Il fonctionne avant ou après le nom de la commande |
--no-color | ne colore jamais la sortie |
NO_, NODE_, VERBATRA_ | toute valeur non vide désactive la couleur ; VERBATRA_ l'emporte aussi sur FORCE_ |
FORCE_ | 1, 2, 3, true ou une valeur vide active la couleur même quand stderr ou stdout n'est pas un terminal, et toute autre valeur, 0 comprise, la désactive. Une fois défini, il l'emporte sur NO_, NODE_, CI et TERM=dumb ; --no-color et VERBATRA_ restent prioritaires |
VERBATRA_ | toute valeur non vide remplace le spinner par des lignes statiques label... done (1.2s), pour les lecteurs d'écran et les enregistrements de terminal |
Les exemples output des pages de commande montrent la forme simple. Un terminal interactif affiche une étape en cours sous forme d'une ligne avec spinner qui se termine par [ok] et le temps écoulé.
Les mots d'état sont en ASCII simple ([ok], [warn], [fail], [skip]), pour que la sortie se lise de la même façon dans tout terminal et tout journal. Chaque ligne passe par le même masquage des clés que le reste de la sortie, et seuls les libellés fixes sont colorés, jamais une clé, un chemin ni un message.