ousterhout-quality-program
Ce que ça fait
À utiliser chaque fois que le code écrit ou revu crée ou modifie une frontière — un nouveau module, une classe, un composant, un helper, un hook, un service ou un wrapper ; toute extraction ou centralisation de code partagé ; tout moment « faisons-en un élément réutilisable » — et lors de la revue, du refactoring ou de la conception explicite d’un module. Juge si une abstraction mérite sa place : profondeur du module, s’il faut cacher une décision de conception, si un code dupliqué protège une invariant partagée ou se contente de rimer, si une interface est stable. Protège contre un SOLID/Clean Code mécanique qui produit de nombreuses classes superficielles. Définit aussi le test du coût pour le lecteur (code facile à lire et modifier pour les humains et les agents) et la procédure pour refactorer une base de code existante selon cette norme.
L'installation ouvre cette fiche dans votre application AgentsRoom. Si l'application n'est pas encore installée, vous serez redirigé vers la page de téléchargement.
SKILL.md
---
name: ousterhout-quality-program
description: À utiliser chaque fois que le code écrit ou revu crée ou modifie une frontière — un nouveau module, une classe, un composant, un helper, un hook, un service ou un wrapper ; toute extraction ou centralisation de code partagé ; tout moment « faisons-en un élément réutilisable » — et lors de la revue, du refactoring ou de la conception explicite d’un module. Juge si une abstraction mérite sa place : profondeur du module, s’il faut cacher une décision de conception, si un code dupliqué protège une invariant partagée ou se contente de rimer, si une interface est stable. Protège contre un SOLID/Clean Code mécanique qui produit de nombreuses classes superficielles. Définit aussi le test du coût pour le lecteur (code facile à lire et modifier pour les humains et les agents) et la procédure pour refactorer une base de code existante selon cette norme.
---
# Programme de Qualité Ousterhout
## Vue d'ensemble
Le rôle d'un module est de cacher la complexité derrière une interface réduite. La mesure centrale est la **profondeur** : un module profond offre une interface simple sur une fonctionnalité substantielle ; l'interface d'un module superficiel est presque aussi complexe que son implémentation, donc il ne se justifie pas. La complexité est ce que vous ressentez lorsqu'un changement vous oblige à comprendre ou toucher du code auquel vous ne vous attendiez pas — Ousterhout nomme deux sources : **dépendances** (vous ne pouvez pas changer A sans changer B) et **obscurité** (l'information importante n'est pas évidente).
Ousterhout seul vous dit ce que *ressent* un bon module. Il est plus puissant combiné à quelques autres perspectives qui indiquent où doivent se situer les frontières et comment s'en approcher en toute sécurité. Cette compétence est cette perspective combinée.
## Où les revues échouent réellement
Les deux échecs que cette compétence vise à corriger — observés à plusieurs reprises dans du code écrit par des agents — se situent dans le **remède**, pas dans le verdict scinder/ne pas scinder lui-même :
1. **La correction superficielle.** Face à six castings `as unknown as`, le réviseur non assisté les centralise en un seul helper générique `castRows<T>()` — plus propre, mais l'obscurité subsiste. La correction profonde est des mappeurs typés ligne→domaine avec des tests fixés en premier (appliquant Parnas : un cast est l'odeur d'une frontière manquante ; Beck : prouver le mapping avant de le déplacer). Nettoyer une odeur n'est pas la supprimer.
2. **L'extraction réflexe.** Face à la même logique de mise à jour répétée dans trois composants frères, chaque réviseur non assisté a dit « extraire un helper partagé » — le réflexe DRY. La règle de ce programme, étendant Metz : attendre l'invariant, pas le troisième sosie — centraliser quand le code protège une règle partagée, pas quand il rime.
Quand vous vous surprenez à recommander une correction, testez-la sur ces deux points : enlève-t-elle l'obscurité ou la déplace-t-elle simplement, et l'extraction protège-t-elle un invariant ou déduplique-t-elle juste une forme ?
## Porte de proportionnalité
Ignorez cette perspective quand un changement n'ajoute aucun nouveau nom exporté/importable, ne crée aucun nouveau module/classe/composant/helper/hook/service/wrapper, et ne centralise rien. Les simples renommages, codemods mécaniques, modifications de config/données, et corrections d'une ligne sont exemptés. En cas de doute, ne faites que les deux tests principaux (profondeur, invariant) et arrêtez-vous là.
## La règle complète
Chaque morceau de code généré ou revu passe par la perspective Ousterhout avant que la tâche soit considérée terminée — pas seulement les revues de conception explicites — sauf les changements sous la porte de proportionnalité (pas de nouvelle frontière, pas de centralisation : renommages, codemods, modifications de config). Deux tests : (1) **Profondeur** — une nouvelle interface doit cacher beaucoup plus qu'elle n'expose ; une interface aussi complexe que ce qu'elle enveloppe ne vaut rien. (2) **Invariant** — extraire du code partagé seulement quand il protège une règle partagée, jamais parce que trois sites riment ; et une correction doit enlever l'obscurité, pas la déplacer (centraliser six casts en un helper reste six casts). Quand un changement crée ou redessine une frontière, trouvez d'abord comment un produit établi résout un problème de cette forme et échelle et adoptez ses conventions sauf raison explicite de ne pas le faire (un pattern rappelé d'une formation est une affirmation, pas une source), puis appliquez les vérifications ci-dessous.
## Quand l'utiliser
- Décider si une nouvelle classe/fonction/hook vaut son interface, ou n'est qu'un simple passage superficiel.
- Un fichier dépasse un seuil de taille et vous décidez *comment* le scinder, pas seulement s'il faut le faire.
- Du code répété vous tente d'extraire un helper partagé.
- Concevoir ou revoir une frontière autour d'une règle métier (un contrôle de portée d'autorisation, une règle d'argent/arrondi, un garde de transition d'automate d'état, une règle de rétention de données).
- Une interface est sur le point de grandir avec un paramètre ou un cas spécial.
- Amener une base de code existante à cette norme — voir « Refactoring d'une base de code existante vers cette norme » ci-dessous.
**Pas pour :** des modifications mécaniques triviales, ou quand une convention de projet dicte déjà la structure — voir la Porte de proportionnalité ci-dessus. Privilégiez `karpathy-guidelines` pour la discipline des changements chirurgicaux et une compétence de développement piloté par les tests pour le filet de sécurité du refactoring, quand ceux-ci sont disponibles.
## Les perspectives
Chaque perspective ajoute exactement une question. Ousterhout est la colonne vertébrale ; les autres corrigent ses angles morts.
| Lentille | La question unique qu'elle ajoute | Quand elle prévaut |
|---|---|---|
| **Ousterhout** — modules profonds | Cette interface cache-t-elle plus qu'elle n'expose ? | Épine dorsale par défaut. |
| **Parnas** — encapsulation de l'information | Quelle décision de conception (susceptible de changer) ce module cache-t-il ? | La *raison* pour laquelle un module doit être profond. S'il ne cache rien qui change, la profondeur est cosmétique. |
| **Brooks** — essentiel vs accidentel | Cela supprime-t-il la complexité accidentelle, ou déplace-t-il simplement la complexité essentielle du domaine ? | Élimine les "refactorings" qui déplacent le désordre sans le réduire. |
| **Evans** — Domain-Driven Design | Cette frontière est-elle nommée dans le langage du domaine, et non dans un langage utilitaire générique ? | Renommer `utils`/`helpers` — nommer la frontière d'après l'invariant que ce dépôt possède réellement. |
| **Fowler** — refactoring / odeurs | Quel est le plus petit mouvement sûr vers une conception plus profonde ? | Transforme "devrait être plus profond" en étapes concrètes derrière des tests réussis. |
| **Beck** — conception simple, test d'abord | Ai-je prouvé le comportement actuel avant d'approfondir la jonction ? | Un frein à l'architecture prématurée. Faire fonctionner et tester d'abord, puis approfondir la bonne jonction. |
| **Hickey** — simple vs facile | Cela entrelace-t-il des concepts non liés, ou est-ce vraiment un seul concept ? | Un helper superficiel est généralement *facile* (proche, rapide), pas *simple* (peu de concepts entrelacés). Préférer simple. |
| **Metz** — duplication plutôt que mauvaise abstraction | Ce code répété protège-t-il un invariant partagé, ou se contente-t-il de se ressembler (règle de ce programme, extension de Metz) ? | Metz : la duplication coûte moins cher qu'une mauvaise abstraction — réintégrer une mauvaise abstraction plutôt que de la déformer. Ce programme étend sa règle : ne **centralisez pas** parce que c'est répété ; centralisez seulement quand cela protège un vrai invariant. Tolérer la duplication jusqu'à ce que l'invariant se révèle. |
| **Loi de Hyrum** — comportement observable | Les appelants dépendront-ils d'un comportement au-delà du contrat de cette interface ? | Plaide pour des interfaces petites et stables : chaque comportement observable finit par devenir critique. |
## La recette de combinaison
Appliquer dans cet ordre — les lentilles suivantes ne comptent que si les précédentes sont validées :
1. **Metz — la porte d'entrée.** Cette frontière/abstraction mérite-t-elle d'exister ? Règle de ce programme, extension de Metz : extraire seulement quand le code protège une règle partagée — trois ressemblances ne sont pas un invariant révélé. Sinon, s'arrêter ici.
2. **Parnas / Ousterhout** — Cacher la décision volatile (portée d'autorisation, règle d'arrondi, garde de transition, règle de rétention) derrière un module profond.
3. **Evans** — Nommer ce module dans le langage du domaine, pas `utils`.
4. **Beck / Fowler** — Pour le code existant, fixer le comportement actuel avec des tests, puis refactorer vers lui par petits mouvements sûrs. Pour le code fraîchement généré, il n'y a pas de comportement actuel à fixer — écrire le test qui définit le comportement attendu.
5. **Hickey** — Rejeter les interfaces qui mélangent des concepts non liés juste parce que les flux de travail semblent similaires.
## L'anti-pattern structurel
**SOLID mécanique / Clean Code produit des modules superficiels.** Une lecture dogmatique — une classe par responsabilité, extraire chaque fonction, tout garder minuscule — produit une nuée de classes dont les interfaces sont aussi complexes que leurs corps. Quand une règle dit "divise ça", demandez quelle *décision* la division cache (Parnas) et si elle cache plus qu'elle n'expose (Ousterhout). Si elle ne cache rien qui change, ne divisez pas. Cette garde est la plus importante sous pression de refactoring ("nettoie ça", "ce fichier est trop gros") — en analyse calme, les relecteurs y résistent déjà ; en plein refactoring, avec un mandat de produire un changement visible, c'est là que la nuée de fichiers superficiels est écrite.
## Erreurs courantes
- **Diviser uniquement sur la taille.** Un module de requête de 400 lignes qui cache une décision cohérente peut être plus profond que quatre modules de 100 lignes qui fuient tous les mêmes jointures.
- **Nommer la division `helpers`/`utils`.** Si vous ne pouvez pas le nommer dans le langage du domaine (Evans), la frontière est probablement mauvaise.
- **Extraire dès la deuxième occurrence.** Règle de ce programme, extension de Metz : attendre l'invariant, pas le troisième semblable.
- **Approfondir avant de fixer le comportement.** Beck : sans test prouvant le comportement actuel, un refactoring "d'approfondissement" est une réécriture.
- **Compter un passage comme un module.** Un wrapper qui transmet ses arguments ajoute une interface et ne cache rien — superficiel par définition.
- **Confondre une rime avec un invariant.** La meilleure preuve d'un invariant partagé est la co-évolution : les copies ont été corrigées ou modifiées ensemble dans l'histoire (le même bug corrigé en deux endroits). Les ressemblances qui changent indépendamment sont des rimes ; laissez-les dupliquées.
- **Nettoyer une odeur au lieu de la supprimer.** Centraliser six casts dans un helper générique est la version ordonnée de la même obscurité. La vraie correction profonde nomme la frontière que le cast masquait.
## Coût pour le lecteur : le troisième test
La profondeur et l'invariant décident si une frontière doit exister. Le coût pour le lecteur décide si le code autour est facile à modifier. Le prochain lecteur, humain ou agent, paie pour chaque ligne qu'il doit charger pour modifier quelque chose en toute sécurité. Les agents paient en tokens et naviguent par recherche textuelle, lectures partielles et boucles de vérification de type/test, donc les mêmes défauts leur coûtent plus cher. Demandez :
- **Facile à trouver ?** Un nom par concept, orthographié de la même façon partout, accessible par une recherche en texte clair. Défauts : noms assemblés à partir de chaînes, câblage par effet de bord d'importation, chaînes de réexportation qui cachent la définition, deux noms pour un même concept.
- **Le lecteur peut-il s'arrêter tôt ?** Le contrat est placé en haut du fichier ou au-dessus de l'export : ce qu'il promet, ce qu'il cache, ce qu'il ne fait jamais. Défaut : le contrat ne peut être déduit qu'en lisant le corps.
- **Vérifiable par machine ?** Types précis à l'entrée et à la sortie de chaque frontière, de sorte qu'une vérification de type remplace la lecture des appelants. Défauts : `any`, dictionnaires nus, drapeaux booléens dont la signification vit dans le corps.
- **Le couplage est-il visible ?** Les endroits qui doivent changer ensemble sont imposés (un type partagé, un test, une source unique) ou, à défaut, marqués aux deux endroits. La preuve d'un couplage caché est un changement conjoint dans l'historique que rien dans le code ne mentionne.
- **Sans bruit ?** Pas de commentaires qui répètent le code, pas de code commenté, pas de branches mortes, pas de commentaires d'historique de changement, pas de chemin obsolète conservé à côté de son remplacement.
- **Prévisible ?** La mise en page suit le modèle existant du dépôt ; le test est là où un lecteur le cherchera et s'exécute de manière autonome.
La taille du fichier est délibérément absente. Un fichier très volumineux est une raison de chercher une seconde décision cachée, jamais une raison de couper : les lecteurs peuvent chercher et lire une plage, et une division qui ne cache rien ajoute des interfaces sans réduire la charge.
Pour les marqueurs dans le code et une carte du dépôt, utilisez `context-audit` lorsque disponible : son ancre `AIDEV-NOTE:` (un fait non récupérable plus une référence de provenance, au maximum deux lignes, sur le site) est la convention pour un couplage qui ne peut pas être imposé.
## Refactorisation d'une base de code existante selon cette norme
Une adaptation est jugée de la même manière que du code neuf ; ce qui diffère est l'ordre et la retenue. La majeure partie d'une base de code doit être laissée intacte.
1. **Recensement, lecture seule.** Lister les frontières (modules, services, helpers partagés). Pour chaque enregistrement : la décision qu'il cache, ou "aucune" ; taille de l'interface par rapport au corps ; partenaires de co-changement dans l'historique ; défauts de coût pour le lecteur. Ne rien changer encore.
2. **Classer par fréquence de changement, pas par laideur.** La priorité est la fréquence des changements multipliée par le coût de lecture. Le code froid qui fonctionne reste tel quel, même superficiel. La complexité essentielle du domaine reste là où elle est (Brooks).
3. **Attribuer un remède par constat :**
- couche de passage ou wrapper qui ne cache rien : le supprimer, les appelants utilisent ce qu'il enveloppait ;
- mauvaise abstraction déformée par des drapeaux et cas spéciaux : la réintégrer en ligne (Metz), puis chercher la vraie invariant ;
- frères superficiels qui partagent une décision : les fusionner derrière une interface unique ;
- décision fuitée (les appelants connaissent le format, la règle, le schéma) : la ramener dans le module qui la possède ;
- nom générique (`utils`, `helpers`, `manager`) : renommer selon la décision qu'il cache, ou le dissoudre dans ses appelants ;
- frontière non typée : la typer, et remplacer les castings par le mapper qu'ils masquaient ;
- couplage caché : l'imposer, ou marquer les deux sites ;
- bruit : le supprimer.
Les rimes qui changent indépendamment n'ont pas de remède.
4. **Fixer le comportement d'abord.** Aucun remède ne commence tant qu'un test ne prouve pas le comportement actuel du code touché (Beck). Les refactorisations préservent le comportement ; un changement de comportement est un commit séparé.
5. **Découper le travail en unités qu'un agent peut finir seul.** Une frontière par unité. Chaque unité nomme les fichiers qu'elle possède, le contrat qu'elle doit préserver, et la commande qui le prouve seule. Aucune unité concurrente n'écrit dans le même fichier ; les fichiers partagés (barils, registres, tables de routage) ont un seul propriétaire ou attendent l'intégration. Les changements d'interface dont plusieurs unités dépendent arrivent en premier, comme leur propre unité.
6. **Mesurer le résultat.** Choisir un changement représentatif avant de commencer et compter les fichiers et lignes qu'un lecteur doit charger pour le faire ; recompter après. Les noms exportés et le total des lignes doivent baisser ou rester stables. Une refactorisation qui ajoute des interfaces doit justifier la raison.
7. **S'arrêter** quand ce qui reste est froid, essentiel ou une rime.
Compétences associées, lorsque disponibles : `repo-review` (type design) produit le recensement comme artefact de conseil ; `design-cleanup` exécute la boucle correction et rescannage pour la complexité accidentelle ; `context-audit` ajoute des ancres et la carte du dépôt ; `ousterhout-build-deep` est la checklist à l'auteur pour les agents réalisant les unités.
## Où cela se situe
Cette compétence est la couche de revue et de jugement : utilisez-la pour décider si une abstraction est profonde, nommée selon la bonne décision, et mérite d'être extraite. `find-shared-code` l'utilise comme test d'admission lorsqu'il balaie l'historique récent à la recherche de code à partager. L'Annexe ci-dessous donne le raisonnement de chaque auteur.
---
## Annexe : Les Lentilles en Profondeur
Le mode d'échec que chaque auteur détecte, et le mouvement que chacun vous propose. Le tableau ci-dessus est la référence rapide ; voici le raisonnement qui le sous-tend.
### Ousterhout — Modules Profonds (la colonne vertébrale)
*Une Philosophie de la Conception Logicielle.*
- **Profondeur** = bénéfice (fonctionnalité cachée) ÷ coût (complexité de l'interface). Un module profond cache beaucoup derrière peu. L'interface d'un module superficiel est presque aussi complexe que son corps, donc il ne rapporte rien.
- **Complexité** est tout ce qui rend le système difficile à comprendre ou modifier. Deux sources :
- **Dépendances** — on ne peut pas changer une partie sans toucher une autre.
- **Obscurité** — l'information importante n'est pas évidente dans le code.
- **Symptômes :** amplification des changements (une décision, de nombreuses modifications), charge cognitive (ce qu'il faut garder en tête), inconnus inconnus (on ne peut pas dire quel code un changement affectera).
- **Mouvement clé :** faire descendre la complexité — le module absorbe le cas difficile pour que les appelants n'aient pas à le faire. Les paramètres de configuration et les couches de passage poussent la complexité vers le haut, vers l'appelant ; c'est la superficialité.
Détecte : interfaces qui fuient leur implémentation ; helpers qui n'aident pas.
### Parnas — Masquage de l'Information (pourquoi la profondeur compte)
*Sur les critères à utiliser pour décomposer les systèmes en modules (1972).*
- Décomposer autour des **décisions de conception susceptibles de changer**, pas autour des étapes d'un calcul. Chaque module cache une telle décision.
- C'est l'ancêtre direct du module profond. Un module est profond *parce qu'il* cache une décision qui, autrement, se répercuterait chez les appelants.
Pièges : un « module » qui ne cache rien de volatile — sa profondeur est cosmétique. Demandez : qu'est-ce qui change derrière cette interface que les appelants ne voient jamais ? Si la réponse est « rien », la frontière est une décoration.
### Brooks — Complexité essentielle vs accidentelle
*Pas de solution miracle.*
- La complexité **essentielle** est inhérente au domaine (l'évaluation est vraiment aussi complexe). La complexité **accidentelle** est ce que nos outils et notre structure imposent.
- Seule la complexité accidentelle est supprimable. Un refactoring qui « nettoie » en déplaçant la complexité essentielle du domaine d'un fichier à un autre n'a rien fait.
Pièges : des réarrangements déguisés en simplification. Demandez : la complexité totale a-t-elle diminué, ou s'est-elle juste déplacée ?
### Evans — Domain-Driven Design
*Domain-Driven Design.*
- Les frontières doivent être nommées dans le **langage omniprésent** du domaine, pas en termes utilitaires génériques. Un module appelé `helpers` ne nomme rien ; un module appelé `AccessScope` ou `PricingPolicy` nomme un invariant.
- Les contextes bornés empêchent les invariants métier de fuir à travers les jonctions.
Pièges : une décomposition correcte avec des noms dénués de sens. Si vous ne pouvez pas nommer le module dans le langage du domaine, vous avez probablement coupé la frontière au mauvais endroit.
### Fowler — Refactoring et odeurs de code
*Refactoring.*
- Donne les mouvements concrets, sûrs et nommés (Extract Function, Move Field, Replace Conditional with Polymorphism) pour passer du design actuel au design plus profond.
- Chaque mouvement préserve le comportement et est petit, donc réversible.
Pièges : le fossé entre « ceci devrait être plus profond » et savoir quel sera le prochain commit. Ousterhout fixe la cible ; Fowler est la route.
### Beck — Design simple, test d'abord
*Test-Driven Development ; XP.*
- Quatre règles du design simple, dans l'ordre publié par Beck : passe les tests, pas de duplication, révèle l'intention, le moins d'éléments possible. Ce programme suit le réordonnancement plus tardif de Fowler/Haines — intention avant duplication — car il sert la règle d'invariant étendue de Metz (voir Metz, ci-dessous) : ne pas agir sur la duplication tant que vous ne pouvez pas nommer l'intention qu'elle protège.
- Le test d'abord est un frein contre une architecture prématurée. Faites fonctionner et prouvez le comportement *d'abord*, puis approfondissez la jonction que les tests protègent désormais.
Pièges : architecture construite avant que le comportement soit fixé. Sans test prouvant le comportement actuel, un refactoring de « profondeur » est une réécriture non vérifiée.
### Hickey — Simple vs Facile
*Simple Made Easy.*
- **Simple** = non entremêlé : un concept, pas mêlé à d'autres (objectif).
- **Facile** = à portée de main, familier, rapide à atteindre (relatif à vous).
- Les deux sont indépendants. Un helper superficiel est généralement *facile* — rapide à écrire, proche — mais pas *simple* s'il mêle des préoccupations sans rapport.
Pièges : la commodité déguisée en design. Préférez des constructions qui gardent les concepts non entremêlés même si une construction entremêlée est plus rapide à taper.
### Metz — Préférez la duplication à la mauvaise abstraction
*« The Wrong Abstraction » (2016).*
- La duplication coûte bien moins cher que la mauvaise abstraction. Une abstraction extraite trop tôt force chaque futur appelant à s'adapter à des hypothèses qui n'ont jamais été vraies pour tous.
- Quand une abstraction s'avère mauvaise, le remède de Metz est de la réintégrer en ligne et de laisser revenir la duplication, plutôt que de la forcer à s'adapter à un cas pour lequel elle n'a jamais été conçue.
- **La règle de ce programme, étendant Metz : ne centralisez pas parce que le code se répète. Centralisez quand cela protège un invariant réel et partagé.** Jusqu'à ce que l'invariant se révèle, tolérez la duplication.
Pièges : la sur-centralisation — le helper partagé superficiel que tout le monde doit maintenant contourner. C'est le contrepoids à un « DRY à tout prix » mécanique.
### Loi de Hyrum — Le comportement observable devient contrat
*« Avec un nombre suffisant d'utilisateurs, chaque comportement observable de votre système sera dépendu par quelqu'un. »*
- Quoi que fasse une interface — ordre, timing, texte d'erreur — quelqu'un finira par s'y fier. Donc la surface que vous exposez est plus grande que celle que vous avez documentée.
- Cela soutient la préférence d'Ousterhout pour des **interfaces petites et stables** : moins vous exposez, moins cela peut devenir un support de charge par accident.
Pièges : interfaces larges qui vont s'ossifier. Chaque observable supplémentaire devient une contrainte future.
### Comment ils s'articulent
- **Parnas → Ousterhout :** cacher une décision volatile → le module est profond.
- **Brooks :** confirmer que la profondeur a supprimé la complexité plutôt que de la déplacer.
- **Evans :** nommer la frontière dans le langage du domaine.
- **Beck → Fowler :** fixer le comportement, puis refactorer par petits mouvements sûrs.
- **Metz :** résister à la centralisation tant que l'invariant n'est pas réel.
- **Hickey :** garder l'interface à un seul concept.
- **Hyrum :** garder cette interface petite pour qu'elle reste stable.
Le danger est de mélanger Ousterhout avec une lecture mécanique de SOLID ou Clean Code : cela produit de nombreuses classes et fonctions minuscules avec des interfaces superficielles — l'exact opposé des modules profonds. Ousterhout, avec Metz comme contrepoids, est l'antidote.
Tags
Pour aller plus loin
Claude Ads : le skill Claude Code qui audite tes comptes publicitaires
Claude Ads est un skill open source pour Claude Code : plus de 250 vérifications sur Google, Meta, LinkedIn, TikTok ou Amazon Ads, un score sur 100 et un plan d'action priorisé, en une dizaine de minutes. Installation, commandes, limites, et comment l'orchestrer dans AgentsRoom.
AGENTS.md : un seul fichier de contexte pour tous tes agents de code (Codex, Antigravity, Claude)
AGENTS.md, c'est le fichier d'instructions portable que tes agents de code lisent avant de toucher à ton code. Ce qu'il faut y mettre, en quoi il diffère de CLAUDE.md, et comment garder un seul contexte entre Codex, Antigravity et Claude.
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.