Skip to content
Apothem
Blog

Au cœur de la conception de l'adaptateur multi-environnement

Une plongée technique dans le protocole HarnessAdapter d'Apothem et les trois classes d'adaptateur qui matérialisent un profil en dix-sept environnements.

Apothem matérialise un unique profil partagé en dix-sept configurations natives d'environnement. Dix-sept cibles, dix-sept formats d'éditeur, dix-sept emplacements d'installation — et une seule interface uniforme dont l'opérateur et la CLI dépendent tous deux. Cet article explique comment la couche d'adaptateurs tient ce contrat ensemble.

Le protocole HarnessAdapter

Chaque adaptateur d'environnement implémente un protocole structurel HarnessAdapter. Le protocole est la couture entre la CLI et les détails propres à l'éditeur. Il déclare les opérations que la CLI invoque et les métadonnées que la CLI lit :

  • name — l'identifiant enregistré de l'adaptateur.
  • output_path — l'emplacement sur disque où atterrit la configuration matérialisée.
  • install — rendre et écrire la configuration native de l'environnement.
  • update — rendre à nouveau la configuration native de l'environnement après une modification du profil.
  • uninstall — supprimer la configuration matérialisée, en laissant le profil partagé intact.
  • is_installed — indiquer si la configuration de l'environnement est présente.
  • verify — détecter la dérive entre le profil et la configuration sur disque.

Comme le contrat est un typing.Protocol, un adaptateur le satisfait par sa forme, et non par héritage. À l'exécution, la CLI résout chaque adaptateur à partir d'un registre statique — la table HARNESS_REGISTRY dans src/apothem/lib/harness_registry_data.py, dont harness_registry.py déclare qu'elle fait autorité à l'exécution — de sorte qu'un simple checkout charge chaque adaptateur sans aucune métadonnée de point d'entrée installée sur sys.path. La table [project.entry-points."apothem.harnesses"] dans pyproject.toml et le balayage discover_adapters() du système de fichiers constituent un contrôle de parité de conformance, et non le résolveur d'exécution : un test affirme que l'ensemble d'adaptateurs découvert égale le registre statique, de sorte qu'un adaptateur conforme à la convention mais non enregistré ressort comme une régression de couverture plutôt que d'être résolu silencieusement. Ajouter un environnement revient donc à l'enregistrer dans les données du registre (et à le refléter dans la table des points d'entrée pour la parité d'empaquetage) — le test de parité échoue bruyamment si l'un des deux est oublié.

Un sous-paquet par adaptateur

Chaque adaptateur vit dans son propre sous-paquet sous src/apothem/harnesses/<name>/ :

  • __init__.py — la classe <Name>Adapter qui implémente le protocole et délègue aux modules d'action voisins.
  • install.py / uninstall.py / update.py / verify.py — les implémentations par action que la classe de l'adaptateur importe et appelle.
  • materializer.py — un materialize_native_config(profile) -> str optionnel qui rend le profil partagé sous forme de texte de configuration natif de l'environnement.

Diviser chaque action dans son propre module garde la classe de l'adaptateur fine : c'est un répartiteur qui relie les méthodes du protocole aux fonctions d'action. Un lecteur qui ouvre verify.py voit exactement la logique de détection de dérive de ce seul environnement, sans bruit d'installation ou de désinstallation à traverser.

Trois classes d'adaptateur

Les dix-sept environnements ne consomment pas tous la configuration de la même façon. Apothem les trie en trois classes selon la quantité de transformation que le profil nécessite avant d'atteindre l'environnement.

Classe I — propagation brute

L'environnement consomme les mêmes artefacts qu'Apothem écrit déjà — des règles .md plates, des agents, des hooks — sans étape de rendu. L'adaptateur copie les modèles bruts dans l'arborescence de configuration de l'environnement. Il n'y a pas de materializer.py, car rien n'est rendu ; les artefacts du profil sont la sortie.

Classe II-A — brut plus modèles d'éditeur

L'environnement consomme les artefacts bruts d'Apothem ET un ensemble de fichiers de modèle propres à l'éditeur (fichiers de paramètres, de manifeste ou d'échafaudage que l'environnement requiert). L'adaptateur copie ensemble les artefacts bruts et les modèles d'éditeur. Les modèles d'éditeur vivent à côté de l'adaptateur dans un répertoire templates/.

Classe II-B — rendu depuis le profil

L'environnement veut un unique fichier de configuration natif rendu à partir des champs structurés du profil partagé. Le materializer.py de l'adaptateur lit le profil et émet le texte natif de l'environnement — un config.yaml de Hermes, un openclaw.json d'Open-Claw, un opencode.json d'OpenCode ou un settings.json de Qwen Code. La Classe II-B est l'endroit où se concentre le travail de réconciliation des formats ; l'analyse approfondie de la convergence des conventions le couvre en détail.

claude-code : l'adaptateur à surface complète

L'adaptateur claude-code a la plus large surface de configuration — règles, agents, hooks, output-styles, paramètres et répertoires de convention. Il appartient à la Classe II-A : il propage les modèles bruts d'Apothem et aplatit les répertoires de convention, et il livre des modèles de paramètres d'éditeur sous src/apothem/harnesses/claude_code/templates/. Il ne porte pas de materializer.py — il ne rend pas de fichier de configuration natif à partir du profil ; il propage directement les artefacts et les répertoires de convention.

Une frontière délibérée : l'adaptateur claude-code ne gère qu'un bloc délimité par des sentinelles à l'intérieur de CLAUDE.md ; la prose située hors de ce bloc est préservée. Le reste de ce fichier relève du territoire de l'opérateur. Apothem matérialise la surface de configuration environnante — les règles, les hooks, les settings — et conserve mot pour mot la prose de l'opérateur située hors de ce bloc. Un adaptateur qui réécrirait tout le fichier effacerait à chaque apothem install les instructions rédigées à la main ; celui-ci ne réécrit que son bloc géré.

Pourquoi l'uniformité compte

Le protocole donne à l'opérateur un seul modèle mental à travers dix-sept outils. apothem install, apothem verify, apothem uninstall se comportent de la même façon, que la cible rende un unique fichier ou aplatisse une arborescence de répertoires. Les différences d'éditeur vivent à l'intérieur des sous-paquets d'adaptateur, derrière le protocole, là où elles ont leur place.

Lisez la référence destinée à l'opérateur sur Environnements et le modèle de profil dans Concepts.

On this page