El estado persistente de la CLI se guarda en tres lugares: dos dentro del proyecto (versionados) y uno 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). Haz commit.
{
"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; nunca se escriben. |
targetLocales | sí | Idiomas a los que se traducirá. Los archivos de salida se escriben en el mismo directorio que la fuente, sustituyendo el código de idioma en el patrón (locales/en.json → locales/de.json). |
files | sí | Lista de patrones de origen. pattern es un glob (barras diagonales normales, recursión **, comodines *). La CLI sustituye los códigos de idioma al resolver las rutas de destino. |
github | no | Configuración de la GitHub App; la CLI la ignora. |
Asignación de patrón → destino#
La CLI reemplaza el idioma de origen en el patrón por cada idioma de destino:
locales/en.json→locales/de.json,locales/fr.json, ...docs/en/**/*.md→docs/de/**/*.md(subárbol en espejo)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. La CLI no puede inferir dónde deben ir los archivos de destino sin esa referencia.
.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 una fuente cambió desde la última ejecución exitosa. Los archivos sin cambios se convierten en una operación sin efecto, sin necesidad de hacer un viaje de ida y vuelta al servidor.lingo pulllo consulta para detectar ediciones locales en los archivos de destino: si el hash de un archivo local difiere de lo que indica el lockfile, pull sobrescribiría el trabajo local, así quepullfalla a menos que pases--force.
Los hashes de los archivos fuente se guardan en el lockfile solo después de un push completamente exitoso, así que una ejecución a medio completar puede reintentarse sin limpieza manual.
Haz commit del 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 obtener los resultados. Funciona incluso si cerraste la terminal y también entre máquinas que comparten 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 de 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 tienen rutas absolutas diferentes).
- Mover el proyecto (
mv ~/Projects/foo ~/Projects/bar) entre push y pull invalida la búsqueda, porque el hash cambia. El JSON sigue 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 con gitignore porque vive completamente 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 sube desde cwd hasta encontrar el .lingo/config.json más cercano. Si ejecutas lingo push desde src/components/, el lockfile se escribe de vuelta en la raíz del proyecto, no se crea un .lingo/ nuevo en components/. Así que no tienes que hacer cd hasta la raíz antes de cada comando.
