Referenz / CLI
Maschinell übersetzte Seite
verbatra init
Lege eine verbatra-Konfiguration und ein .env-Beispiel für dieses Projekt an, erkannt aus deinen Locale-Dateien, interaktiv oder vollständig unbeaufsichtigt.
Setze ein Projekt auf: init schreibt eine verbatra.config.ts, eine .env.example, die die API-Key-Variable deines Providers nennt (nie einen Key-Wert), und die .gitignore-Einträge für .env, .env.local, .verbatra-local/ und verbatra.cache.json. Es liest zuerst die Locale-Dateien im Projekt, meist musst du ihm also nur den Provider sagen.
Synopsis
verbatra init [flags]Beispiele
# prompt for anything not passed or detected
verbatra init --provider gemini
# fully unattended, one JSON document on stdout
verbatra init --provider gemini --yes --json
# choose the format and pattern yourself
verbatra init --provider deepl --format yaml --path "config/locales/{locale}.yml" --yes
# a local server that needs no key
verbatra init --provider openai-compatible --base-url http://localhost:11434/v1 --model llama3.1 --yes
# a self-hosted LibreTranslate server, no language model
verbatra init --provider libretranslate --base-url http://localhost:5000 --yes
# human-only: no provider, no API key
verbatra init --provider none --yes
# also set the project up for coding agents
verbatra init --provider gemini --yes --agent
# wire Cursor and VS Code, and only show what would change
verbatra init --agent --client cursor,vscode --dry-runFlags
| Flag | Argument | Standard | Wirkung |
|---|---|---|---|
--provider | <id> | keiner (erforderlich, sofern nicht abgefragt) | Provider, der aufgesetzt wird: anthropic, openai, gemini, deepl, google-translate, opencode, openai-compatible, libretranslate oder none |
--format | <id> | erkannt, sonst i18next-json | das Format der Locale-Dateien, eine der IDs unter Formate |
--source | <locale> | erkannt, sonst en | die Quell-Locale, in der deine Strings geschrieben sind |
--targets | <locales> | erkannt, sonst de | kommagetrennte Ziel-Locales, in die übersetzt wird |
--path | <pattern> | erkannt, sonst das übliche Layout des Formats (Erkennung) | Muster der Locale-Dateien; muss das Token {locale} enthalten |
--model | <name> | der Standard des Scaffolds | das Modell; erforderlich für openai-compatible, optional für anthropic, openai, gemini und opencode |
--base-url | <url> | keiner | die Server-URL; nur für openai-compatible und libretranslate und dort erforderlich |
--api-key-env-var | <name> | OPENAI_ | die Variable, aus der openai-compatible seinen Key liest |
--yes | keins | aus | nie nachfragen; für alles, was weder übergeben noch erkannt wurde, den Standardwert nehmen |
--force | keins | aus | eine bestehende verbatra.config.ts mit abweichendem Inhalt überschreiben |
--agent | keins | aus | zusätzlich den Abschnitt für Coding-Agenten in AGENTS.md oder CLAUDE.md und den verbatra-MCP-Server in die Projektkonfiguration jedes erkannten Clients schreiben (Coding-Agenten einrichten) |
--client | <ids> | erkannt | kommagetrennte Clients, die --agent statt der erkannten einrichtet: claude, cursor, vscode, codex, gemini oder all; braucht --agent |
--dry-run | keins | aus | jede Datei melden, die init schreiben oder ändern würde, und nichts schreiben (Probelauf) |
Nimmt außerdem die globalen Flags --cwd und --json, aber nicht --config. Hier ist --cwd das Verzeichnis, das durchsucht und beschrieben wird, und es muss schon existieren. --json fragt nie nach.
Verhalten
Rückfragen
Ein Flag gewinnt immer. Was du weglässt, wird aus dem Projekt erkannt, dann abgefragt, wenn stdin ein Terminal ist und weder --yes noch --json angegeben ist, und sonst nur unter --yes aus seinem Standardwert genommen. Enter übernimmt den vorgeschlagenen Wert. Ein Flag mit leerem Wert, etwa --targets '', ist ein Verwendungsfehler (INVALID_) und nie eine Bitte um den Standardwert. Endet stdin bei einer Abfrage (Ctrl-D), bricht init mit 2 und MISSING_ ab.
Jede Antwort wird sofort geprüft. Eine ungültige wird auf stderr erklärt und bis zu dreimal neu abgefragt, deine bisherigen Antworten bleiben erhalten; nach der dritten ungültigen Antwort bricht init mit dem Fehlercode dieser Antwort ab (etwa INVALID_), nennt das Flag, das du stattdessen übergeben kannst, und schreibt nichts.
Erkennung
init durchsucht das Verzeichnis nach Dateien, die ein Format-Adapter beansprucht, überspringt versteckte Verzeichnisse, node_ und Build-Ausgabe und findet den Teil jedes Pfads, der eine Locale ausschreibt, etwa de.json, messages_, de.lproj/ oder Androids values-de/. Das Dateimuster, das die meisten Locales abdeckt, gewinnt, und daraus ergeben sich:
format: das eine Format, dessen Adapter jede gefundene Datei liest. Jeder JSON-Adapter liest.json, deshalb entscheidet bei JSON-Dateien eine einzelne passende Dependency inpackage.json(i18next,vue-i18n,next-intloder@ngx-translate/core).files.patternundfiles.localeStyle:posix, wenn die Dateienpt_schreiben,BR androidfürvalues-*-Verzeichnisse, sonstliteral.sourceLocale: die Quellsprache eines.xcstrings-Katalogs, sonstenoder die einzige gefundeneen-*-Locale, sonst die einzige gefundene Locale.targetLocales: jede andere gefundene Locale.
Eine Datei neben den Locale-Dateien, die Strings unter keinem Locale-Namen enthält, etwa messages.properties, Strings.resx oder eine gettext-Datei app.pot, wird als unqualifiedSourceFile gemeldet. verbatra kann die Quelle nicht aus so einer Datei lesen, deshalb rät init die Quell-Locale nicht: Übergib --source, auch mit --yes, und die nächsten Schritte nennen die Datei, in die du die Basisdatei umbenennen oder kopieren sollst.
Gibt es gar keine Locale-Datei, entscheiden allein die Dependencies über das Format, und das Muster folgt dem üblichen Layout des Formats, wie es für jedes Format unter Wähle deinen Stack steht.
Ein apple-xcstrings-Katalog ist eine einzige Datei für alle Locales, und verbatra legt ihn nie an: Erstelle ihn zuerst in Xcode. --format, --path und --source grenzen die Erkennung ein, statt von ihr überschrieben zu werden, --format yaml sieht sich also nur YAML-Dateien an.
init rät nie zwischen Gleichwertigen. Lesen mehrere Formate die Dateien (reines JSON ohne i18n-Dependency), endet es mit 2 und FORMAT_, und liegen mehrere Dateimuster gleichauf (eine Datei pro Namespace), mit 2 und LAYOUT_. Beide listen die Kandidaten auf; übergib --format oder --path, um einen zu wählen. Am Terminal fragt es stattdessen nach.
Unbeaufsichtigte Läufe
Ohne Terminal oder mit --json fragt init nie nach. Ein Wert, der weder übergeben noch erkannt noch durch --yes gefüllt wird, ist ein Fehler: init endet mit 2 und MISSING_ und nennt alle fehlenden Flags auf einmal. Eine Mehrdeutigkeit oder ein ungültiges Flag listet zusätzlich die noch fehlenden Flags auf, sodass ein einziger Lauf einem Agenten alles sagt, was er übergeben muss. --provider hat keinen Standardwert, ebenso wenig --base-url und --model für openai-compatible oder --base-url für libretranslate. Diesen Befehl führt ein Agent aus:
npx @verbatra/cli init --provider gemini --yes --jsonJSON-Ausgabe
Schema: init-envelope.json validiert den ganzen Envelope; Schemas listet die übrigen auf.
Mit --json steht auf stdout genau ein Envelope. Sein result:
interface InitResult {
configPath: string; // absolute path of verbatra.config.ts, or of the config --agent kept
files: { path: string; action: "created" | "overwritten" | "updated" | "unchanged" }[];
dryRun: boolean; // true under --dry-run: files holds the planned actions
config: { // the config that was validated and written
sourceLocale: string;
targetLocales: string[];
format: string;
files: { pattern: string; localeStyle?: "posix" | "android" };
provider: { id: string; options?: Record<string, unknown> };
sensitiveData?: { mode: "warn" };
} | null;
sources: { // where each value came from
provider: "flag" | "prompt";
format: "flag" | "prompt" | "files" | "dependencies" | "default";
pattern: "flag" | "prompt" | "detected" | "default";
sourceLocale: "flag" | "prompt" | "detected" | "default";
targetLocales: "flag" | "prompt" | "detected" | "default";
} | null;
apiKeyEnvVar: string | null; // the variable to set; null for provider none
detection: {
format: { id: string; from: "input" | "files" | "dependencies" } | null;
layout: {
pattern: string;
localeStyle: "literal" | "posix" | "android";
locales: string[];
sourceLocale: string | null;
unqualifiedSourceFile: string | null;
files: string[];
} | null;
ambiguities: { subject: "format" | "layout"; candidates: string[] }[];
confidence: "high" | "medium" | "low" | "none";
reasons: string[]; // one sentence per decision or doubt
} | null;
agent: { // null without --agent
instructionsFile: "AGENTS.md" | "CLAUDE.md";
mcpServer: "added" | "present" | "differs" | "skipped" | null; // Claude Code; null when not wired
configKept: boolean; // true when --agent kept an existing config
clients: {
id: "claude" | "cursor" | "vscode" | "codex" | "gemini";
file: string; // the client's config file, such as .mcp.json
server: "added" | "present" | "differs" | "skipped";
reason: "plugin" | "symlink" | null; // why the client was skipped
selectedBy: "flag" | "markers" | "default";
markers: string[]; // the client's marker files found in the project
}[];
} | null;
nextSteps: { description: string; command: string | null }[];
}confidence ist high, wenn allein die Dateien alles entschieden haben, medium, wenn eine Konvention oder eine Dependency eine Lücke gefüllt hat (etwa en als Quelle) oder eine Lücke offen blieb, low, wenn keine Locale-Datei das Format gestützt hat, und none, wenn nichts erkannt wurde. Ein default in sources ist der Wert, den du noch einmal prüfen solltest. nextSteps endet mit den genauen nächsten Befehlen.
Ein Fehler-Envelope für FORMAT_, LAYOUT_, INVALID_ oder INVALID_ trägt zusätzlich candidates, die Werte zur Auswahl. Jeder Verwendungsfehler, der Flags unbeantwortet lässt, trägt missing mit ihren Namen, etwa "--source <locale>".
Provider
--provider nonelegt eine rein menschliche Konfiguration ohneoptionsan und schreibt keine.env.example, weil nie ein API-Key gelesen wird.--provider openai-compatiblesetzt einen lokalen oder selbst gehosteten Server aus--base-urlund--modelauf, mitmaxOutputTokens: 4096. Sein Key ist optional: Ein Server, der keinen braucht, lässtOPENAI_ungesetzt, undCOMPATIBLE_ API_ KEY --api-key-env-varnennt eine andere Variable, in Großbuchstaben wieLLM_. Ein abgelehnter Wert wird nie wiederholt, falls es der Key selbst war.API_ KEY --provider libretranslatesetzt einen selbst gehosteten LibreTranslate-Server allein aus--base-urlauf, etwahttp://localhost:5000, und lehnt--modelund--api-key-env-varab..env.examplenenntLIBRETRANSLATE_für einen Server, der mitAPI_ KEY --api-keysgestartet wurde.
init schreibt den Namen einer Variable in die Konfiguration und in .env.example, nie einen Wert, und lehnt eine Base-URL mit Zugangsdaten, Query-String oder Fragment ab (https://user:key@host, https://host/v1?api-key=...), über die ein Key in der eingecheckten Konfiguration landen könnte.
Bestehende Dateien
Ein erneutes init mit denselben Antworten ändert nichts und ist erfolgreich. Eine verbatra.config.ts mit anderem Inhalt wird mit CONFIG_ abgelehnt, außer du übergibst --force, und diese Ablehnung kommt vor jeder Frage und jedem anderen Fehler. Eine andere verbatra-Konfiguration im Verzeichnis (eine .verbatrarc.json oder eine verbatra-Property in package.json) wird auch unter --force abgelehnt, weil sie zuerst gelesen würde. Wenn init ablehnt, wird nichts geschrieben. Deckt eine Konfiguration in einem übergeordneten Verzeichnis dieses mit ab, warnt init auf stderr (auch im Dry Run): Die neue verbatra.config.ts ersetzt sie hier.
Ein Verzeichnis, in das init nicht schreiben kann, wird mit INIT_ abgelehnt, samt der Datei und jeder schon geschriebenen Datei. Eine verbatra.config.ts, .env.example oder .gitignore, die ein symbolischer Link aus dem Projekt hinaus oder ins Leere ist, wird mit INIT_ abgelehnt, bevor irgendetwas geschrieben wird. Eine bestehende .env.example bleibt; nennt sie die Key-Variable noch nicht, wird genau diese Zeile angehängt, und unter --force wird eine Kopfzeile, die init selbst geschrieben hat, für den neuen Provider neu geschrieben. .gitignore bekommt nur die Einträge, die ihr fehlen.
Probelauf
--dry-run durchläuft jede Prüfung und Ablehnung eines echten Laufs außer einem fehlgeschlagenen Schreibvorgang, etwa in einem schreibgeschützten Verzeichnis, gibt für jede Datei would create, would update, would overwrite oder unchanged aus und schreibt nichts. Das JSON-Ergebnis listet die geplanten Aktionen und setzt dryRun auf true.
Coding-Agenten einrichten
--agent bereitet das Projekt zusätzlich für Coding-Agenten vor. Es schreibt keinen Key-Wert, schreibt nie durch einen Link aus dem Projekt hinaus und legt an:
- Die Anweisungsdatei. Ein verbatra-Abschnitt zwischen den Markierungen
<!-- verbatra:start -->und<!-- verbatra:end -->, Wort für Wort das Snippet aus Deinem Agenten von verbatra erzählen. Es landet inAGENTS.mdoder inCLAUDE.md, wenn das die einzige Anweisungsdatei ist; gibt es beide, gewinntAGENTS.md. Enthält eine Datei den Abschnitt schon, wird der Text zwischen den Markierungen durch den aktuellen ersetzt und alsupdatedgemeldet, oder alsunchanged, wenn er schon passt. - Die MCP-Konfiguration jedes Clients. Der
verbatra-Servereintrag aus MCP-Client verbinden,npx -y @verbatra/mcpohne--allow-spendund ohneVERBATRA_, sodass die Tools, die Geld kosten, verborgen bleiben.MCP_ ALLOW_ SPEND @verbatra/cliexportiert diese Einträge alsAGENT_.CLIENT_ CONFIGS
| Client | --client | Datei | Erkannt an |
|---|---|---|---|
| Claude Code | claude | .mcp.json | CLAUDE.md, .claude/, .mcp.json |
| Cursor | cursor | .cursor/mcp.json | .cursor/, .cursorrules |
| VS Code | vscode | .vscode/mcp.json, unter servers | .vscode/mcp.json |
| Codex | codex | .codex/config.toml, als [mcp_ | .codex/ |
| Gemini CLI | gemini | .gemini/settings.json | .gemini/, GEMINI.md |
init richtet jeden erkannten Client ein, und nur Claude Code, wenn es keine Markierungsdatei findet. AGENTS.md wählt die Anweisungsdatei, keinen Client. Ein .vscode-Ordner ohne mcp.json wird nicht eingerichtet: Ein nächster Schritt nennt den Befehl dafür. Gemini CLI liest GEMINI.md: Laden seine Einstellungen oder GEMINI.md die Anweisungsdatei nicht, sagt ein nächster Schritt, wie. Ein erkannter Client, dessen Konfigurationspfad über einen symbolischen Link führt, wird mit dem Grund symlink und einem nächsten Schritt übersprungen. --client ersetzt die Erkennung; eine unbekannte ID, eine leere Liste oder --client ohne --agent endet mit 2 und INVALID_ samt den Kandidaten.
Außerhalb der Markierungen wird nichts angefasst, und andere Server und Schlüssel behalten ihre Bytes, Einrückung und Zeilenenden, wenn die Datei einen Eintrag pro Zeile hat; sonst wird sie mit demselben Inhalt neu geschrieben. Die Codex-Tabelle wird angehängt. Ein vorhandener verbatra-Server wird nie angefasst: Die Datei wird als unchanged gemeldet, und server des Clients ist present, wenn der Eintrag dem Scaffold entspricht, oder differs, wenn nicht, was zusätzlich einen Hinweis in nextSteps ergibt.
Aktiviert .claude/settings.json oder .claude/settings.local.json das verbatra-Plugin für Claude Code, überspringt init die .mcp.json: Claude Code wird als skipped mit dem Grund plugin und einem nächsten Schritt gemeldet, und ein vorhandener Eintrag wird nie gelöscht. Eine Einstellungsdatei hinter einem symbolischen Link wird ignoriert.
In einem Projekt, das schon eine Konfiguration hat, schreibt init --agent nur die Agenten-Dateien, behält die Konfiguration, gibt kept verbatra.config.ts aus, fragt nie nach und erkennt nichts. Das JSON-Ergebnis führt die Konfiguration als unchanged, setzt agent.configKept auf true und enthält null für config, sources, apiKeyEnvVar und detection. Ein Konfigurations-Flag oder --force nimmt die Konfiguration wieder in den Lauf auf, wie ohne --agent.
init lehnt mit AGENT_ ab, bevor irgendetwas geschrieben wird, wenn eine Client-Datei kein reines JSON ist (Kommentare oder nachgestellte Kommas schreibt es nie um), kein Objekt ist, einen Schlüssel wiederholt oder einen Server-Wert hat, der kein Objekt ist; wenn .codex/config.toml mcp_ oder den verbatra-Server inline, mit gepunkteten Schlüsseln oder als Array von Tabellen setzt, diese Tabelle oder einen Schlüssel darin wiederholt oder einen nicht abgeschlossenen String, ein offenes Array oder einen offenen Header hat; wenn ein Client, den --client nennt, einen symbolischen Link auf seinem Konfigurationspfad hat oder eine Anweisungsdatei aus dem Projekt hinaus verlinkt; oder wenn die Anweisungsdatei eine ungepaarte, falsch geordnete oder doppelte Markierung hat. Die Meldung zitiert die Datei nie.
Exit-Codes
| Code | Bedeutung |
|---|---|
0 | Dateien geschrieben oder schon auf dem aktuellen Stand |
2 | ein Verwendungsfehler: MISSING_, INVALID_, INVALID_, INVALID_, INVALID_, INVALID_, FORMAT_, LAYOUT_, CONFIG_, INIT_, AGENT_ oder CONFIG_, wenn die Antworten keine gültige Konfiguration ergeben würden |
Wie jeder Befehl diese Codes nutzt, steht im Exit-Code-Vertrag.
Siehe auch
- verbatra mit einem KI-Agenten einrichten ist der Agenten-Prompt, der auf diesem Befehl aufbaut.
- Schnellstart führt von init bis zum ersten Lauf.
- Konfigurationsdatei dokumentiert jeden Key, den das Scaffold setzt.
- Provider behandelt die Provider-Optionen und API-Key-Variablen.