n24q02m/agent-chat-plugin

Les sessions d'agents IA conversent entre pairs via des fichiers markdown dans des dossiers partagés — sans relais humain, sans orchestrateur, compatible Windows, et ne consommant aucun jeton en attente.

Qu'est-ce que agent-chat-plugin ?

agent-chat est un protocole de coordination décentralisé pour agents IA, permettant à plusieurs sessions d'agents (comme Claude Code, Cursor ou Codex) de dialoguer en échangeant des fichiers Markdown dans des dossiers de canal partagés, sans superviseur, courtier de messages ni mémoire partagée. Chaque canal constitue un salon de discussion de groupe complet, avec un fil de conversation lisible par l'homme, versionnable par Git et reproductible. La conception minimise la consommation de jetons : la commande `wait` n'effectue aucun appel de modèle, se contentant de surveiller le système de fichiers. L'outil en ligne de commande, écrit en Python standard sans dépendances externes (`chat.py`), fonctionne sur Windows, WSL et Linux. Il gère les messages, les tâches structurées, les baux, les verrous de chemins, les événements de capacité/statut et l'état dérivé — tout cela localement, sans faire appel à des services externes. Des hooks optionnels s'intègrent au cycle de vie de l'hôte (par exemple, pour Claude Code). Il est particulièrement adapté aux scénarios où plusieurs agents travaillent ensemble sur le même problème, où un agent a besoin d'un autre pour effectuer une tâche et attend le résultat, ou lorsque vous souhaitez une piste d'audit complète d'une négociation entre agents.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add n24q02m/agent-chat-plugin

Installed? Explore more Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

agent-chat

Présentation

Des sessions d'agents pairs se coordonnent en échangeant des fichiers Markdown dans des dossiers de canal partagés — sans superviseur, sans courtier de messages, sans mémoire partagée entre elles. Chaque canal correspond à un unique « salon de discussion de groupe ». L'intégralité du fil de discussion est en Markdown brut : versionnable par Git, lisible par un humain, reproductible. Une session qui plante ne perd rien — les fichiers constituent l'état.

L'interface en ligne de commande utilisant uniquement la bibliothèque standard (chat.py et le package frère agent_chat/) fonctionne sur Windows, WSL et Linux. wait reste en sommeil entre les vérifications du système de fichiers et n'effectue aucun appel de modèle.

Principe fondamental : communiquer via des fichiers, pas directement entre processus. Les résumés sont des artefacts, pas des transcriptions complètes échangées en permanence.

Il s'agit d'une couche de données de coordination locale, et non d'un serveur MCP ou d'un exécuteur d'agent. Les messages, tâches, baux, verrous de chemins, événements de capacité/statut et l'état dérivé n'effectuent aucun appel de complétion, d'intégration, de reclassement, de service de graphe ou de relais.

Quand l'utiliser

  • Plusieurs sessions d'agents OMP ou autres agents compatibles travaillant sur le même problème en tant qu'égaux.
  • Une session a besoin qu'une autre fasse quelque chose, puis attend le résultat.
  • Vous voulez un enregistrement vérifiable d'une négociation entre agents.
  • Vous avez besoin de plusieurs salons de discussion de groupe indépendants (un par sujet/équipe) — créez un canal pour chacun.

Quand NE PAS l'utiliser : un seul agent avec des sous-agents peu coûteux est plus économique et plus simple — ce modèle échange des jetons contre du parallélisme, de la tolérance aux pannes et de la vérifiabilité. Si le budget de jetons est serré, utilisez uniquement le chemin asynchrone/de transfert (publier un résumé à la fin de la session ; la session suivante le lit) — ce mode ne coûte pratiquement rien.

Référence rapide

Utilisez agent-chat <cmd> après pipx install agent-chat-plugin, ou uvx --from agent-chat-plugin agent-chat <cmd> pour chaque invocation ponctuelle. uvx n'installe pas de commande persistante. Avec une compétence autonome, conservez SKILL.md, chat.py et l'intégralité du répertoire agent_chat/ ensemble et exécutez python "/chemin/vers/compétence/chat.py" <cmd>. Les exemples abrègent ceci en chat.py.

Le greffon Claude Code utilise python "${CLAUDE_PLUGIN_ROOT}/chat.py" <cmd>. Les autres hôtes utilisent un chemin de répertoire réel, pas une variable de greffon présumée. La priorité de la racine est --root > $AGENT_CHAT_ROOT > ~/agent-chat ; placez --root avant la sous-commande. Les racines par défaut de machines différentes ne sont pas synchronisées.

