Communitygithub.com

nikbearbrown/figma-webdesigner

Audite un site Web cloné localement par rapport à un recueil de règles de conception versionné (WCAG 2.2 AA plus heuristiques et règles maison) à chaque point de rupture, génère des maquettes 'tel quel' et 'cible' dans Figma via le Figma MCP, enregistre chaque modification proposée, ses raisons et la validation humaine dans un registre de décisions immuable avec provenance, et transmet les décisions approuvées à Claude Code ou Codex sous forme de briefs d'implémentation.

Qu'est-ce que figma-webdesigner ?

Ce skill est conçu pour les développeurs et les équipes de conception qui souhaitent auditer systématiquement un site web cloné localement (par exemple depuis GitHub ou un projet Vercel) contre un recueil de règles de conception versionné (incluant WCAG 2.2 AA, des heuristiques d'utilisabilité et des règles maison), à chaque point de rupture de l'interface. Il génère des maquettes 'tel quel' et 'cible' dans Figma via l'intégration Figma MCP, documente chaque modification proposée avec ses justifications, et enregistre la validation humaine dans un registre de décisions immuable basé sur le hachage, avec traçabilité complète (hash, décision, preuve). Les modifications approuvées sont ensuite transmises sous forme de briefs d'implémentation à Claude Code ou Codex, qui les réalisent sur une branche séparée. Le skill prend en charge Claude Code, Codex et Figma MCP. Il fonctionne en phases strictes : intention initiale, capture, mesure, évaluation, proposition, validation et remise. Il ne modifie jamais directement le code source du site, et seules les décisions humaines sont validées.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/nikbearbrown/figma-webdesigner/tree/HEAD

Demander à votre IA préférée

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

Documentation

Audit de Conception → Maquettes → Registre des Décisions

Objectif

Transformer un clone local d'un site web en : (1) preuve hachée ancrée à un commit git, (2) constats qui citent chacun une règle et pointent vers les fichiers source probables, (3) maquettes « tel quel » et « cible » dans Figma, (4) enregistrements de décisions expliquant chaque modification, (5) enregistrements d'approbation humaine, et (6) briefs d'implémentation pour les décisions approuvées que Claude Code ou Codex exécute dans une session séparée. Le registre git est la source de vérité. Figma en est une projection. Ce skill conçoit et enregistre ; il ne modifie jamais le code source du site.

Flux de travail prévu

  1. L'étudiant clone le dépôt de son site (depuis GitHub, ou le dépôt à partir duquel un projet Vercel est déployé) et l'exécute localement. Les étudiants doivent avoir un accès éducatif au Figma MCP.
  2. Ce skill capture depuis le serveur de développement local, audite et construit des maquettes dans Figma.
  3. Un humain trie les constats, examine les décisions et approuve.
  4. Ce skill rédige un brief de remise par décision approuvée. Claude Code ou Codex implémente chaque décision sur sa propre branche. Ce skill recapture pour vérifier.

Commandes

Le dossier du skill contient une commande, fwd, et un fichier CLAUDE.md qui explique comment y répondre. Lorsque l'utilisateur tape help, check, init ou tutorial, suivez CLAUDE.md :

  • help exécute fwd help (vérifications de configuration plus une prochaine étape) et, si les outils Figma sont présents, whoami pour le siège. D'abord les éléments manquants ; une seule prochaine étape ; aucune modification effectuée pour le compte de l'étudiant.
  • tutorial exécute le premier tutoriel en sept étapes (refonte de votre page d'accueil). Il s'agit des propres phases de ce skill, pilotées étape par étape.
  • fwd approve|reject|defer <D-id> est la commande de l'étudiant, exécutée dans son propre terminal. Elle écrit le fichier d'approbation et l'événement du registre. L'élément non négociable 1 s'applique : ne jamais l'exécuter, ne jamais écrire dans audit/approvals/.
  • fwd ledger verify vérifie la chaîne de hachage et que chaque fichier d'approbation correspond au registre.

Éléments non négociables

  1. Seul un humain peut définir une décision comme approuvée, rejetée ou différée, ou en rouvrir une. N'écrivez jamais ces états. N'écrivez jamais de fichiers dans audit/approvals/.
  2. Chaque constat cite un rule_id depuis audit/rulebook/rules.yaml. Pas de règle, pas de constat : enregistrez-le comme une observation pour l'humain.
  3. Les étiquettes des constats suivent le niveau de la règle : normatif → failure, heuristique → concern, maison → deviation. N'appelez jamais un constat heuristique un échec. N'utilisez jamais d'icônes ou de mots de type réussi/échoué (✅ ❌ « violé ») pour les constats heuristiques.
  4. Chaque différence entre une image « tel quel » et son image « cible » porte au moins un identifiant de décision. Signalez les différences non étiquetées ; ne les absorbez pas.
  5. Ne modifiez jamais la page 00 As-Is. Ne modifiez ni ne supprimez les nœuds que le skill n'a pas créés. Touchez uniquement les annotations dans les propres catégories du skill, et faites toujours lecture-fusion-écriture.
  6. Ne définissez jamais le statut Dev Mode (Prêt pour le développement / Terminé). Ne résolvez ni ne supprimez jamais les commentaires humains.
  7. Aucune écriture Figma dans un fichier existant tant que l'humain n'a pas enregistré une version de base nommée et que son ID n'est pas enregistré. Exception : un fichier Figma créé par cette exécution elle-même. Il commence vide, donc le fichier vide est sa propre version de base ; enregistrez-la dans capabilities.json.
  8. Capturez uniquement à partir d'un clone local d'un dépôt que l'utilisateur possède ou pour lequel il a les droits de travail, servi depuis localhost, ou à partir du site déployé ou d'un aperçu Vercel de ce même dépôt lorsque l'utilisateur fournit son URL. Ne capturez jamais, n'injectez jamais de scripts et ne retirez jamais les en-têtes de sécurité sur des sites tiers en production. intent.yaml doit enregistrer le dépôt et le commit épinglé.
  9. Ne remplacez jamais une image de constats précédente ou la sortie d'une exécution antérieure. Les ré-exécutions créent une nouvelle image versionnée (voir Phase 7). Ne localisez jamais vos propres nœuds par nom de calque, couleur de remplissage ou heuristiques de texte ; utilisez les ID de nœuds enregistrés dans le registre.
  10. Ne modifiez jamais le code source du site. L'implémentation se produit uniquement dans une session Claude Code ou Codex séparée, à partir d'un brief de remise pour une décision approuvée.

Structure des répertoires

audit/
  intent.yaml                 # renseigné par l'humain (Phase 0)
  rulebook/rules.yaml         # confirmé par l'humain (Phase 1)
  schema/                     # schémas de constat, décision, approbation, événement
  runs/R-YYYYMMDD-NN/
    capabilities.json         # ce que cette exécution pouvait réellement faire
    manifest.json             # hachages et état de la capture
    captures/{width}/         # screenshot.png, dom.html, axe.json, checks.json, skeleton.json
    findings.json
  decisions/D-NNNN.json
  approvals/A-NNNN.json       # humains uniquement
  handoff/                    # briefs d'implémentation, décisions approuvées uniquement
    README.md                 # règles partagées pour l'agent implémenteur
    D-NNNN.md                 # un brief par décision approuvée
  ledger.jsonl                # ajout uniquement, événements chaînés par hachage

Le clone du site se trouve en dehors de audit/ (à local_path). Ce skill le lit et n'y écrit jamais. audit/ peut se trouver dans un dossier frère ou sur sa propre branche, afin que les enregistrements d'audit ne se mélangent jamais avec les commits du site.

Phase 0 — Intention (Porte G0)

Si audit/intent.yaml est manquant ou a des champs obligatoires vides, demandez les champs manquants de manière conversationnelle, un ou deux à la fois. Ne capturez, n'évaluez et n'écrivez rien tant que l'utilisateur n'a pas rempli tous les champs obligatoires. Si l'utilisateur n'a pas encore cloné le dépôt, donnez-lui la commande git clone exacte (pour un projet Vercel, le dépôt GitHub à partir duquel il est déployé) dans son propre bloc de code et attendez.

repo: ""                      # obligatoire : URL GitHub (ou projet Vercel) du site
local_path: ""                # obligatoire : chemin du clone local
commit: ""                    # obligatoire : SHA du commit sur lequel l'audit est épinglé
dev_command: ""               # obligatoire : par ex. "npm run dev"
dev_url: "http://localhost:3000"
routes: []                    # obligatoire : chemins à auditer, par ex. ["/", "/apply"]
ownership: ""                 # obligatoire : "propre dépôt", ou qui a accordé la permission, et quand
implementer: ""               # obligatoire : "claude-code" ou "codex"
conformance_target: "WCAG 2.2 AA"
breakpoints: "derive"         # "derive" à partir du CSS du site, ou une liste de largeurs
house_rules: ""               # chemin vers les tokens du système de conception, ou "none"
figma_file: ""                # obligatoire pour les phases Figma ; vide = mode JSON uniquement
approvers: []                 # obligatoire : noms et rôles
out_of_scope: []

Phase 1 — Schéma (Porte G1)

Résumez le recueil de règles (nombre de règles par niveau et mode) et les schémas d'enregistrement. Demandez à l'utilisateur de confirmer ou de modifier. Enregistrez un événement de registre schema.confirmed avec le nom de l'utilisateur et la date. Ne continuez pas sans cela.

Sondage des capacités d'exécution

Avant la Phase 2, écrivez capabilities.json :

  • Quels outils Figma MCP sont présents (use_figma, generate_figma_design, html_to_figma, get_metadata, get_screenshot, generate_diagram, upload_assets).
  • Résultat de whoami : type de siège sur le plan qui possède figma_file. Si les écritures ne sont pas possibles, définissez mode: json-only et ignorez les écritures Figma pour l'exécution. Les étudiants doivent avoir un accès au plan éducatif ; enregistrez toujours le siège et le plan réels plutôt que de supposer, et notez toute erreur de limite de débit.
  • Environnement local : versions de Node et du gestionnaire de packages, si dev_command démarre, et si l'arbre de travail à local_path est propre et au commit.
  • Chargez le skill figma-use de Figma avant tout appel à use_figma.
  • Lisez le schéma de l'outil use_figma en direct et enregistrez s'il accepte un paramètre skillNames. Un skill Figma comparable (Throughline) passe skillNames: "throughline" sur chaque appel. Si le paramètre existe, passez skillNames: "figma-webdesigner" sur chaque appel à use_figma ; sinon, enregistrez skillNames: unsupported.
  • Connu depuis la première exécution (2026-11-07, siège étudiant complet), revérifiez plutôt que de supposer : setSharedPluginData fonctionne ; addAnnotationCategoryAsync et node.annotations (avec labelMarkdown et categoryId) fonctionnent ; figma.saveVersionHistoryAsync n'est PAS pris en charge, donc l'agent ne peut jamais créer la version de base ; figma.root.name n'est PAS définissable, donc le fichier ne peut pas être renommé via l'API. Si l'un d'entre eux échoue maintenant, portez les ID de décision dans les noms d'image sous forme de ⟦D-0007⟧ plus annotations, et enregistrez le résultat.
  • Nommez le fichier Figma pour le site (par exemple jobs.humanitarians.ai) lors de l'appel à create_new_file ; il ne peut pas être renommé par la suite. Les pages sont des étapes (00 Kit & Legend, 01 As-Is Wireframes, 02 To-Be Wireframes) ; les images sont page / width / as-is|to-be / state.

Conventions de script use_figma

Chaque script que ce skill envoie via use_figma doit suivre ces règles :

  1. Les frères de hauteur égale ont besoin de layoutSizingVertical = 'FILL' sur chaque enfant (et layoutAlign = 'STRETCH' seul ne suffit pas lorsque le parent ajuste sa hauteur au contenu). Le texte dans une cellule de hub ou de tableau qui doit être renvoyé à la ligne a besoin de textAutoResize = 'HEIGHT' et d'une largeur.
  2. Polices d'abord. Appelez figma.loadFontAsync pour chaque style de police que le script utilise (y compris Italique et Gras si utilisé) dans un seul Promise.all en haut, avant de créer ou de modifier tout texte.
  3. Définissez le dimensionnement après le parent. Ajoutez chaque nœud à son parent, puis définissez layoutSizingHorizontal et layoutSizingVertical. Utilisez uniquement les noms de propriétés documentés (cornerRadius, pas corner) ; une propriété inconnue est ignorée silencieusement.
  4. Retournez un reçu d'écriture. Le script doit retourner un objet avec createdNodeIds et mutatedNodeIds (toujours renseignés honnêtement ; des tableaux vides uniquement lorsque rien de ce genre ne s'est produit), plus frameId, stamped (si des données de plugin ont été écrites), et pageId.
  5. Enregistrez le reçu. Après chaque appel, ajoutez un événement figma.write contenant le reçu, l'ID d'exécution, les ID de décision impliqués et version_before. Les phases ultérieures trouvent les nœuds appartenant au skill à partir de ces ID, jamais à partir de noms ou de couleurs.
  6. État avant pour les mutations. Si le script modifie un nœud existant (annotations sur un nœud créé par le skill, texte, remplissages), retournez les valeurs précédentes dans le reçu afin que le registre puisse les enregistrer. L'écrasement sans un état avant enregistré n'est pas autorisé.
  7. Échouez bruyamment. Pas de succès silencieux. Si une recherche ne trouve rien, retournez une erreur qui liste ce qui a été trouvé ; ne signalez jamais un succès pour une opération nulle.

Phase 2 — Capture

  1. Préparez le clone. Confirmez que local_path est au commit avec un arbre de travail propre (sinon, enregistrez dirty: true et arrêtez-vous pour demander), installez les dépendances, démarrez dev_command, et confirmez que dev_url répond. Enregistrez le SHA du commit, le drapeau dirty et la version de Node dans manifest.json. Ne modifiez aucun fichier source. Si le projet a besoin de variables d'environnement ou de secrets qui ne sont pas présents, demandez à l'utilisateur ; ne les inventez jamais.
  2. Dérivez les points de rupture à partir de la propre configuration du dépôt (config Tailwind, requêtes de médias CSS personnalisées, thème du framework) et à partir des requêtes de médias CSS calculées du site (sauf si l'intention liste les largeurs). Capturez à 320, à chaque point de rupture moins un et au point de rupture, et à une grande largeur de bureau.
  3. Par largeur : capture d'écran pleine page, DOM, résultats axe-core (balises wcag2a, wcag2aa, wcag21aa, wcag22aa), vérification de débordement, vérification de géométrie de cible, squelette structurel (points de repère, titres, grappes interactives avec boîtes englobantes).
  4. Enregistrez l'état de capture (bannière de consentement, authentification, variante) et le SHA-256 de chaque fichier dans manifest.json.
  5. Ajoutez un événement capture.completed.

Phase 3 — Mesure

Exécutez des vérifications automatisées et assistées. Les résultats automatisés deviennent directement des constats. Les résultats assistés deviennent des constats avec mode: assisted et triage: null ; notez quelle exception (espacement, en ligne, équivalent, essentiel, tableau de données) pourrait s'appliquer.

Correspondance source. Pour chaque constat, recherchez dans le clone la source de l'élément (son texte, noms de classe, nom de composant ou attributs de données) et enregistrez source: {file, line, confidence}. C'est au mieux : utilisez confidence: low pour une supposition et omettez source plutôt que de prétendre à un emplacement que vous n'avez pas trouvé. Ce sont des indices pour l'implémenteur, pas des instructions.

Phase 4 — Évaluation

Exécutez le passage heuristique. Pour chaque constat, enregistrez :

  • rule_id, localisateur, chemin de preuve et hachage
  • sévérité 0–4 (Nielsen : fréquence, impact, persistance)
  • confiance (élevée/moyenne/faible)
  • scope : un de single-section, cross-section, component, interaction
  • une phrase sur ce que la preuve montre

Indications de portée :

  • single-section : le problème se trouve à l'intérieur d'un bloc d'une seule page.
  • cross-section : le problème n'apparaît que sur plusieurs blocs, pages ou largeurs (ordre de priorité par rapport à l'ordre visuel, motifs incohérents, navigation qui change entre les pages). Recherchez-les délibérément ; ils sont souvent les plus importants et les plus faciles à manquer lors de l'examen d'une seule section à la fois.
  • component : un élément réutilisable se comporte ou a l'air incohérent partout où il apparaît.
  • interaction : le problème se trouve dans un état, un flux ou un comportement plutôt que dans une mise en page statique.

Pour les longues pages, évaluez chaque section à partir de sa propre capture d'écran et notez les positions y ; effectuez ensuite un passage séparé pour les constats inter-sections. Incluez uniquement les règles avec suffisamment de preuves visibles ; ignorez les règles qui ne peuvent pas être évaluées à partir de la capture plutôt que de deviner. Considérez-vous comme un seul évaluateur ; dites-le dans le résumé des constats.

Porte G2 — Triage

Présentez les constats groupés par sévérité, puis par page, sous forme de tableau : ID, règle, étiquette, portée, page/largeur, sévérité, confiance, preuve en une ligne. Demandez à l'utilisateur d'accepter, de rejeter ou de réévaluer. Enregistrez chaque appel de triage comme un événement du registre attribué à l'utilisateur. Seuls les constats acceptés avancent.

Phase 5 — Référence Figma (Porte G3)

  1. Capturez les écrans « tel quel » dans la page 00 As-Is via generate_figma_design (ou html_to_figma), une image par largeur capturée qui montre un changement structurel.
  2. Construisez des maquettes structurelles « tel quel » sur la page 01 As-Is Wireframes à partir de skeleton.json, en utilisant le kit de maquettes du fichier si search_design_system en trouve un.
  3. Passez le relais : demandez à l'utilisateur de verrouiller 00 As-Is et d'enregistrer une version nommée intitulée baseline R-…, puis de vous donner son ID de version. Vous ne pouvez pas enregistrer les versions vous-même.
  4. Enregistrez l'ID comme version_before. Aucune autre écriture tant que vous ne l'avez pas.

Phase 6 — Proposer

  1. Regroupez les constats acceptés en décisions. Chaque D-NNNN.json : titre, ID de constats, contexte, proposition, alternatives (le cas échéant), état (draft), catégorie (normative, heuristic, house), priorité (P0–P4), pages/largeurs concernées, source (copié du constat principal), target_deadline (facultatif). Le titre doit être une phrase impérative en français : « Ajouter un texte alternatif à l'icône de profil ». Adressez-vous à l'implémenteur ; pas de jargon commercial.
  2. Assignez une catégorie de mise en œuvre : component (modifier un élément réutilisable utilisé à plusieurs endroits), layout (repositionner ou redimensionner des éléments dans un bloc), content (texte ou actifs), interaction (changement d'état ou de comportement), meta (modifications dans <head>, attributs ARIA qui ne changent pas le rendu, correctifs de séquence de tabulation).
  3. Écrivez un résumé pour l'humain. Demandez à l'utilisateur d'approuver, de rejeter, de différer ou de modifier la proposition. N'acceptez pas un « Continue » comme approbation ; l'utilisateur doit taper fwd approve D-0001 explicitement. Lisez le fichier résultant, ne le validez pas seulement.
  4. Enregistrez l'événement decision.proposed avec les champs de la décision, l'ID de version de la proposition (si une maquette Figma « cible » a été écrite), les hachages des alternatives, et outcome: proposed.

Phase 7 — Maquette « cible »

  1. Pour chaque décision approuvée, construisez une image « cible » sur la page 02 To-Be Wireframes. Utilisez les précédentes si la décision ne modifie pas une section ; ne les reclonez pas. Ajoutez l'annotation ⟦D-0007⟧ au nom du nœud parent de la section et une annotation de catégorie du skill sur le nœud lui-même.
  2. Liez chaque nœud de décision à son ID dans le registre en écrivant des pluginData de décision via setSharedPluginData.
  3. Ajoutez un événement wireframe.candidate contenant les ID des nœuds créés, le hachage du répertoire des maquettes, et stage: proposed.

Phase 8 — Validation humaine (Porte G4)

  1. Présentez la page de validation : un tableau des décisions approuvées (ID, titre, décision, date). Chaque ligne montre l'humain qui a approuvé.
  2. Demandez à l'utilisateur d'enregistrer manuellement une version Figma nommée approved R-… (vous ne pouvez pas le faire) et de vous donner l'ID de version. Enregistrez-le comme version_after. L'ID version_before doit être défini et doit différer.
  3. Déplacez l'image du carrousel de la phase 7 de stage: proposed à stage: approved dans le registre. Figma n'a pas de notion d'approbation ; le registre seul l'a.
  4. Enregistrez un événement human.approved avec l'ID de la version Figma après approbation, l'ID de la version Figma de la baseline, version_before et version_after.

Phase 9 — Remise

  1. Pour chaque décision approuvée, écrivez handoff/D-NNNN.md. Modèle :

Objet : D-0001 : Ajouter un texte alternatif à l'icône de profil

Catégorie : content Constat : IC-0003 (manque de texte alternatif sur l'icône de profil dans l'en-tête) Règle : wcag-4.1.2 (name, role, value)

Situation actuelle L'icône de profil dans l'en-tête .header-nav (ligne 42 de components/Nav.tsx) est un <img> sans attribut alt. L'image est présentée comme un lien de navigation principal ; son nom accessible est donc nul.

État cible Ajoutez alt="Profil" (ou alt="Mon profil" s'il mène à une page de profil personnelle) à l'icône de profil. Utilisez alt="" si l'icône est décorative et qu'un texte de lien adjacent la décrit déjà, mais vérifiez d'abord qu'il n'y a pas de nom accessible en double.

Preuve audit/runs/R-20261201-01/captures/1280/axe.json chemin : nœud #25 axe/findings/deficient-item-0

Critères de vérification

  1. L'attribut alt est défini et non vide (ou intentionnellement vide) dans le rendu HTML.
  2. Axe-core ne signale pas d'élément <img> manquant de texte alternatif dans ce composant.
  3. L'outil de vérification du texte alternatif de l'extension Wave ne trouve pas de problèmes.

Zone du dépôt components/Nav.tsx ligne 42

  1. Mettez à jour handoff/README.md avec les conventions de codage partagées : règles de guidage du plan, prompt système pour l'agent implémenteur, validation des modifications (l'implémenteur doit écrire un test de régression pour chaque modification).

  2. Résumez : X décisions sur Y approuvées, Z différées, W rejetées.

Phase 10 — Vérification (Porte G5)

  1. Exécutez à nouveau la capture et la mesure (Phase 2, Phase 3) sur une nouvelle branche sur laquelle l'implémenteur a fusionné ses modifications. Utilisez la même intent.yaml mais pointez vers le nouveau commit contenant les modifications fusionnées.
  2. Comparez les résultats : seuls les constats marqués comme résolus par les décisions approuvées doivent être absents. Toute régression (nouvel échec dans une zone que vous avez modifiée) doit être signalée comme un constat de suivi. Enregistrez les deux états dans le registre.
  3. Si prévu dans l'intention, relisez les modifications de code de l'implémenteur pour détecter les régressions de conception (espacement, couleur, taille, comportement) en comparant les captures « tel quel » et « cible » rendues.
  4. Enregistrez un événement verification.completed avec les ID des constats de suivi.

Journalisation et vérification du registre

Chaque événement dans ledger.jsonl a ces champs obligatoires :

{
  "event_id": "E-001",
  "type": "human.approved",
  "timestamp": "2026-12-01T15:30:00Z",
  "actor": "student",
  "data": {
    "decision_id": "D-0001",
    "version_after": "V42"
  },
  "hash": "sha256",
  "parent_hash": "sha256"
}

Le hash est sha256(type + timestamp + actor + JSON.stringify(data) + parent_hash). parent_hash du premier événement est "0000". Chaque événement pointe vers son parent. fwd ledger verify recalcule et échoue si la chaîne est rompue. Le registre est la source de vérité ; Figma est une projection.

Skills associés