nodefony-skill — gérer les skills Nodefony

Créer, éditer, fusionner ou auditer les skills du dépôt Nodefony. Applique les standards Agent Skills, calibre les déclencheurs et maintient la conformité.

Spar Skills Guide Bot
DeveloppementIntermédiaire
0007/09/2026
Claude Code
#nodefony#skill-creation#agent-skills#skill-audit

Recommandé pour


name: nodefony-skill metadata: version: 1.2.0 description: > Créer, éditer, fusionner, retirer ou auditer un skill du dépôt Nodefony. Dérive de skill-creator (qui porte la mécanique générique) et ajoute ce que Nodefony exige en propre : nommage nodefony-*, description calibrée pour se DÉCLENCHER (formulations de besoin, pas de noms d'outils), metadata.version, ressources en references/, note de maintenance intemporelle, table « quand passer la main », et la barrière skills-doc qui contrôle la conformité au standard Agent Skills et régénère la fiche publique. Porte les pièges vécus : une règle recopiée dans le CLAUDE.md rend le skill inatteignable, un renvoi survit au refactor qui a supprimé sa cible, une capacité absorbée sans ses déclencheurs devient introuvable. Déclencheurs : "créer un skill", "nouveau skill", "éditer un skill", "fusionner deux skills", "retirer un skill", "mon skill ne se déclenche jamais", "skill non conforme", "skills-ref validate", "conformité Agent Skills", "fiche de skill", "à quoi sert ce skill".

nodefony-skill — écrire un skill qui se déclenche et qui reste vrai

Ce skill dérive de skill-creator (bundlé) : la mécanique générique — structure d'un dossier, divulgation progressive, rédaction d'une description — y vit et n'est pas recopiée ici. Ce fichier porte ce que Nodefony ajoute, et rien d'autre.

Maintenance : vérité courante, jamais un journal. Éditer en place ; l'historique vit dans git log. Une leçon durable devient une règle d'une section, pas une entrée datée.

1. Quand m'utiliser

  • Créer un skill du dépôt (.claude/skills/nodefony-<nom>/).
  • Réparer un skill qui ne se déclenche jamais (le cas le plus fréquent — voir §5).
  • Auditer la conformité avant une publication npm (chantier devkit).
  • Décider s'il faut un skill plutôt qu'une règle de CLAUDE.md ou une commande (§2).

Passer la main : mécanique générique d'un skill → skill-creator. Écrire une page de documentation → nodefony-documentation. Scaffolder un module → nodefony-create-module.

2. La question préalable : skill, commande, ou règle ?

| Le besoin | La bonne forme | | ------------------------------------------------------------------- | ------------------------------------------------------------- | | Une procédure que l'agent doit suivre (décor, gates, pièges) | Skill — c'est ce que l'invocation apporte | | Une frappe courte pour l'humain sur une procédure existante | Commande .claude/commands/<nom>.md qui délègue au skill | | Une règle permanente qui doit s'appliquer sans qu'on la demande | CLAUDE.md — pas un skill (il ne se chargerait jamais) | | Un outil qu'on lance | Un script ; le skill est ce qui l'entoure (protocole) |

⚠️ Ne jamais écrire la même règle aux deux endroits. Un skill dont le CLAUDE.md redonne la commande n'est jamais invoqué : l'agent lit la règle au démarrage, exécute, et n'ouvre pas le skill — qui portait pourtant le diagnostic. Mesuré sur ce dépôt : c'est la cause n°1 des skills à zéro invocation. Le CLAUDE.md pointe, le skill détaille.

3. Conventions Nodefony (en plus du standard)

  • Nom : nodefony-<sujet> en minuscules, identique au dossier. Les commandes restent courtes et non préfixées (/start-server).
  • metadata.version — jamais version: à la racine : le standard n'autorise que name, description, license, metadata, allowed-tools.
  • Ressources : references/ (au pluriel) pour le détail chargé à la demande, scripts/ pour l'exécutable, assets/ pour les gabarits. Le corps reste sous 500 lignes et sert d'index.
  • Note de maintenance en tête : édition en place, pas de changelog, pas de date. L'avancement vit dans MIGRATION_STATUS.md, l'historique dans git log.
  • Table « quand passer la main » : un skill dit toujours ce qu'il ne fait PAS, avec le nom du skill qui le fait.
  • Exemples vérifiés au source — jamais de signature recopiée de mémoire.

4. Écrire la description (c'est elle qui décide de tout)

La description est le seul texte lu à chaque session : elle décide si le skill s'active. Deux règles issues de la mesure d'usage :

  1. Nommer le MOMENT, pas l'outil. « RPS », « stress » ne se déclenchent pas — la demande réelle arrive en besoin : « est-ce que ça tient la charge ? », « c'est plus rapide ? », « je vais commiter une modif du pipeline ». Écrire les deux, en commençant par le besoin.
  2. Dire quand charger le skill par rapport à l'action. Pour un skill à scripts : « à charger AVANT de lancer un de ces scripts » — sinon on lance le script sans le protocole, et le chiffre obtenu ne vaut rien.

Forme : troisième personne, capacité et moment, ≤ 1024 caractères, aucune roadmap.

5. Réparer un skill qui ne se déclenche jamais

Dans l'ordre, parce que les causes n'ont pas la même fréquence :

  1. Sa règle est-elle recopiée dans CLAUDE.md ? → retirer la copie, y mettre un pointeur.
  2. Ses déclencheurs nomment-ils l'outil au lieu du moment ? → §4.
  3. Ses renvois pointent-ils encore quelque part ?node .claude/skills/nodefony-skill/scripts/skills-doc.mjs puis vérifier les cibles. Un refactor supprime un fichier ; le renvoi, lui, survit et envoie dans le vide.
  4. Est-il seulement lu, jamais invoqué ? C'est un signal de description, pas de contenu : ses references/ servent, sa porte d'entrée ne s'ouvre pas.
  5. Le besoin existe-t-il encore ? Si non, le retirer franchement (règle projet : pas de legacy).

6. Fusionner, absorber ou retirer un skill

Trois gestes distincts, une même exigence : aucune capacité ne doit disparaître en silence. Un skill qu'on retire emporte avec lui ses déclencheurs — c'est-à-dire la seule chose qui permettait de l'atteindre.

| Geste | Quand | Ce qu'il faut préserver | | -------------- | ----------------------------------------------------------------------- | ------------------------------------------------- | | Fusion | plusieurs skills répondent à la même intention sous des noms différents | le contenu et les déclencheurs des deux | | Absorption | un skill est un chapitre d'un kit plus large | le détail part en references/, pas au panier | | Retrait | le besoin lui-même a disparu (prouvé, pas supposé) | la décision, si elle vaut, va dans le CLAUDE.md |

Dans l'ordre :

  1. Inventorier les renvois — avec les dossiers cachés. rg ignore .claude/ sans --hidden : une recherche qui l'oublie conclut « aucun consommateur » sur un skill cité partout.

    rg -n --hidden 'nodefony-<skill-retiré>' -g '!**/node_modules/**' -g '!.git/**'
    

    Les retex archivés (docs/session-retros/archive/) sont de l'histoire : ne pas les réécrire.

  2. Écrire la destination avant de supprimer la source — sinon le contenu est perdu entre les deux.

  3. Déplacer les déclencheurs, pas seulement le contenu. Une capacité absorbée dont les formulations ne rejoignent pas la description du skill d'accueil devient inatteignable : le corps existe, la porte n'existe plus.

  4. Supprimer avec git rm (l'historique reste), puis réparer chaque renvoi trouvé en 1.

  5. Mettre à jour l'outillage : cas du banc de déclenchement, table d'icônes/familles de skills-doc, et toute table « passer la main » qui nommait le disparu.

  6. Passer le gate (§7). Le contrôle « aucun renvoi vers un skill inexistant » est là pour ça.

Une table « passer la main » se périme sans bruit. Vérifier que ce qu'elle promet existe : une table citant bash <skill>/<script> pour quatre skills dont aucun n'avait de script a survécu des mois — chaque ligne était fausse. Nommer le skill, pas un chemin supposé.

7. Gate — obligatoire avant de dire « fait »

node .claude/skills/nodefony-skill/scripts/skills-doc.mjs        # conformité des 26+ skills + régénère docs/skills/
node .claude/skills/nodefony-skill/scripts/skills-doc.mjs --check   # contrôle seul (CI)

Il vérifie, avec pour chaque contrôle sa nature (normatif = MUST du standard · recommandé = SHOULD · projet = propre à Nodefony) : name conforme (1-64, minuscules alphanumériques + -, ni au bord ni consécutifs, = nom du dossier) · description de 1 à 1024 caractères · aucun champ hors standard (compatibility désormais admis, ≤500) · compatibility ≤500 si présent · ressources en references/ · aucun renvoi vers un skill inexistant (projet) · corps < 500 lignes (recommandation). Sur un manquement dur il sort en échec, et il régénère la fiche publique dans docs/skills/<nom>.md — version, contenu, déclencheurs, table des references/ avec l'objet de chacune, scripts avec options et variables, et une conformité qui cite la règle exacte du standard (nature + source), pour qu'un lecteur voie d'où sort chaque contrôle.

Les constantes du standard vivent en tête de skills-doc.mjs (ALLOWED_FIELDS, MAX_DESC, MAX_COMPAT, NAME_RE) avec un lien vers la spec. Le standard bouge (le champ compatibility est une addition récente) → revalider contre tmp/specs-agents/ avant de durcir un contrôle.

Le contrôle des renvois ne lit que les noms entre accents graves, dans le SKILL.md et les references/ — les scripts citent des conteneurs et des titres de processus qui portent le même préfixe. Les quelques nodefony-… qui ne désignent pas un skill (le dépôt lui-même, un service, un composant) sont déclarés dans NON_SKILL_TERMS, en tête de skills-doc.mjs : y ajouter un terme demande de justifier pourquoi ce n'en est pas un.

Validateur officiel du standard — il attrape ce qu'un contrôle maison rate, à commencer par un frontmatter YAML invalide (une description en ligne contenant un : casse le mapping sans que rien d'autre ne s'en aperçoive) :

npm pack skills-ref && tar xzf skills-ref-*.tgz     # dans un dossier jetable
node package/dist/cli.js validate ./<skill>          # après y avoir installé commander + js-yaml

⚠️ Auditer avant d'exécuter. Le paquet skills-ref n'a ni repository ni homepage sur npm et n'est pas attribuable à l'AAIF : il lit tous les skills du dépôt. Audité une fois (20 Ko, node:fs/node:path seulement, aucun accès réseau, MIT) — refaire cette lecture à chaque montée de version plutôt que de lui faire confiance sur son nom. C'est pour ça que la commande ci-dessus dépaquette au lieu d'un npx qui exécuterait sans regarder.

Banc de déclenchement — la garde anti-régression des descriptions :

node .claude/skills/nodefony-skill/scripts/trigger-bench.mjs            # phrases réelles → skill élu
node .claude/skills/nodefony-skill/scripts/trigger-bench.mjs --verbose  # + le détail des scores

Il porte quatre mesures, à relancer après toute retouche de description :

  1. Phrases réelles (issues des retex et des mémoires) → le bon skill doit sortir en tête. Une phrase qui rate son skill fait échouer le banc.
  2. Cas NÉGATIFS → une phrase qui ne DOIT PAS élire un skill donné (ex. « crée un module » ne doit pas élire nodefony-inspect). C'est ce qui attrape la sur-portée : élargir une description sans y penser vole une demande à un autre skill. Une violation fait échouer le banc.
  3. Couverture → tout skill a au moins une porte testée (un skill neuf sans cas est signalé).
  4. Recouvrements de déclencheurs, séparés en arbitrés (documentés dans ACCEPTED_OVERLAPS avec la raison — « fuite mémoire » est mieux capté par check-memory-health que par debug) et à trancher (le vrai bruit). Un nouveau recouvrement non documenté ressort seul, à arbitrer puis documenter. Les cas verts fragiles (faible marge sur le 2ᵉ) sont comptés (--verbose les détaille).

Audit de placement — où vit chaque script, et qui l'appelle :

node .claude/skills/nodefony-skill/scripts/scripts-audit.mjs           # rapport
node .claude/skills/nodefony-skill/scripts/scripts-audit.mjs --strict  # échoue sur orphelin, renvoi mort ou écart d'acquittement

Il classe les scripts du dépôt selon le critère du §2 : dépend d'un protocole → sa place est dans un skill ; déterministe et câblé au package.json → il reste à la racine. Il signale aussi les scripts que personne ne cite (morts, ou simplement non documentés) et les renvois vers un fichier absent. Trois faux positifs ont été corrigés avant de lui faire confiance : .js capturé dans .json, renvois croisés entre skills déclarés morts faute d'être cherchés ailleurs, et « mentionne docker » confondu avec « lance docker ».

🔴 Être NOMMÉ dans une page n'est pas être EXÉCUTÉ. Le contrôle a longtemps compté une phrase de documentation comme un appel : il annonçait « 0 orphelin » pendant qu'une vingtaine d'auto-contrôles, énumérés un par un dans leur page de skill, n'étaient lancés par rien — dont celui qui savait nommer quinze causes qu'aucun juge ne classait. Un script n'est « lancé » que par un automate : un script npm, un étage de forge, ou un autre source qui le nomme (le nommer dans un .mjs, c'est s'en servir ; le nommer dans un .md, c'est en parler). Les autres sortent en 📄 documenté, jamais lancé — un état, pas une faute : un banc de charge se tape à la main, et c'est très bien.

Ce qui serait une faute, c'est qu'un script NEUF y entre sans qu'on le remarque. La liste versionnée scripts-audit.attendus.json fige l'état connu, et --strict ne mord que sur l'écart : une entrée non acquittée, ou un acquittement devenu faux parce que le script est désormais câblé. Un gate qui rouge en permanence ne garde plus rien — celui-ci ne rouge que sur un changement. Câbler un script, c'est le RETIRER de la liste ; le laisser ferait échouer la passe.

Le critère « invocation adjacente » a été essayé et écarté : il accusait 39 juges parfaitement vivants, dont le chemin est assemblé dans une constante et remis à un lanceur dix lignes plus loin.

Ce banc mesure la surface lexicale, pas le jugement du modèle : un cas vert ne garantit pas l'invocation, mais un cas rouge est un vrai défaut — aucun mot de la demande ne rejoint la description.

8. Le hook de doc — un script se décrit lui-même

Un script documenté ailleurs que dans son source diverge le jour où on l'édite. Six tags facultatifs, lus par skills-doc, suffisent à rendre la fiche exacte au lieu de devinée :

| Tag | Rôle | | ----------- | -------------------------------------------------------- | | @usage | une ligne d'invocation réelle (répétable) | | @option | --drapeau puis son rôle | | @env | NOM_VARIABLE puis son rôle | | @requires | ce que le décor doit fournir (docker, serveur UP, …) | | @output | ce que le script produit |

Sans eux, le générateur retombe sur l'heuristique : première ligne de commentaire, drapeaux trouvés dans le source, variables lues hors variables de travail. Avec eux, la fiche gagne un détail par script — invocations, options et variables avec leur explication.

Piège de l'auto-référence : écrire ces tags en exemple dans un commentaire les fait moissonner par leur propre lecteur. Les entourer d'accents graves.

9. Ce que consomme un registre de skills

skills-doc écrit aussi docs/skills/registry.json — la même donnée que les fiches, sérialisée pour une machine : résumé d'une ligne, famille, mots-clés, déclencheurs, coût d'activation en tokens, prérequis, ressources et scripts (options, variables, sortie), graphe de voisinage entre skills, état de conformité contrôle par contrôle, et liens source/fiche. C'est le format qu'un moteur de recherche de skills ou un registre lit sans ouvrir vingt-sept markdown — et c'est aussi ce qui rendra une publication npm possible sans réécrire l'inventaire à la main.

10. Gabarit

---
name: nodefony-<sujet>
metadata:
  version: 1.0.0
description: >
  <Ce qu'il fait, en une phrase à la troisième personne.> <Ce qu'il apporte que l'exécution nue
  n'apporte pas : protocole, décor, pièges.> <Ce qu'il ne couvre passkill qui le couvre.>
  Déclencheurs : "<formulation de besoin>", "<moment : avant de …>", "<terme technique>".
---

# nodefony-<sujet><promesse en une ligne>

> **Maintenance** : vérité courante, jamais un journal. Éditer en place ; historique = `git log`.

## 1. Quand m'utiliser / quand passer la main

| Besoin | Skill |
| ------ | ----- |

## 2. La procédure

<Les étapes, dans l'ordre, avec les commandes exactes.>

## 3. Pièges

<Ce qui a déjà coûté cher, formulé en règle.>

## 4. Gate

<Comment on prouve que c'est fait.>

11. Pièges vécus

  • Une fiche écrite à la main diverge du skill dès la première édition → les fiches docs/skills/ sont générées ; ne jamais les éditer.
  • Un renvoi survit à la disparition de sa cible : un refactor a supprimé des references/recipes-*.md en laissant huit renvois morts, plus un renvoi vers une section « §4 » réorganisée entre-temps. Vérifier les cibles fait partie du gate — désormais les renvois vers un skill inexistant le font échouer (§7). Vécu à la fusion des quatre skills d'inspection : frontend-verify était cité par debug, studio-dev et leurs references/.
  • Mesurer une description avec une regex $ en mode multiligne ne lit que sa première ligne — le contrôle disait « conforme » sur des descriptions à 1900 caractères. Un gate qu'on n'a jamais vu mordre n'est pas un gate.
  • Un déclencheur improbable ne coûte rien mais ne rapporte rien : « 59 fails framework sans serveur » n'a jamais rien déclenché. Préférer trois formulations naturelles à dix exactes.

12. Liens

  • docs/outillage-agents.md — inventaire, usage mesuré, étude des fusions et retraits.
  • docs/skills/index.md — les fiches générées, une par skill.
  • skill-creator — la mécanique générique (structure, divulgation progressive, évaluation).
Skills similaires