verbatra doctor
Prüfe die Projekteinrichtung, ohne einen Provider aufzurufen oder einen API-Key zu lesen.
Maschinell übersetzte Seite
Verfügbar ab 0.9.0
Beantworte eine Frage, bevor du irgendetwas anderes ausführst: Ist dieses Projekt korrekt eingerichtet? doctor prüft die Konfiguration, den Format-Adapter, den Provider, die API-Key-Variable und die Quell-Locale-Datei und meldet dann alle gefundenen Probleme auf einmal. Es kostet nichts: kein Provider wird konstruiert, keine Netzwerkanfrage gestellt, keine Datei geschrieben, und kein API-Key-Wert wird je gelesen.
Nimm ihn bei einem frischen Checkout, direkt nach verbatra init, oder immer dann, wenn ein anderer Befehl fehlgeschlagen ist und du die vollständige Liste statt des ersten Fehlers willst. verbatra check ist die günstigste Prüfung, sobald ein Projekt schon funktioniert, aber es liest die Locale-Dateien und bricht beim ersten Fehler des gesamten Laufs ab, kann dir also nicht sagen, was an einem Projekt falsch ist, das noch keine Quelldatei hat.
Synopsis
verbatra doctor [flags]Flags
| Flag | Argument | Standard | Wirkung |
|---|---|---|---|
--cwd | <path> | aktuelles Verzeichnis | Konfiguration und Locale-Dateien von diesem Verzeichnis aus auflösen |
--config | <path> | wird gesucht | diese Konfigurationsdatei laden, statt eine zu suchen |
--literals | keins | aus | statt der Einrichtung die Quell-Roots des extract-Blocks nach hartcodierten, für Nutzer sichtbaren Strings durchsuchen (siehe Nicht übersetzte Literale) |
--json | keins | aus | einen JSON-Envelope auf stdout ausgeben, der den Bericht unter result trägt; die menschenlesbare Fehlerzeile geht weiter auf stderr |
Was geprüft wird
| Prüfung | Besteht, wenn |
|---|---|
| Configuration | eine Konfigurationsdatei gefunden wurde und die Validierung besteht |
| Format adapter | das konfigurierte format zu einem Datei-Adapter auflöst |
| Provider | die konfigurierte provider.id zu einer Provider-Factory auflöst |
| API key environment variable | die Variable gesetzt ist, aus der dieser Provider seinen Key liest |
| Source locale file | die Quell-Locale-Datei unter ihrem aufgelösten Pfad existiert, eine reguläre Datei ist und sich im konfigurierten Format parsen lässt |
Jede Prüfung läuft auch dann, wenn eine frühere fehlgeschlagen ist; ein Lauf meldet also jedes unabhängige Problem. Die einzige Ausnahme ist die Konfiguration selbst: Kann sie nicht geladen werden, werden die vier Prüfungen, die sie brauchen, übersprungen, statt zu einem Urteil zu kommen. Eine solche Prüfung erscheint im menschenlesbaren Bericht als [skip] und trägt im --json-Envelope "status": "skipped".
Vier Details sind wichtig:
- Der API-Key wird nur über den Namen geprüft.
doctorfragt, ob die Variable gesetzt ist, nie was sie enthält. Der Wert wird nicht gelesen, nicht ausgegeben und nirgendwohin gesendet. Welche Variable welcher Provider nutzt, steht unter Provider. - Der Provider
openai-compatibleist die Ausnahme. Er fällt auf einen Platzhalter-Key zurück, eine fehlende Variable ist also in Ordnung. Er schlägt nur fehl, wenn deine Konfiguration überprovider.options.apiKeyEnvVareine eigene Variable benennt und diese nicht gesetzt ist. - Eine fehlende Ziel-Locale-Datei ist kein Problem:
verbatra translatelegt sie an. Ziel-Dateien werden überhaupt nicht geprüft. - Die Quell-Locale-Datei wird gelesen und geparst, nicht nur auf Existenz geprüft. Ein Verzeichnis an ihrer Stelle, eine leere Datei und fehlerhafter Inhalt scheitern alle an dieser Prüfung, mit derselben Meldung, die auch
verbatra checkausgeben würde, denn genau diese Fälle bringen jeden anderen Befehl zum Scheitern. Wenn das konfigurierteformatzu keinem Adapter auflöst, gibt es nichts zum Parsen, also fällt die Prüfung auf die reine Existenz zurück und sagt das auch.
Wie verbatra translate lädt doctor .env.local und dann .env aus dem Arbeitsverzeichnis, bevor es die Umgebung ansieht; ein Key in einer dotenv-Datei zählt also als gesetzt. Mit --literals lädt es keine der beiden Dateien.
Nicht übersetzte Literale
Verfügbar ab 0.11.0
verbatra doctor --literals sucht nach dem einen i18n-Fehler, den keine andere Prüfung sieht: einem für Nutzer sichtbaren String, der nie in einem Katalog gelandet ist. Es durchläuft die Quell-Roots deines extract-Blocks und meldet jeden hartcodierten String, der sich wie Text für Nutzer liest, aber durch keinen Übersetzungsaufruf geht. Es liest deinen Quellcode und schreibt ihn nie, konstruiert keinen Provider, liest keine API-Key-Variable und lädt keine .env-Datei; es besteht also auch in einem Job ohne Secrets. In diesem Modus laufen nur zwei Prüfungen: die Konfiguration und der Literal-Scan.
Jeder Fund nennt Datei, Zeile und Spalte. In seinem Text wird Leerraum zusammengefasst, in JSX werden Zeichenreferenzen wie & aufgelöst, und er wird auf höchstens 80 Zeichen gekürzt:
verbatra doctor
[ok ] Configuration: Loaded /app/verbatra.config.ts.
[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."
1 problem found (run verbatra doctor again after fixing them)Was als Fund zählt:
- JSX-Text wie
<p>Welcome back</p>in.tsx-,.jsx- und.js-Dateien. - Der Wert eines für Nutzer sichtbaren JSX-Attributs:
alt,title,placeholder,label,aria-labelund die anderen Text tragendenaria-*-Attribute. - Ein String an jeder anderen Stelle, der sich wie Fließtext liest, also aus zwei oder mehr Wörtern besteht. Ein einzelnes Wort außerhalb von JSX, etwa ein Event-Name oder ein Optionswert, wird nicht gemeldet.
Was nie gemeldet wird: ein String, der an einen erkannten Übersetzungsaufruf (t(...), $t(...), i18n.t(...) oder ein aus useTranslation umbenanntes t, wie in const { t: translate } = useTranslation(), ab dieser Zeile bis zum Ende des umschließenden Blocks) übergeben oder in <Trans> oder <Translation> gerendert wird, ein Objekt-Key, ein Import-Specifier, ein Klassenname oder CSS-Wert, eine Test-ID oder ein data-*-Attribut, ein Attribut, das IDs oder ein Schlüsselwort statt Text enthält (etwa aria-describedby, aria-labelledby, aria-controls, rel, sandbox, allow, autoComplete, referrerPolicy oder crossOrigin), eine URL, ein Literal an einer Typposition (auch eines nach as oder satisfies; der Wert davor, wie in "Welcome" as const, wird weiter geprüft), eine Log-Meldung, die Meldung eines konstruierten Fehlers (new ValidationError(...)) oder eines eingebauten Fehlers, der ohne new aufgerufen wird (throw Error(...)), ein Vergleichsoperand, ein Template-Literal mit Ausdruck, ein String ohne Buchstaben (Satzzeichen, Leerraum, eine Zahl, ein Emoji, ein Symbol) und alles in Test-, Story-, Deklarations- und Konfigurationsdateien.
Aufrufe, die eine Abfrage, ein Format oder einen Namen statt Text erwarten, werden ebenfalls übersprungen: ein String, der direkt als Argument an describe (zod), query, execute, prepare, format oder parse übergeben wird, ein String im Array, das direkt an z.enum geht, jedes String-Argument von setItem, getItem und removeItem sowie das erste Argument von on, off, once, emit, addEventListener und einem get- oder set-Aufruf auf einem Objekt wie cookies().get(...). Nur die direkten Argumente werden übersprungen: Text, der tiefer in so einem Aufruf steckt, etwa in einem Callback (query(() => ({ message: "..." }))), einem Objekt oder JSX, wird weiter gemeldet. Eine Funktion, deren Name nur zufällig auf Error endet, etwa setError oder showError, wird nicht übersprungen; die Meldung, die du ihr übergibst, wird also weiter gemeldet.
Um ein einzelnes Literal zurückzuhalten, setze // verbatra-ignore-next-line darüber (in JSX {/* verbatra-ignore-next-line */}) oder // verbatra-ignore-line ans Ende seiner eigenen Zeile. Eine Next-Line-Direktive zielt auf die nächste Zeile mit Code (leere Zeilen und Zeilen nur mit Kommentaren werden übersprungen) und gilt für jedes Literal, das in dieser Zeile beginnt. Beginnt dort ein öffnendes JSX-Tag, gilt sie auch für alle Attribute dieses Tags, selbst wenn das Tag über mehrere Zeilen geht. Text und verschachtelte Elemente in späteren Zeilen deckt sie nicht ab; gib ihnen jeweils eine eigene Direktive. Für einen String, der überall in Ordnung ist, etwa einen Markennamen, trage ihn unter extract.literals.ignore in der Konfigurationsdatei ein. Ein Eintrag trifft den Text so, wie er gemeldet wird, mit aufgelösten Zeichenreferenzen, also schreibe Tom & Jerry, nicht Tom & Jerry. Ein zurückgehaltenes Literal wird trotzdem als unterdrückt aufgeführt, mit Grund; nichts verschwindet stillschweigend.
Die Prüfung schlägt fehl, wenn sie ein Literal findet, und auch dann, wenn eine Datei nicht gescannt werden konnte. Eine Datei, die der Scanner nicht bis zum Ende lesen kann (ein nicht geschlossener Kommentar oder Template-Literal oder ein JSX-Element, das nie geschlossen wird oder vom Tag eines umgebenden Elements geschlossen wird), sie gar nicht erst öffnen kann oder sie als zu groß einstuft, wird als nicht gescannt aufgeführt, und der restliche Scan läuft weiter, aber der Lauf wird nie als sauber gemeldet. Ein generischer Funktionstyp wie type Fn = <T>(x: T) => T oder eine Typparameterliste wie <const T extends object = {}>(x: T) => x in einer .tsx-Datei wird als normaler Code gelesen und lässt die Datei also nie scheitern, und ein Element mit beliebig langen Typargumenten, etwa <Table<Row>>, wird weiter als JSX gelesen. Ein Projekt ohne extract-Block lässt die Prüfung mit einer Meldung scheitern, die den Block nennt. Mit --json steht der Scan im Envelope unter result.literals, aufgeteilt in findings, suppressed und diagnostics.
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 in your source, with no key set
verbatra doctor --literalsEin Lauf mit zwei Problemen sieht so aus:
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.
[fail] Source locale file: The source locale file was not found at /app/locales/en.json.
2 problems found (run verbatra doctor again after fixing them)Exit-Codes
| Code | Bedeutung |
|---|---|
0 | alle Prüfungen bestanden |
1 | mindestens eine Prüfung ist fehlgeschlagen (der vollständige Bericht wird trotzdem ausgegeben); mit --literals: ein Literal wurde gefunden oder eine Datei konnte nicht gescannt werden |
2 | konnte nicht laufen: ein Verwendungsfehler oder ein explizit angegebener --config-Pfad, der nicht existiert |
Exit 1 heißt "es lief, und es wurden Probleme gefunden". Exit 2 ist dafür reserviert, dass doctor überhaupt nicht laufen kann. Deshalb ist eine per Suche nicht gefundene Konfigurationsdatei eine fehlgeschlagene Prüfung und Exit 1, während ein --config-Pfad ins Leere Exit 2 ergibt.
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.