Communitygithub.com

robcsaszar/tend

Compétences de maintenance locales et à la demande pour les dépôts SvelteKit + TypeScript — sécurité, performance, refactoring, accessibilité et couverture de tests

Qu'est-ce que tend ?

Tend A11y est une compétence d'agent IA spécialisée dans la détection et la correction d'un seul problème de haute priorité lié à l'accessibilité, à l'expérience utilisateur ou au ton de la copie dans les dépôts SvelteKit + TypeScript. Elle analyse le balisage HTML, les composants Svelte et les blocs `<script>` pour identifier des violations telles que des éléments interactifs sans nom accessible, des images sans attribut `alt`, des champs de formulaire sans libellé, ou encore des incohérences de ton. La compétence s'appuie sur une configuration locale (fichier `.claude/tend/config.yaml`) pour définir les globs exclus et les notes de projet, et elle lit les composants existants avant le scan pour connaître les conventions de la bibliothèque de composants. Chaque exécution ne traite qu'un seul problème, applique une correction minimale (≤50 lignes pour une correction structurelle, ≤10 lignes pour une correction de copie), vérifie que le linting et le typage passent toujours, puis présente le diff sans jamais commit ni ouvrir de PR. Cette approche garantit des révisions faciles et évite les régressions cachées.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add robcsaszar/tend

Demander à votre IA préférée

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

Documentation

Tend A11y — le héraut

Trouve le problème unique de plus haute priorité en matière d'accessibilité, d'UX ou de ton de copie dans le balisage de ce dépôt, le corrige minimalement, vérifie, et remet le diff pour révision. Un problème par exécution.

0. Charger la configuration

  • Lire .claude/tend/config.yaml. Utiliser skills.a11y (globs exclus, notes). Cette compétence n'a pas de modules de capacité — ignorer complètement le filtrage par module, il n'y a pas d'étape de filtrage modules: ici.
  • Pas de configuration ? Exécuter au niveau de base : hypothèses de base SvelteKit + TS, exclusifs intégrés conservateurs (ne jamais toucher aux lockfiles, CI, .env, configuration). Émettre une fois : « exécutez tend-onboard pour affiner. » Continuer.

1. Triage

LECTURE OBLIGATOIRE de references/scan-core.md.

  • Établir l'ensemble des exclus : les skills.a11y.off-limits de la configuration plus les garde-fous intégrés (ne jamais toucher aux lockfiles, configuration CI, .env, configuration du projet, ou logique backend/API-route — cette compétence est limitée à la présentation).
  • Établir les points d'entrée : les fichiers de balisage de ce dépôt — composants .svelte, routes +page.svelte / +layout.svelte, ou tout autre fichier template utilisé par la stack. Vérifier skills.a11y.notes pour un répertoire de bibliothèque de composants nommé (par ex. src/lib/components/ui) — s'il existe, ses exports sont la liste cible « utiliser ceci au lieu du HTML brut » pour la Phase 2.
  • Lire 1 à 2 composants existants avant de scanner pour apprendre les conventions réelles de la bibliothèque de composants et de gestion des états/chargement du dépôt — vous devez avoir le motif réel en main avant de pouvoir qualifier un écart de violation.

Critère d'achèvement : ensemble des exclus connu, convention de bibliothèque de composants (si elle existe) identifiée, globs des points d'entrée identifiés.

2. Analyse — par ordre de priorité, s'arrêter au premier résultat réel

