Zum Inhalt springen
Zum Inhalt springen

Referenz / Konfiguration

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.

Konfigurationsdatei

Jeder Konfigurations-Key mit Typ, Default und der Version, die ihn eingeführt hat, dazu wo die Datei liegt und wie eine fehlerhafte Konfiguration scheitert.

verbatra liest ein geheimnisfreies Konfigurationsobjekt und validiert es vor jeder Arbeit. Kein API-Schlüssel wird je daraus gelesen (Provider), die Konfiguration bleibt also gefahrlos committbar.

Eine minimale Konfiguration

verbatra.config.ts
import { defineConfig } from "@verbatra/cli";

export default defineConfig({
  // Locales and files: required
  sourceLocale: "en",
  targetLocales: ["de", "fr"],
  format: "i18next-json",
  files: {
    // {locale} is the only token
    pattern: "locales/{locale}.json",
  },

  // Provider: required; the API key comes from the environment, never from here
  provider: {
    id: "gemini",
    options: {
      // example model id; use your provider's current one
      model: "gemini-2.5-flash",
      maxOutputTokens: 4096,
    },
  },

  // Optional groups, each off or at its default until you add it:
  // tone: "informal",
  // glossary: "glossary.json",
  // network: { policy: "local-only" },
  // sensitiveData: { mode: "warn" },
  // maxTokens: 200000,
  // budgetBehavior: "stop",
});

Siehe Locales und Dateien, provider, glossary, network, sensible Inhalte, Budget, rates und extract.

defineConfig typisiert sein Argument nur: options.model vervollständigt die Modell-IDs des Providers, zur Laufzeit gilt aber jeder nicht-leere String.

Jeder Key

Unbekannte Keys werden auf jeder Ebene außer $schema und Maps, deren Keys du selbst benennst, etwa maxLength, rates.table, localeMap und ein Inline-glossary, abgelehnt, also kann kein API-Schlüssel in der Konfiguration leben.

KeyTypDefaultSeitWirkung
$schemaStringkeiner0.9.0Zeigt einem Editor das JSON-Schema; zur Laufzeit ignoriert.
sourceLocaleLocale-Codeerforderlich0.1.0Die Locale, in der deine Quellstrings geschrieben sind.
targetLocalesArray von Locale-Codeserforderlich0.1.0Mindestens eine; nie sourceLocale, nie zwei, die sich nur in der Groß- und Kleinschreibung unterscheiden.
formatFormat-Iderforderlich0.1.0Das Format deiner Locale-Dateien, oder eine custom:-Id für einen Adapter von außerhalb.
files.patternStringerforderlich0.1.0Der Pfad zu jeder Locale-Datei, mit einem {locale}-Token.
files.localeStyle"literal", "posix", "android""literal"0.7.0Wie {locale} im Pfad geschrieben wird.
provider.idProvider-Iderforderlich0.1.0Der Übersetzungs-Provider, oder none für keine maschinelle Übersetzung.
provider.optionsObjekterforderlich, außer bei none0.1.0Die eigenen Optionen des Providers.
glossaryObjekt oder Dateipfadkeines0.1.0Feste Übersetzungen, verbotene Wiedergaben und Begriffe, die unübersetzt bleiben.
tone"formal", "informal", "neutral"keiner0.1.0Das Register, in dem übersetzt wird, angewendet pro Provider.
pruneBooleanfalse0.3.0Entfernt verwaiste Keys aus Zieldateien und der Lock-Datei; translate --prune überschreibt es.
generatePluralsBooleanfalse0.3.0Synthetisiert die CLDR-Pluralformen, die eine Zielsprache braucht.
fuzzyCache.enabledBooleanim Block erforderlich0.11.0Übersetzung einer leicht geänderten Quelle wiederverwenden.
fuzzyCache.thresholdZahl, 0.5 bis 10.90.11.0Wie ähnlich alte und neue Quelle sein müssen.
humanEdits"protect", "suggest", "overwrite""protect"0.12.0Was ein Lauf mit einem veralteten Key macht, den ein Mensch geschrieben hat.
pinnedKeysString-Arraykeiner0.12.0Key-Muster (* als Platzhalter), die kein maschinelles Schreiben anfasst.
network.policy"any", "local-only", "allowlist""any"0.12.0Zu welchen Hosts sich ein Provider verbinden darf.
network.allowedHostsString-Arraykeiner; bei "allowlist" erforderlich0.12.0Zusätzlich erlaubte Hosts: Namen, *.suffix-Platzhalter, IPs oder CIDR-Bereiche.
sensitiveData.mode"off", "warn", "block", "redact"im Block Pflicht; "off" ohne den Block0.12.0Was ein Lauf mit sensiblen Inhalten vor dem Senden macht.
sensitiveData.detectorsArray von Detektor-IDssecret, email, iban, credit-card0.12.0Aktive Detektoren; phone, ip, private-host sind optional.
sensitiveData.patternsString-Arraykeiner0.12.0Reguläre Ausdrücke für eigene Begriffe, etwa Codenamen.
sensitiveData.allowString-Arraykeiner0.12.0Nie gemeldete Treffer; * ist ein Platzhalter, Groß- und Kleinschreibung zählt nicht.
maxBatchSizepositive Ganzzahl500.3.0Die meisten Einträge pro Provider-Anfrage.
maxLengthZuordnung von Key zu positiver Ganzzahlkeines0.11.0Längenbudgets pro Key in Graphemclustern.
maxTokenspositive Ganzzahlkeines0.5.0Ein Token-Budget für den ganzen Lauf.
budgetBehavior"warn", "stop""warn"0.5.0Ob das Erreichen von maxTokens warnt oder das Senden stoppt.
rates.asOfDatum YYYY-MM-DDim Block erforderlich0.11.0Das Datum, an dem du die Raten gelesen hast.
rates.currencydrei Großbuchstabenim Block erforderlich0.11.0Die Währung jeder Rate, etwa USD.
rates.tableZuordnung von Raten-Key zu Rateim Block erforderlich0.11.0Raten pro Raten-Key.
extract.framework"i18next"im Block erforderlich0.11.0Nach welchen Aufrufstellen der Quell-Scan sucht.
extract.rootsString-Arrayim Block erforderlich0.11.0Die zu scannenden Verzeichnisse, mindestens eines.
extract.excludeString-Arraykeiner0.11.0Weitere zu überspringende Verzeichnisnamen.
extract.literals.ignoreString-Arraykeiner0.11.0Exakte Texte, die doctor --literals zurückhält.
extract.unused.ignoreString-Arraykeiner0.11.0Keys oder *-Muster, die diff --unused nie meldet.

