Конфигурация

Max PrilutskiyГенеральный директор и соучредитель3 мин чтения

Постоянное состояние CLI хранится в трёх местах: два — внутри проекта (коммитятся), одно — в домашней директории пользователя (для конкретной машины).

.lingo/config.json — коммитится#

Создаётся через lingo init (раздел локализации) и lingo link (привязка org/движок). Добавьте файл в коммит.

json
{
  "orgId": "org_a8c...",
  "engineId": "eng_b9d...",
  "sourceLocale": "en",
  "targetLocales": ["de", "fr", "es"],
  "files": [
    { "pattern": "locales/en.json" },
    { "pattern": "docs/en/**/*.md" }
  ]
}

Справочник по полям#

ПолеОбязательноОписание
orgIdда (после link)Организация, которой принадлежит движок.
engineIdда (после link)Движок, который выполняет перевод. Хранит конфигурацию модели, глоссарий и тональность бренда.
sourceLocaleдаКод локали исходных файлов (например, "en"). Исходные файлы только читаются и никогда не перезаписываются.
targetLocalesдаЛокали, на которые нужно переводить. Результаты записываются в ту же директорию, что и исходные файлы, с подстановкой кода локали в шаблон (locales/en.json → locales/de.json).
filesдаМассив шаблонов исходных файлов. pattern — это glob-шаблон (прямые слэши, рекурсия **, маски *). CLI подставляет коды локалей при определении путей к целевым файлам.
githubнетНастройки для GitHub App — самим CLI не используются.

Сопоставление шаблона с целевым путём#

CLI заменяет локаль исходника в шаблоне на каждую целевую локаль:

  • locales/en.json → locales/de.json, locales/fr.json, ...
  • docs/en/**/*.md → docs/de/**/*.md (зеркальное поддерево)
  • copy/en/marketing.md → copy/de/marketing.md

Если в структуре исходных файлов код локали не включён в путь, её нужно перестроить. Иначе CLI не сможет определить, куда записывать целевые файлы.

Команды push, pull и purge также проверяют, куда на самом деле ведёт каждый путь. Если исходный файл, целевой файл, .lingo/lock.json или .lingo/config.json указывает за пределы корневого каталога проекта или внутрь .git, например через символическую ссылку, команда завершается с ошибкой ещё до чтения, записи или удаления по этому пути. Ссылки, которые ведут внутрь проекта, по-прежнему работают. Но если сам целевой файл или Lockfile — ссылка, запись через неё не выполняется. В монорепозитории запускайте CLI из корневого каталога, в котором находятся общие файлы, вместо того чтобы ссылаться на них из пакета.

.lingo/lock.json — коммитится#

Хранит последний известный серверу хеш для каждого исходного и целевого файла. Используется для двух задач:

  1. lingo push сверяется с ним, чтобы понять, изменился ли исходный файл с момента последнего успешного запуска. Если файл не менялся, операция становится no-op без лишнего обращения к серверу.
  2. lingo pull сверяется с ним, чтобы обнаружить локальные правки в целевых файлах — если хеш локального целевого файла отличается от того, что записан в lockfile, pull перезапишет локальные изменения, поэтому pull завершится с ошибкой, если не передать --force.

Хэши источников записываются в lockfile только после успешного завершения запуска (lingo push --wait или lingo pull после него), так что неудачный или отменённый запуск можно повторить без ручной очистки.

Коммитьте lockfile вместе с переведёнными файлами. С конфликтами обращайтесь так же, как с конфликтами package-lock.json: просто пересоздайте файл, снова запустив lingo push --wait.

~/.lingo/runs/<hash>.json — отдельно для каждой машины #

Сохраняет последний отправленный push, чтобы lingo pull знал, из какого запуска брать результаты — работает даже после закрытия терминала, на той же машине и с тем же путём к проекту.

json
{
  "runId": "lrg_a8c...",
  "engineId": "eng_b9d...",
  "organizationId": "org_a8c...",
  "sourceLocale": "en",
  "createdAt": "2026-05-22T14:32:01.000Z"
}

Хеш в имени файла вычисляется на основе абсолютного пути к корню проекта, а не содержимого файлов, поэтому:

  • Изменения в en.json не делают файл недействительным — тот же pull всё равно найдёт запуск.
  • Два checkout одного и того же репозитория на одной машине получат разные файлы (из-за разных абсолютных путей).
  • Если переместить проект (mv ~/Projects/foo ~/Projects/bar) между push и pull, поиск перестанет работать, потому что изменится хеш. Сам JSON по-прежнему останется в ~/.lingo/runs/, если понадобится вручную восстановить ID запуска.

Этот файл — состояние конкретной машины, а не состояние проекта — он не попадает в gitignore, потому что полностью находится вне репозитория.

Учётные данные для аутентификации — ~/.lingo/auth.json#

Сохраняются через lingo login (в потоке OTP сохраняется сессия Supabase, в потоке --api-key — ключ). Не коммитятся и никогда не читаются ничем, кроме самого CLI.

bash
lingo logout         # clear credentials
lingo whoami         # check what's stored and which org/engine the cwd resolves to

Разрешение путей из поддиректорий#

Каждая команда поднимается вверх от cwd в поисках ближайшего .lingo/config.json. Если запустить lingo push из src/components/, lockfile будет записан обратно в корень проекта, а не как новый .lingo/ в components/. Поэтому перед каждой командой не нужно делать cd в корень.