Docs et Traductions
ZeroClaw dispose de deux couches de traduction indépendantes :
| Couche | Format | Ce que cela couvre |
|---|---|---|
| Chaînes de l’application | Mozilla Fluent (.ftl) | Texte d’aide de la CLI, descriptions de commandes, messages d’exécution |
| Docs | gettext (.po) | Tout ce qui se trouve dans ce mdBook |
Pour connaître la source de vérité, le stockage, le chargement, les mécanismes de repli et les limites de publication qui sous-tendent ces procédures, consultez Cycle de vie du catalogue de localisation. Les références anglaises générées qui alimentent l’extraction de la documentation sont mises en correspondance dans Pipeline de documentation générée.
Ils sont remplis séparément et stockés séparément. Les deux utilisent le chemin d’exécution partagé indépendant du fournisseur : configurez un fournisseur de modèle sous providers.models.<kind>.<alias> et passez --model-provider <alias> aux commandes de remplissage. Tout alias configuré est sélectionnable : un alias simple (--model-provider <alias>), ou un qualificateur kind.alias (--model-provider anthropic.<alias>) lorsque le même alias existe sous plusieurs kinds. Le résolveur exige que l’entrée correspondante désigne un modèle, puis délègue les valeurs par défaut du point de terminaison, l’authentification, le protocole filaire et la gestion optionnelle d’uri personnalisée à la pile de fournisseurs d’exécution.
Les modèles locaux via Ollama sont une option de premier ordre : aucune clé API requise, aucun coût par appel. Un fournisseur hébergé convient également pour une qualité de niveau production. La traduction est une opération locale. Exécutez cargo mdbook sync pour les PR dédiées au cache de traduction, les passes de traduction de version et les nouvelles locales ; les PR de documentation anglaise courantes peuvent reporter les modifications massives des fichiers .po générés à un suivi ciblé.
Configuration du fournisseur
Ollama est actuellement la source canonique pour la documentation. Assurez-vous d’avoir Ollama installé et d’avoir récupéré qwen3:30b-a3b, puis configurez une entrée de fournisseur Ollama. uri est l’URL complète du point de terminaison et est optionnel : laissez-le non défini pour utiliser le point de terminaison par défaut de la famille du fournisseur (résolu par la pile de fournisseurs du runtime). Définissez-le uniquement pour pointer vers une passerelle ou un proxy auto-hébergé. Toute famille configurée fonctionne (Anthropic, OpenAI, OpenRouter, Ollama, …) ; les outils de traduction construisent le véritable fournisseur du runtime, de sorte que le point de terminaison, l’en-tête d’authentification et le protocole de communication de chaque famille sont gérés pour vous : aucune exigence de compatibilité OpenAI.
Génération de la documentation localement
Catalogues de traduction (git submodule)
Les catalogues .po traduits se trouvent dans le sous-module zeroclaw-labs/zeroclaw-docs-translations monté à docs/book/po. La boucle de développement Rust (cargo build, cargo test, cargo clippy) n’en a pas besoin, mais construire ou synchroniser la documentation en a besoin. Initialisez-le une fois :
sh
git clone --recurse-submodules https://github.com/zeroclaw-labs/zeroclaw # nouveau clone
git submodule update --init docs/book/po # clone existant
Sans le sous-module extrait, l’anglais se construit toujours (les sources anglaises se trouvent dans docs/book/src/), mais les locales traduites s’affichent vides.
Démarrage rapide en une commande
sh
cargo mdbook serve # servir toutes les langues à http://localhost:3000/en/
cargo mdbook serve --locale ja # rechargement automatique contre des sources en japonais
cargo mdbook build # build statique de chaque locale dans docs/book/book/
cargo mdbook refs # régénérer les pages de référence générées automatiquement
cargo mdbook sync # passe translation-cache : ré-extraction + fusion des fichiers .po
cargo mdbook sync --locale ja # synchroniser uniquement une locale
cargo mdbook sync --force # forcer la retraduction de tout (passage de qualité)
cargo mdbook sync --locale ja --force # forcer la retraduction d'une locale
cargo mdbook stats # afficher les chaînes traduites/floues/non traduites par locale
cargo mdbook check # valider le format .po (à exécuter avant une PR de traduction)
Utilisez toujours le wrapper
cargo mdbook …. Exécutermdbook builddirectement depuisdocs/book/ignore l’étape xtask qui génèretheme/lang-switcher.jsà partir delocales.toml, ce qui fait échouer la compilation avecfailed to open theme/lang-switcher.js for hashing.
Outils requis
cargo mdbook échouera rapidement et vous indiquera ce qui manque, mais à titre de référence :
| Outil | Installer |
|---|---|
mdbook | cargo install mdbook --version 0.5.4 --locked |
mdbook-mermaid | cargo install mdbook-mermaid --version 0.17.1 |
mdbook-i18n-helpers | cargo install mdbook-i18n-helpers --locked |
cargo | https://rustup.rs |
gettext (msgfmt, msgmerge) | apt install gettext / brew install gettext |
La version de mdbook-mermaid est verrouillée, mais son fichier de verrouillage publié sélectionne encore le préprocesseur mdBook 0.5.0. Omettez --locked pour cet outil afin que Cargo résolve le préprocesseur 0.5.x compatible utilisé par mdBook 0.5.4.
Ce qui est construit où
| Source | Sortie | Généré par |
|---|---|---|
docs/book/src/**/*.md (rédigé à la main) | docs/book/book/<locale>/ | mdbook build |
docs/book/src/reference/cli.md | (même chemin ; ignoré par git) | cargo mdbook refs |
docs/book/src/reference/config.md | (même chemin ; ignoré par git) | cargo mdbook refs |
target/doc/ (rustdoc) | docs/book/book/api/ | cargo doc --no-deps --workspace --exclude zeroclaw-desktop |
Les deux fichiers reference/*.md sont générés à partir des dérives clap réelles et du schéma JSON présents dans le code, ne les modifiez jamais à la main. Modifiez plutôt les commentaires de documentation /// sur les types Rust concernés.
cargo mdbook est un alias pour cargo run -p xtask --bin mdbook -- (défini dans la configuration cargo). Pour une version allégée de cette section destinée aux contributeurs, consultez Building the docs locally.
[!NOTE] La recherche en texte intégral n’est construite que pour la locale principale (anglais, en premier dans
locales.toml). Les locales traduites se construisent sans index de recherche ni boîte de recherche. Les index de recherche par locale sont volumineux (~6-7 Mo chacun) et dominent la taille du clonegh-pages; restreindre la recherche à l’anglais permet de garder les clones légers. Réajouter une boîte de recherche à une locale traduite implique de réactiveroutput.html.search.enablepour cette construction dansbuild_locales(xtask/src/cmd/mdbook/build.rs).
Comment les traductions restent à jour
Lorsque la source anglaise est modifiée, cargo mdbook sync exécute deux étapes :
- Extraction :
mdbook-xgettextrégénèrepo/messages.potà partir de la source anglaise actuelle. - Fusion :
msgmerge --no-fuzzy-matchingmet à jour le fichier.pode chaque locale, attribue unmsgstr ""vide aux chaînes sources nouvelles ou modifiées, et supprime les entrées obsolètes. Seules les entrées floues déjà présentes avant la fusion peuvent rester disponibles pour une révision ultérieure ou une acceptation de remplissage.
La commande compte ensuite les entrées floues + non traduites et, lorsque --model-provider est fourni, remplit uniquement celles-ci. Les chaînes inchangées ne coûtent rien : le cache .po fait qu’une réexécution sur une source inchangée est une opération sans effet. Sans --model-provider, sync exécute quand même l’extraction + la fusion et signale le delta ; les chaînes sans msgstr reviennent à l’anglais au moment du rendu.
La synchronisation normalise les catalogues avec des règles de sortie stables (msgcat --sort-output --no-wrap --add-location=file), de sorte que les diffs restent concentrés sur les changements réels de la source. Variations inévitables : les métadonnées d’en-tête (POT-Creation-Date, etc.), les mises à jour d’emplacement de référence lorsqu’une chaîne change de fichier, et les modifications effectives des chaînes sources.
Les PR de documentation anglaise courantes peuvent reporter les modifications massives des fichiers .po à un suivi dédié. N’incluez les mises à jour des fichiers .po que lorsque la PR est une passe de cache de traduction, une passe de traduction de version, ajoute une locale ou produit un diff restreint et facile à relire.
Remplissage des chaînes de l’application (Fluent)
Les chaînes de l’application se trouvent dans crates/zeroclaw-runtime/locales/. L’anglais est la source de référence et est intégré au moment de la compilation.
Limite de chargement à l’exécution.
- Sources intégrées : les fichiers
cli.ftlettools.ftlen anglais sont intégrés.builtin_cli_ftl_source()énumère les catalogues CLI non anglais intégrés par le runtime ;zeroclaw-toolsintègre séparément les chaînes d’outils en anglais afin de préserver le sens des dépendances entre crates.- Surcouche disque : Un catalogue situé dans
<config-dir>/data/ftl/<locale>/remplace une valeur CLI intégrée et fournit des valeurs traduites pour l’environnement d’exécution et les outils.zeroclaw locales fetchremplit ce répertoire partagé.- Mise en garde sur la consommation : Remplir et valider un fichier
.ftlmet à jour la source du catalogue suivi, mais un consommateur ne l’utilise que si son chargeur intègre ce catalogue ou si le fichier est installé à l’emplacement où ce chargeur le lit.Le TUI
apps/zerocodemaintient un catalogue Fluent indépendant (apps/zerocode/locales/), voir chaînes zerocode ci-dessous.cargo fluentparcourt les deux racines de catalogue (runtime + zerocode), donc chaque sous-commande ci-dessous couvre les deux par défaut.
sh
cargo fluent stats # couverture par langue, par catalogue
cargo fluent check # valider la syntaxe .ftl dans les deux catalogues
cargo fluent fill --locale ja --model-provider anthropic.<alias> # fill missing keys (default batch 50)
cargo fluent fill --locale ja --model-provider anthropic.<alias> --batch 10 # lots plus petits : moins d'entrées par requête (réduit les limites de débit / la troncature)
cargo fluent fill --locale ja --model-provider anthropic.<alias> --force # retranslate everything
cargo fluent scan # Trouver les clés périmées ou manquées par rapport à la source Rust
Limiter à un seul catalogue : chaque sous-commande accepte --catalog <runtime|zerocode> (par défaut : les deux). Pour traduire uniquement la TUI :
sh
cargo fluent fill --locale ja --model-provider anthropic.<alias> --catalog zerocode
cargo fluent check --catalog zerocode # vérification de syntaxe uniquement zerocode
Une valeur --catalog inconnue génère une erreur indiquant les choix valides.
fill génère <locale>/<domain>.ftl pour chaque racine de catalogue sélectionnée disposant d’un répertoire en/ : les fichiers cli.ftl/tools.ftl du runtime et le fichier zerocode.ftl de zerocode.
La résolution du fournisseur est partagée avec le runtime. --model-provider accepte tout alias configuré sous [providers.models.<kind>.<alias>] : un alias simple (<alias>) ou un qualificatif kind.alias (anthropic.<alias>) en cas d’ambiguïté. L’outil construit le fournisseur runtime réel, de sorte que le point de terminaison, l’en-tête d’authentification et le protocole de transport sont résolus par famille (Anthropic /v1/messages + x-api-key, compatible OpenAI /v1/chat/completions + Bearer, etc.) : rien n’est présumé. Les valeurs api_key chiffrées sont déchiffrées via le SecretStore canonique. Utilisez --config-dir <dir> (équivalent de zeroclaw --config-dir) pour lire la configuration + .secret-key depuis un emplacement non standard ; par défaut, ~/.zeroclaw puis ~/.config/zeroclaw.
Traitement par lots : fill envoie une requête par lot (les N entrées sous forme d’un seul objet JSON) ; --batch réduit N pour atténuer les limites de débit du fournisseur ou la troncature des réponses sur les entrées longues. Chaque lot est écrit sur disque avant la requête suivante, donc un échec en cours d’exécution ne fait perdre que le lot en cours. Une nouvelle exécution ignore les clés déjà présentes dans le fichier .ftl cible, la reprise est donc automatique : pas besoin de --force.
chaînes zerocode (Fluent, indépendant)
apps/zerocode embarque sa propre configuration Fluent autonome, distincte des catalogues d’exécution mentionnés ci-dessus. La TUI est volontairement découplée du reste de l’espace de travail : elle ne dépend d’aucun crate zeroclaw-*, et ses chaînes résident à côté de son code source plutôt que sous zeroclaw-runtime/locales/.
| Où | Que |
|---|---|
apps/zerocode/locales/en/zerocode.ftl | Source de vérité, intégrée à la compilation |
apps/zerocode/locales/<locale>/zerocode.ftl | Source de catalogue traduit suivie, utilisée par les workflows fill/fetch et release ; non intégrée automatiquement |
$ZEROCODE_LOCALE_DIR/<locale>/zerocode.ftl | Remplacement explicite, utile pour tester les traductions |
<config-dir>/data/ftl/<locale>/zerocode.ftl | Catalogue partagé par utilisateur écrit par zeroclaw locales fetch et chargé par zerocode |
Espace de noms de clés
Toutes les clés zerocode sont préfixées par zc- et n’entrent jamais en collision avec les espaces de noms cli-, channel- ou tool- du runtime. La convention au sein de zc- est zc-<pane>-<purpose> :
zc-pane-<name>: libellés de la barre de mode de premier niveauzc-app-<purpose>: chaînes appartenant àapp.rs(boîtes de dialogue, aide, statut)zc-<pane>-<purpose>: chaînes locales à un volet spécifique (zc-dashboard-*,zc-chat-*, …)
Les littéraux d’accords ne sont pas traduits
Les symboles de raccourcis comme Ctrl+C, Esc, Shift+Up relèvent du protocole, pas de la langue. Les constructeurs HelpEntry et HelpNode prennent le vecteur de raccourcis sous forme de &'static str et la description sous forme de String, de sorte que les littéraux de raccourcis restent codés en dur tandis que les descriptions passent par t(). Lorsqu’un texte intègre un raccourci en ligne, utilisez un emplacement Fluent { $keys } et transmettez le raccourci au moment du rendu plutôt que de concaténer du texte traduit autour d’un littéral.
Résolution des paramètres régionaux
La locale provient d’un champ locale de premier niveau dans la configuration de zerocode. Lorsqu’il n’est pas défini, i18n::detect_locale() lit le répertoire de configuration résolu comme --config-dir, puis ZEROCLAW_CONFIG_DIR, puis ~/.zeroclaw, et sinon se rabat sur en. zerocode résout sa locale indépendamment à partir de sa propre configuration ; il ne partage pas la recherche du démon.
Ajout de chaînes
- Ajoutez la clé + la valeur en anglais à
apps/zerocode/locales/en/zerocode.ftl. Regroupez les clés par fichier source avec un commentaire de section afin que le catalogue reste facile à parcourir. - Remplacez le littéral dans la source par
crate::i18n::t("zc-…"). Pour les bras dematchenum→libellé, retournez la constante de clé (&'static str) depuis une méthodefluent_key()et appelezt()au point de rendu, jamais dematchsur une chaîne. cargo check -p zerocodeet les tests unitairesi18n(cargo test -p zerocode i18n) détectent les clés manquantes au moment de la compilation/des tests. Les clés manquantes à l’exécution s’affichent sous la forme{zc-key-name}et émettent un avertissement unique sur stderr.
Remplissage des traductions
cargo fluent parcourt le catalogue zerocode en même temps que le catalogue d’exécution, de sorte qu’aucune commande fill distincte n’est nécessaire. L’exécution de cargo fluent fill --locale <code> --model-provider <alias> génère apps/zerocode/locales/<code>/zerocode.ftl dans la même passe qui remplit le catalogue d’exécution. cargo fluent check et cargo fluent stats rendent compte de zerocode de la même façon ; scan indexe apps/ afin que les références aux clés zc- soient résolues par rapport à la source de zerocode. Pour tester la traduction dans zerocode, installez-la via zeroclaw locales fetch ou placez-la sous l’une des deux racines de recherche sur disque mentionnées ci-dessus.
Remplissage des traductions de documentation (gettext)
Les traductions de la documentation se trouvent dans docs/book/po/. cargo mdbook sync exécute extraction → fusion → suppression des éléments obsolètes → remplissage par IA en une seule étape. Sans --model-provider, sync exécute quand même l’extraction + la fusion et indique combien de chaînes nécessitent une traduction : les traductions partielles reviennent à l’anglais au moment du rendu.
sh
cargo mdbook sync --model-provider anthropic.<alias> # delta fill
cargo mdbook sync --model-provider anthropic.<alias> --force # passage de qualité : retraduire toutes les entrées
cargo mdbook sync --model-provider anthropic.<alias> --batch 1 # écrire après chaque entrée (reprise la plus sûre)
cargo mdbook sync --locale ja --model-provider anthropic.<alias> # single locale
cargo mdbook sync --model-provider anthropic.<alias> --config-dir ~/.zeroclaw # alias qualifié + répertoire de configuration explicite
--model-provider est résolu via le même chemin de fournisseur d’exécution partagé que cargo fluent (toute famille/alias configuré, point de terminaison + authentification + protocole de transmission par famille, déchiffrement SecretStore, prise en charge de --config-dir). Contrairement à cargo fluent, qui envoie un lot entier sous forme d’un seul objet JSON, le remplisseur gettext émet une requête par chaîne source afin de garder le mappage msgid → msgstr sans ambiguïté, donc --batch contrôle la fréquence à laquelle le .po est écrit sur le disque (l’intervalle de point de contrôle), et non la taille des requêtes. Une locale en catalogue complet représente des milliers de requêtes séquentielles ; pour les remplissages delta de routine, un alias Ollama local peu coûteux est le choix économique.
Le pipeline possède une résilience intégrée :
- Détection de fuite : si un modèle renvoie ses propres instructions au lieu d’une traduction, l’outil détecte le motif (via le ratio de longueur de réponse et la structure en liste à puces), tente de récupérer la véritable traduction à la fin de la réponse, et vide l’entrée pour une nouvelle traduction si la récupération échoue.
- Vérifications des littéraux protégés :
cargo mdbook checkrejette également la corruption de littéraux à haute confiance dans les fichiers.pogénérés. Les noms de produits tels queZeroClaw Maturity Framework, les littéraux de commande tels quezeroclaw daemonet les littéraux de sections/clés TOML dans les blocs de code doivent rester intacts octet par octet dans les traductions. Traduisez la prose environnante, pas le texte destiné à la machine. - Vérifications de fuites de chemins : les traductions générées ne doivent pas introduire de chemins absolus spécifiques à la machine absents de la source en anglais ; ces entrées sont vidées pour re-traduction et rejetées par
cargo mdbook check. - Écritures incrémentales : après chaque lot, le fichier
.poest réécrit. Un Ctrl-C en cours d’exécution ne fait pas perdre la progression accomplie jusque-là. - Suppression des entrées obsolètes :
msgmerge+msgattrib --no-obsoleteempêchent les chaînes sources supprimées de s’accumuler sous forme d’entrées#~.
Les mainteneurs doivent accepter l’exception relative à la documentation courante en anglais décrite dans Building the docs locally. Ne demandez de mises à jour des fichiers .po que lorsque la PR est elle-même une passe de cache de traduction, une passe de traduction de version, une modification de nouvelle locale, ou lorsque le diff généré est suffisamment petit pour être relu.
Ajout d’une nouvelle locale
-
Modifiez
locales.tomlà la racine du dépôt, le seul fichier que vous devez modifier : -
Traduisez les chaînes de l’application :
sh
cargo fluent fill --locale <code> --model-provider ollama -
Initialiser et remplir le fichier de documentation
.po:sh
cargo mdbook sync --locale <code> --model-provider ollama -
L’exécution de
cargo fluent fillà l’étape 2 génère déjàapps/zerocode/locales/<code>/zerocode.ftldans la même passe, puisquecargo fluentparcourt à la fois les catalogues runtime et zerocode. Aucune étape manuelle pour zerocode n’est nécessaire ; vérifiez la couverture aveccargo fluent stats.
Tout le reste, lang-switcher.js, la liste des cibles de déploiement CI, la sortie de cargo mdbook locales, est lu automatiquement depuis locales.toml.
Sous-module de catalogue de traduction
Les catalogues .po traduits ne se trouvent pas dans l’arborescence principale de ce dépôt. Ils résident dans le dépôt dédié zeroclaw-labs/zeroclaw-docs-translations, monté en tant que sous-module git à docs/book/po (branche par défaut main). Le point de montage est transparent pour les chemins : le préprocesseur gettext de book.toml, cargo mdbook sync et cargo mdbook build lisent tous po/ exactement comme auparavant.
La boucle de dev du crate Rust n’a jamais besoin du sous-module. Seuls les builds de documentation et les jobs docs-deploy / release en ont besoin ; ces checkouts passent submodules: recursive. Tout le reste reste sans sous-module.
À chaque version, scripts/release/refresh-translations.sh publie les catalogues modifiés sur la branche main du sous-module, crée une balise v{version} pour ce commit, se positionne sur la balise et ajoute à l’index le gitlink du dépôt principal. bump-version.sh laisse délibérément à cet utilitaire le soin de verrouiller la version des traductions. messages.pot et *.failures.log sont des artefacts régénérés, ignorés par Git dans les deux dépôts et non suivis.
Flux de travail de traduction des versions
La procédure d’actualisation, de validation, d’étiquetage, de push et de gitlink-pin au moment de la publication fait partie de l’étape 2 du Release Runbook. Cette page documente le système de traduction ; utilisez le runbook comme source de vérité opérationnelle lors de la préparation d’une publication.
Notes sur la qualité du modèle
La qualité de la traduction varie considérablement selon la langue et le modèle.
| Paramètres régionaux | Bien pris en charge par | Notes |
|---|---|---|
ja, zh-CN | famille qwen3, tout modèle hébergé de pointe | Qwen est d’abord chinois ; le japonais est également très fort. |
es, fr | qwen3, mistral, gemma3, hébergé | Les langues romanes sont globalement bien entraînées. |
| Locales à ressources limitées | Modèles de pointe hébergés uniquement | Les modèles locaux ont souvent tendance à halluciner des mots. |
Pour les passes de qualité de production, privilégiez un modèle hébergé via --force. Pour les mises à jour incrémentales continues pendant le développement, un modèle local Ollama est suffisant et gratuit.