Locales und Dateien

  • files.pattern muss {locale} enthalten, sein einziges Token, und wird gegen die Projektwurzel aufgelöst: locales/{locale}.json wird zu locales/de.json. Es ist ein wörtlicher Pfad, nie ein Glob, eine Konfiguration adressiert also eine Datei pro Locale (Namespace-Layouts); apple-xcstrings löst jede Locale zum selben Katalog auf (Xcode String Catalogs).

  • files.localeStyle entscheidet, wozu das Token expandiert:

    • literal schreibt das Tag wie konfiguriert, wie es die meisten Layouts brauchen.
    • posix ersetzt - durch _ für gettext und Javas messages_{locale}.properties (aus pt-BR wird pt_BR); eine Variante wie de-1996 hat keine posix-Schreibweise. gettext-po schreibt Schriften auf die gettext-Art (nächster Abschnitt).
    • android expandiert zu einem Ressourcenverzeichnis, geschrieben als res/{locale}/strings.xml: values für die Quelle, dann values-de, values-pt-rBR, values-b+zh+Hans.

    Ein Style lehnt eine Locale ab, die er nicht schreiben kann.

gettext-Locale-Namen

Mit format: "gettext-po" und localeStyle: "posix" tragen Dateien gettext-Namen (language_REGION@modifier), während die Konfiguration BCP-47-Codes behält:

Code in der KonfigurationDateiname
pt-BRpt_BR
es-419es_419
sr-Latnsr@latin
sr-Latn-RSsr_RS@latin
uz-Cyrluz@cyrillic
ks-Deva-INks_IN@devanagari
zh-Hant-TWzh_TW
sr-Cyrl-RSsr_RS

Eine Schrift, die Sprache und Region vorgeben, fällt weg, deshalb scheitern zh-TW und zh-Hant-TW zusammen mit LOCALE_PATH_COLLISION; eine Schrift ohne gettext-Modifikator, etwa zh-Hant allein, scheitert mit LOCALE_LAYOUT_INVALID. verbatra init liest diese Namen zurück. Andere Formate behalten die ICU-Schreibweise (sr_Latn).

