Voir ce que votre agent de code exécute sur vos serveurs
Votre agent travaille sur un serveur de production et son terminal dit seulement qu'il appelle un outil. Quelle commande a-t-il lancée, et qu'a répondu la machine ? Le transcript vous le dit après coup. Voici comment on l'a rendu visible pendant que ça se passe, ce qu'on a essayé d'abord, et comment obtenir la même chose sans notre app.
Vous demandez à un agent DevOps pourquoi l'API de production rame. Il se met au travail. Dans son terminal, une ligne dit qu'il appelle un outil, puis une autre, puis une autre. Six appels plus tard, il vous annonce que le disque est plein à 97 % et propose de vider le dossier des logs.
Qu'a-t-il réellement lancé sur cette machine ? Quel du, quel find, a-t-il déjà supprimé quelque chose ? La réponse existe, mais elle est dans le transcript de la session, écrite en JSON, et vous la lisez après coup. Sur un ordinateur portable, ça va. Sur un serveur de production, après coup, c'est trop tard pour dire « attends, pas ce dossier-là ».
On développe AgentsRoom, une app desktop qui fait tourner des agents de code et leur donne des outils pour atteindre vos serveurs, vos bases de données et vos clusters. Voici comment on a rendu ces appels visibles pendant qu'ils se passent, la version qui n'a pas marché, les chiffres de celle qui marche, et comment obtenir la même chose si vous n'utilisez pas notre app.
La réponse courte
- Le CLI vous montre qu'un outil a tourné, pas la session de l'autre côté. La commande complète et sa sortie partent dans le transcript sur votre disque.
- Pour suivre en direct, il faut enregistrer chaque appel au moment où il part, pas à la fin de la session.
- Un journal par connexion marche. Un onglet de terminal par commande, non. On a mesuré 166 commandes distantes dans une seule session.
- Gardez ce journal sur votre machine. Une ligne de commande sur un serveur de production transporte des secrets et des données clients.
- Sans notre app : un hook de Claude Code qui ajoute chaque commande shell à un fichier fait l'essentiel du chemin, et le transcript fait le reste.
Pourquoi le transcript ne suffit pas sur un serveur
Claude Code, Codex et les autres CLI enregistrent bien tout. Claude Code écrit un fichier JSONL par session sous ~/.claude/projects/, Codex un sous ~/.codex/sessions/. Chaque appel d'outil y figure, avec son entrée et son résultat.
Le problème n'est pas l'exhaustivité, c'est le moment et la forme. Le transcript est écrit pour le CLI, pour qu'il puisse reprendre une session. Vous le lisez une fois l'agent arrêté, en fouillant des lignes de JSON. Quand trois agents travaillent en même temps, vous lisez trois fichiers. Et le terminal de l'agent, l'endroit que vous regardez vraiment, ne montre qu'un résumé replié de chaque appel.
Pour du code sur votre portable, relire après coup est la boucle normale : vous regardez le diff avant de commiter. Un serveur n'a pas de diff. Un systemctl restart ou un DELETE prend effet à l'instant où il tourne.
Ce qu'on a essayé d'abord, et les 166 commandes
Notre premier outil distant pour les agents ouvrait la connexion dans un onglet de terminal. Ça semblait juste : l'utilisateur voyait la session. Ça a échoué d'une façon qu'on n'avait pas prévue.
L'outil ne donnait à l'agent aucun moyen de lire ce qui se passait dans l'onglet qu'il venait d'ouvrir. Alors, sur le projet d'un utilisateur, l'agent a cessé de s'en servir. Le compte de cette session : 16 appels à notre outil de connexion, et 166 commandes sshpass lancées par l'outil shell de l'agent lui-même, l'agent redemandant le mot de passe à l'utilisateur, qui le collait dans la conversation. Des identifiants de production se sont retrouvés en clair dans les transcripts, dans ps aux pendant chaque commande, et dans un fichier sous /tmp.
La leçon n'était pas « les agents sont imprudents ». L'agent a fait la seule chose qui marchait. Un outil sûr qui ne permet pas à l'agent de faire son travail est contourné, et le contournement est pire que l'absence d'outil.
On a donc écrit ssh_exec : l'agent envoie une commande, AgentsRoom l'exécute sur la connexion enregistrée en gardant le mot de passe dans l'app, et rend la sortie et le code de retour. L'agent ne voit jamais l'identifiant et n'a plus aucune raison de fabriquer une ligne sshpass.
Ça a réglé le problème de sécurité et créé un problème de visibilité. Si chaque ssh_exec avait ouvert un onglet, cette session en aurait produit 166. Donc ssh_exec n'en ouvrait aucun, et pendant deux mois le seul endroit où voir ces commandes était, encore une fois, la conversation de l'agent.
Un journal par connexion
La version livrée le 29 octobre 2026 (AgentsRoom 1.242.0) garde une règle : pas d'onglet par commande. À la place, chaque appel arrive dans un journal, un par connexion.
- L'onglet Activité du panneau de droite, à côté de Fichiers, Changements et Tests, liste en cartes les connexions que les agents ont touchées (dernière commande, agent, heure, état) et les 40 derniers appels sur une frise. Il se filtre par agent et cherche dans les commandes, les noms de connexion et les sorties.
- Le journal d'une connexion se lit comme un terminal :
agent · heure, puis$ commande, puis la sortie, puisTerminé · code 0 · 1,2 s. La sortie SSH défile en direct et la vue suit le bas tant que vous ne remontez pas. Un bouton copie tout le journal en texte. - Des pastilles dans l'en-tête de l'agent, une par serveur, base ou cluster que cet agent a touché, avec un point vert pendant un appel. Un clic ouvre ce journal.
- Un badge Agent au travail sur la ligne de la connexion dans les fenêtres Serveurs, Bases de données et Kubernetes, seulement pendant un appel.
Le journal est en lecture seule. Pour taper vous-même sur la machine, l'onglet SSH de la fenêtre Serveurs reste la porte d'entrée. La page complète de la feature est celle du gestionnaire de connexions SSH, et le côté bases de données est sur Connexions bases de données.
Ce qui est enregistré, et ce qui ne l'est pas
| Appel | Dans le journal | Pourquoi |
|---|---|---|
ssh_exec (SSH, AWS SSM, WinRM) | Oui | Le cas principal : une commande sur une machine distante, sans onglet à elle |
ssh_transfer | Oui | Un fichier copié vers un serveur ou depuis lui est une action sur ce serveur |
db_query, db_schema | Oui | Le SQL tel que l'agent l'a écrit, et les premières lignes du résultat |
kube_kubectl | Oui | Affiché comme la ligne kubectl avec ses arguments |
commands_run, ssh_connect | Non | Ils ouvrent déjà un onglet de terminal que vous pouvez regarder |
L'outil shell de l'agent (ssh, psql, kubectl tapés directement) | Non | Ça ne passe pas par AgentsRoom : c'est dans le terminal et le transcript de l'agent |
La dernière ligne est la limite honnête. Le journal voit ce qui passe par nos outils. Si vous voulez que chaque action distante y apparaisse, les outils doivent être le chemin le plus simple pour l'agent : c'est la leçon des 166 commandes.
Un détail encore : seul SSH fait défiler la sortie pendant que la commande tourne, parce qu'il passe par un vrai terminal sur votre machine. Les résultats de WinRM, du SQL et de kubectl apparaissent à la fin de l'appel.
Ce que coûte la tenue du journal
Nos utilisateurs font tourner beaucoup d'agents à la fois : 45 agents sur 18 projets sur une machine, 48 consoles sur une autre. Tout ce qui se compte par agent ou par morceau de sortie est multiplié par ces nombres, donc le journal a des bornes fixes :
- 120 appels par projet, les plus anciens partent en premier.
- 32 000 caractères de sortie par appel, en gardant la fin, là où sont les erreurs et les codes de retour.
- 2 000 caractères de commande ou de SQL par appel.
- Un message de mise à jour par appel toutes les 120 ms pour la sortie en direct, jamais un par morceau de sortie du terminal.
- Aucun timer au repos. Tant qu'aucun agent n'appelle un outil distant, le journal ne coûte rien.
L'enregistrement se fait à un seul endroit : le pont par lequel passent les appels d'outils de tous les CLI. C'est pour ça qu'il fonctionne de la même façon pour Claude Code, Codex, Antigravity CLI ou n'importe quel autre CLI que l'app fait tourner, sans code par provider.
La limite qu'on a choisie : rien ne quitte la machine
Le journal est gardé dans la mémoire de l'app desktop et disparaît quand vous la quittez. Il n'est pas synchronisé avec nos serveurs, ce qui est inhabituel chez nous : presque tout le reste d'AgentsRoom suit votre compte d'un ordinateur à l'autre.
Celui-là non, exprès. La sortie d'un env sur un serveur contient des secrets. Un SELECT sur une table clients contient des données clients. Un outil fait pour rendre ces choses visibles ne doit pas, en plus, les recopier ailleurs.
Le téléphone peut suivre le même journal depuis la fiche de l'agent (app mobile 2.47 et suivantes). Le flux va de votre ordinateur à votre téléphone par la liaison chiffrée de bout en bout, les secrets sont masqués avant de partir (clés d'API, couples CLE=valeur, mots de passe dans les URL, jetons), et rien n'est stocké sur un serveur. Le même appel reste aussi lisible dans la conversation de l'agent, comme avant.
Les audit logs de Claude Code, c'est autre chose
Si vous avez cherché « Claude Code audit log », vous êtes sans doute tombé sur la Compliance API d'Anthropic pour Claude Enterprise : un fil d'activité, des événements d'audit et, pour les sessions locales connectées au compte Enterprise, les transcripts des sessions. Elle est faite pour les administrateurs et les équipes de conformité, elle couvre l'organisation, et on la lit après coup.
Elle répond à « qui, dans l'entreprise, a fait quoi avec Claude ». Elle ne répond pas à « quelle commande mon agent lance-t-il en ce moment sur le serveur de base de données ». Les deux peuvent coexister, et si vous travaillez dans une entreprise soumise à une obligation de conformité, vous avez sans doute besoin de la première, quoi que vous utilisiez pour la seconde.
Si vous n'utilisez pas AgentsRoom
Vous pouvez obtenir une bonne partie de tout ça avec ce que les CLI fournissent déjà.
Journalisez chaque commande shell au moment où elle part. Les hooks de Claude Code peuvent lancer une commande avant chaque appel d'outil. Le guide des hooks montre le motif : un hook PreToolUse sur l'outil Bash qui envoie jq -r .tool_input.command dans un fichier de log. Lancez tail -f sur ce fichier dans un second terminal et vous voyez chaque commande à l'instant où l'agent l'envoie, lignes ssh comprises.
Lisez le transcript quand il vous faut la sortie. Le hook vous donne la commande, pas ce que le serveur a répondu. Pour ça, le fichier de session sous ~/.claude/projects/ (ou ~/.codex/sessions/ pour Codex) contient le résultat complet de chaque appel.
Donnez à l'agent son propre compte sur le serveur. Un utilisateur dédié rend chaque connexion attribuable dans le journal d'authentification du serveur, et si vos serveurs font tourner auditd, une règle sur execve pour cet utilisateur enregistre chaque processus qu'il lance, côté serveur, là où l'agent ne peut pas y échapper.
Gardez les identifiants hors de portée de l'agent. Si la seule façon de se connecter est un mot de passe que l'agent doit vous demander, vous verrez des lignes sshpass dans la conversation. Utilisez une clé que l'agent ne lit jamais, ou un outil qui garde le secret pour lui. On a écrit un guide à part sur comment donner un secret à un agent sans le mettre dans le prompt.
Ce que ce montage ne vous donne pas, c'est le lien entre les trois : quel agent, sur quelle connexion, avec quelle sortie en direct, au même endroit. C'est la partie qu'on a construite.
Les questions qu'on nous pose vraiment
Peut-on voir ce que fait Claude Code sur un serveur distant pendant qu'il travaille ?
Dans le terminal, vous voyez l'appel d'outil puis, une fois fini, un résultat abrégé. La commande complète et sa sortie sont écrites dans le transcript de la session sur votre disque, que vous lisez après coup. Pour suivre en direct, il faut quelque chose qui enregistre chaque appel au moment où il part : un hook de Claude Code qui écrit chaque commande Bash dans un fichier, ou une app qui exécute les appels distants pour l'agent et les affiche en direct, ce que fait l'onglet Activité d'AgentsRoom.
Où Claude Code garde-t-il la trace des commandes qu'il a lancées ?
Dans le transcript de la session, un fichier JSONL sous ~/.claude/projects/, un dossier par projet et un fichier par session. Chaque appel d'outil y est une ligne avec son entrée et son résultat. Codex tient un fichier du même genre par session sous ~/.codex/sessions/. Les deux sont complets, et les deux sont écrits pour que le CLI reprenne une session, pas pour qu'une personne les parcoure.
Est-ce la même chose que les audit logs de Claude Code ?
Non. Les audit logs qu'on trouve sous ce nom sont les enregistrements à l'échelle de l'organisation qu'Anthropic propose sur son offre Enterprise via la Compliance API : un fil d'activité, des événements d'audit et, pour les sessions connectées, les transcripts, lus plus tard par un administrateur. Ils répondent à « qui a fait quoi dans l'organisation ». Une vue en direct des commandes sur un serveur est un autre outil, pour une autre personne.
Pourquoi ne pas ouvrir un onglet de terminal par commande de l'agent ?
On a suivi ce chemin et on l'a mesuré : un agent qui traitait un incident de production a lancé 166 commandes distantes dans une seule session. Un onglet par commande rend la barre d'onglets inutilisable en dix minutes. Ce qui marche, c'est un journal par connexion, où chaque appel est une entrée avec sa commande, sa sortie en direct, son code de retour et sa durée.
AgentsRoom envoie-t-il les commandes et leur sortie à un serveur ?
Non. Le journal vit dans la mémoire de l'app desktop, limité à 120 appels par projet, et il disparaît quand vous quittez l'app. Le téléphone peut le suivre depuis la fiche de l'agent (app mobile 2.47 et suivantes) : le flux va de votre ordinateur à votre téléphone par la liaison chiffrée de bout en bout, secrets masqués, et rien n'est stocké sur un serveur.
Quelles commandes de l'agent l'onglet Activité ne montre-t-il pas ?
Seuls les appels qui passent par les outils d'AgentsRoom sont enregistrés : ssh_exec, ssh_transfer, db_query, db_schema et kube_kubectl. Une commande que l'agent lance avec son propre outil shell, une ligne ssh ou psql écrite à la main, est dans son terminal et son transcript, pas dans le journal. commands_run et ssh_connect sont laissés de côté exprès, parce qu'ils ouvrent déjà un onglet de terminal que vous pouvez regarder.
La version courte
Un agent sur un serveur a besoin de deux choses de votre part : une façon de travailler qui ne passe pas par votre mot de passe, et une façon pour vous de voir ce qu'il fait pendant qu'il le fait. La première sans la seconde vous laisse lire du JSON après coup. La seconde sans la première est contournée par un agent qui colle des lignes sshpass.
On a fini avec un journal par connexion, borné, gardé sur votre machine. Pour l'essayer, AgentsRoom se télécharge gratuitement, et la page Connexions SSH montre la mise en place pas à pas. Si vous préférez rester avec votre CLI seul, commencez par le hook PreToolUse et un tail -f : ça prend cinq minutes, et vous ne vous demanderez plus jamais ce qu'étaient les six derniers appels d'outils.
Télécharger AgentsRoom
Lancez tous vos agents IA, sur tous vos projets, depuis une seule fenêtre.
App companion : suivez vos agents en déplacement
Utilisez Claude, Codex, Antigravity CLI ou un autre fournisseur IA.
Remontez bugs et demandes directement dans votre backlog public.
Continuer la lecture
Garder Claude Code actif après une coupure SSH : la recette tmux
Garde Claude Code actif après une coupure SSH avec tmux. Retrouve le même processus et vérifie la persistance avant de quitter AgentsRoom.
Lire l'articleFaut-il encore relire le code de ses agents IA ?
Vos agents écrivent du meilleur code que la moitié des pull requests que vous mergiez avant. Faut-il encore lire chaque ligne ? Le débat pris au sérieux des deux côtés, les 10 signaux qui trahissent un agent qui a déconné, et le niveau de relecture que mérite vraiment chaque changement.
Lire l'articleDonner un secret à un agent de code sans jamais le mettre dans le prompt
Un agent a besoin d'une clé Stripe ou d'un mot de passe de base pour lancer sa commande. Collez-la dans la conversation et elle part dans le transcript sur votre disque, chez le fournisseur du modèle, parfois dans un commit. La règle à laquelle on est arrivés après trois de nos propres erreurs : un secret atteint un agent par une variable d'environnement, et par rien d'autre.
Lire l'article