Zum Inhalt springen
Zum Inhalt springen

Referenz / CLI

Maschinell übersetzte Seite

Diese Seite wurde automatisch übersetzt und kann daher Fehler oder seltsame Formulierungen enthalten. Die englische Version ist die maßgebliche Quelle. Das englische Original lesen.

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-run

Flags

FlagArgumentStandardWirkung
--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-jsondas Format der Locale-Dateien, eine der IDs unter Formate
--source<locale>erkannt, sonst endie Quell-Locale, in der deine Strings geschrieben sind
--targets<locales>erkannt, sonst dekommagetrennte 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 Scaffoldsdas Modell; erforderlich für openai-compatible, optional für anthropic, openai, gemini und opencode
--base-url<url>keinerdie Server-URL; nur für openai-compatible und libretranslate und dort erforderlich
--api-key-env-var<name>OPENAI_COMPATIBLE_API_KEYdie Variable, aus der openai-compatible seinen Key liest
--yeskeinsausnie nachfragen; für alles, was weder übergeben noch erkannt wurde, den Standardwert nehmen
--forcekeinsauseine bestehende verbatra.config.ts mit abweichendem Inhalt überschreiben
--agentkeinsauszusä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>erkanntkommagetrennte Clients, die --agent statt der erkannten einrichtet: claude, cursor, vscode, codex, gemini oder all; braucht --agent
--dry-runkeinsausjede 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_OPTION) und nie eine Bitte um den Standardwert. Endet stdin bei einer Abfrage (Ctrl-D), bricht init mit 2 und MISSING_OPTIONS 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_LOCALE), 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_modules und Build-Ausgabe und findet den Teil jedes Pfads, der eine Locale ausschreibt, etwa de.json, messages_pt_BR.properties, 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 in package.json (i18next, vue-i18n, next-intl oder @ngx-translate/core).
  • files.pattern und files.localeStyle: posix, wenn die Dateien pt_BR schreiben, android für values-*-Verzeichnisse, sonst literal.
  • sourceLocale: die Quellsprache eines .xcstrings-Katalogs, sonst en oder die einzige gefundene en-*-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_AMBIGUOUS, und liegen mehrere Dateimuster gleichauf (eine Datei pro Namespace), mit 2 und LAYOUT_AMBIGUOUS. 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_OPTIONS 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 --json

JSON-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_AMBIGUOUS, LAYOUT_AMBIGUOUS, INVALID_PROVIDER oder INVALID_FORMAT 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 none legt eine rein menschliche Konfiguration ohne options an und schreibt keine .env.example, weil nie ein API-Key gelesen wird.
  • --provider openai-compatible setzt einen lokalen oder selbst gehosteten Server aus --base-url und --model auf, mit maxOutputTokens: 4096. Sein Key ist optional: Ein Server, der keinen braucht, lässt OPENAI_COMPATIBLE_API_KEY ungesetzt, und --api-key-env-var nennt eine andere Variable, in Großbuchstaben wie LLM_API_KEY. Ein abgelehnter Wert wird nie wiederholt, falls es der Key selbst war.
  • --provider libretranslate setzt einen selbst gehosteten LibreTranslate-Server allein aus --base-url auf, etwa http://localhost:5000, und lehnt --model und --api-key-env-var ab. .env.example nennt LIBRETRANSLATE_API_KEY für einen Server, der mit --api-keys gestartet 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_EXISTS 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_UNWRITABLE 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_UNWRITABLE 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 in AGENTS.md oder in CLAUDE.md, wenn das die einzige Anweisungsdatei ist; gibt es beide, gewinnt AGENTS.md. Enthält eine Datei den Abschnitt schon, wird der Text zwischen den Markierungen durch den aktuellen ersetzt und als updated gemeldet, oder als unchanged, wenn er schon passt.
  • Die MCP-Konfiguration jedes Clients. Der verbatra-Servereintrag aus MCP-Client verbinden, npx -y @verbatra/mcp ohne --allow-spend und ohne VERBATRA_MCP_ALLOW_SPEND, sodass die Tools, die Geld kosten, verborgen bleiben. @verbatra/cli exportiert diese Einträge als AGENT_CLIENT_CONFIGS.
Client--clientDateiErkannt an
Claude Codeclaude.mcp.jsonCLAUDE.md, .claude/, .mcp.json
Cursorcursor.cursor/mcp.json.cursor/, .cursorrules
VS Codevscode.vscode/mcp.json, unter servers.vscode/mcp.json
Codexcodex.codex/config.toml, als [mcp_servers.verbatra].codex/
Gemini CLIgemini.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_OPTION 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_FILE_INVALID 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_servers 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

CodeBedeutung
0Dateien geschrieben oder schon auf dem aktuellen Stand
2ein Verwendungsfehler: MISSING_OPTIONS, INVALID_PROVIDER, INVALID_FORMAT, INVALID_OPTION, INVALID_LOCALE, INVALID_LOCALES, FORMAT_AMBIGUOUS, LAYOUT_AMBIGUOUS, CONFIG_EXISTS, INIT_UNWRITABLE, AGENT_FILE_INVALID oder CONFIG_INVALID, wenn die Antworten keine gültige Konfiguration ergeben würden

Wie jeder Befehl diese Codes nutzt, steht im Exit-Code-Vertrag.

Siehe auch

Auf GitHub bearbeiten

Auf dieser Seite