Locale-Codes

Jeder Locale-Code muss ein Tag sein, den Intl.getCanonicalLocales akzeptiert, mit einem Sprach-Subtag aus zwei oder drei Buchstaben, sonst scheitert das Laden mit CONFIG_INVALID: pt_BR (schreib pt-BR mit localeStyle: "posix") und german werden abgelehnt. Ein gültiger, nicht kanonischer Code wie zh-hant-tw oder das veraltete iw funktioniert wie geschrieben.

provider

provider.id wählt einen der Provider oder none, dessen options fehlen darf und sonst {} sein muss (Ohne maschinelle Übersetzung arbeiten). Jeder andere Provider akzeptiert options.localeMap und options.requestTimeoutMs (Provider); ab 0.12.0 scheitert ein falsch platzierter Key unter provider, etwa localeMap, mit CONFIG_INVALID.

glossary

Begriffe, die auf eine feste Weise übersetzt werden, inline oder als Pfad zu einer JSON-Datei mit derselben Form (nie zusammengeführt). Version 1 ordnet jedem Quellbegriff eine Übersetzung für alle Locales zu:

verbatra.config.ts
export default defineConfig({
  // ...
  glossary: {
    "Sign in": "Anmelden",
  },
  // or: glossary: "glossary.json",
});

Ein relativer Pfad wird gegen das Verzeichnis der Konfigurationsdatei aufgelöst; die Datei muss UTF-8 und höchstens 1 MiB groß sein und wird einmal beim Laden gelesen. Eine fehlende Datei, ungültiges JSON oder eine ungültige Form scheitert mit CONFIG_INVALID und nennt den Pfad sowie bei Version 2 das Feld. Leg einen Begriff __proto__ in eine Datei; ein JavaScript-Literal macht daraus den Prototyp.

Glossar pro Locale (Version 2)

Version 2 ergänzt Übersetzungen pro Locale, verbotene Wiedergaben und Begriffe, die bleiben, wie sie geschrieben sind:

glossary.json
{
  "version": 2,
  "terms": [
    {
      "source": "Dashboard",
      "targets": { "de": "Übersicht", "fr": "Tableau de bord" },
      "forbidden": { "de": ["Instrumententafel"] },
      "note": "The start page after sign-in",
      "partOfSpeech": "noun"
    },
    { "source": "Sign in", "target": "Anmelden", "caseSensitive": true }
  ],
  "doNotTranslate": ["verbatra", { "term": "Acme", "caseSensitive": false }]
}
FeldBedeutung
versionImmer 2; jede andere Zahl scheitert.
terms[].sourceDer Quellbegriff; jeder Begriff kommt einmal vor.
terms[].targetDie Übersetzung für jede Locale ohne eigenen Eintrag in targets.
terms[].targetsÜbersetzungen pro Locale. Eine Locale nimmt ihren eigenen Eintrag, dann den ihrer Basissprache (de deckt de-AT ab), dann target; verglichen werden kanonische Codes ohne Groß- und Kleinschreibung.
terms[].forbiddenWiedergaben, die eine Locale nie verwenden darf; eine regionale Locale befolgt auch die Liste ihrer Basissprache.
terms[].caseSensitiveBegriff, Übersetzungen und verbotene Wiedergaben mit Groß- und Kleinschreibung vergleichen. Default false.
terms[].note, terms[].partOfSpeechFreitext-Kontext, den ein LLM-Provider als Daten erhält.
doNotTranslateBegriffe, die unübersetzt übernommen werden. Ein reiner String behält seine Groß- und Kleinschreibung; bei { "term", "caseSensitive": false } darf sie sich ändern.

Jeder Begriff braucht ein target, einen Eintrag in targets oder eine forbidden-Liste; er darf seine eigene Übersetzung nicht verbieten, keine Locale doppelt nennen und nicht in doNotTranslate stehen. Kein Text darf leer sein; ein Begriff hat höchstens 200 Zeichen, eine Übersetzung oder verbotene Wiedergabe 2000, eine note 500 und eine partOfSpeech 50. Der Cache-Fingerprint einer Locale deckt nur ihre eigenen Begriffe ab. Eine Datei der Version 1 behält ihren Fingerprint; updateGlossaryTerm schreibt sie nur für eine Änderung, die Version 1 nicht ausdrücken kann, als Version 2 neu.