Classée par ordre décroissant de valeur (le plus silencieux pour les utilisateurs en premier) — s'arrêter au premier résultat réel et fondé sur des preuves :

  1. HTML interactif brut alors qu'un équivalent de bibliothèque de composants existe — un <button>/<a>/<input> brut à côté d'un export Button/Link/Input ailleurs dans le dépôt.
  2. Éléments interactifs à icône uniquement ou à icône principale sans nom accessible — pas de aria-label, pas de texte visuellement caché, pas de secours title.
  3. <img> sans alt — un attribut manquant est la violation ; un alt="" intentionnellement vide sur une image décorative n'en est pas une.
  4. Champs de formulaire sans libellé associé — pas de label for=, aria-label, ou prop de libellé de la bibliothèque de composants. Auditer le nombre rendu, pas seulement le template : les champs générés dans une boucle ({#each} ou équivalent) produisent N contrôles anonymes à l'exécution.
  5. role="button" (ou un onclick nu sur un élément non interactif) sans le gestionnaire de clavier correspondant — onkeydown pour Entrée + Espace. Le <button> natif obtient cela gratuitement ; cela ne se déclenche que sur l'échappatoire de l'élément brut.
  6. Retour asynchrone de succès/erreur/chargement rendu comme un élément brut non annoncé — pas de role="alert"/role="status", pas de aria-live, et pas de primitive existante de bannière/toast de la bibliothèque de composants déjà utilisée ailleurs dans le dépôt.
  7. Une action destructrice (supprimer/supprimer définitivement/réinitialiser) sans étape de confirmation avant qu'elle ne prenne effet.
  8. Violations du ton de la copie, vérifiées par rapport à la liste d'autorisation/refus basée sur la configuration (skills.a11y.notes, ou un document de ton de projet auquel elle renvoie). Si aucune liste spécifique au dépôt n'existe, se rabattre sur les valeurs par défaut génériques : un adoucisseur impératif comme « Veuillez » précédant une instruction de validation/erreur (« Veuillez saisir un nom » vs. « Saisissez un nom »), ou un point d'exclamation inutile dans la copie de confirmation/instruction courante. Analyser à la fois le texte du balisage rendu et les chaînes littérales à l'intérieur des blocs <script> — la copie assignée à une variable, passée à un appel toast/alert, ou définie via .textContent/.innerText se trouve dans les blocs script, pas seulement dans le balisage, et une recherche grep uniquement dans le balisage manquera les véritables chaînes de validation.

3. Correction — un changement atomique

Avant de modifier, répondre :

  1. Est-ce vraiment peu clair ou inaccessible pour un utilisateur réel (lecteur d'écran, utilisateur clavier uniquement, ou quelqu'un lisant le ton) — pas une préférence stylistique de ma part ?
  2. La correction touche-t-elle uniquement la présentation/la copie — pas de logique, pas de backend, pas de nouvelle dépendance ?
  3. Existe-t-il déjà un équivalent de bibliothèque de composants pour ce motif ? Si oui, l'utiliser au lieu de bricoler une correction en HTML brut (ne pas visser role="alert" sur un <div> brut si le dépôt a déjà un composant statut/bannière qui le porte).

Vérification de base : exécuter le lint/typecheck du dépôt (et la suite de tests si rapide) avant de modifier — noter les échecs préexistants pour ne pas les attribuer plus tard à votre modification.

Budget de taille : ≤50 lignes modifiées pour une correction de balisage/structurelle, ≤10 lignes pour une correction de copie pure ; un composant ou une page par exécution.

Ne jamais toucher aux chemins exclus. Si la correction réelle nécessiterait d'en toucher un, s'arrêter et signaler pourquoi au lieu de forcer le passage ailleurs.

4. Vérifier et présenter

Réexécuter le lint/typecheck (et les tests, s'ils ont été exécutés à l'étape 3) — abandonner uniquement si votre modification introduit un nouvel échec ; les échecs préexistants ne sont pas à corriger ici. Montrer le diff. S'ARRÊTER — ne pas commiter, ne pas ouvrir de PR.

JAMAIS

  • NE JAMAIS signaler ou corriger plus d'un problème par exécution Au lieu de cela : Arrêter l'analyse au premier résultat réel, le corriger, le présenter. Pourquoi : Les diffs groupés d'accessibilité/copie sont difficiles à réviser individuellement et cachent quelle correction spécifique a causé une régression.

  • NE JAMAIS bricoler une correction en HTML brut quand un équivalent de bibliothèque de composants existe déjà Au lieu de cela : Utiliser le composant Button/Input/Link/bannière d'état du dépôt lui-même. Pourquoi : Une correction parallèle unique crée un second motif incohérent au lieu de converger vers celui sur lequel le reste du dépôt compte déjà — le prochain audit le re-signalera comme une dérive.

  • NE JAMAIS inventer une règle de ton de copie non étayée par skills.a11y.notes ou une valeur par défaut générique clairement étiquetée Au lieu de cela : Utiliser la liste d'autorisation/refus basée sur la configuration, ou indiquer explicitement que vous vous rabattez sur un motif par défaut générique. Pourquoi : Une règle inventée sur le champ n'est ni réutilisable ni vérifiable lors de la prochaine exécution, et peut contredire le style maison réel du dépôt.

  • NE JAMAIS analyser uniquement le balisage et ignorer les blocs <script> pour les chaînes de copie Au lieu de cela : Rechercher aussi les chaînes littérales à l'intérieur des blocs <script> — la copie de validation et de retour est fréquemment assignée là, pas écrite directement dans le template. Pourquoi : La véritable chaîne destinée à l'utilisateur est souvent une variable interpolée dans le template ; une recherche grep uniquement dans le balisage correspond au site d'interpolation, pas au texte réel incriminé, et ne signale rien à corriger.

  • NE JAMAIS toucher aux chemins exclus ni commiter/ouvrir une PR Au lieu de cela : Respecter skills.a11y.off-limits plus les garde-fous intégrés ; s'arrêter après avoir présenté le diff. Pourquoi : Le travail de cette compétence s'arrête à « diff vérifié, prêt pour révision humaine » — commiter ou toucher aux chemins exclus supprime la porte de révision dont dépend tout le flux de travail.

Fichiers

  • references/scan-core.md — contrôles de base (chargés Phase 1)
  • evals/ — assertions ai-forge-eval

Skills associés