Referencia / CLI
Página traducida automáticamente
verbatra doctor
Comprueba si un proyecto está bien configurado y recibe todos los problemas en un informe, sin llamar a un proveedor ni leer una clave de API.
Comprueba si un proyecto está bien configurado y recibe todos los problemas en un solo informe. doctor no construye ningún proveedor, no escribe ningún archivo y solo lee el valor de una clave de API con --live, que la envía en una petición de la lista de idiomas del proveedor (LibreTranslate no recibe ninguna). Úsalo después de verbatra init o cuando otro comando falle.
Sinopsis
verbatra doctor [flags]Ejemplos
# report every setup problem at once
verbatra doctor
# validate a project in another directory, with an explicit config
verbatra doctor --cwd apps/web --config verbatra.config.ts
# machine-readable report for a CI preflight step
verbatra doctor --json
# list hardcoded user-facing strings, with no key set
verbatra doctor --literals
# what the provider supports for each target locale
verbatra doctor --locales
# the same, against the provider's current language list
verbatra doctor --live
# a data-flow manifest to attach to a DPA or NDA review
verbatra doctor --data-flow --jsonFlags
| Flag | Argumento | Por defecto | Efecto |
|---|---|---|---|
--literals | ninguno | desactivado | en lugar de revisar la configuración, busca strings visibles para el usuario escritos a mano en las raíces de código del bloque extract (ver Literales sin traducir) |
--locales | ninguno | desactivado | tras las comprobaciones, lista por locale de destino el código enviado, el soporte del proveedor, el glosario y la formalidad (ver Soporte de locales) |
--live | ninguno | desactivado | primero descarga la lista de idiomas actual del proveedor, sin gastar cuota de traducción; implica --locales |
--data-flow | ninguno | desactivado | en lugar de revisar la configuración, describe qué se envía a qué host y qué se escribe en local (ver Flujo de datos) |
También acepta los flags globales --cwd, --config y --json. --locales y --live no se pueden combinar con --literals (INVALID_, salida 2), y --data-flow con ninguno de los tres.
Comportamiento
Qué comprueba
Una ejecución de configuración informa de estas comprobaciones, en este orden. Plural rules, Plural completeness, Locale codes, Locale state y Length limits son informativas y nunca fallan: cada una muestra [warn] cuando nombra algo y [ok ] en caso contrario.
| Comprobación | Falla cuando |
|---|---|
| Configuration | no se encuentra ningún archivo de configuración o no pasa la validación |
| Format adapter | el format configurado no se resuelve a ningún adaptador de archivos |
| Provider | el provider.id configurado no se resuelve a ninguna factoría de proveedor |
| API key environment variable | la variable de la que ese proveedor lee su clave no está definida |
| Network policy | la política de red efectiva rechaza el host del proveedor o un proxy que usaría |
| Source locale file | el archivo de locale de origen falta en su ruta resuelta, no es un archivo normal o no se analiza con el formato configurado |
| Plural rules | nunca; nombra las versiones de ICU y CLDR en uso y avisa cuando un locale de destino no tiene reglas de plural en ICU |
| Plural completeness | nunca; avisa y nombra cada plural de destino al que le falta una categoría CLDR que usa su idioma, y juzga un plural sin formas en el destino por lo que una ejecución escribiría allí (una forma de origen vacía cuenta como ausente, y la generación de plurales solo donde de verdad se ejecuta), a propósito más estricto que el aviso de translate, solo para i18next (diez como máximo; verbatra check lista los huecos de los plurales que un destino ya tiene); se omite para un formato que no guarda las formas de plural por categoría CLDR |
| Locale codes | nunca; avisa y nombra cada código válido pero no canónico, como en-us o iw, con su forma canónica (ver Códigos de locale) |
| Locale state | nunca; avisa y nombra cada locale con estado en el archivo de bloqueo, la caché o el archivo de procedencia que la configuración no lista, y si translate lo traslada |
| Length limits | nunca; avisa cuando verbatra.limits.json no se puede usar (una ejecución lo ignora y no se puede fijar un límite hasta arreglarlo), nombra un límite de una clave que la fuente ya no tiene o uno que el maxLength de la configuración sobrescribe, y lo dice si no se pudo leer la fuente para comprobar las claves; pasa cuando el archivo no existe (límites de longitud) nuevo |
| Locale support | el proveedor no admite el locale de origen o un locale de destino; avisa cuando un locale lleva un aviso (ver Soporte de locales) |
Cada comprobación se ejecuta aunque una anterior haya fallado. La única excepción es la configuración: si no se puede cargar, las comprobaciones que la necesitan aparecen como [skip] ("status": "skipped" en JSON), igual que Plural completeness para un formato sin formas de plural CLDR. Una comprobación que encuentra algo que merece atención sin fallar aparece como [warn] ("status": "warn" en JSON) y nunca cambia el código de salida. Una comprobación fallida lleva además un fix, un siguiente paso en imperativo que se imprime como línea fix: y viaja como "fix" en JSON, para que un agente actúe sin analizar detail.
Una ejecución con dos problemas:
verbatra doctor
[ok ] Configuration: Loaded /app/verbatra.config.ts.
[ok ] Format adapter: Format "i18next-json" resolves to an adapter.
[ok ] Provider: Provider "anthropic" resolves to a factory.
[fail] API key environment variable: The ANTHROPIC_API_KEY environment variable is not set.
fix: Set ANTHROPIC_API_KEY in the environment, or, with the CLI, in a .env file in the project directory.
[ok ] Network policy: any host (config: unset; VERBATRA_NETWORK_POLICY: unset). Provider "anthropic" connects to api.anthropic.com: permitted.
[fail] Source locale file: The source locale file was not found at /app/locales/en.json.
fix: Create the source locale file, or fix `files.pattern` and `sourceLocale` in the config so they point at it.
...
[warn] Locale codes: "iw" is canonically "he". Consider the canonical form in your config; file names follow the configured code and are never renamed for you.
[ok ] Locale support: Provider "anthropic" is an LLM and accepts any locale (well-tested list of 2026-09-28).
2 problems found (run verbatra doctor again after fixing them)Claves y archivos
- La clave de API se comprueba solo por nombre:
doctorpregunta si la variable está definida, nunca qué contiene. La variable de cada proveedor está en Proveedores. openai-compatiblerecurre a una clave de relleno, así que solo falla cuando la configuración nombra su propia variable enprovider.options.apiKeyEnvVary esa variable no está definida.libretranslatenunca hace fallar la comprobación, porque su clave es opcional.- Con
provider: { id: "none" }, las comprobaciones Provider, API key y Network policy pasan, y Locale support se omite. - Que falte un archivo de destino no es problema:
translatelo crea. El archivo de origen se analiza, así que un directorio, un archivo vacío o un contenido mal formado la hacen fallar. doctorcarga primero los archivos de entorno, así que una clave en un archivo dotenv cuenta como definida; con--literalsno carga ninguno.
Soporte de locales
La comprobación Locale support pregunta si el proveedor puede traducir cada locale configurado. DeepL y Google Cloud Translation se evalúan contra una tabla de idiomas fechada que verbatra incluye; un proveedor LLM acepta cualquier locale. Falla justo en el locale que verbatra translate rechazaría con LOCALE_ y, si no, muestra [warn] cuando un locale lleva un aviso o --live no pudo obtener la lista. Soporte de idiomas explica los veredictos.
--locales imprime el veredicto por locale después de las comprobaciones:
locale support (deepl, language table of 2026-09-28, static)
en sent as EN source, supported
de sent as DE supported glossary: yes formality: yes
sv sent as SV supported glossary: yes formality: no
warning [FORMALITY_UNSUPPORTED_BY_PROVIDER] Provider "deepl" has no formality control for "sv", so the configured formal tone is not applied and the provider's default register is used.
chr sent as CHR unsupported glossary: no formality: noCada línea nombra el locale, el código que recibe el proveedor (tras localeMap, marcado con (localeMap)), el veredicto y si se aplican un glosario y un tono formal o informal. Un aviso es solo orientativo.
--live evalúa en cambio contra la lista actual del proveedor (DeepL /v3/languages, Cloud Translation languages, LibreTranslate /languages). Para LibreTranslate, que no incluye tabla, es la única forma de obtener un veredicto distinto de unverified, así que Locale support muestra [warn] hasta que se ejecute --live. La petición solo se envía si la variable de la clave está definida (LibreTranslate no la necesita) y la política de red permite el host; si no, o si falla, se usa la tabla incluida y una línea live language list explica por qué.
Literales sin traducir
--literals encuentra strings visibles para el usuario que nunca llegaron a un catálogo. Recorre las raíces de código de tu bloque extract, lee tu código sin escribirlo nunca, no construye proveedor, no lee ninguna clave y no carga ningún .env. Solo se ejecutan dos comprobaciones: Configuration y Untranslated literals. Cada hallazgo nombra archivo, línea y columna, con los espacios colapsados, las referencias de caracteres de JSX decodificadas y 80 caracteres como máximo:
[fail] Untranslated literals: Scanned 42 source files: 2 untranslated literals found (1 suppressed).
src/components/Header.tsx:12:9 "Welcome back"
src/pages/settings.tsx:40:22 "Save changes"
suppressed (directive) src/pages/legal.tsx:8:5 "Acme Inc."Se informa de: texto JSX en archivos .tsx, .jsx y .js, atributos JSX visibles para el usuario (alt, title, placeholder, label, aria-label y los demás aria-* con texto) y cualquier otro string de dos o más palabras.
Nunca se informa de:
- un string pasado a
t(...),$t(...),i18n.t(...)o a untrenombrado deuseTranslation, o renderizado dentro de<Trans>o<Translation>; - claves de objeto, especificadores de import, nombres de clase, valores CSS, ids de test,
data-*y atributos de id o palabra clave (aria-describedby,aria-labelledby,aria-controls,rel,sandbox,allow,autoComplete,referrerPolicy,crossOrigin), URLs y strings sin letras; - literales en posición de tipo (el valor antes de
asosatisfiessí se comprueba), mensajes de log, mensajes de error (new ValidationError(...),throw Error(...)), operandos de comparación y template literals con una expresión; - argumentos directos de
describe(zod),query,execute,prepare,format,parse,z.enum,setItem,getItemyremoveItem, y el primer argumento deon,off,once,emit,addEventListenery de ungetosetsobre un objeto; el texto más anidado y los mensajes pasados a funciones comosetErrorsí se informan; - todo lo que esté en archivos de test, story, declaración o configuración.
Para retener un literal, pon // verbatra-ignore-next-line encima (en JSX, {/* verbatra-ignore-next-line */}) o // verbatra-ignore-line al final de su línea. Una directiva de siguiente línea apunta a la siguiente línea con código y, en una etiqueta JSX de apertura, a todos sus atributos. Un string que vale en todas partes lo añades a extract.literals.ignore con las referencias decodificadas (Tom & Jerry). Los literales suprimidos se siguen listando con su motivo.
La comprobación falla con un hallazgo y con un archivo que no pudo abrir, leer hasta el final o que consideró demasiado grande (el escaneo continúa). Un proyecto sin bloque extract la hace fallar.
Flujo de datos
--data-flow describe adónde van los datos de este proyecto en lugar de revisar la configuración, como evidencia para una revisión de DPA o NDA; Tratamiento de datos explica cada categoría. No lee ninguna clave de API ni hace ninguna petición de red. Solo se ejecutan dos comprobaciones: Configuration y Data flow. Data flow nunca falla: muestra [warn] cuando la política de red rechaza un host o tiene un valor no válido, o cuando no se puede leer el archivo de origen para los recuentos.
[ok ] Data flow: Provider "deepl" sends source-text, placeholder-markers, language-codes to api.deepl.com (permitted), api-free.deepl.com (permitted).
data flow (manifest version 1)
provider deepl (machine-translation)
network any host (no policy set)
destination api.deepl.com default paid-key before-construction permitted
destination api-free.deepl.com default free-key before-construction permitted
sent source-text, placeholder-markers, language-codes
api key required
placeholders masked
sensitive off
counts 3 source keys, 0 with a description or meaning, 1 with placeholders it cannot mask (withheld)
locale de sent as DE glossary terms: 0
local lock verbatra.lock.json (no source text, translations or personal data)
local provenance verbatra.provenance.json (reviewer names)
local cache verbatra.cache.json (source text, translations, gitignored by init)
local local-state .verbatra-local (source text, host name and process ID of a run holding a write lock, gitignored by init)
request language-list verbatra doctor --live sends the API key
request dns-lookup each connection to a destination host
agent mcp verbatra mcp redactable
agent studio-agent-tools verbatra studio --expose-agent-toolsEl manifiesto nombra el proveedor; cada host de destino, de dónde sale (integrado, provider.options.baseUrl o una variable *_) y el veredicto de la política (permitted, deferred, refused o invalid-policy); los tipos de datos enviados, con el número de claves de origen, de claves con descripción o significado y de claves cuyos placeholders el proveedor no puede enmascarar (una estimación sobre las claves de origen: una ejecución solo envía claves que faltan o cambiaron y puede retener más con sensitiveData: redact); el código y el número de términos del glosario por locale de destino; los archivos locales con sus rutas relativas al proyecto y si contienen texto de origen, traducciones o datos personales; y las demás peticiones y superficies de agentes. DeepL aparece con sus dos hosts, porque la clave que elige uno nunca se lee. Un proxy en uso aparece con su variable y su host, nunca con sus credenciales, y los campos solo nombran lo que esta config puede enviar. Con provider: { id: "none" } indica que no se envía nada. Nombra hosts, categorías de datos y condiciones, nunca el valor de una clave ni el contenido de un archivo.
Con --json el manifiesto está en result.dataFlow. Su campo version solo cambia cuando se renombra o elimina un campo; pueden aparecer campos nuevos sin cambiarla, así que ignora los que no conozcas. dataFlowManifestSchema del SDK lo valida.
Salida JSON
Esquema: doctor-envelope.json valida el envoltorio completo; Esquemas enumera los demás.
Con --json, el envoltorio lleva el informe en result. ok es verdadero exactamente cuando el comando termina con 0:
interface DoctorResult {
ok: boolean; // true exactly when the command exits 0
checks: DoctorCheck[]; // one per check, always in the same order
literals?: LiteralScan; // only with --literals: findings, suppressed, diagnostics
dataFlow?: DataFlowManifest; // only with --data-flow: what goes where, version 1
locales?: LocaleCapabilityReport; // per-locale provider support, with or without --locales
}
interface DoctorCheck {
id:
| "config"
| "format-adapter"
| "provider"
| "api-key"
| "network-policy"
| "source-file"
| "plural-rules"
| "plural-completeness"
| "locale-codes"
| "locale-state"
| "limits" // 0.13.0
| "locales"
| "untranslated-literals"
| "data-flow";
title: string; // stable, human-readable name
status: "pass" | "warn" | "fail" | "skipped"; // only "fail" makes ok false
detail: string; // why it reached that verdict; never an API key value
fix?: string; // the next step, only on a failed check
}
interface LocaleCapabilityReport {
provider: string;
coverage: "listed" | "open"; // "open" for an LLM provider
tableVersion: string; // the table's date (YYYY-MM-DD)
tableOrigin: "static" | "live"; // "live" only when --live fetched the list
live?: { status: "refreshed" | "skipped" | "failed"; detail: string }; // only with --live
source: {
locale: string;
providerCode: string;
mapped: boolean;
support: "supported" | "unverified" | "unsupported";
warnings: { code: string; message: string }[];
};
locales: {
locale: string;
providerCode: string; // the code the provider receives
mapped: boolean; // true when localeMap set providerCode
support: "supported" | "unverified" | "unsupported";
glossary: boolean;
formality: boolean;
warnings: { code: string; message: string }[];
}[];
}result.locales no aparece cuando no se pudo cargar la configuración, con un proveedor desconocido ni con provider: { id: "none" }.
Información en el terminal
Mientras se ejecuta, doctor muestra una línea en stderr, que --quiet omite: checking the setup, checking the setup and fetching the provider's language list con --live, describing the data flow con --data-flow o scanning the source for literals con un recuento de archivos con --literals. El informe se queda en stdout. Consulta Salida en el terminal.
Códigos de salida
| Código | Significado |
|---|---|
0 | ninguna comprobación falló (un warn también sale con 0) |
1 | al menos una comprobación falló, incluido un locale no admitido; con --literals, se encontró un literal o no se pudo escanear un archivo |
2 | no pudo ejecutarse: un error de uso o una ruta --config explícita que no existe |
Una configuración que la búsqueda no encuentra, o que no pasa la validación, es una comprobación fallida (salida 1), porque informar de ello es justo la tarea del comando. Consulta el contrato de códigos de salida.
Relacionado
verbatra initcrea la configuración y el.env.exampleque validadoctor.verbatra checkes la puerta contra la deriva cuando la configuración ya está bien.- El archivo de configuración documenta cada clave que valida
doctor. - Proveedores lista la variable de clave de API que lee cada proveedor.
- Soporte de idiomas lista las tablas de idiomas que usa la comprobación Locale support.