Studio bearbeitet nur die Dateiform, Begriff für Begriff. Welche Provider das Glossar anwenden, steht unter Provider; jede Ausgabe wird danach geprüft.

generatePlurals

Wenn true, synthetisiert verbatra die CLDR-Pluralformen, die ein Ziel braucht, der Quelle aber fehlen, etwa few und many im Polnischen, und Ordinal-Keys (<key>_ordinal_<category>) nach den CLDR-Ordinalregeln. Nur i18next-json mit einem LLM-Provider unterstützt das; alles andere, und eine Locale ohne CLDR-Regeln, bekommt die Plural-Warnung (Ordinalzahlen nehmen other an). Es gibt kein CLI-Flag; translate() im SDK nimmt einen Override pro Lauf.

fuzzyCache

fuzzyCache: { enabled: true } lässt eine geänderte Quelle die Übersetzung ihrer früheren Form wiederverwenden, wenn beide mindestens threshold ähnlich sind, immer als FUZZY_CACHE_REUSE markiert (Unscharfe Wiederverwendung); --no-cache umgeht es.

humanEdits und pinnedKeys

humanEdits betrifft einen veralteten Key, dessen Wert ein Mensch geschrieben hat (Provenance human, import oder external); ein Key, der auf pinnedKeys passt (etwa ["legal.*", "brand.name"]), wird nie maschinell geschrieben, egal was humanEdits sagt. * passt auf jede Zeichenfolge, Punkte eingeschlossen, und der Abgleich unterscheidet Groß- und Kleinschreibung. Was jeder Modus macht, steht unter Menschliche Übersetzungen behalten.

network

Siehe Netzwerkzugriff einschränken.

verbatra.config.ts
network: { policy: "local-only", allowedHosts: ["gpu.lan"] }

maxBatchSize

Fehlende und geänderte Einträge gehen in sequenziellen Sub-Batches von höchstens dieser Größe hinaus. Kein CLI-Flag überschreibt es.

maxLength

Längengrenzen pro Key, für Strings unter einer Layout-Vorgabe:

verbatra.config.ts
maxLength: {
  "nav.dashboard": 18,
  "cta.submit": 12,
}
  • Hier oder in verbatra.limits.json. neu Keys werden wörtlich verglichen, nie als Globs; ein Key, der an keinem der beiden Orte gesetzt ist, wird nie gemessen. setKeyLengthLimit nimmt nur Keys der Quelle, also kann Studio für eine erzeugte Pluralform kein Limit setzen; ein von Hand geschriebener Eintrag für ihren eigenen Key gilt. Die eingecheckte Datei neben der Lock-Datei nimmt { "version": 1, "maxLength": { ... } }, die Konfiguration gewinnt pro Key, und setKeyLengthLimit schreibt sie.
  • Graphemcluster. Die Länge zählt wahrgenommene Zeichen, Leerraum eingeschlossen: Ein Emoji, ein Buchstabe mit Akzent oder ein CJK-Zeichen zählt als eines. Die Grenze ist inklusiv.
  • Wann. Jeder Wert, den translate für den Key erzeugt, Cache-Wiederverwendungen eingeschlossen; ein aktueller Key wird erst gemessen, wenn sich seine Quelle ändert, oder durch export --include-unchanged.
  • Beratend. Eine Überschreitung wird trotzdem geschrieben und gelockt und als MAX_LENGTH_EXCEEDED zum Review markiert.

maxTokens und budgetBehavior

maxTokens ist ein Budget für den ganzen Lauf: Eingabe- plus Ausgabe-Tokens über jeden Provider-Aufruf (Übersetzung und Pluralgenerierung) und jede Ziel-Locale. translate --max-tokens kann es für einen Lauf verschärfen, nie lockern, und zwar immer als hartes "stop".

budgetBehavior entscheidet, was dann passiert:

  • "warn", der Default, zählt die Ausgaben und vermerkt die Überschreitung, läuft aber weiter.
  • "stop" macht es zur Obergrenze für jeden Provider. Vor jeder Anfrage projiziert der Lauf ihre Kosten wie die Vorab-Schätzung und lehnt eine ab, die maxTokens überschreiten würde. Die Keys dieser Anfrage und jeder noch nicht versuchte Key (der Rest der Locale und jede spätere Locale, deren Vergleich und Verwaisten-Meldung trotzdem laufen) werden zurückgehalten, behalten ihren vorherigen Lock-Hash und werden beim nächsten Lauf erneut versucht.

