Referencia / CLI
Página traducida automáticamente
Códigos de salida y salida JSON
El contrato de códigos de salida, el envoltorio JSON de cada comando con --json, los códigos propios de la CLI y cómo escribe verbatra en stderr.
Todo aquello en lo que un script o un paso de CI puede confiar en todos los comandos. Cada página de comando añade solo lo específico de ese comando.
Códigos de salida
El código de salida es el contrato sobre el que tu paso de CI toma su decisión:
| Código | Significado |
|---|---|
0 | éxito, por comando como se indica bajo la tabla |
1 | la ejecución llegó al final, pero el resultado no está limpio: translate o import terminó con al menos un locale fallido o parcial, check encontró un locale desincronizado (o, con --qa, una traducción confirmada con un error de integridad o, con --strict, con una advertencia de revisión o un plural incompleto, o, con --require-reviewed, una traducción escrita por máquina que nadie aprobó, o, con --sensitive, contenido que parece sensible en el archivo de origen o el glosario), check --file encontró un error de sintaxis o de integridad en el archivo (o, con --strict, una advertencia de revisión o un plural incompleto), diff encontró una clave ausente o cambiada (o, con --unused, un análisis completo encontró una clave de origen sin uso), report provenance encontró verbatra.provenance.json corrupto o escrito por un verbatra más nuevo, doctor encontró al menos una comprobación fallida, types --check encontró que la declaración confirmada está desactualizada, o studio o mcp falló al apagar su servidor |
2 | no se pudo ejecutar: un error de toda la ejecución (configuración incorrecta, origen ilegible, archivo de bloqueo corrupto, un locale que el proveedor no admite), un error de uso (una lista --locales vacía, INVALID_, o un --debounce o --port inválido), un valor --locales no configurado (UNKNOWN_), init al que le falta un flag que necesita, que encuentra varios formatos o patrones de archivo que encajan, que se niega a sobrescribir una configuración existente o que es incapaz de generar una configuración válida, un arranque o una parada fallidos de watch, studio incapaz de cargar la configuración, de importar @verbatra/studio o de arrancar su servidor, o mcp con un --config que nombra una ruta inexistente, o incapaz de importar @verbatra/mcp, de arrancar su servidor o de aplicar --redact-values con el @verbatra/mcp instalado (una configuración ausente o inválida que encuentra la búsqueda lo arranca sin configurar) |
3 | translate (también una ejecución de prueba y --estimate) en un proyecto solo humano (provider: { id: "none" }) terminó sin errores, pero dejó claves para una traducción humana; un locale fallido o parcial sigue saliendo con 1 |
130 | translate o import se interrumpió con Ctrl-C (SIGINT) tras liberar sus bloqueos de escritura, o watch, studio o mcp fue detenido a la fuerza por una segunda interrupción |
143 | translate o import se detuvo con SIGTERM tras liberar sus bloqueos de escritura |
El código 0 significa, por comando:
translateoimport: cada locale terminó completocheck: todos los locales están sincronizadosdiff: no hay cambios pendientesreport: imprimió su informedoctor: ningún problema de configuración del proyectoextract: completó su análisispseudo: generó su pseudolocaletypes: generó su declaraciónexport: escribió su librotmx: importó o exportó su memoria de traduccióninit: preparó el proyecto o lo encontró ya al díawatch,studioomcp: se detuvo limpiamente--helpo--version: imprimió la ayuda o la versión
Con 130 y 143, stderr termina con verbatra: interrupted (SIGINT), released locks (o SIGTERM), o, con --json, con el registro {"type":"interrupted","signal":"SIGINT","locksReleased":true}. Si liberar los bloqueos falla o no termina en 5 segundos, la línea lo dice en su lugar (could not release locks: <reason> o lock release did not finish within 5s), y el registro JSON lleva "locksReleased":false con "reason":"failed" (más message) o "reason":"timed-out" (más deadlineMs).
Algunos casos límite que conviene conocer:
Disponible a partir de 0.9.0- Un locale parcial cuenta como fallo. Significa que el archivo se escribió pero todavía faltan algunas claves, normalmente porque un sublote del proveedor falló o la puerta de integridad rechazó una traducción. Sale con
1exactamente igual que un locale fallido. Leepartialen el resumen para distinguir los dos casos. Un sublote fallido deja en el locale un avisoSUB_que nombra el código de error del proveedor, oBATCH_ FAILED PROVIDER_cuando el fallo no fue un error estructurado del proveedor.CALL_ FAILED - Un locale que el proveedor no admite también es un error de toda la ejecución, nunca un único locale fallido.
translate(incluidos un dry run y--estimate),watchal arrancar y la retraducción de una sola clave lo rechazan conLOCALE_y salen conUNSUPPORTED_ BY_ PROVIDER 2antes de construir ningún proveedor o gastar nada, así que ningún locale de la ejecución ha empezado y no se ha escrito nada. Se evalúa contra la tabla de idiomas que verbatra incluye para DeepL y Google Cloud Translation; un proveedor LLM acepta cualquier locale. Deja fuera ese locale con--localespara traducir los demás, y ejecutaverbatra doctor --localespara ver por qué. Consulta Soporte de idiomas. - Un archivo de bloqueo corrupto es un error de toda la ejecución tanto en
translatecomo enimport, nunca un único locale fallido. Es un solo archivo compartido, así que un archivo de bloqueo que se corrompe con la ejecución en marcha la detiene con2en vez de seguir con los locales restantes. Lo que se escribió antes del corte permanece en disco: repara el archivo de bloqueo y vuelve a ejecutar el comando. - Una sola interrupción es una parada limpia, y los tres comandos de larga duración (
watch,studioymcp) salen con0ante ella. Más allá de eso no des por hecho que se comportan igual: si la propia parada falla,watchsale con2mientras questudioymcpsalen con1. - Una ejecución fallida durante
watchaparece como un registro en el flujo de salida, nunca como un código de salida distinto de cero. exportno tiene modo de fallo por locale: sale con0o2, nunca con1.doctorlee una configuración rota de forma distinta al resto de comandos: una configuración que la búsqueda no encuentra, o una que no supera la validación, es una comprobación fallida y da1, porque informar precisamente de eso es el trabajo del comando. Sale con2solo cuando no puede ejecutarse en absoluto, por ejemplo con una ruta--configexplícita que no existe.- Hay un modo de fallo que queda fuera del contrato: un fallo de análisis que no es un error de uso se vuelve a lanzar, y el binario no lo captura, así que se aplica el comportamiento por defecto de Node ante un rechazo no gestionado en lugar de cualquiera de los seis códigos.
- Una clave protegida (un valor obsoleto que escribió, importó o cambió una persona fuera de verbatra, o una clave fijada) no cambia el código de salida de
translateen un proyecto con proveedor: sale con0e indica en stderr cuántas claves dejó (las claves fijadas no cuentan).checksigue saliendo con1por ella, porque la clave sigue obsoleta hasta que una persona la resuelva. En un proyecto solo humano cuenta para la salida3.
Salida JSON
Todos los comandos salvo studio y mcp aceptan --json para una salida legible por máquina en stdout: translate, watch, check, diff, report, export, import, tmx, doctor, pseudo, types, extract e init. Cada registro ocupa una línea, y cada registro va dentro del mismo envoltorio, así que decides según un solo campo y nunca tienes que adivinar de qué comando son los datos que tienes delante:
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 es la versión de esta forma de envoltorio, no la versión del paquete. Es un entero, así que lo comparas con === en lugar de analizar un rango, y solo cambia cuando un campo existente cambia de significado o desaparece. Pueden aparecer campos nuevos sin incrementarla, así que ignora los que no reconozcas.
Una ejecución que falla por completo escribe exactamente un registro ok: false en stdout y sale con 2. Su code es el mismo código de error estable que lleva la línea de stderr, y es el valor sobre el que decides:
{ "ok": false, "version": 1, "command": "translate", "code": "CONFIG_INVALID", "message": "..." }command es null solo cuando el fallo ocurrió antes de resolver un subcomando. candidates aparece solo en un error que te pide elegir, como FORMAT_ de init, y lista los valores entre los que elegir. missing aparece en un error de uso de init que deja flags sin responder y nombra cada flag que aún tienes que pasar. causeCode aparece cuando el error envuelve otro error con código, como un PROVIDER_ causado por MISSING_; la línea de stderr termina entonces con (cause: MISSING_.
hint aparece cuando el error tiene un siguiente paso: una frase breve en imperativo que lo resuelve, como "Set GEMINI_ para una clave ausente o "Run `verbatra check --help` to see the options and arguments it accepts." para un USAGE_. Actúa según él en lugar de analizar message. Nombra variables, flags y rutas, nunca el valor de una clave. Cada código del SDK, de un proveedor y de un adaptador de formato tiene uno (el SDK exporta el mismo texto como errorHint), y también cada código de error de la CLI excepto CLI_. Sin --json, el mismo texto sigue a la línea de error en stderr como next: ..., salvo que uses --quiet. mcp --json es la excepción: se rechaza con una sola línea USAGE_ en stderr, sin envoltorio y sin next:. Los errores de arranque de studio y mcp tampoco llevan una línea next:.
El result de un envoltorio correcto es distinto en cada comando y se describe en su página, bajo Salida JSON: extract, translate, watch, check, diff, report, doctor, pseudo, types, export, import, tmx, init.
Esquemas Disponible a partir de 0.12.0
Cada registro que imprime --json tiene un JSON Schema (draft 2020-12). Los esquemas vienen dentro de los paquetes de npm y se sirven en URL estables, para que un script, un agente o un editor pueda validar la salida en lugar de leer prosa. Cada esquema de salida admite propiedades que no enumera, como promete el contrato del envoltorio de arriba; mantenlo así si copias uno. El esquema de la configuración es la excepción a propósito: describe lo que tú escribes, así que rechaza una clave desconocida para detectar una errata.
| Documento | URL | Archivo en el paquete |
|---|---|---|
| Cualquier envoltorio, de éxito o de error | envelope.json | @verbatra/cli/schemas/envelope.json |
El envoltorio de un comando, con su result | https://verbatra.kreitz-webdev.de/schema/v1/<command>-envelope.json | @verbatra/cli/schemas/<command>-envelope.json |
| El envoltorio de error | error-envelope.json | @verbatra/cli/schemas/error-envelope.json |
El resultado de init por sí solo, sin envoltorio | init-result.json | @verbatra/cli/schemas/init-result.json |
| Una línea JSON en stderr: progreso, espera de un bloqueo, interrupción | stderr-record.json | @verbatra/cli/schemas/stderr-record.json |
| El archivo de configuración | config.json | @verbatra/sdk/schemas/config.json o @verbatra/sdk/config-schema.json: el mismo esquema sin $id ni title |
Cada página de comando enlaza su envoltorio en Salida JSON, y https://verbatra.kreitz-webdev.de/schema/v1 enumera cada documento con su título. El envoltorio de un comando apunta al esquema de su result por URL en $ref, así que un validador lo carga por la red, o desde node_ si registras antes esos archivos.
v1 sigue la version: 1 del envoltorio y siempre sirve la última versión publicada. Un campo nuevo se queda en v1; un cambio que rompe una carga útil sube la version del envoltorio y añade /schema/v2/. El esquema de la configuración usa el mismo esquema de URL, pero sigue los cambios de la propia configuración. La URL siempre sirve la última versión publicada, mientras que una copia de npm se queda en su versión, así que una copia antigua puede rechazar un registro de una CLI más nueva allí donde un esquema enumera valores cerrados, como el type de un registro de stderr o el command de un envoltorio.
Códigos de error de la CLI Disponible a partir de 0.12.0
La CLI lanza estos códigos por sí misma. La misma lista se publica como CLI_ (con el tipo CliErrorCode) desde @verbatra/cli, así que un script puede comprobar un código contra ella. Cualquier otro código viene del SDK, de un proveedor o de un adaptador de formato. Qué significa cada código, qué comandos lo lanzan y cuál es el siguiente paso está en Códigos de error.
Errores en stderr
Todo error va a stderr como una línea estructurada (verbatra: error [CODE] message) en ambos modos. Desde 0.12.0 eso incluye un error al analizar los argumentos (una opción o un comando desconocidos, un argumento ausente): imprime verbatra: error [USAGE_ y sale con 2, donde antes imprimía el propio error: unknown option '--nope' de commander, sin código. init sigue la misma gramática desde 0.12.0; antes, un proveedor ausente imprimía verbatra: --provider is required (...) sin código. Desde 0.12.0, sin --json una pista sigue a la línea como next: ..., y con --json un error de análisis escribe en stdout el envoltorio USAGE_ con su hint; mcp reserva stdout para el protocolo, así que rechaza --json solo en stderr. El arranque de studio y mcp es la excepción a la línea estructurada: si @verbatra/studio o @verbatra/mcp no está instalado, stderr lleva solo la instrucción de instalación, sin el prefijo verbatra:. Con --json, el message de un error de análisis es el texto propio de commander, con el prefijo error: . Sin --json, una ejecución fallida sigue sin escribir absolutamente nada en stdout. Los registros de progreso y de espera de bloqueo van siempre a stderr, así que stdout no lleva más que envoltorios.
Salida en el terminal Disponible a partir de 0.12.0
Los resultados van a stdout. El progreso, los avisos, las sugerencias, las advertencias y los errores van a stderr, y verbatra los adapta según a dónde vaya stderr:
- En un terminal interactivo, las etiquetas fijas como
error,[ok]ynext:llevan color, y un paso que tarda más de 300 ms muestra un spinner ASCII (| / - \). - Cuando stderr se redirige o va a una tubería,
CItiene un valor distinto de vacío,0ofalse, oTERMvaledumb, la salida son líneas simples que solo se añaden, sin color ni animación. - Las etiquetas de estado del informe de
doctoren stdout ([ok ],[warn],[fail],[skip]) tienen color cuando stdout es un terminal interactivo; un informe redirigido queda sin formato salvo queFORCE_active el color.COLOR --jsonnunca añade color ni animación, y stdout no lleva más que envoltorios. Las líneas simples de avisoverbatra:aún pueden llegar a stderr, así que quien consume la salida analiza solo las líneas de stderr que empiezan por{. Consulta Salida JSON.
| Flag o variable | Efecto |
|---|---|
-q, --quiet | muestra solo resultados, advertencias y errores: omite las líneas de progreso, las sugerencias next: y las líneas informativas de stderr, mientras que el resumen del resultado, avisos incluidos, se mantiene. Funciona antes o después del nombre del comando |
--no-color | nunca colorea la salida |
NO_, NODE_, VERBATRA_ | cualquier valor no vacío desactiva el color; VERBATRA_ también se impone a FORCE_ |
FORCE_ | 1, 2, 3, true o un valor vacío activa el color aunque stderr o stdout no sea un terminal, y cualquier otro valor, 0 incluido, lo desactiva. Si está definido, se impone a NO_, NODE_, CI y TERM=dumb; --no-color y VERBATRA_ siguen teniendo prioridad |
VERBATRA_ | cualquier valor no vacío sustituye el spinner por líneas estáticas label... done (1.2s), para lectores de pantalla y grabaciones del terminal |
Los ejemplos output de las páginas de comando muestran la forma simple. Un terminal interactivo muestra un paso en curso como una línea con spinner que termina en [ok] y el tiempo transcurrido.
Las palabras de estado son ASCII simple ([ok], [warn], [fail], [skip]), así que la salida se lee igual en cualquier terminal y registro. Cada línea pasa por la misma ocultación de claves que el resto de la salida, y solo se colorean las etiquetas fijas, nunca una clave, una ruta ni un mensaje.