Git
Interagissez avec l’agent via les commentaires des issues et des pull requests d’une forge Git, et exposez les événements du dépôt, incluant le cycle de vie des PR, les commentaires de révision, les résultats CI et les releases, via une table de routage par événement. Le canal est structuré autour d’un seam de fournisseur : un champ provider permet de sélectionner la forge. GitHub, Gitea et Forgejo sont des fournisseurs intégrés ; d’autres forges s’ajoutent en tant que fournisseurs équivalents sans modifier le canal générique.
Nouveau sur ZeroClaw ? Commencez par le Quickstart pour faire fonctionner un agent, puis parcourez Concepts pour les termes (agent, groupe de pairs, autonomie, SOP) que cette page suppose.
Avec le fournisseur GitHub, ZeroClaw s’authentifie en tant que GitHub App et répond sous l’identité de bot propre à l’application (your-app[bot]), ce qui lui permet de fonctionner sur n’importe quel dépôt sur lequel l’application est installée. Il n’y a ni jeton d’accès personnel ni compte utilisateur partagé.
Avec le fournisseur Gitea/Forgejo, ZeroClaw s’authentifie avec un jeton d’accès personnel auprès de l’API compatible Gitea de l’instance et répond en tant que propriétaire du jeton.
Remarque de compilation : le canal Git est inclus dans les artefacts de distribution standard, mais pas dans la configuration par défaut allégée de Cargo. Les compilations personnalisées à partir des sources doivent ajouter
channel-git; les compilations qui désactivent les fonctionnalités par défaut doivent également ajouteragent-runtime. La fonctionnalitéchannel-gitintègre tous les fournisseurs de forge pris en charge, de sorte qu’un seul binaire prend en charge toutes les forges compatibles ; il n’existe pas de sous-ensemble de compilation plus réduit, par fournisseur, à sélectionner.
Qui peut parler à l’agent
Les expéditeurs entrants sont filtrés par rapport au peer set résolu pour l’agent lié, issu de la configuration peer_groups à laquelle l’agent appartient. La correspondance supprime le @ initial et est insensible à la casse par rapport à l’identifiant d’expéditeur natif du canal. Un ensemble vide refuse tout le monde ; un ensemble contenant "*" accepte n’importe qui ; sinon, seuls les pairs externes listés (et les agents pairs) sont acceptés. Ceci est distinct de l’appairage de la passerelle (gateway.require_pairing), qui authentifie les clients HTTP/WebSocket, et non les expéditeurs des canaux de discussion.
Un groupe de pairs pour git définit channel sur git, liste les expéditeurs autorisés dans external_peers (pour git, le nom d’utilisateur (identifiant) de la forge de l’auteur du commentaire ; ["*"] accepte n’importe qui), nomme éventuellement les agents pairs pour le dispatch inter-agents, une liste noire ignore, et une output_modality (mirror, voice ou text). Voir Groupes de pairs pour la référence des champs.
Où définir ce paramètre :
Tableau de bord de la passerelle
Ouvrez /config/peer_groups dans le tableau de bord web.
zerocode
Dans le volet Config, sous Peer groups.
Comment ça fonctionne
- Polling, pas de webhooks. Le canal interroge l’API REST de la forge pour les nouvelles issues, pull requests et commentaires à partir d’un curseur
since. Le daemon n’a besoin d’aucune URL publique, tunnel ni accès entrant ; il fonctionne derrière un NAT. - Conversations limitées à une issue. Tous les messages sur une même issue ou PR partagent un seul fil de conversation ; l’agent répond sous forme de commentaire sur cette issue.
- Réponses en continu. L’agent publie un commentaire brouillon et le modifie sur place à mesure que la réponse progresse (les modifications sont espacées de ≥ 2 s pour respecter les limites anti-abus du forge).
- Réactions. Les réactions de reconnaissance correspondent à l’ensemble des réactions de la forge (avec GitHub : 👀 →
eyes, ✅ →+1, ⚠️ →confused, …) ; les emoji non mappables sont ignorés. - Démarrage à froid. Les événements créés avant le démarrage du démon ne sont jamais traités, le redémarrage ne permet donc pas de rejouer l’historique. L’inconvénient : les commentaires publiés pendant l’arrêt du démon ne sont pas pris en compte, veuillez donc mentionner l’application à nouveau.
- Les modifications de commentaires sont ignorées. Seuls les commentaires nouvellement créés et les publications d’ouverture d’issue/PR déclenchent l’agent.
Identifiants
Chaque fournisseur s’authentifie différemment, et chacun dispose d’un guide étape par étape complet :
- GitHub s’authentifie en tant qu’application GitHub (App ID plus une clé privée générée). Voir Création d’une application GitHub.
- Gitea / Forgejo s’authentifie à l’aide d’un jeton d’accès personnel auprès de l’API compatible Gitea de l’instance. Voir Créer un jeton Gitea / Forgejo (Codeberg).
Configurer
Définissez les champs de canal sur la surface de votre choix :
Tableau de bord de la passerelle
Ouvrez /config/channels/git dans le tableau de bord web.
zerocode
Dans le volet Config, sous Channels.
La référence complète des champs, directement depuis le schéma :
access_token 🔑
Jeton d’accès personnel pour les requêtes API Gitea/Forgejo. Le jeton nécessite un accès en lecture au dépôt plus un accès en écriture aux commentaires d’issues/PR pour les réponses et les réactions. Fournisseur Gitea/Forgejo uniquement.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.access_token.
zerocode
Dans le panneau Config, définissez le champ channels.git.<alias>.access_token.
zeroclaw config
zeroclaw config set channels.git.<alias>.access_token # entrée masquée, stockée chiffrée
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__access_token=
api_base_url
URL de base de l’API Gitea/Forgejo, incluant /api/v1, par exemple https://git.example.org/api/v1 (pour le service public Gitea : https://gitea.com/api/v1). Obligatoire lorsque provider est "gitea" ou "forgejo" - aucun hôte par défaut n’est défini, car chaque requête API transmet access_token ; le canal échoue au démarrage plutôt que d’envoyer le jeton à un point de terminaison que l’opérateur n’a jamais spécifié. Réservé au fournisseur Gitea/Forgejo.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.api_base_url.
zerocode
Dans le panneau Configuration, définissez le champ channels.git.<alias>.api_base_url.
zeroclaw config
zeroclaw config set channels.git.<alias>.api_base_url <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__api_base_url=
app_id
ID de l’application GitHub (affiché sur la page des paramètres de l’application). Fournisseur GitHub uniquement.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.app_id.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.app_id.
zeroclaw config
zeroclaw config set channels.git.<alias>.app_id <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__app_id=
events
Table de routage par événement, indexée par type d’événement normalisé ("issue_comment.created", "pull_request.opened", "workflow_run.failed", …). Les types d’événements absents de la table basculent sur le défaut conversationnel : issue_comment.created, issues.opened et pull_request.opened sont délivrés en tant que messages (conditionnés par mention) ; tout le reste est ignoré. Les points de terminaison API interrogés sont dérivés de cette table ; router un type d’événement revient aussi à s’y abonner.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.events.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.events.
zeroclaw config
zeroclaw config set channels.git.<alias>.events <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__events=
events_backbone
Poller également l’API Events du dépôt (/repos/{owner}/{repo}/events) en tant que couche de transport principale : une requête conditionnelle (ETag) par dépôt par tick, de sorte qu’un dépôt inactif ait un coût quasi nul. Limitations : les événements arrivent avec un délai pouvant atteindre ~5 minutes et le flux ne contient aucun événement Actions/check (les exécutions de workflows utilisent toujours leur point de terminaison dédié). Les éléments également remontés par un point de terminaison ciblé sont désdupliqués. Par défaut : false.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.events_backbone.
zerocode
Dans le panneau Config, définissez le champ channels.git.<alias>.events_backbone.
zeroclaw config
zeroclaw config set channels.git.<alias>.events_backbone <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__events_backbone=
excluded_tools
Outils exclus de la spécification d’outils de ce canal. Lorsque ce paramètre est défini, ces outils ne sont pas exposés au modèle lors des réponses via ce canal.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.excluded_tools.
zerocode
Dans le panneau Config, définissez le champ channels.git.<alias>.excluded_tools.
zeroclaw config
zeroclaw config set channels.git.<alias>.excluded_tools <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__excluded_tools=
installation_id
Identifiant d’installation à utiliser. Lorsqu’il n’est pas défini, les installations de l’application sont listées lors de la première utilisation et une seule est sélectionnée automatiquement ; le démarrage échoue si l’application n’a aucune installation ou plusieurs.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.installation_id.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.installation_id.
zeroclaw config
zeroclaw config set channels.git.<alias>.installation_id <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__installation_id=
listen_to_bots
Traiter les commentaires rédigés par d’autres comptes de bots. Les commentaires de l’application elle-même sont toujours ignorés. Par défaut : false.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.listen_to_bots.
zerocode
Dans le volet Configuration, définissez le champ channels.git.<alias>.listen_to_bots.
zeroclaw config
zeroclaw config set channels.git.<alias>.listen_to_bots <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__listen_to_bots=
mention_only
Répondre uniquement aux commentaires qui @-mentionnent le login du bot de l’application. Par défaut : true.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.mention_only.
zerocode
Dans le volet Configuration, définissez le champ channels.git.<alias>.mention_only.
zeroclaw config
zeroclaw config set channels.git.<alias>.mention_only <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__mention_only=
poll_interval_secs
Intervalle d’interrogation en secondes pour les nouveaux problèmes et commentaires. Les valeurs inférieures à 15 sont limitées à 15. Par défaut : 30.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.poll_interval_secs.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.poll_interval_secs.
zeroclaw config
zeroclaw config set channels.git.<alias>.poll_interval_secs <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__poll_interval_secs=
private_key 🔑
Clé privée PEM RS256, le contenu du fichier .pem que GitHub génère sur la page des paramètres de l’application, en ligne et chiffré au repos. Inclure les lignes BEGIN/END. Fournisseur GitHub uniquement.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.private_key.
zerocode
Dans le volet Config, définissez le champ `channels.git.<alias>.private_key`.
zeroclaw config
zeroclaw config set channels.git.<alias>.private_key # entrée masquée, stockée chiffrée
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__private_key=
private_key_path
Chemin Filesystem vers le fichier .pem de la clé privée RS256, lu au démarrage lorsque private_key (PEM en ligne) n’est pas défini. Mécanisme de repli rétrocompatible pour les configurations antérieures au champ de PEM en ligne. Fournisseur GitHub uniquement.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.private_key_path.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.private_key_path.
zeroclaw config
zeroclaw config set channels.git.<alias>.private_key_path <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__private_key_path=
provider
Fournisseur de forge Git. Pris en charge : "github", "gitea" et "forgejo" (Forgejo utilise le fournisseur REST compatible avec Gitea). Par défaut : "github".
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.provider.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.provider.
zeroclaw config
zeroclaw config set channels.git.<alias>.provider <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__provider=
proxy_url
Surcharge de proxy par canal pour les requêtes de l’API GitHub.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.proxy_url.
zerocode
Dans le panneau Config, définissez le champ channels.git.<alias>.proxy_url.
zeroclaw config
zeroclaw config set channels.git.<alias>.proxy_url <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__proxy_url=
repos
Dépôts à interroger, au format owner/repo. Vide = tous les dépôts visibles par l’installation.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/channels/git et définissez le champ channels.git.<alias>.repos.
zerocode
Dans le volet Config, définissez le champ channels.git.<alias>.repos.
zeroclaw config
zeroclaw config set channels.git.<alias>.repos <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_channels__git__<alias>__repos=
L’alias default est l’instance initiale courante. C’est également celui que les envois ponctuels utilisent : zeroclaw channel send --channel-id git recherche spécifiquement l’alias default. Nommez donc l’instance default, sauf si tous les envois proviennent d’un agent lié à un alias portant un autre nom. Laissez repos vide pour interroger tous les dépôts accessibles avec les identifiants, ou définissez une liste explicite de dépôts pour réduire l’utilisation du quota. Définissez listen_to_bots uniquement si les commentaires provenant d’autres comptes de bots doivent être traités. Une valeur provider inconnue provoque une erreur explicite au démarrage, plutôt qu’un repli silencieux.
La configuration des identifiants varie selon le fournisseur et chacun dispose de son propre secret chiffré ; les deux tutoriels le couvrent de bout en bout :
- GitHub : ID d’application et une clé privée. Voir Création d’une application GitHub.
- Gitea / Forgejo : un jeton d’accès et une URL de base de l’API. Voir Création d’un jeton Gitea / Forgejo (Codeberg).
Événements & routage
Au-delà de la conversation, le canal normalise l’activité du dépôt en événements typés et redirige chaque type d’événement en fonction de la configuration. Le routage d’un événement vers sop le dispatche vers une Procédure Opérationnelle Standard, une procédure déterministe et auditable avec correspondance des déclencheurs et portes d’approbation. La page Git SOP fan-in détaille précisément comment un événement de forge devient une exécution de SOP.
| Type d’événement | Exemple de route | Résultat |
|---|---|---|
pull_request.opened | sop = pr-triage | Transmet le payload de la PR à la pr-triage SOP. |
issues.opened | sop = issue-triage | Transmet le payload de l’issue vers la SOP issue-triage. |
issue_comment.created | message = true | Transmet le commentaire à la boucle normale de l’agent conversationnel. |
workflow_run.failed | sop = ci-failure | Transmet le payload d’échec CI à l’ingress SOP. |
release.published | message = true | Transmet l’événement de release à la boucle d’agent normale. |
Types d’événements connus : issue_comment.created, issues.opened, pull_request.opened, pull_request.closed, pull_request.merged, pull_request_review_comment.created, workflow_run.completed, workflow_run.failed, release.published.
- Par défaut. En l’absence de tableau
events, le canal se comporte de manière conversationnelle :issue_comment.created,issues.openedetpull_request.openedsont transmis en tant que messages (filtrés par mention comme décrit ci-dessus) ; tout le reste est ignoré. Les types d’événements absents d’un tableau non vide bénéficient des mêmes valeurs par défaut par type : listerworkflow_run.failedne désactive pas le mode conversationnel. Une entrée ne contenant nimessage = truenisopdésactive explicitement ce type d’événement. - Le routage d’un type d’événement correspond à son abonnement. Le canal déduit les endpoints API à interroger à partir du tableau : les commentaires de revue, les publications et les exécutions d’Actions ne sont récupérés que lorsque leurs types d’événements sont routés, ainsi un canal non configuré coûte exactement ce qu’il coûtait auparavant. GitHub prend en charge tous les types d’événements répertoriés ; le fournisseur Gitea/Forgejo prend en charge les commentaires d’issue, les ouvertures d’issue/PR, les transitions de clôture/fusion de PR, les publications, les réponses, les modifications, les suppressions et les réactions.
- Routage de
sop. Une routesopémet un événement SOP provenant d’un canal, avec pour topicgit.<alias>:<event_type>et une charge utile JSON structurée. L’événement routé est consommé par l’ingress SOP plutôt que transmis comme un message de chat. Faites-le correspondre dansSOP.tomlà l’aide d’un déclencheurchannelqui nomme le canal et l’instance (channel = "git",alias = "main"); la chaînegit.<alias>:<event_type>est le topic d’événement généré par le canal, et non un champ du déclencheur. Utilisez uneconditionfacultative pour affiner davantage, par ex.$.event_type == "pull_request.opened"ou$.repo == "octo/repo". - Filtrage des mentions par route. Le filtre
mention_onlys’applique aux événements conversationnels sur le chemin de messagerie. Les événementssop-routés l’ignorent : un PR acheminé verspr-triageest capté que l’auteur ait mentionné l’application ou non. Les événements Lifecycle/CI/release n’ont pas de surface de mention et ne sont jamais filtrés. L’activité de l’application elle-même est systématiquement ignorée ; l’activité des autres bots suitlisten_to_bots; chaque événement passe la liste d’autorisation du groupe pair en fonction de l’identifiant de l’auteur. - Surfaces de réponse. Les événements de commentaire, d’issue et de PR répondent dans le fil de discussion correspondant à l’issue/PR. Les événements de workflow-run répondent à la PR associée à l’exécution lorsque la forge en indique une ; sinon, ainsi que pour les releases, la cible est le dépôt nu et l’agent ne peut pas répondre sur la plateforme (redirigez-les vers une SOP ou traitez-les via d’autres outils).
- Backbone de l’API Events (optionnel, GitHub).
events_backbone = trueinterroge également/repos/{owner}/{repo}/eventsà l’aide de requêtes conditionnelles ETag (une requête par dépôt par cycle ; un dépôt inactif renvoie un 304 et ne coûte presque rien). Limitations : le flux peut présenter un retard d’environ ~5 minutes maximum, les payloads sont tronqués, et les événements Actions n’y apparaissent jamais : les exécutions de workflow utilisent toujours leur point de terminaison dédié. Tout élément renvoyé à la fois par le flux et un point de terminaison ciblé est dédupliqué, il est donc possible de les combiner en toute sécurité. Gitea/Forgejo ignorent cette option actuellement.
Notes de fonctionnement
- Budget de taux : sur GitHub, chaque installation obtient 5 000 requêtes/heure ; la valeur par défaut conversationnelle consomme 2 requêtes par dépôt par tick de poll (5 dépôts à un intervalle de 30 s ≈ 1 200/h). Chaque famille d’endpoints supplémentaire acheminée (review comments, releases, Actions runs) ajoute 1 requête par dépôt et par tick, et le backbone de l’API Events ajoute 1 requête conditionnelle (les 304 pour les dépôts inactifs sont pratiquement gratuits). Les limites de taux Gitea/Forgejo dépendent de l’instance. En cas de réponse de dépassement de limite, le canal applique un backoff jusqu’à la réinitialisation de la fenêtre de limite.
- De nombreux dépôts : lorsque
reposest vide et que l’identifiant peut voir plus de 100 dépôts, seule la première page est récupérée (un avertissement est enregistré pour GitHub). Listez explicitementreposdans ce cas.
Sécurité
Les commentaires sur les issues et les PR des dépôts publics constituent des entrées hostiles. Maintenez mention_only = true, contrôlez l’accès des expédieurs via un groupe de pairs (un ensemble de pairs vide refuse à tous, ["*"] accepte tout le monde), et maintenez l’autonomie à Supervised ou un niveau inférieur pour les dépôts publics. Il s’agit des mêmes recommandations que pour les canaux sociaux.
Docs associés
- Configurer les identifiants : Créer une application GitHub · Créer un jeton Gitea / Forgejo (Codeberg)
- Qui peut accéder à l’agent : Groupes de pairs
- Ce que l’agent peut faire : Sécurité et autonomie · Niveaux d’autonomie
- Automatisation événementielle : Procédures opérationnelles standard · Git SOP fan-in
- Vue d’ensemble : Agents · Aperçu des canaux