Unter "stop":

  • Nach jeder Anfrage wird die Summe auf den vom Provider gemeldeten Verbrauch abgeglichen, ein Lauf kann also knapp über maxTokens enden (das budget der Laufzusammenfassung). Maschinenübersetzungs-Provider melden keine Tokens und werden über die Projektion budgetiert.
  • Eine fehlgeschlagene oder abgeschnittene Anfrage wird voll belastet.
  • Die Projektion enthält einen festen Aufschlag für den LLM-Prompt, auch für Maschinenübersetzungs-Provider, und umfasst einen ganzen Batch, ein maxTokens unterhalb der Projektion eines Batches lehnt ihn also bei jedem Lauf ab; der Hinweis sagt, maxBatchSize zu senken oder maxTokens zu erhöhen.
  • Eine Locale mit zurückgehaltenen Keys ist partial, oder failed, wenn kein Key ankam, und beide enden mit Exit 1. Unter "warn" ändert sich der Exit-Code nie.

Das Budget begrenzt einen translate-Lauf, nie eine Neuübersetzung eines einzelnen Eintrags; watch startet pro Lauf ein frisches. Ein Budget schließt --concurrency über 1 bei einem echten Lauf aus; ein Dry-Run ist ausgenommen. budgetBehavior ohne maxTokens hat keine Wirkung.

Zwei verschiedene maxTokens

Das Top-Level-maxTokens ist dieses Budget für den ganzen Lauf; Anthropics davon unabhängiges provider.options.maxTokens begrenzt eine Antwort (Provider).

rates

Wird nur von translate --estimate gelesen, das aus Raten Geld macht; ein echter Lauf ignoriert es.

verbatra.config.ts
rates: {
  asOf: "2026-01-15",
  currency: "USD",
  table: {
    // placeholders: copy the current rates from each provider's pricing page
    "gemini/gemini-2.5-flash": { inputPerMillionTokens: 1, outputPerMillionTokens: 2 },
    deepl: { perMillionCharacters: 1 },
  },
}

Ein table-Key ist provider/model, oder die blanke Id für einen Provider ohne Modell (deepl, google-translate). Ein Eintrag wird nach Tokens (inputPerMillionTokens, outputPerMillionTokens) oder nach Zeichen (perMillionCharacters) abgerechnet, nie beides, und eine negative Rate, eine Rate über 1.000.000.000 pro Million oder die falsche Einheit wird abgelehnt. openai-compatible und libretranslate stellen keine Rechnung, deshalb wird ihre Menge ohne Rate gemeldet.

extract

Wird nur von extract, doctor --literals und diff --unused gelesen.

verbatra.config.ts
extract: {
  framework: "i18next",
  roots: ["src", "app"],
  exclude: ["generated"],
  literals: { ignore: ["Acme Inc."] },
  unused: { ignore: ["emails.*"] },
}
  • framework muss eines mit Extractor nennen (Aufrufformen); jedes andere wird abgelehnt.
  • roots werden gegen die Projektwurzel aufgelöst; exclude ergänzt Verzeichnisnamen (keine Pfade), die überall unterhalb eines Roots passen, zur immer übersprungenen Menge.
  • literals.ignore trifft den ganzen Text eines Literals, Leerraum zusammengefasst und Referenzen aufgelöst (Nicht übersetzte Literale).
  • unused.ignore gleicht den dekodierten Key ab (diff --unused).

Suchreihenfolge

verbatra sucht vom Arbeitsverzeichnis aus aufwärts und nimmt den ersten Treffer. Die Suche endet beim nächsten Verzeichnis mit .git, sonst bei deinem Home-Verzeichnis (oder beim Arbeitsverzeichnis, wenn Home nicht darüber liegt), greift also nie eine Konfiguration oberhalb deines Repositorys auf:

  1. package.json (eine "verbatra"-Eigenschaft)
  2. .verbatrarc
  3. .verbatrarc.json
  4. .verbatrarc.yaml
  5. .verbatrarc.yml
  6. .verbatrarc.js
  7. .verbatrarc.cjs
  8. .verbatrarc.ts
  9. verbatra.config.js
  10. verbatra.config.cjs
  11. verbatra.config.ts

