From 47fd9e7c4b2e2d3ef560270026615451f2ca9026 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:13:00 +0200 Subject: [PATCH 1/4] docs: Sync translated sidebars and regroup configuration pages The translated meta..json files had drifted from the English sidebars, so 15 pages were missing from the navigation in all 13 locales. Add scripts/sync-locale-meta.mjs to rebuild each translated page list from English while keeping translated separators and link labels, and a check:locale-meta CI step so they cannot drift again. Also regroup the configuration sidebar: RAG API moves under Services, Meilisearch under Infrastructure, and the UI group becomes Administration. --- .github/workflows/ci.yml | 3 + .../configuration/authentication/meta.de.json | 1 + .../configuration/authentication/meta.es.json | 1 + .../configuration/authentication/meta.fr.json | 1 + .../configuration/authentication/meta.id.json | 1 + .../configuration/authentication/meta.it.json | 1 + .../configuration/authentication/meta.ja.json | 1 + .../configuration/authentication/meta.ko.json | 1 + .../configuration/authentication/meta.nl.json | 1 + .../configuration/authentication/meta.pl.json | 1 + .../authentication/meta.pt-BR.json | 1 + .../configuration/authentication/meta.tr.json | 1 + .../configuration/authentication/meta.vi.json | 1 + .../configuration/authentication/meta.zh.json | 1 + .../librechat_yaml/ai_endpoints/meta.de.json | 1 + .../librechat_yaml/ai_endpoints/meta.es.json | 1 + .../librechat_yaml/ai_endpoints/meta.fr.json | 1 + .../librechat_yaml/ai_endpoints/meta.id.json | 1 + .../librechat_yaml/ai_endpoints/meta.it.json | 1 + .../librechat_yaml/ai_endpoints/meta.ja.json | 1 + .../librechat_yaml/ai_endpoints/meta.ko.json | 1 + .../librechat_yaml/ai_endpoints/meta.nl.json | 1 + .../librechat_yaml/ai_endpoints/meta.pl.json | 1 + .../ai_endpoints/meta.pt-BR.json | 1 + .../librechat_yaml/ai_endpoints/meta.tr.json | 1 + .../librechat_yaml/ai_endpoints/meta.vi.json | 1 + .../librechat_yaml/ai_endpoints/meta.zh.json | 1 + .../object_structure/meta.de.json | 1 + .../object_structure/meta.es.json | 1 + .../object_structure/meta.fr.json | 1 + .../object_structure/meta.id.json | 1 + .../object_structure/meta.it.json | 1 + .../object_structure/meta.ja.json | 1 + .../object_structure/meta.ko.json | 1 + .../object_structure/meta.nl.json | 1 + .../object_structure/meta.pl.json | 1 + .../object_structure/meta.pt-BR.json | 1 + .../object_structure/meta.tr.json | 1 + .../object_structure/meta.vi.json | 1 + .../object_structure/meta.zh.json | 1 + content/docs/configuration/meta.de.json | 13 +- content/docs/configuration/meta.es.json | 13 +- content/docs/configuration/meta.fr.json | 13 +- content/docs/configuration/meta.id.json | 13 +- content/docs/configuration/meta.it.json | 13 +- content/docs/configuration/meta.ja.json | 13 +- content/docs/configuration/meta.json | 14 +- content/docs/configuration/meta.ko.json | 13 +- content/docs/configuration/meta.nl.json | 13 +- content/docs/configuration/meta.pl.json | 13 +- content/docs/configuration/meta.pt-BR.json | 13 +- content/docs/configuration/meta.tr.json | 13 +- content/docs/configuration/meta.vi.json | 13 +- content/docs/configuration/meta.zh.json | 13 +- .../docs/configuration/mongodb/meta.de.json | 3 +- .../docs/configuration/mongodb/meta.es.json | 3 +- .../docs/configuration/mongodb/meta.fr.json | 3 +- .../docs/configuration/mongodb/meta.id.json | 3 +- .../docs/configuration/mongodb/meta.it.json | 3 +- .../docs/configuration/mongodb/meta.ja.json | 3 +- .../docs/configuration/mongodb/meta.ko.json | 3 +- .../docs/configuration/mongodb/meta.nl.json | 3 +- .../docs/configuration/mongodb/meta.pl.json | 3 +- .../configuration/mongodb/meta.pt-BR.json | 3 +- .../docs/configuration/mongodb/meta.tr.json | 3 +- .../docs/configuration/mongodb/meta.vi.json | 3 +- .../docs/configuration/mongodb/meta.zh.json | 3 +- content/docs/features/meta.de.json | 9 + content/docs/features/meta.es.json | 9 + content/docs/features/meta.fr.json | 9 + content/docs/features/meta.id.json | 9 + content/docs/features/meta.it.json | 9 + content/docs/features/meta.ja.json | 9 + content/docs/features/meta.ko.json | 9 + content/docs/features/meta.nl.json | 9 + content/docs/features/meta.pl.json | 9 + content/docs/features/meta.pt-BR.json | 9 + content/docs/features/meta.tr.json | 9 + content/docs/features/meta.vi.json | 9 + content/docs/features/meta.zh.json | 9 + content/docs/quick_start/meta.de.json | 1 + content/docs/quick_start/meta.es.json | 1 + content/docs/quick_start/meta.fr.json | 1 + content/docs/quick_start/meta.id.json | 1 + content/docs/quick_start/meta.it.json | 1 + content/docs/quick_start/meta.ja.json | 1 + content/docs/quick_start/meta.ko.json | 1 + content/docs/quick_start/meta.nl.json | 1 + content/docs/quick_start/meta.pl.json | 1 + content/docs/quick_start/meta.pt-BR.json | 1 + content/docs/quick_start/meta.tr.json | 1 + content/docs/quick_start/meta.vi.json | 1 + content/docs/quick_start/meta.zh.json | 1 + package.json | 2 + scripts/sync-locale-meta.mjs | 181 ++++++++++++++++++ scripts/sync-locale-meta.test.mjs | 69 +++++++ 96 files changed, 548 insertions(+), 98 deletions(-) create mode 100644 scripts/sync-locale-meta.mjs create mode 100644 scripts/sync-locale-meta.test.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea691acd13..401cf08e14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,9 @@ jobs: - name: Check config versions run: pnpm check:config-version + - name: Check translated sidebars + run: pnpm check:locale-meta + - name: Typecheck run: pnpm typecheck diff --git a/content/docs/configuration/authentication/meta.de.json b/content/docs/configuration/authentication/meta.de.json index 5823bd6a15..d59c478f36 100644 --- a/content/docs/configuration/authentication/meta.de.json +++ b/content/docs/configuration/authentication/meta.de.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.es.json b/content/docs/configuration/authentication/meta.es.json index 535aa2cfd6..0fe46a645e 100644 --- a/content/docs/configuration/authentication/meta.es.json +++ b/content/docs/configuration/authentication/meta.es.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.fr.json b/content/docs/configuration/authentication/meta.fr.json index 49d2f12ce4..ad5c7c4516 100644 --- a/content/docs/configuration/authentication/meta.fr.json +++ b/content/docs/configuration/authentication/meta.fr.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.id.json b/content/docs/configuration/authentication/meta.id.json index 63fb7de4ad..9c7f7fbf1c 100644 --- a/content/docs/configuration/authentication/meta.id.json +++ b/content/docs/configuration/authentication/meta.id.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.it.json b/content/docs/configuration/authentication/meta.it.json index 8fbfc00669..42ece176ac 100644 --- a/content/docs/configuration/authentication/meta.it.json +++ b/content/docs/configuration/authentication/meta.it.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.ja.json b/content/docs/configuration/authentication/meta.ja.json index d36ffaf2e3..3d6199ab0a 100644 --- a/content/docs/configuration/authentication/meta.ja.json +++ b/content/docs/configuration/authentication/meta.ja.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.ko.json b/content/docs/configuration/authentication/meta.ko.json index a6638d429a..12b4c0be3c 100644 --- a/content/docs/configuration/authentication/meta.ko.json +++ b/content/docs/configuration/authentication/meta.ko.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.nl.json b/content/docs/configuration/authentication/meta.nl.json index 544e8a93ba..c51dce49f0 100644 --- a/content/docs/configuration/authentication/meta.nl.json +++ b/content/docs/configuration/authentication/meta.nl.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.pl.json b/content/docs/configuration/authentication/meta.pl.json index 404e616398..69542fe096 100644 --- a/content/docs/configuration/authentication/meta.pl.json +++ b/content/docs/configuration/authentication/meta.pl.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.pt-BR.json b/content/docs/configuration/authentication/meta.pt-BR.json index e417df6ebd..5755a693c5 100644 --- a/content/docs/configuration/authentication/meta.pt-BR.json +++ b/content/docs/configuration/authentication/meta.pt-BR.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.tr.json b/content/docs/configuration/authentication/meta.tr.json index 52137decf8..799170ba9a 100644 --- a/content/docs/configuration/authentication/meta.tr.json +++ b/content/docs/configuration/authentication/meta.tr.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.vi.json b/content/docs/configuration/authentication/meta.vi.json index 6955a952d3..6e08c0a574 100644 --- a/content/docs/configuration/authentication/meta.vi.json +++ b/content/docs/configuration/authentication/meta.vi.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/authentication/meta.zh.json b/content/docs/configuration/authentication/meta.zh.json index c8d68f5dd9..9592dcf212 100644 --- a/content/docs/configuration/authentication/meta.zh.json +++ b/content/docs/configuration/authentication/meta.zh.json @@ -3,6 +3,7 @@ "icon": "Lock", "pages": [ "email", + "passkeys", "ldap", "OAuth2-OIDC", "SAML" diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.de.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.de.json index e77c3b42d8..332e7c704c 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.de.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.de.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.es.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.es.json index 317d28582b..3e2bbff757 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.es.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.es.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.fr.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.fr.json index dc74dde831..757c760a50 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.fr.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.fr.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.id.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.id.json index 8eed998324..5edda54f1e 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.id.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.id.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.it.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.it.json index 8eed998324..5edda54f1e 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.it.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.it.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ja.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ja.json index c753444f56..0811cb6374 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ja.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ja.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ko.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ko.json index 952fc1493a..a514bbd3b1 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ko.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.ko.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.nl.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.nl.json index 8041e3141b..d6e2495c9c 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.nl.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.nl.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pl.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pl.json index 8e293b25d8..d3181723e6 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pl.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pl.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pt-BR.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pt-BR.json index 317d28582b..3e2bbff757 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pt-BR.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.pt-BR.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.tr.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.tr.json index c1b7705c8e..2d2557db3a 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.tr.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.tr.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.vi.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.vi.json index c2c2b775aa..46539e0db6 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.vi.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.vi.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.zh.json b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.zh.json index 2b8304d2a2..477cd77592 100644 --- a/content/docs/configuration/librechat_yaml/ai_endpoints/meta.zh.json +++ b/content/docs/configuration/librechat_yaml/ai_endpoints/meta.zh.json @@ -13,6 +13,7 @@ "groq", "helicone", "huggingface", + "lemonade", "litellm", "mistral", "mlx", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.de.json b/content/docs/configuration/librechat_yaml/object_structure/meta.de.json index 6c3af20738..41c95e41e5 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.de.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.de.json @@ -5,6 +5,7 @@ "---Allgemein---", "config", "interface", + "theme", "registration", "turnstile", "---Modelle & Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.es.json b/content/docs/configuration/librechat_yaml/object_structure/meta.es.json index de02423fbf..31ace4f1af 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.es.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.es.json @@ -5,6 +5,7 @@ "---General---", "config", "interface", + "theme", "registration", "turnstile", "---Modelos y Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.fr.json b/content/docs/configuration/librechat_yaml/object_structure/meta.fr.json index 273e0e8cf5..10a1627c24 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.fr.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.fr.json @@ -5,6 +5,7 @@ "---Général---", "config", "interface", + "theme", "registration", "turnstile", "---Modèles et Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.id.json b/content/docs/configuration/librechat_yaml/object_structure/meta.id.json index 3bd2d7a3f0..8bf7c35473 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.id.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.id.json @@ -5,6 +5,7 @@ "---Umum---", "config", "interface", + "theme", "registration", "turnstile", "---Model & Spesifikasi---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.it.json b/content/docs/configuration/librechat_yaml/object_structure/meta.it.json index 4f73ebd042..4eb8402725 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.it.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.it.json @@ -5,6 +5,7 @@ "---Generale---", "config", "interface", + "theme", "registration", "turnstile", "---Modelli e Model Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.ja.json b/content/docs/configuration/librechat_yaml/object_structure/meta.ja.json index 9951f2e257..63ff236359 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.ja.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.ja.json @@ -5,6 +5,7 @@ "---全般---", "config", "interface", + "theme", "registration", "turnstile", "---モデルとModel Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.ko.json b/content/docs/configuration/librechat_yaml/object_structure/meta.ko.json index beacadd46f..2284df644f 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.ko.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.ko.json @@ -5,6 +5,7 @@ "---일반---", "config", "interface", + "theme", "registration", "turnstile", "---모델 및 Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.nl.json b/content/docs/configuration/librechat_yaml/object_structure/meta.nl.json index c789686dd5..0bc58254e9 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.nl.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.nl.json @@ -5,6 +5,7 @@ "---Algemeen---", "config", "interface", + "theme", "registration", "turnstile", "---Modellen & Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.pl.json b/content/docs/configuration/librechat_yaml/object_structure/meta.pl.json index 05a0e2a98c..9365a990d4 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.pl.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.pl.json @@ -5,6 +5,7 @@ "---Ogólne---", "config", "interface", + "theme", "registration", "turnstile", "---Modele i specyfikacje---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.pt-BR.json b/content/docs/configuration/librechat_yaml/object_structure/meta.pt-BR.json index 3fae4c71f0..394c8591ea 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.pt-BR.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.pt-BR.json @@ -5,6 +5,7 @@ "---Geral---", "config", "interface", + "theme", "registration", "turnstile", "---Modelos e Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.tr.json b/content/docs/configuration/librechat_yaml/object_structure/meta.tr.json index 0b4e984ff3..aa23d6292b 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.tr.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.tr.json @@ -5,6 +5,7 @@ "---Genel---", "config", "interface", + "theme", "registration", "turnstile", "---Modeller ve Özellikler---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.vi.json b/content/docs/configuration/librechat_yaml/object_structure/meta.vi.json index 300f3a3af8..a8612ba1e6 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.vi.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.vi.json @@ -5,6 +5,7 @@ "---Chung---", "config", "interface", + "theme", "registration", "turnstile", "---Các mô hình & Model Specs---", diff --git a/content/docs/configuration/librechat_yaml/object_structure/meta.zh.json b/content/docs/configuration/librechat_yaml/object_structure/meta.zh.json index 52e660398e..03dcd4e85a 100644 --- a/content/docs/configuration/librechat_yaml/object_structure/meta.zh.json +++ b/content/docs/configuration/librechat_yaml/object_structure/meta.zh.json @@ -5,6 +5,7 @@ "---常规---", "config", "interface", + "theme", "registration", "turnstile", "---模型与 Model Specs---", diff --git a/content/docs/configuration/meta.de.json b/content/docs/configuration/meta.de.json index 8a3d44d8f7..c7c6bfbd53 100644 --- a/content/docs/configuration/meta.de.json +++ b/content/docs/configuration/meta.de.json @@ -5,26 +5,27 @@ "---Kern---", "dotenv", "librechat_yaml", + "security_headers", "---Dienste---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastruktur---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Überwachung & Moderation---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Benutzeroberfläche---", - "banner", + "langfuse", + "mod_system", + "---Administration---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.es.json b/content/docs/configuration/meta.es.json index d7014daf5c..634c92673e 100644 --- a/content/docs/configuration/meta.es.json +++ b/content/docs/configuration/meta.es.json @@ -5,26 +5,27 @@ "---Núcleo---", "dotenv", "librechat_yaml", + "security_headers", "---Servicios---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infraestructura---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitoreo y moderación---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Interfaz de usuario---", - "banner", + "langfuse", + "mod_system", + "---Administración---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.fr.json b/content/docs/configuration/meta.fr.json index 41aba41e05..c6358823b1 100644 --- a/content/docs/configuration/meta.fr.json +++ b/content/docs/configuration/meta.fr.json @@ -5,26 +5,27 @@ "---Noyau---", "dotenv", "librechat_yaml", + "security_headers", "---Services---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastructure---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Surveillance et modération---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Interface utilisateur---", - "banner", + "langfuse", + "mod_system", + "---Administration---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.id.json b/content/docs/configuration/meta.id.json index c1b955bd95..12484b2631 100644 --- a/content/docs/configuration/meta.id.json +++ b/content/docs/configuration/meta.id.json @@ -5,26 +5,27 @@ "---Inti---", "dotenv", "librechat_yaml", + "security_headers", "---Layanan---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastruktur---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Pemantauan & Moderasi---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---UI---", - "banner", + "langfuse", + "mod_system", + "---Administrasi---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.it.json b/content/docs/configuration/meta.it.json index 07448f297f..f15153ea28 100644 --- a/content/docs/configuration/meta.it.json +++ b/content/docs/configuration/meta.it.json @@ -5,26 +5,27 @@ "---Principale---", "dotenv", "librechat_yaml", + "security_headers", "---Servizi---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastruttura---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitoraggio e moderazione---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Interfaccia utente---", - "banner", + "langfuse", + "mod_system", + "---Amministrazione---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.ja.json b/content/docs/configuration/meta.ja.json index 515d100cf8..ad5f99c6de 100644 --- a/content/docs/configuration/meta.ja.json +++ b/content/docs/configuration/meta.ja.json @@ -5,26 +5,27 @@ "---コア---", "dotenv", "librechat_yaml", + "security_headers", "---サービス---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---インフラストラクチャ---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---監視とモデレーション---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---UI---", - "banner", + "langfuse", + "mod_system", + "---管理---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.json b/content/docs/configuration/meta.json index e9a2c6f1e9..b4b042222b 100644 --- a/content/docs/configuration/meta.json +++ b/content/docs/configuration/meta.json @@ -4,28 +4,28 @@ "pages": [ "---Core---", "dotenv", - "security_headers", "librechat_yaml", + "security_headers", "---Services---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastructure---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitoring & Moderation---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---UI---", - "banner", + "langfuse", + "mod_system", + "---Administration---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.ko.json b/content/docs/configuration/meta.ko.json index 827c32d034..3dd37c63b3 100644 --- a/content/docs/configuration/meta.ko.json +++ b/content/docs/configuration/meta.ko.json @@ -5,26 +5,27 @@ "---핵심---", "dotenv", "librechat_yaml", + "security_headers", "---서비스---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---인프라---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---모니터링 및 조정---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---UI---", - "banner", + "langfuse", + "mod_system", + "---관리---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.nl.json b/content/docs/configuration/meta.nl.json index fba564a602..c4f009b08a 100644 --- a/content/docs/configuration/meta.nl.json +++ b/content/docs/configuration/meta.nl.json @@ -5,26 +5,27 @@ "---Kern---", "dotenv", "librechat_yaml", + "security_headers", "---Services---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastructuur---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitoring & Moderatie---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---UI---", - "banner", + "langfuse", + "mod_system", + "---Beheer---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.pl.json b/content/docs/configuration/meta.pl.json index 506187e73c..64ba8d1e2c 100644 --- a/content/docs/configuration/meta.pl.json +++ b/content/docs/configuration/meta.pl.json @@ -5,26 +5,27 @@ "---Podstawowe---", "dotenv", "librechat_yaml", + "security_headers", "---Usługi---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infrastruktura---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitorowanie i moderacja---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Interfejs użytkownika---", - "banner", + "langfuse", + "mod_system", + "---Administracja---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.pt-BR.json b/content/docs/configuration/meta.pt-BR.json index 31ad4da1d3..6403a84fec 100644 --- a/content/docs/configuration/meta.pt-BR.json +++ b/content/docs/configuration/meta.pt-BR.json @@ -5,26 +5,27 @@ "---Núcleo---", "dotenv", "librechat_yaml", + "security_headers", "---Serviços---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Infraestrutura---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Monitoramento e Moderação---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Interface do Usuário---", - "banner", + "langfuse", + "mod_system", + "---Administração---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.tr.json b/content/docs/configuration/meta.tr.json index 1e5b7d7966..b8ea10a8c7 100644 --- a/content/docs/configuration/meta.tr.json +++ b/content/docs/configuration/meta.tr.json @@ -5,26 +5,27 @@ "---Çekirdek---", "dotenv", "librechat_yaml", + "security_headers", "---Hizmetler---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Altyapı---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---İzleme ve Denetleme---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Arayüz---", - "banner", + "langfuse", + "mod_system", + "---Yönetim---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.vi.json b/content/docs/configuration/meta.vi.json index 6b4990fd8f..ffd129edd9 100644 --- a/content/docs/configuration/meta.vi.json +++ b/content/docs/configuration/meta.vi.json @@ -5,26 +5,27 @@ "---Cốt lõi---", "dotenv", "librechat_yaml", + "security_headers", "---Dịch vụ---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---Cơ sở hạ tầng---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---Giám sát & Kiểm duyệt---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---Giao diện người dùng---", - "banner", + "langfuse", + "mod_system", + "---Quản trị---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/meta.zh.json b/content/docs/configuration/meta.zh.json index d95a1c624f..42da38ffee 100644 --- a/content/docs/configuration/meta.zh.json +++ b/content/docs/configuration/meta.zh.json @@ -5,26 +5,27 @@ "---核心---", "dotenv", "librechat_yaml", + "security_headers", "---服务---", "authentication", "pre_configured_ai", "tools", + "rag_api", "stt_tts", "---基础设施---", "mongodb", "redis", + "meilisearch", "cdn", "sharepoint", "docker_override", "---监控与审核---", - "mod_system", - "langfuse", "logging", "metrics", - "meilisearch", - "---界面---", - "banner", + "langfuse", + "mod_system", + "---管理---", "token_usage", - "rag_api" + "banner" ] } diff --git a/content/docs/configuration/mongodb/meta.de.json b/content/docs/configuration/mongodb/meta.de.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.de.json +++ b/content/docs/configuration/mongodb/meta.de.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.es.json b/content/docs/configuration/mongodb/meta.es.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.es.json +++ b/content/docs/configuration/mongodb/meta.es.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.fr.json b/content/docs/configuration/mongodb/meta.fr.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.fr.json +++ b/content/docs/configuration/mongodb/meta.fr.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.id.json b/content/docs/configuration/mongodb/meta.id.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.id.json +++ b/content/docs/configuration/mongodb/meta.id.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.it.json b/content/docs/configuration/mongodb/meta.it.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.it.json +++ b/content/docs/configuration/mongodb/meta.it.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.ja.json b/content/docs/configuration/mongodb/meta.ja.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.ja.json +++ b/content/docs/configuration/mongodb/meta.ja.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.ko.json b/content/docs/configuration/mongodb/meta.ko.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.ko.json +++ b/content/docs/configuration/mongodb/meta.ko.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.nl.json b/content/docs/configuration/mongodb/meta.nl.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.nl.json +++ b/content/docs/configuration/mongodb/meta.nl.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.pl.json b/content/docs/configuration/mongodb/meta.pl.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.pl.json +++ b/content/docs/configuration/mongodb/meta.pl.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.pt-BR.json b/content/docs/configuration/mongodb/meta.pt-BR.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.pt-BR.json +++ b/content/docs/configuration/mongodb/meta.pt-BR.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.tr.json b/content/docs/configuration/mongodb/meta.tr.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.tr.json +++ b/content/docs/configuration/mongodb/meta.tr.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.vi.json b/content/docs/configuration/mongodb/meta.vi.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.vi.json +++ b/content/docs/configuration/mongodb/meta.vi.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/configuration/mongodb/meta.zh.json b/content/docs/configuration/mongodb/meta.zh.json index f0bfd30214..95b4b03129 100644 --- a/content/docs/configuration/mongodb/meta.zh.json +++ b/content/docs/configuration/mongodb/meta.zh.json @@ -4,6 +4,7 @@ "pages": [ "mongodb_atlas", "mongodb_auth", - "mongodb_community" + "mongodb_community", + "tenant_index_migration" ] } diff --git a/content/docs/features/meta.de.json b/content/docs/features/meta.de.json index 9a2b1f9a01..f5ae5b04ce 100644 --- a/content/docs/features/meta.de.json +++ b/content/docs/features/meta.de.json @@ -5,11 +5,14 @@ "---Agentische KI---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Suche & Wissen---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.es.json b/content/docs/features/meta.es.json index 5337829c7d..0eeed4a73a 100644 --- a/content/docs/features/meta.es.json +++ b/content/docs/features/meta.es.json @@ -5,11 +5,14 @@ "---IA Agéntica---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Búsqueda y Conocimiento---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.fr.json b/content/docs/features/meta.fr.json index 513f9761f2..a5293817a3 100644 --- a/content/docs/features/meta.fr.json +++ b/content/docs/features/meta.fr.json @@ -5,11 +5,14 @@ "---IA agentique---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Recherche et connaissances---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.id.json b/content/docs/features/meta.id.json index dcb9706562..b06ad51a74 100644 --- a/content/docs/features/meta.id.json +++ b/content/docs/features/meta.id.json @@ -5,11 +5,14 @@ "---AI Agen---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Pencarian & Pengetahuan---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Obrolan---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.it.json b/content/docs/features/meta.it.json index 089f493627..1e6ccf7ac1 100644 --- a/content/docs/features/meta.it.json +++ b/content/docs/features/meta.it.json @@ -5,11 +5,14 @@ "---IA Agente---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Ricerca e Conoscenza---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.ja.json b/content/docs/features/meta.ja.json index 52e047fb7e..d029e41fbf 100644 --- a/content/docs/features/meta.ja.json +++ b/content/docs/features/meta.ja.json @@ -5,11 +5,14 @@ "---エージェント型AI---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---検索とナレッジ---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---チャット---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.ko.json b/content/docs/features/meta.ko.json index ae802015ef..c222427536 100644 --- a/content/docs/features/meta.ko.json +++ b/content/docs/features/meta.ko.json @@ -5,11 +5,14 @@ "---에이전트형 AI---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---검색 및 지식---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---채팅---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.nl.json b/content/docs/features/meta.nl.json index 0390060676..5f93437872 100644 --- a/content/docs/features/meta.nl.json +++ b/content/docs/features/meta.nl.json @@ -5,11 +5,14 @@ "---Agentic AI---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Zoeken & Kennis---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.pl.json b/content/docs/features/meta.pl.json index bfe258ab74..d4c62d1a63 100644 --- a/content/docs/features/meta.pl.json +++ b/content/docs/features/meta.pl.json @@ -5,11 +5,14 @@ "---Agentowa sztuczna inteligencja---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Wyszukiwanie i wiedza---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Czat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.pt-BR.json b/content/docs/features/meta.pt-BR.json index 241b1c6538..3655d7896e 100644 --- a/content/docs/features/meta.pt-BR.json +++ b/content/docs/features/meta.pt-BR.json @@ -5,11 +5,14 @@ "---IA Agêntica---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Pesquisa e Conhecimento---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Chat---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.tr.json b/content/docs/features/meta.tr.json index 07bd83d357..a671ba18ed 100644 --- a/content/docs/features/meta.tr.json +++ b/content/docs/features/meta.tr.json @@ -5,11 +5,14 @@ "---Ajan Tabanlı Yapay Zeka---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Arama & Bilgi---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Sohbet---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.vi.json b/content/docs/features/meta.vi.json index 3b52ab0828..134efb3006 100644 --- a/content/docs/features/meta.vi.json +++ b/content/docs/features/meta.vi.json @@ -5,11 +5,14 @@ "---AI tác nhân---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---Tìm kiếm & Kiến thức---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---Trò chuyện---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/features/meta.zh.json b/content/docs/features/meta.zh.json index c40ea85a34..df6d457e97 100644 --- a/content/docs/features/meta.zh.json +++ b/content/docs/features/meta.zh.json @@ -5,11 +5,14 @@ "---代理式 AI---", "mcp", "agents", + "scheduled_chats", "skills", + "agent_plugins", "subagents", "agents_api", "artifacts", "code_interpreter", + "pull_requests", "---搜索与知识---", "web_search", "search", @@ -20,7 +23,12 @@ "ocr", "image_gen", "---聊天---", + "composer", "resumable_streams", + "smooth_streaming", + "settings", + "navigation", + "message_actions", "projects", "fork", "shareable_links", @@ -31,6 +39,7 @@ "authentication", "access_control", "admin_panel", + "insights", "password_reset", "mod_system" ] diff --git a/content/docs/quick_start/meta.de.json b/content/docs/quick_start/meta.de.json index e4c1ca4566..aa44fae236 100644 --- a/content/docs/quick_start/meta.de.json +++ b/content/docs/quick_start/meta.de.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.es.json b/content/docs/quick_start/meta.es.json index a932432739..26c53dd59c 100644 --- a/content/docs/quick_start/meta.es.json +++ b/content/docs/quick_start/meta.es.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.fr.json b/content/docs/quick_start/meta.fr.json index 7f09135de9..0f5489037e 100644 --- a/content/docs/quick_start/meta.fr.json +++ b/content/docs/quick_start/meta.fr.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.id.json b/content/docs/quick_start/meta.id.json index 431c4199e5..f224085a89 100644 --- a/content/docs/quick_start/meta.id.json +++ b/content/docs/quick_start/meta.id.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.it.json b/content/docs/quick_start/meta.it.json index 522946dc4f..a2ab9acbfb 100644 --- a/content/docs/quick_start/meta.it.json +++ b/content/docs/quick_start/meta.it.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.ja.json b/content/docs/quick_start/meta.ja.json index 80fd06208c..6cb6cc179e 100644 --- a/content/docs/quick_start/meta.ja.json +++ b/content/docs/quick_start/meta.ja.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.ko.json b/content/docs/quick_start/meta.ko.json index a119df2df2..f1f11f43bd 100644 --- a/content/docs/quick_start/meta.ko.json +++ b/content/docs/quick_start/meta.ko.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.nl.json b/content/docs/quick_start/meta.nl.json index 6216921448..6be8ed67cd 100644 --- a/content/docs/quick_start/meta.nl.json +++ b/content/docs/quick_start/meta.nl.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.pl.json b/content/docs/quick_start/meta.pl.json index 6e11ce184c..7c7195c686 100644 --- a/content/docs/quick_start/meta.pl.json +++ b/content/docs/quick_start/meta.pl.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.pt-BR.json b/content/docs/quick_start/meta.pt-BR.json index 74889e35cd..2c277b3e57 100644 --- a/content/docs/quick_start/meta.pt-BR.json +++ b/content/docs/quick_start/meta.pt-BR.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.tr.json b/content/docs/quick_start/meta.tr.json index 0bebdd3ea7..a4798cd3d3 100644 --- a/content/docs/quick_start/meta.tr.json +++ b/content/docs/quick_start/meta.tr.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.vi.json b/content/docs/quick_start/meta.vi.json index cb6db450a1..9b5747ed72 100644 --- a/content/docs/quick_start/meta.vi.json +++ b/content/docs/quick_start/meta.vi.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/content/docs/quick_start/meta.zh.json b/content/docs/quick_start/meta.zh.json index 43c228613a..d4895456d7 100644 --- a/content/docs/quick_start/meta.zh.json +++ b/content/docs/quick_start/meta.zh.json @@ -3,6 +3,7 @@ "icon": "Rocket", "pages": [ "local_setup", + "first_chat", "custom_endpoints" ] } diff --git a/package.json b/package.json index 343f027160..cbba79c55b 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "test:watch": "vitest", "sync:config-version": "node scripts/sync-config-version.mjs --write", "check:config-version": "node scripts/sync-config-version.mjs --check", + "sync:locale-meta": "node scripts/sync-locale-meta.mjs --write", + "check:locale-meta": "node scripts/sync-locale-meta.mjs --check", "docs:archive": "tsx scripts/archive-docs-version.ts", "typecheck": "fumadocs-mdx && tsc --noEmit", "lint": "eslint --cache --max-warnings 0 .", diff --git a/scripts/sync-locale-meta.mjs b/scripts/sync-locale-meta.mjs new file mode 100644 index 0000000000..e869b1c604 --- /dev/null +++ b/scripts/sync-locale-meta.mjs @@ -0,0 +1,181 @@ +import { readdir, readFile, writeFile } from 'node:fs/promises' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +export const DEFAULT_DOCS_DIR = 'content/docs' + +const LOCALE_META_PATTERN = /^meta\.([\w-]+)\.json$/ +const SEPARATOR_PATTERN = /^---.*---$/ +const LINK_PATTERN = /^\[[^\]]*\]\(([^)]+)\)$/ + +function linkTarget(entry) { + return LINK_PATTERN.exec(entry)?.[1] ?? null +} + +/** + * Rebuilds a locale's `pages` list from the English one. Page slugs always + * follow English, so a page added to `meta.json` cannot go missing from a + * translated sidebar. Translated separators are reused by position when the + * section count still matches, and translated link labels by URL; anything + * without a translation keeps its English label. + */ +export function syncLocalePages(englishPages, localePages = []) { + const englishSeparators = englishPages.filter((entry) => SEPARATOR_PATTERN.test(entry)) + const localeSeparators = localePages.filter((entry) => SEPARATOR_PATTERN.test(entry)) + const reuseSeparators = englishSeparators.length === localeSeparators.length + const localeLinks = new Map( + localePages.filter(linkTarget).map((entry) => [linkTarget(entry), entry]), + ) + let separatorIndex = 0 + + return englishPages.map((entry) => { + if (SEPARATOR_PATTERN.test(entry)) { + const translated = reuseSeparators ? localeSeparators[separatorIndex] : undefined + separatorIndex += 1 + return translated ?? entry + } + + const target = linkTarget(entry) + if (target) { + return localeLinks.get(target) ?? entry + } + + return entry + }) +} + +async function listMetaDirs(dir) { + const entries = await readdir(dir, { withFileTypes: true }) + const nested = await Promise.all( + entries + .filter((entry) => entry.isDirectory()) + .map((entry) => listMetaDirs(path.join(dir, entry.name))), + ) + const own = entries.some((entry) => entry.isFile() && entry.name === 'meta.json') ? [dir] : [] + return own.concat(...nested) +} + +export async function syncLocaleMeta({ + docsDir = path.join(process.cwd(), DEFAULT_DOCS_DIR), + write = false, +} = {}) { + const changedFiles = [] + + for (const dir of await listMetaDirs(docsDir)) { + const english = JSON.parse(await readFile(path.join(dir, 'meta.json'), 'utf8')) + if (!Array.isArray(english.pages)) { + continue + } + + const localeFiles = (await readdir(dir)).filter((name) => LOCALE_META_PATTERN.test(name)) + + for (const name of localeFiles) { + const filePath = path.join(dir, name) + const original = await readFile(filePath, 'utf8') + const locale = JSON.parse(original) + const pages = syncLocalePages(english.pages, locale.pages) + + if (JSON.stringify(pages) === JSON.stringify(locale.pages)) { + continue + } + + changedFiles.push(filePath) + + if (write) { + await writeFile(filePath, `${JSON.stringify({ ...locale, pages }, null, 2)}\n`) + } + } + } + + return { changedFiles } +} + +function usage() { + return [ + 'Usage: node scripts/sync-locale-meta.mjs [--check|--write]', + '', + 'Options:', + ' --check Report translated sidebars whose pages differ from English (default)', + ' --write Rewrite translated sidebars to follow the English pages', + ' --docs-dir= Docs content directory', + ].join('\n') +} + +function parseArgs(argv) { + const options = { write: false } + + for (const arg of argv) { + if (arg === '--check') { + options.write = false + continue + } + + if (arg === '--write') { + options.write = true + continue + } + + if (arg === '--help' || arg === '-h') { + options.help = true + continue + } + + if (arg.startsWith('--docs-dir=')) { + options.docsDir = arg.slice('--docs-dir='.length) + continue + } + + throw new Error(`Unknown argument: ${arg}`) + } + + return options +} + +async function main() { + let options + + try { + options = parseArgs(process.argv.slice(2)) + } catch (error) { + console.error(`[locale-meta] ${error.message}`) + console.error(usage()) + process.exitCode = 1 + return + } + + if (options.help) { + console.log(usage()) + return + } + + const { changedFiles } = await syncLocaleMeta(options) + + if (changedFiles.length === 0) { + console.log('[locale-meta] translated sidebars match the English pages') + return + } + + const action = options.write ? 'updated' : 'found' + console.error(`[locale-meta] ${action} ${changedFiles.length} stale translated sidebar(s)`) + + for (const filePath of changedFiles) { + console.error(`[locale-meta] ${filePath}`) + } + + if (options.write) { + return + } + + console.error('[locale-meta] run `pnpm sync:locale-meta` to update them') + process.exitCode = 1 +} + +const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : null +const modulePath = fileURLToPath(import.meta.url) + +if (invokedPath === modulePath) { + main().catch((error) => { + console.error(error) + process.exitCode = 1 + }) +} diff --git a/scripts/sync-locale-meta.test.mjs b/scripts/sync-locale-meta.test.mjs new file mode 100644 index 0000000000..fea865581b --- /dev/null +++ b/scripts/sync-locale-meta.test.mjs @@ -0,0 +1,69 @@ +import { mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import path from 'node:path' +import { describe, expect, it } from 'vitest' +import { syncLocaleMeta, syncLocalePages } from './sync-locale-meta.mjs' + +describe('syncLocalePages', () => { + it('adds pages that only exist in the English sidebar', () => { + expect(syncLocalePages(['---Core---', 'a', 'b', 'c'], ['---Kern---', 'a', 'c'])).toEqual([ + '---Kern---', + 'a', + 'b', + 'c', + ]) + }) + + it('drops pages removed from English and follows the English order', () => { + expect(syncLocalePages(['c', 'a'], ['a', 'old', 'c'])).toEqual(['c', 'a']) + }) + + it('keeps English separators when the section count changed', () => { + expect(syncLocalePages(['---One---', 'a', '---Two---', 'b'], ['---Eins---', 'a', 'b'])).toEqual( + ['---One---', 'a', '---Two---', 'b'], + ) + }) + + it('reuses translated link labels by URL', () => { + expect( + syncLocalePages( + ['a', '[Security Policy](https://x/SECURITY.md)', '[New](https://x/new)'], + ['[Sicherheitsrichtlinie](https://x/SECURITY.md)', 'a'], + ), + ).toEqual(['a', '[Sicherheitsrichtlinie](https://x/SECURITY.md)', '[New](https://x/new)']) + }) +}) + +describe('syncLocaleMeta', () => { + async function fixture() { + const docsDir = await mkdtemp(path.join(tmpdir(), 'locale-meta-')) + await mkdir(path.join(docsDir, 'features')) + await writeFile( + path.join(docsDir, 'features', 'meta.json'), + JSON.stringify({ title: 'Features', pages: ['agents', 'skills'] }), + ) + await writeFile( + path.join(docsDir, 'features', 'meta.de.json'), + JSON.stringify({ title: 'Funktionen', icon: 'Star', pages: ['agents'] }), + ) + return docsDir + } + + it('reports stale translated sidebars without writing in check mode', async () => { + const docsDir = await fixture() + const result = await syncLocaleMeta({ docsDir }) + expect(result.changedFiles).toEqual([path.join(docsDir, 'features', 'meta.de.json')]) + const unchanged = JSON.parse(await readFile(result.changedFiles[0], 'utf8')) + expect(unchanged.pages).toEqual(['agents']) + }) + + it('rewrites only the pages list in write mode', async () => { + const docsDir = await fixture() + await syncLocaleMeta({ docsDir, write: true }) + const updated = JSON.parse( + await readFile(path.join(docsDir, 'features', 'meta.de.json'), 'utf8'), + ) + expect(updated).toEqual({ title: 'Funktionen', icon: 'Star', pages: ['agents', 'skills'] }) + expect((await syncLocaleMeta({ docsDir })).changedFiles).toEqual([]) + }) +}) From 54d901b3ed3999cd4df1e806af9e4fda5c9b9134 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:24:35 +0200 Subject: [PATCH 2/4] fix: Match translated sidebar separators by section Separators were reused by position whenever the section count matched, so reordering or regrouping English sections left translated headings above the wrong pages while the check still passed. Reuse each translated separator for the English section that shares the most pages with it, and keep the English label when no section matches. --- scripts/sync-locale-meta.mjs | 52 +++++++++++++++++++++++++------ scripts/sync-locale-meta.test.mjs | 19 +++++++++-- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/scripts/sync-locale-meta.mjs b/scripts/sync-locale-meta.mjs index e869b1c604..078e6b1a4b 100644 --- a/scripts/sync-locale-meta.mjs +++ b/scripts/sync-locale-meta.mjs @@ -12,27 +12,59 @@ function linkTarget(entry) { return LINK_PATTERN.exec(entry)?.[1] ?? null } +function entryKey(entry) { + return linkTarget(entry) ?? entry +} + +/** Maps each separator to the pages listed under it, up to the next separator. */ +function sectionPages(pages) { + const sections = [] + for (const entry of pages) { + if (SEPARATOR_PATTERN.test(entry)) { + sections.push({ separator: entry, pages: new Set() }) + } else if (sections.length > 0) { + sections[sections.length - 1].pages.add(entryKey(entry)) + } + } + return sections +} + /** * Rebuilds a locale's `pages` list from the English one. Page slugs always * follow English, so a page added to `meta.json` cannot go missing from a - * translated sidebar. Translated separators are reused by position when the - * section count still matches, and translated link labels by URL; anything - * without a translation keeps its English label. + * translated sidebar. A translated separator is reused for the English + * section that shares the most pages with it, so reordered or regrouped + * sections keep the right heading, and translated link labels are reused by + * URL; anything without a translation keeps its English label. */ export function syncLocalePages(englishPages, localePages = []) { - const englishSeparators = englishPages.filter((entry) => SEPARATOR_PATTERN.test(entry)) - const localeSeparators = localePages.filter((entry) => SEPARATOR_PATTERN.test(entry)) - const reuseSeparators = englishSeparators.length === localeSeparators.length + const localeSections = sectionPages(localePages) + const translatedSeparators = new Map() + for (const { separator, pages } of sectionPages(englishPages)) { + let best = null + let bestShared = 0 + for (const section of localeSections) { + if (section.used) { + continue + } + const shared = [...section.pages].filter((page) => pages.has(page)).length + if (shared > bestShared) { + best = section + bestShared = shared + } + } + if (best) { + best.used = true + translatedSeparators.set(separator, best.separator) + } + } const localeLinks = new Map( localePages.filter(linkTarget).map((entry) => [linkTarget(entry), entry]), ) - let separatorIndex = 0 return englishPages.map((entry) => { if (SEPARATOR_PATTERN.test(entry)) { - const translated = reuseSeparators ? localeSeparators[separatorIndex] : undefined - separatorIndex += 1 - return translated ?? entry + return translatedSeparators.get(entry) ?? entry } const target = linkTarget(entry) diff --git a/scripts/sync-locale-meta.test.mjs b/scripts/sync-locale-meta.test.mjs index fea865581b..31984b96e6 100644 --- a/scripts/sync-locale-meta.test.mjs +++ b/scripts/sync-locale-meta.test.mjs @@ -18,10 +18,25 @@ describe('syncLocalePages', () => { expect(syncLocalePages(['c', 'a'], ['a', 'old', 'c'])).toEqual(['c', 'a']) }) - it('keeps English separators when the section count changed', () => { + it('translates each section by the pages it shares', () => { + expect( + syncLocalePages( + ['---Services---', 's', '---Infrastructure---', 'i'], + ['---Infrastruktur---', 'i', '---Dienste---', 's'], + ), + ).toEqual(['---Dienste---', 's', '---Infrastruktur---', 'i']) + }) + + it('keeps the English separator for a section without shared pages', () => { expect(syncLocalePages(['---One---', 'a', '---Two---', 'b'], ['---Eins---', 'a', 'b'])).toEqual( - ['---One---', 'a', '---Two---', 'b'], + ['---Eins---', 'a', '---Two---', 'b'], ) + expect(syncLocalePages(['---New---', 'n', '---Old---', 'o'], ['---Alt---', 'o'])).toEqual([ + '---New---', + 'n', + '---Alt---', + 'o', + ]) }) it('reuses translated link labels by URL', () => { From 447f0d3a1c108e7f7dd6dfe0ae5063b3994299af Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:31:32 +0200 Subject: [PATCH 3/4] fix: Assign translated separators by strongest overlap first Matching sections in English order let a newly split section take the heading of the section that kept most of the original pages. --- scripts/sync-locale-meta.mjs | 43 +++++++++++++++++++------------ scripts/sync-locale-meta.test.mjs | 6 +++++ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/scripts/sync-locale-meta.mjs b/scripts/sync-locale-meta.mjs index 078e6b1a4b..478c91ec95 100644 --- a/scripts/sync-locale-meta.mjs +++ b/scripts/sync-locale-meta.mjs @@ -38,33 +38,42 @@ function sectionPages(pages) { * URL; anything without a translation keeps its English label. */ export function syncLocalePages(englishPages, localePages = []) { + const englishSections = sectionPages(englishPages) const localeSections = sectionPages(localePages) + // Strongest overlap first, so a split section cannot take the heading of + // the section that kept most of the original pages. + const candidates = englishSections.flatMap((english, englishIndex) => + localeSections.map((locale, localeIndex) => ({ + english, + locale, + englishIndex, + localeIndex, + shared: [...locale.pages].filter((page) => english.pages.has(page)).length, + })), + ) + candidates.sort( + (a, b) => + b.shared - a.shared || a.englishIndex - b.englishIndex || a.localeIndex - b.localeIndex, + ) const translatedSeparators = new Map() - for (const { separator, pages } of sectionPages(englishPages)) { - let best = null - let bestShared = 0 - for (const section of localeSections) { - if (section.used) { - continue - } - const shared = [...section.pages].filter((page) => pages.has(page)).length - if (shared > bestShared) { - best = section - bestShared = shared - } - } - if (best) { - best.used = true - translatedSeparators.set(separator, best.separator) + const usedLocale = new Set() + for (const { english, locale, shared } of candidates) { + if (shared === 0 || translatedSeparators.has(english) || usedLocale.has(locale)) { + continue } + translatedSeparators.set(english, locale.separator) + usedLocale.add(locale) } + const separatorByIndex = englishSections.map((section) => translatedSeparators.get(section)) const localeLinks = new Map( localePages.filter(linkTarget).map((entry) => [linkTarget(entry), entry]), ) + let sectionIndex = -1 return englishPages.map((entry) => { if (SEPARATOR_PATTERN.test(entry)) { - return translatedSeparators.get(entry) ?? entry + sectionIndex += 1 + return separatorByIndex[sectionIndex] ?? entry } const target = linkTarget(entry) diff --git a/scripts/sync-locale-meta.test.mjs b/scripts/sync-locale-meta.test.mjs index 31984b96e6..47a6aa3542 100644 --- a/scripts/sync-locale-meta.test.mjs +++ b/scripts/sync-locale-meta.test.mjs @@ -39,6 +39,12 @@ describe('syncLocalePages', () => { ]) }) + it('gives a split section the heading of the part that kept most pages', () => { + expect( + syncLocalePages(['---New---', 'a', '---Core---', 'b', 'c'], ['---Kern---', 'a', 'b', 'c']), + ).toEqual(['---New---', 'a', '---Kern---', 'b', 'c']) + }) + it('reuses translated link labels by URL', () => { expect( syncLocalePages( From 49f8f7c6af3bd99c9f35c3489b8f3d41229a7f0a Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:44:19 +0200 Subject: [PATCH 4/4] fix: Report translated sidebars missing from a folder The check only validated locale files that existed, so a deleted file or a new folder without translations passed. Expect every locale used in any sidebar folder, and create missing files from English in write mode. Document that renamed headings keep their old translation. --- scripts/sync-locale-meta.mjs | 33 ++++++++++++++++++++++--------- scripts/sync-locale-meta.test.mjs | 16 +++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/scripts/sync-locale-meta.mjs b/scripts/sync-locale-meta.mjs index 478c91ec95..6b5d0b4233 100644 --- a/scripts/sync-locale-meta.mjs +++ b/scripts/sync-locale-meta.mjs @@ -35,7 +35,10 @@ function sectionPages(pages) { * translated sidebar. A translated separator is reused for the English * section that shares the most pages with it, so reordered or regrouped * sections keep the right heading, and translated link labels are reused by - * URL; anything without a translation keeps its English label. + * URL; anything without a translation keeps its English label. A renamed + * English heading keeps its old translation, because the pages cannot tell a + * rename from a regroup, so update the translated headings by hand when you + * rename one. */ export function syncLocalePages(englishPages, localePages = []) { const englishSections = sectionPages(englishPages) @@ -101,22 +104,34 @@ export async function syncLocaleMeta({ write = false, } = {}) { const changedFiles = [] + const metaDirs = await listMetaDirs(docsDir) + const localeFilesByDir = new Map() + for (const dir of metaDirs) { + localeFilesByDir.set( + dir, + (await readdir(dir)).filter((name) => LOCALE_META_PATTERN.test(name)), + ) + } + // Every sidebar folder needs the locales used anywhere else, so a deleted + // file or a new folder without translations is reported too. + const expectedFiles = [...new Set([...localeFilesByDir.values()].flat())].sort() - for (const dir of await listMetaDirs(docsDir)) { + for (const dir of metaDirs) { const english = JSON.parse(await readFile(path.join(dir, 'meta.json'), 'utf8')) if (!Array.isArray(english.pages)) { continue } - const localeFiles = (await readdir(dir)).filter((name) => LOCALE_META_PATTERN.test(name)) + const present = new Set(localeFilesByDir.get(dir)) - for (const name of localeFiles) { + for (const name of expectedFiles) { const filePath = path.join(dir, name) - const original = await readFile(filePath, 'utf8') - const locale = JSON.parse(original) + const locale = present.has(name) + ? JSON.parse(await readFile(filePath, 'utf8')) + : { ...english, pages: undefined } const pages = syncLocalePages(english.pages, locale.pages) - if (JSON.stringify(pages) === JSON.stringify(locale.pages)) { + if (present.has(name) && JSON.stringify(pages) === JSON.stringify(locale.pages)) { continue } @@ -136,8 +151,8 @@ function usage() { 'Usage: node scripts/sync-locale-meta.mjs [--check|--write]', '', 'Options:', - ' --check Report translated sidebars whose pages differ from English (default)', - ' --write Rewrite translated sidebars to follow the English pages', + ' --check Report translated sidebars that are missing or whose pages differ from English (default)', + ' --write Rewrite translated sidebars to follow the English pages, creating missing ones from English', ' --docs-dir= Docs content directory', ].join('\n') } diff --git a/scripts/sync-locale-meta.test.mjs b/scripts/sync-locale-meta.test.mjs index 47a6aa3542..cb45716e4a 100644 --- a/scripts/sync-locale-meta.test.mjs +++ b/scripts/sync-locale-meta.test.mjs @@ -87,4 +87,20 @@ describe('syncLocaleMeta', () => { expect(updated).toEqual({ title: 'Funktionen', icon: 'Star', pages: ['agents', 'skills'] }) expect((await syncLocaleMeta({ docsDir })).changedFiles).toEqual([]) }) + + it('reports and creates a translated sidebar missing from one folder', async () => { + const docsDir = await fixture() + await mkdir(path.join(docsDir, 'guides')) + await writeFile( + path.join(docsDir, 'guides', 'meta.json'), + JSON.stringify({ title: 'Guides', pages: ['intro'] }), + ) + const missing = path.join(docsDir, 'guides', 'meta.de.json') + expect((await syncLocaleMeta({ docsDir })).changedFiles).toContain(missing) + await syncLocaleMeta({ docsDir, write: true }) + expect(JSON.parse(await readFile(missing, 'utf8'))).toEqual({ + title: 'Guides', + pages: ['intro'], + }) + }) })