El estado persistente de la CLI se guarda en tres ubicaciones: dos dentro del proyecto (versionadas) y una en tu directorio personal (por máquina).
.lingo/config.json — versionado#
Lo crean lingo init (sección de localización) y lingo link (vinculación org/motor). Añádelo al repositorio.
{
"orgId": "org_a8c...",
"engineId": "eng_b9d...",
"sourceLocale": "en",
"targetLocales": ["de", "fr", "es"],
"files": [
{ "pattern": "locales/en.json" },
{ "pattern": "docs/en/**/*.md" }
]
}Referencia de campos#
| Campo | Obligatorio | Descripción |
|---|---|---|
orgId | sí (después de link) | Organización propietaria del motor. |
engineId | sí (después de link) | Motor que realiza la traducción. Incluye la configuración del modelo, el glosario y la voz de marca. |
sourceLocale | sí | Código de idioma de tus archivos fuente (p. ej., "en"). Los archivos fuente se leen, pero nunca se escriben. |
targetLocales | sí | Idiomas a los que traducir. Los archivos de salida se escriben en el mismo directorio que la fuente, sustituyendo en el patrón el código de idioma (locales/en.json → locales/de.json). |
files | sí | Array de patrones de origen. pattern es un glob (barras normales, recursión **, comodines *). La CLI sustituye los códigos de idioma al resolver las rutas de destino. |
github | no | Ajustes de la GitHub App; la propia CLI los ignora. |
Asignación de patrón → destino#
La CLI sustituye el idioma de origen del patrón por cada idioma de destino:
locales/en.json→locales/de.json,locales/fr.json, ...docs/en/**/*.md→docs/de/**/*.md(subárbol reflejado)copy/en/marketing.md→copy/de/marketing.md
Si la estructura de tus archivos fuente no incluye el código de idioma en la ruta, tendrás que reorganizarla. Sin él, la CLI no puede deducir dónde deben ir los archivos de destino.
.lingo/lock.json — versionado#
Registra el último hash conocido en el servidor de cada archivo fuente y de destino. Se usa para dos cosas:
lingo pushlo consulta para decidir si un archivo fuente ha cambiado desde la última ejecución correcta. Los archivos sin cambios se omiten sin necesidad de hacer una ida y vuelta al servidor.lingo pulllo consulta para detectar ediciones locales en los archivos de destino: si el hash de un destino local difiere de lo que indica el lockfile, hacer pull sobrescribiría trabajo local, así quepullda error a menos que pases--force.
Los hashes de origen se guardan en el lockfile solo después de un push completamente correcto, de modo que una ejecución incompleta pueda reintentarse sin limpieza manual.
Versiona el lockfile junto con los archivos traducidos. Trata los conflictos igual que tratarías los de package-lock.json: vuelve a generarlo ejecutando lingo push otra vez.
~/.lingo/runs/<hash>.json — por máquina#
Registra el push enviado más recientemente para que lingo pull sepa de qué ejecución debe recuperar los resultados. Funciona aunque cierres la terminal y también entre máquinas que compartan el mismo checkout.
{
"runId": "run_a8c...",
"engineId": "eng_b9d...",
"organizationId": "org_a8c...",
"sourceLocale": "en",
"createdAt": "2026-05-22T14:32:01.000Z"
}El hash del nombre de archivo se deriva de la ruta absoluta a la raíz del proyecto, no del contenido de los archivos, así que:
- Editar
en.jsonno invalida el archivo: el mismopullseguirá encontrando la ejecución. - Dos checkouts del mismo repositorio en la misma máquina generan archivos distintos (porque sus rutas absolutas son diferentes).
- Mover el proyecto (
mv ~/Projects/foo ~/Projects/bar) entre push y pull invalida la búsqueda, ya que cambia el hash. El JSON sigue estando en~/.lingo/runs/si necesitas recuperar manualmente el ID de la ejecución.
Este archivo es estado por máquina, no estado del proyecto; no se ignora en git porque vive por completo fuera del repositorio.
Credenciales de autenticación — ~/.lingo/auth.json#
Las almacena lingo login (el flujo OTP guarda una sesión de Supabase; el flujo --api-key guarda la clave). No se versionan y nada las lee salvo la propia CLI.
lingo logout # clear credentials
lingo whoami # check what's stored and which org/engine the cwd resolves toResolución desde subdirectorios#
Cada comando asciende desde cwd en busca del .lingo/config.json más cercano. Si ejecutas lingo push desde src/components/, el lockfile se vuelve a escribir en la raíz del proyecto, no se crea un .lingo/ nuevo en components/. Así que no hace falta cd a la raíz antes de cada comando.
