Referenz / CLI
Maschinell übersetzte Seite
verbatra doctor
Prüfe, ob ein Projekt richtig eingerichtet ist, und erhalte jedes Problem in einem Bericht, ohne einen Provider aufzurufen oder einen API-Key zu lesen.
Prüfe, ob ein Projekt korrekt eingerichtet ist, und bekomm jedes Problem in einem einzigen Bericht. doctor konstruiert keinen Provider, schreibt keine Datei und liest den Wert eines API-Keys nur für --live, das ihn in einer Anfrage nach der Sprachliste des Providers mitsendet (LibreTranslate bekommt keinen). Nimm es nach verbatra init oder wenn ein anderer Befehl scheitert.
Synopsis
verbatra doctor [flags]Beispiele
# 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 | Argument | Standard | Wirkung |
|---|---|---|---|
--literals | keins | aus | statt der Einrichtung die Quell-Roots des extract-Blocks nach hartcodierten, für Nutzer sichtbaren Strings durchsuchen (siehe Nicht übersetzte Literale) |
--locales | keins | aus | nach den Prüfungen je Ziel-Locale den gesendeten Code, die Unterstützung durch den Provider, Glossar und Formality auflisten (siehe Locale-Unterstützung) |
--live | keins | aus | zuerst die aktuelle Sprachliste des Providers abrufen, ohne Übersetzungskontingent zu verbrauchen; schließt --locales ein |
--data-flow | keins | aus | statt der Einrichtung beschreiben, was an welchen Host geht und was lokal geschrieben wird (siehe Datenfluss) |
Nimmt außerdem die globalen Flags --cwd, --config und --json. --locales und --live lassen sich nicht mit --literals kombinieren (INVALID_, Exit 2), --data-flow mit keinem der drei.
Verhalten
Was geprüft wird
Ein Einrichtungslauf meldet diese Prüfungen in dieser Reihenfolge. Plural rules, Plural completeness, Locale codes, Locale state und Length limits sind rein informativ und schlagen nie fehl: Jede zeigt [warn], wenn sie etwas nennt, und sonst [ok ].
| Prüfung | Schlägt fehl, wenn |
|---|---|
| Configuration | keine Konfigurationsdatei gefunden wird oder sie die Validierung nicht besteht |
| Format adapter | das konfigurierte format zu keinem Datei-Adapter auflöst |
| Provider | die konfigurierte provider.id zu keiner Provider-Factory auflöst |
| API key environment variable | die Variable, aus der dieser Provider seinen Key liest, nicht gesetzt ist |
| Network policy | die wirksame Netzwerkrichtlinie den Host des Providers oder einen Proxy abweist, den er nutzen würde |
| Source locale file | die Quell-Locale-Datei unter ihrem aufgelösten Pfad fehlt, keine reguläre Datei ist oder sich im konfigurierten Format nicht parsen lässt |
| Plural rules | nie; nennt die genutzten ICU- und CLDR-Versionen und warnt, wenn eine Ziel-Locale keine ICU-Pluralregeln hat |
| Plural completeness | nie; warnt und nennt jeden Ziel-Plural, dem eine CLDR-Kategorie seiner Sprache fehlt, und beurteilt einen Plural ohne Formen im Ziel danach, was ein Lauf dort schreiben würde (eine leere Quellform zählt als fehlend, Plural-Generierung nur, wo sie wirklich läuft), bewusst strenger als der i18next-Hinweis von translate (höchstens zehn; verbatra check listet die Lücken in Plurals, die ein Ziel schon hat); übersprungen bei einem Format, das Pluralformen nicht nach CLDR-Kategorie speichert |
| Locale codes | nie; warnt und nennt jeden gültigen, aber nicht kanonischen Code wie en-us oder iw mit der kanonischen Form (siehe Locale-Codes) |
| Locale state | nie; warnt und nennt jede Locale, für die Lock-Datei, Cache oder Provenance-Datei Zustand halten, die die Konfiguration aber nicht aufführt, und ob translate sie übernimmt |
| Length limits | nie; warnt, wenn verbatra.limits.json sich nicht verwenden lässt (ein Lauf ignoriert sie, und ein Limit lässt sich erst nach der Reparatur setzen), nennt ein Limit für einen Schlüssel, den die Quelle nicht mehr hat, oder eines, das das maxLength der Konfiguration überschreibt, und sagt es, wenn sich die Quelle zum Prüfen der Schlüssel nicht lesen ließ; besteht, wenn die Datei fehlt (Längenlimits) neu |
| Locale support | der Provider die Quell-Locale oder eine Ziel-Locale nicht unterstützt; warnt, wenn eine Locale eine Warnung trägt (siehe Locale-Unterstützung) |
Jede Prüfung läuft auch dann, wenn eine frühere fehlgeschlagen ist. Die eine Ausnahme ist die Konfiguration: Kann sie nicht geladen werden, erscheinen die Prüfungen, die sie brauchen, als [skip] ("status": "skipped" in JSON), ebenso Plural completeness bei einem Format ohne CLDR-Pluralformen. Eine Prüfung, die etwas Beachtenswertes findet, ohne fehlzuschlagen, erscheint als [warn] ("status": "warn" in JSON) und ändert nie den Exit-Code. Eine fehlgeschlagene Prüfung trägt außerdem ein fix, einen nächsten Schritt im Imperativ, ausgegeben als fix:-Zeile und in JSON als "fix" mitgeliefert, damit ein Agent handeln kann, ohne detail zu parsen.
Ein Lauf mit zwei Problemen:
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)Keys und Dateien
- Der API-Key wird nur über den Namen geprüft:
doctorfragt, ob die Variable gesetzt ist, nie was sie enthält. Die Variable jedes Providers steht unter Provider. openai-compatiblefällt auf einen Platzhalter-Key zurück und scheitert nur, wenn die Konfiguration mitprovider.options.apiKeyEnvVareine eigene Variable benennt und diese nicht gesetzt ist.libretranslatelässt die Prüfung nie scheitern, weil sein Key optional ist.- Mit
provider: { id: "none" }bestehen die Prüfungen Provider, API key und Network policy, und Locale support wird übersprungen. - Eine fehlende Ziel-Datei ist in Ordnung:
translatelegt sie an. Die Quell-Datei wird geparst, also scheitert die Prüfung an einem Verzeichnis, einer leeren Datei oder fehlerhaftem Inhalt. doctorlädt zuerst die Umgebungsdateien, ein Key in einer dotenv-Datei zählt also als gesetzt; mit--literalslädt es keine der beiden.
Locale-Unterstützung
Die Prüfung Locale support fragt, ob der Provider jede konfigurierte Locale übersetzen kann. DeepL und Google Cloud Translation werden gegen eine datierte Sprachtabelle beurteilt, die verbatra mitliefert; ein LLM-Provider akzeptiert jede Locale. Sie scheitert genau an der Locale, die verbatra translate mit LOCALE_ ablehnen würde, und zeigt sonst [warn], wenn eine Locale eine Warnung trägt oder --live die Liste nicht abrufen konnte. Sprachunterstützung erklärt die Urteile.
--locales gibt nach den Prüfungen das Urteil je Locale aus:
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: noJede Zeile nennt die Locale, den Code, den der Provider bekommt (nach localeMap, dann mit (localeMap) markiert), das Urteil und ob ein Glossar und ein formal- oder informal-Tonfall greifen. Eine Warnung ist nur ein Hinweis.
--live urteilt stattdessen gegen die aktuelle Liste des Providers (DeepL /v3/languages, Cloud Translation languages, LibreTranslate /languages). Für LibreTranslate, das keine Tabelle mitbringt, ist das der einzige Weg zu einem anderen Urteil als unverified, daher zeigt Locale support [warn], bis --live läuft. Die Anfrage geht nur raus, wenn die Key-Variable gesetzt ist (LibreTranslate braucht keine) und die Netzwerkrichtlinie den Host erlaubt; sonst, oder wenn sie scheitert, gilt die mitgelieferte Tabelle, und eine Zeile live language list sagt, warum.
Nicht übersetzte Literale
--literals findet für Nutzer sichtbare Strings, die nie in einem Katalog gelandet sind. Es durchläuft die Quell-Roots deines extract-Blocks, liest deinen Quellcode und schreibt ihn nie, konstruiert keinen Provider, liest keinen Key und lädt keine .env-Datei. Nur zwei Prüfungen laufen: Configuration und Untranslated literals. Jeder Fund nennt Datei, Zeile und Spalte, mit zusammengefasstem Leerraum, aufgelösten JSX-Zeichenreferenzen und höchstens 80 Zeichen:
[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."Gemeldet werden: JSX-Text in .tsx-, .jsx- und .js-Dateien, für Nutzer sichtbare JSX-Attribute (alt, title, placeholder, label, aria-label und die anderen Text tragenden aria-*) und jeder andere String aus zwei oder mehr Wörtern.
Nie gemeldet werden:
- ein String, der an
t(...),$t(...),i18n.t(...)oder ein umbenanntestaususeTranslationgeht oder in<Trans>oder<Translation>gerendert wird; - Objekt-Keys, Import-Specifier, Klassennamen, CSS-Werte, Test-IDs,
data-*sowie ID- oder Schlüsselwort-Attribute (aria-describedby,aria-labelledby,aria-controls,rel,sandbox,allow,autoComplete,referrerPolicy,crossOrigin), URLs und Strings ohne Buchstaben; - Literale an einer Typposition (der Wert vor
asodersatisfieswird weiter geprüft), Log-Meldungen, Fehlermeldungen (new ValidationError(...),throw Error(...)), Vergleichsoperanden und Template-Literale mit Ausdruck; - direkte Argumente von
describe(zod),query,execute,prepare,format,parse,z.enum,setItem,getItemundremoveItemsowie das erste Argument vonon,off,once,emit,addEventListenerund einemgetodersetauf einem Objekt; tiefer verschachtelter Text und Meldungen an Funktionen wiesetErrorwerden weiter gemeldet; - alles in Test-, Story-, Deklarations- und Konfigurationsdateien.
Um ein Literal zurückzuhalten, setz // verbatra-ignore-next-line darüber (in JSX {/* verbatra-ignore-next-line */}) oder // verbatra-ignore-line ans Ende seiner Zeile. Eine Next-Line-Direktive zielt auf die nächste Zeile mit Code und bei einem öffnenden JSX-Tag auf alle seine Attribute. Einen String, der überall passt, trägst du mit aufgelösten Referenzen (Tom & Jerry) unter extract.literals.ignore ein. Unterdrückte Literale werden trotzdem mit Grund aufgeführt.
Die Prüfung scheitert an einem Fund und an einer Datei, die sie nicht öffnen, nicht bis zum Ende lesen oder als zu groß einstuft (der Scan läuft weiter). Ein Projekt ohne extract-Block lässt sie scheitern.
Datenfluss
--data-flow beschreibt statt der Einrichtung, wohin die Daten dieses Projekts gehen, als Nachweis für ein AVV- oder NDA-Review; Datenverarbeitung erklärt jede Kategorie. Es liest keinen API-Key und macht keinen Netzwerk-Request. Nur zwei Prüfungen laufen: Configuration und Data flow. Data flow schlägt nie fehl: Es zeigt [warn], wenn die Network Policy einen Host ablehnt oder einen ungültigen Wert hat, oder wenn die Quelldatei für die Zählungen nicht lesbar ist.
[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-toolsDas Manifest nennt den Provider; jeden Ziel-Host, woher er kommt (eingebaut, provider.options.baseUrl oder eine *_-Variable) und das Urteil der Policy (permitted, deferred, refused oder invalid-policy); die Arten gesendeter Daten, mit der Zahl der Quell-Keys, der Keys mit Beschreibung oder Bedeutung und der Keys, deren Platzhalter der Provider nicht maskieren kann (eine Schätzung über die Quell-Keys: Ein Lauf sendet nur fehlende oder geänderte Keys und kann unter sensitiveData: redact mehr zurückhalten); Code und Zahl der Glossarbegriffe je Ziel-Locale; die lokalen Dateien mit ihren projektrelativen Pfaden und ob sie Quelltext, Übersetzungen oder personenbezogene Daten enthalten; und die übrigen Requests und Agent-Schnittstellen. DeepL steht mit beiden Hosts drin, weil der Key, der einen davon wählt, nie gelesen wird. Ein wirksamer Proxy steht mit Variable und Host drin, nie mit seinen Zugangsdaten, und die Felder nennen nur, was diese Config senden kann. Mit provider: { id: "none" } sagt es, dass nichts gesendet wird. Es nennt Hosts, Datenkategorien und Bedingungen, nie einen Key-Wert oder Dateiinhalte.
Mit --json steht das Manifest unter result.dataFlow. Sein Feld version ändert sich nur, wenn ein Feld umbenannt oder entfernt wird; neue Felder können ohne Erhöhung dazukommen, ignoriere also die, die du nicht kennst. dataFlowManifestSchema aus dem SDK validiert es.
JSON-Ausgabe
Schema: doctor-envelope.json validiert den ganzen Envelope; Schemas listet die übrigen auf.
Mit --json trägt der Envelope den Bericht unter result. ok ist genau dann wahr, wenn der Befehl mit 0 endet:
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 fehlt, wenn die Konfiguration nicht geladen werden konnte, bei einem unbekannten Provider und bei provider: { id: "none" }.
Rückmeldung im Terminal
Während es läuft, zeigt doctor eine Zeile auf stderr, die --quiet weglässt: checking the setup, unter --live checking the setup and fetching the provider's language list, unter --data-flow describing the data flow oder unter --literals scanning the source for literals mit Dateianzahl. Der Bericht bleibt auf stdout. Siehe Terminalausgabe.
Exit-Codes
| Code | Bedeutung |
|---|---|
0 | keine Prüfung fehlgeschlagen (auch ein warn endet mit 0) |
1 | mindestens eine Prüfung ist fehlgeschlagen, auch bei einer nicht unterstützten Locale; mit --literals: ein Literal gefunden oder eine Datei nicht scannbar |
2 | konnte nicht laufen: ein Verwendungsfehler oder ein explizit angegebener --config-Pfad, der nicht existiert |
Eine Konfiguration, die die Suche nicht findet oder die die Validierung nicht besteht, ist eine fehlgeschlagene Prüfung (Exit 1), denn genau das zu melden ist die Aufgabe des Befehls. Siehe den Exit-Code-Vertrag.
Siehe auch
verbatra initerzeugt die Konfiguration und die.env.example, diedoctorprüft.verbatra checkist das Drift-Gate, sobald die Einrichtung steht.- Die Konfigurationsdatei dokumentiert jeden Key, den
doctorvalidiert. - Provider listet die API-Key-Variable, die jeder Provider liest.
- Sprachunterstützung listet die Sprachtabellen, die die Prüfung Locale support nutzt.