L'installation via PyPI ne fournit que les modules CLI/d'exécution. Les hooks/*.py facultatifs proviennent du répertoire de la compétence/du greffon et nécessitent un câblage explicite du cycle de vie de l'hôte. Leurs points d'entrée Python sont portables ; leur enregistrement et leur contrat de sortie ne sont pas automatiquement une intégration OMP. Les notifications de session/requête sont du texte ; Stop émet du JSON systemMessage compatible Claude. Les hooks inspectent sans avancer les curseurs et se terminent toujours par 0 ; les CLAUDE_PLUGIN_ROOT non résolus ou les racines de greffons relatives au script sont ignorés avec un diagnostic d'une ligne sur stderr.

Pour faire ceciCommande
Créer un salon de discussion de groupechat.py init review --members alice,bob --topic "..."
Lister tous les salons de discussion de groupechat.py channels
Publier un messagechat.py post review --from alice --to bob --title "Schéma v0.2" --body-file msg.md
Diffuser au groupechat.py post review --from alice --to all --title "..." (ou omettez --to)
Lire ce qui est nouveau pour moichat.py read review --as bob
Attendre une réponse (0 jetons)chat.py wait review --as alice --timeout 900
Aperçu récent, conserver le curseurchat.py peek review -n 3
Revendiquer un marqueur de tâchechat.py claim work task-12.md --as bob
Verrouiller des chemins d'espace de travailchat.py lock review src/main.py --as alice --lease-seconds 300
Vérifier les conflits de cheminschat.py check review src/main.py
Libérer un verrou de cheminchat.py unlock review <lock-id-or-path> --as alice
Récupérer un verrou obsolètechat.py recover review <lock-id-or-path> --as bob --reason "obsolète"
Récupérer une transaction de chemin en attentechat.py recover-pending review --as alice
Afficher l'état du canalchat.py state review
Compacter l'état du canalchat.py compact review --as alice
Publier un événement de capacité/statutchat.py event post review --from alice --type capability --harness omp
Lire les événements de l'adaptateurchat.py event read review --type capability

Les événements neutres vis-à-vis de l'adaptateur utilisent le numéro de version de schéma 1 et sont transportés sous forme de corps JSON dans des messages de canal ordinaires. Les événements de capacité ne font la publicité que des primitives portables messages, cursors, wait, tasks, dependencies, leases, path_locks, et state_summary. Les événements de statut utilisent ready, busy, idle, blocked ou stopped, avec des détails facultatifs. Les champs, primitives, versions, horodatages, identités et statuts inconnus échouent avec des erreurs EVENT_* stables. Ce protocole ne revendique pas MCP, ACP, pont de réveil ou exécution d'agent. Les tâches structurées utilisent la même racine de canal et écrivent des enregistrements JSON faisant autorité sous <root>/<channel>/tasks/ ; les enregistrements de bail actifs se trouvent sous <root>/<channel>/claims/<task-id>.<owner>.json. Chaque mutation réussie de tâche ou de bail publie également un événement d'audit via le protocole de message existant :

chat.py task create <channel> <task-id> --from <agent> --title <title>
chat.py task list <channel>
chat.py task show <channel> <task-id>
chat.py task update <channel> <task-id> --as <agent> [fields...]
chat.py task claim <channel> <task-id> --as <agent> --lease-seconds 300
chat.py task renew <channel> <task-id> --as <agent> --lease-seconds 300
chat.py task done <channel> <task-id> --as <agent>
chat.py task block <channel> <task-id> --as <agent>
chat.py task release <channel> <task-id> --as <agent>
chat.py task recover <channel> <task-id> --as <agent> \
  --reason "session obsolète" --lease-seconds 300
chat.py task recover-pending <channel> --as <agent> \
  [--resolve-publication rollback|published]

claim, renew et recover pour tâche obsolète acceptent --lease-seconds, --lease, ou --ttl ; la valeur doit être une durée finie positive. claim fait passer une tâche prête à in_progress, attribue le propriétaire et écrit son expiration de manière atomique avec l'enregistrement de la revendication. Seul le propriétaire peut renouveler, libérer ou terminer une revendication non expirée. task done efface une revendication active de manière atomique ; lorsqu'aucune revendication n'existe, elle préserve la transition directe de la Tâche 3. task release préserve de même la transition non louée de la Tâche 3. Une revendication expirée n'est jamais silencieusement volée : task recover pour une tâche obsolète nécessite un nouveau propriétaire et une raison non vide et enregistre previous_owner, previous_lease_expires_at et recovery_reason. Après un plantage, task recover-pending <channel> --as <agent> finalise explicitement le nettoyage/retour arrière du marqueur de transaction durable ; il ne vole jamais silencieusement ni ne réaffecte une tâche obsolète. Les marqueurs applied v1 hérités dont la publication d'audit ne peut pas être prouvée échouent avec LEASE_TRANSACTION_PUBLICATION_UNKNOWN ; relancez la commande avec --resolve-publication rollback ou published après inspection par l'opérateur.

create accepte --owner, --depends-on, --files-hint, --acceptance, et --branch. Répétez les options de liste pour ajouter plusieurs valeurs. update accepte --title, --owner, --depends-on, --files-hint, --acceptance, --branch et --status ; utilisez --clear-owner ou --clear-branch pour réinitialiser les champs nullables à null. Les mises à jour génériques ne peuvent pas muter un bail actif ; utilisez les commandes de bail à la place. Les valeurs de liste peuvent également être séparées par des virgules.

Les statuts des tâches sont open, in_progress, blocked, done et cancelled. done et cancelled sont terminaux. Les transitions autorisent open -> in_progress | blocked | cancelled, in_progress -> open | blocked | done | cancelled, et blocked -> open | in_progress | cancelled. Les écritures sur le même état sont intentionnellement idempotentes. task done déplace in_progress (ou done idempotent) vers done ; task block déplace open, in_progress, ou blocked vers blocked ; et task release déplace blocked, in_progress, ou open vers open. Une tâche ne peut avancer vers in_progress ou done que lorsque chaque identifiant dans depends_on a un enregistrement de tâche dont le statut est done. La préparation est calculée à partir des enregistrements JSON de tâche, jamais à partir du texte du message.

Les échecs de tâche et de bail sont non nuls (statut de sortie 2) et incluent un code stable. Les codes de tâche incluent TASK_INVALID_COMMAND, TASK_INVALID_ARGUMENT, TASK_INVALID_CHANNEL, TASK_CHANNEL_NOT_FOUND, TASK_NOT_FOUND, TASK_ALREADY_EXISTS, TASK_INVALID_STATUS, TASK_INVALID_UPDATE, TASK_INVALID_TRANSITION, TASK_DEPENDENCY_NOT_READY, TASK_UNKNOWN_DEPENDENCY, TASK_DEPENDENCY_CYCLE, TASK_PATH_OUTSIDE_WORKSPACE, TASK_LOCK_TIMEOUT, TASK_IO_ERROR, et TASK_AUDIT_FAILED. Les codes de bail incluent LEASE_CONFLICT, LEASE_RECOVERY_REQUIRED, LEASE_OWNER_MISMATCH, LEASE_NOT_EXPIRED, LEASE_NOT_FOUND, LEASE_INCONSISTENT, LEASE_MUTATION_REQUIRED, LEASE_INVALID_OWNER, LEASE_INVALID_TASK_ID, LEASE_INVALID_CHANNEL, LEASE_INVALID_REASON, LEASE_INVALID_DURATION, LEASE_INVALID_TIMESTAMP, LEASE_INVALID_RECORD, LEASE_REQUIRED_FIELD_MISSING, LEASE_UNKNOWN_FIELD, LEASE_RECORD_ID_MISMATCH, LEASE_STORAGE_INVALID, LEASE_PATH_OUTSIDE_WORKSPACE, LEASE_TRANSACTION_PENDING, LEASE_TRANSACTION_CLEANUP_FAILED, LEASE_TRANSACTION_PUBLICATION_UNKNOWN, LEASE_TRANSACTION_INVALID, LEASE_TRANSACTION_NOT_FOUND, LEASE_TRANSACTION_RECOVERY_FAILED, LEASE_AUDIT_FAILED et LEASE_AUDIT_ROLLBACK_FAILED. Les écritures de bail utilisent un marqueur de transaction durable avec des phases préparées/appliquées/publiées ; après un plantage ou un échec de nettoyage, l'accès échoue en mode fermé jusqu'à ce que task recover-pending/LeaseStore.recover_pending() revienne explicitement en arrière ou termine la transaction publiée.

Les verrous de chemin coordonnent l'accès exclusif aux fichiers et répertoires relatifs à l'espace de travail :

chat.py lock <channel> <paths...> --as <agent> [--lease-seconds 300]
chat.py check <channel> <paths...> [--as <agent>]
chat.py unlock <channel> <lock-id-or-path> --as <agent>
chat.py recover <channel> <lock-id-or-path> --as <agent> \
  --reason "session obsolète" [--lease-seconds 300]
chat.py recover-pending <channel> --as <agent> \
  [--resolve-publication rollback|published]

lock et recover acceptent --lease-seconds, --lease, ou --ttl. La cible peut être l'identifiant du verrou ou le chemin normalisé exact. La normalisation résout les chemins relatifs à l'espace de travail, empêche les évasions de répertoire, de racine/canal/lien symbolique, applique les règles de casse de la plateforme (insensible à la casse sur Windows) et rejette les noms réservés de Windows, les points/espaces de fin, les caractères de contrôle et les paires de substitution isolées. Les collisions fichier/fichier et les chevauchements répertoire/fichier sont en conflit. Seul le propriétaire peut déverrouiller un verrou actif ; les verrous expirés nécessitent un recover explicite enregistrant previous_owner, previous_expires_at et recovery_reason. Les mutations utilisent une publication de fichier atomique en termes de contenu, des verrous de fichier consultatifs et une journalisation de transaction à sécurité de plantage. Les erreurs de verrou de chemin se terminent avec un code non nul et des codes stables tels que PATH_LOCK_INVALID_PATH, PATH_LOCK_PATH_OUTSIDE_WORKSPACE, PATH_LOCK_CONFLICT, PATH_LOCK_RECOVERY_REQUIRED, PATH_LOCK_OWNER_MISMATCH, PATH_LOCK_NOT_FOUND, PATH_LOCK_NOT_STALE, PATH_LOCK_INVALID_OWNER, PATH_LOCK_INVALID_LOCK_ID, PATH_LOCK_INVALID_CHANNEL, PATH_LOCK_INVALID_REASON, PATH_LOCK_INVALID_DURATION, PATH_LOCK_INVALID_TIMESTAMP, PATH_LOCK_INVALID_RECORD, PATH_LOCK_STORAGE_INVALID, PATH_LOCK_STORAGE_ERROR, PATH_LOCK_TIMEOUT, PATH_LOCK_TRANSACTION_PENDING, PATH_LOCK_TRANSACTION_CLEANUP_FAILED, PATH_LOCK_TRANSACTION_INVALID, PATH_LOCK_AUDIT_FAILED, et PATH_LOCK_AUDIT_ROLLBACK_FAILED.

Le résumé et le compactage de l'état du canal produisent un artefact state.md déterministe :

chat.py state <channel> [--write] [--json] [--strict]
chat.py compact <channel> [--as <agent>] [--no-audit] [--json] [--strict]

state affiche ou imprime le résumé dérivé du canal contenant :

  • Objectif / Sujet (depuis _meta.json)
  • Décisions (extraites des messages et des enregistrements structurés)
  • Tâches Ouvertes (depuis tasks/*.json, incluant le statut, le propriétaire, le bail, les dépendances)
  • Bloqueurs (bloqueurs de dépendances de tâches, statuts de tâches bloquées et messages de blocage)
  • Propriétaires et Baux (revendications actives, propriétés de tâches et verrous de chemin)
  • Verrous de Chemin (verrous de chemin actifs depuis locks/*.json)
  • Dernière Preuve de Vérification (critères d'acceptation et messages de vérification)

compact écrit le résumé dérivé dans <root>/<channel>/state.md en utilisant le remplacement atomique par fichier temporaire frère (.state.md.tmp.*) et par défaut publie un événement de message state.compacted vérifiable dans le canal.

state.md est strictement un artefact dérivé et n'est jamais faisant autorité. Le compactage est non destructif : il ne supprime, ne mute ni ne tronque jamais aucun fichier de message, enregistrement de tâche, revendication active, verrou de chemin ou curseur de lecture. Tous les enregistrements source restent la vérité fondamentale immuable. Les erreurs d'état se terminent avec un code non nul et des codes stables tels que STATE_INVALID_CHANNEL, STATE_CHANNEL_NOT_FOUND, STATE_INVALID_RECORD, STATE_MALFORMED_SOURCE, STATE_RECORD_NOT_FOUND, STATE_IO_ERROR et STATE_AUDIT_FAILED. --reply <seq> chaîne un message à un précédent. python chat.py <cmd> --help pour tous les indicateurs.

Commandes d'événement neutres vis-à-vis de l'adaptateur :

chat.py event post <channel> --from <agent> --type capability --harness <harness>
chat.py event post <channel> --from <agent> --type status --harness <harness> --status ready
chat.py event read <channel> [--type capability|status]

Le corps de l'événement est du JSON versionné validé par rapport à schemas/agent-chat-event.schema.json. Les messages Markdown ordinaires restent inchangés et sont ignorés par event read.

Structure des dossiers

<root>/
  review/                     # un canal = un salon de discussion de groupe
    _meta.json                # membres, sujet, création
    state.md                  # résumé d'état dérivé (non faisant autorité)
    0001-alice-schema-draft.md # NNNN-<from>-<slug>.md, préface + corps
    0002-bob-schema-review.md
    tasks/                    # enregistrements de tâches structurées
    claims/                   # enregistrements de baux actifs
    locks/                    # verrous de chemin d'espace de travail actifs
    .cursors/bob.txt          # "dernier seq lu" par agent
  deploy/                    # un DEUXIÈME salon de discussion de groupe, espace de séquence distinct
    ...

Mess...

Skills associés