CLI の永続状態は 3 か所に保存されます。2 つはプロジェクト内(コミット対象)、1 つはホームディレクトリ内(マシンごと)です。
.lingo/config.json — コミット対象#
lingo init(localization セクション)と lingo link(org/エンジンの紐付け)によって作成されます。必ずコミットしてください。
{
"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 はロケールコードがないと、ターゲットファイルの配置先を推測できません。
.lingo/lock.json — コミット対象#
すべてのソースファイルとターゲットファイルについて、last-known-server hash を記録します。用途は 2 つあります。
lingo pushはこれを参照して、前回正常に完了した実行以降にソースが変更されたかどうかを判断します。変更のないファイルは、サーバーとの往復なしで no-op になります。lingo pullはこれを参照して、ローカルでのターゲット編集を検出します。ローカルターゲットのハッシュが lockfile の内容と異なる場合、pull を実行するとローカルの作業が上書きされてしまうため、--forceを渡さない限りpullはエラーになります。
ソースハッシュが lockfile にコミットされるのは、push が完全に成功した後だけです。そのため、中途半端な状態で終わった実行でも、手動でクリーンアップせずに再試行できます。
lockfile は翻訳済み出力とあわせてコミットしてください。競合が起きた場合は、package-lock.json の競合と同じように扱います。つまり、lingo push をもう一度実行して再生成します。
~/.lingo/runs/<hash>.json — マシンごと#
直近で送信された push を記録し、lingo pull がどの実行結果を取得すべきか判断できるようにします。ターミナルを閉じたあとでも、同じチェックアウトを共有する別のマシン間でも機能します。
{
"runId": "run_a8c...",
"engineId": "eng_b9d...",
"organizationId": "org_a8c...",
"sourceLocale": "en",
"createdAt": "2026-05-22T14:32:01.000Z"
}ファイル名のハッシュはファイル内容ではなく、プロジェクトルートの絶対パスから導き出されます。そのため、次のようになります。
en.jsonを編集しても、このファイルは無効になりません。同じpullで引き続き実行を見つけられます。- 同じマシン上にある同一リポジトリの 2 つのチェックアウトには、それぞれ別のファイルが作られます(絶対パスが異なるため)。
- push と pull の間にプロジェクトを移動すると(
mv ~/Projects/foo ~/Projects/bar)、ハッシュが変わるため参照は無効になります。実行 ID を手動で復旧する必要がある場合でも、JSON 自体は~/.lingo/runs/に残っています。
このファイルはプロジェクトの状態ではなく、マシンごとの状態です。保存場所がリポジトリの完全に外側にあるため、gitignore の対象にはなりません。
認証情報 — ~/.lingo/auth.json#
lingo login によって保存されます(OTP フローでは Supabase セッション、--api-key フローではキーを保存)。コミットされることはなく、CLI 自体以外から読み取られることもありません。
lingo logout # clear credentials
lingo whoami # check what's stored and which org/engine the cwd resolves toサブディレクトリからの解決#
すべてのコマンドは cwd から親ディレクトリ方向にたどり、最も近い .lingo/config.json を探します。src/components/ から lingo push を実行しても、lockfile は components/ に新しく .lingo/ を作るのではなく、プロジェクトルートに書き戻されます。つまり、コマンドのたびにルートへ cd する必要はありません。