--config <path> lädt stattdessen genau eine Datei, relativ zum Arbeitsverzeichnis; den Vorrang im SDK beschreibt loadConfig.

Validierung im Editor

@verbatra/sdk liefert ein JSON Schema aus seinem zod-Schema aus, auch unter einer festen URL für jede Installation, npx, ein Monorepo mit Hoisting oder einen entfernten Agenten:

https://verbatra.kreitz-webdev.de/schema/v1/config.json

Offline, oder um die installierte Version festzulegen, nimmst du die Kopie im Paket, ./node_modules/@verbatra/sdk/dist/config-schema.json (alle Schemas).

.verbatrarc.json und .verbatrarc nehmen einen $schema-Key für VS Code:

.verbatrarc.json
{
  "$schema": "https://verbatra.kreitz-webdev.de/schema/v1/config.json",
  "sourceLocale": "en",
  "targetLocales": ["de", "fr"],
  "format": "i18next-json",
  "files": { "pattern": "locales/{locale}.json" },
  "provider": { "id": "gemini", "options": { "model": "gemini-2.5-flash", "maxOutputTokens": 4096 } }
}

Das endungslose .verbatrarc braucht zusätzlich eine Workspace-Dateizuordnung:

.vscode/settings.json
{
  "json.schemas": [
    {
      "fileMatch": [".verbatrarc", ".verbatrarc.json"],
      "url": "https://verbatra.kreitz-webdev.de/schema/v1/config.json"
    }
  ]
}

Eine YAML-Konfiguration nimmt einen YAML-Language-Server-Kommentar:

.verbatrarc.yaml
# yaml-language-server: $schema=https://verbatra.kreitz-webdev.de/schema/v1/config.json
sourceLocale: en
targetLocales: [de, fr]
format: i18next-json
files:
  pattern: "locales/{locale}.json"
provider:
  id: gemini
  options:
    model: gemini-2.5-flash
    maxOutputTokens: 4096

package.json nimmt kein Schema; ausführbare Formen typisiert defineConfig.

Was das Dokument nicht prüfen kann

Nur das Laden der Konfiguration prüft diese Regeln: die Regeln für targetLocales und Locale-Codes, die Keys von localeMap und die Regeln für baseUrl und apiKeyEnvVar von openai-compatible, gültige Adressen und Bereiche in network.allowedHosts, sensitiveData.patterns innerhalb der Sicherheitsregeln für Muster und die Begriffsregeln eines Inline-Glossars der Version 2.

Das Arbeitsverzeichnis und .env

Das Arbeitsverzeichnis (wo du verbatra ausführst, oder --cwd) startet die Konfigurationssuche und hält die Umgebungsdateien. Locale-Pfade, verbatra.lock.json, der Cache, die Provenienzdatei und .verbatra-local/ werden gegen die Projektwurzel aufgelöst, das Verzeichnis der gefundenen Konfiguration, sodass ein Lauf aus einem Unterverzeichnis dieselben Dateien nutzt. Mit --config ist das Arbeitsverzeichnis die Wurzel, und eine Konfiguration an anderer Stelle bekommt einen Hinweis auf stderr, weil ihr Glossarpfad gegen ihr eigenes Verzeichnis aufgelöst wird. Ein Pfad, den du übergibst, etwa bei --out oder check --file, wird gegen das Arbeitsverzeichnis aufgelöst.

Wenn das Laden fehlschlägt

  • CONFIG_NOT_FOUND: an keinem der durchsuchten Orte eine Konfiguration, oder der --config-Pfad existiert nicht.
  • CONFIG_INVALID: Eine Konfiguration wurde gefunden, ist aber nicht verwendbar. Die Meldung listet jedes Problem mit seinem Key-Pfad; ein unbekannter Key bekommt den Hinweis, dass API-Schlüssel aus der Umgebung kommen. Ein Parse-Fehler nennt die Datei (bei YAML mit Zeile und Spalte), zitiert aber nie ihren Inhalt, und jede Meldung läuft durch die Schlüssel-Redaktion.

Die CLI endet in beiden Fällen mit Exit 2.

Auf GitHub bearbeiten

Auf dieser Seite