Moksa1123/wporg-plugin-submission

Compétence portable pour agent Claude permettant de faire passer n'importe quel plugin WordPress via le scan automatisé et la revue manuelle de wordpress.org — références, scripts de build/preflight, correspondance code→correction.

Qu'est-ce que wporg-plugin-submission ?

Cette compétence est conçue pour les développeurs et agents IA (comme Claude Code, Cursor, Codex) qui travaillent avec des plugins WordPress destinés au répertoire wordpress.org. Elle fournit un guide complet, des références et des scripts pour réussir à la fois le scan automatisé (Plugin Check) et la revue manuelle, deux étapes obligatoires avant la mise en ligne d'un plugin. L'utilisateur peut déclencher la compétence pour empaqueter un zip propre, corriger des retours de l'équipe de revue, diagnostiquer un rejet de scan, ou mettre à jour les numéros de version de manière cohérente. La compétence s'appuie sur une carte de références détaillée couvrant tous les sujets critiques : validation des entrées, échappement, préfixage, i18n, enqueue, capacités, guidelines de politique, sécurité, et désinstallation. Elle inclut également un script de build (`build-zip.sh`) qui nettoie automatiquement les fichiers cachés et dev, et un script de pré-vérification (`preflight.sh`). Les cas d'échec coûteux (comme un simple fichier `.gitkeep` faisant échouer tout le scan) sont documentés pour éviter les pièges courants. Elle ne doit pas être utilisée pour des projets non-WordPress ou des plugins privés qui n'iront jamais sur wp.org.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add Moksa1123/wporg-plugin-submit

Installed? Explore more Productivité et collaboration skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Demander à votre IA préférée

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

Documentation

Compétence de soumission de plugin WordPress.org

Faites passer n'importe quel plugin via le scan automatisé et la revue manuelle de wp.org sans devoir le téléverser cinq fois. Tirée de cycles de revue réels (le genre où un simple .gitkeep fait échouer tout le scan).

Mainteneur : moksa · moksaweb.com · Licence : MIT

Quand l'utiliser

Déclenchez cette compétence lorsque l'utilisateur demande :

  • Empaqueter / construire un zip d'installation propre pour wordpress.org
  • Soumettre ou resoumettre un plugin dans le répertoire wp.org
  • Corriger les retours de l'équipe de revue wp.org (les 4 catégories classiques)
  • Diagnostiquer un rejet du scan automatisé (fichiers cachés, préfixes, appels DB…)
  • Mettre à jour la version d'un plugin de manière cohérente (en-tête + readme + constantes)
  • Pré-vérifier un plugin avant téléversement

Ne PAS utiliser pour :

  • Projets non-WordPress
  • Plugins privés/internes qui n'iront jamais sur wp.org (les règles de revue ne s'appliquent pas, bien que les pratiques de sécurité soient toujours utiles)

Les deux portes

  1. Scan automatisé (Plugin Check, exécuté au téléversement) — blocages stricts. Doit être réussi pour même atteindre un humain. Voir references/automated-scan.md.
  2. Revue manuelle (un humain, après la réussite du scan) — vous envoie des problèmes par email, vous corrigez + répondez. Presque toujours l'une des 4 catégories de code (references/review-categories.md) plus des directives de politique qu'aucun linter ne détecte — licence, code à distance, suivi, notifications d'administration, marques déposées, divulgation de service externe (references/guidelines.md).

Carte des références

SujetFichier
Plugin Check (PCP) manuel d'utilisation — UI/CLI, les 31 vérifications → correspondance correction, erreurs vs avertissementsreferences/plugin-check.md
Blocages stricts du scan automatisé (fichiers cachés, DB, appels interdits)references/automated-scan.md
Les 4 catégories de revue manuelle + formulation de réponsereferences/review-categories.md
Leçons de revues réelles (exemple→généralisation, nonce à 3 cas, phpcs:ignore≠escape, cast≠sanitize, chemins, préfixes de fork)references/real-review-lessons.md
Préfixage de chaque globale (fonctions/options/hooks/handles/CPT/meta…)references/prefixing.md
Sanitize · validate · escape + $wpdb->prepare + signatures de webhookreferences/sanitization-escaping.md
Enqueue JS/CSS (dépendances/version, en ligne, condition, blocs, pas de balises brutes)references/enqueue.md
i18n (textdomain==slug, chaînes littérales, commentaires de traducteurs, JS)references/i18n.md
Capacités et callbacks de permission (authz, REST, priv/nopriv)references/capabilities.md
Directives de politique (licence, code à distance, suivi, notifications, marques, divulgation)references/guidelines.md
Format readme.txt (en-têtes, balises≤5, description courte≤150, captures d'écran, services externes)references/readme-txt.md
API Abilities · Client IA · MCP (authz par capacité, frontière de données, confirmation destructive, divulgation du fournisseur)references/abilities-ai-mcp.md
Sécurité supplémentaire (fichiers/WP_Filesystem, téléversements, SSRF, appels interdits/obfusqués)references/security-extras.md
Désinstallation et cycle de vie (nettoyage des données, ne pas supprimer le contenu utilisateur, multisite)references/uninstall.md
Empaquetage du zip + cohérence version/en-tête/readme + .moreferences/packaging.md
Correspondance scan/PHPCS code → correctiondata/plugin-check-errors.csv

Liste de vérification rapide avant téléversement (copier-coller-vérifier)

SCAN AUTOMATISÉ (blocages stricts)
[ ] Aucun fichier caché dans le zip : `find . -name '.*' -not -name '.' -not -name '..'` est VIDE
    (.gitkeep / .gitignore / .DS_Store / .editorconfig échouent tous le test "hidden_files")
[ ] Aucun node_modules/, .git/, tests/, scripts/, phpcs.xml, webpack.config.js dans le zip
[ ] Toutes les globales appartenant au plugin utilisent un préfixe unique >=4 caractères (pas de wp_ / __ / _ seul)
[ ] Pas de requêtes $wpdb directes sans prepare() ; pas d'exécution de code à distance ; pas de phone-home

REVUE MANUELLE (les 4 catégories)
[ ] Enqueue : pas de raw echo '<script>'/'<style>' ; wp_enqueue_* + wp_add_inline_*
[ ] Nonce + current_user_can sur chaque AJAX/admin_post qui modifie l'état ; les webhooks vérifient la
    signature du fournisseur avec hash_equals avant utilisation (nonce WP impossible)
[ ] Chaque $_POST/$_GET nettoyé (wp_unslash + sanitize_*) ; json_decode -> map_deep ;
    sortie échappée tardive (esc_html/esc_attr/esc_url/wp_kses)
[ ] textdomain == slug ; les arguments de __() sont des chaînes littérales ; /* translators: */ avant %s

POLITIQUE (revue manuelle, aucun linter ne les détecte — references/guidelines.md)
[ ] Licence compatible GPL indiquée + fichier LICENSE ; chaque bibliothèque/ressource incluse
    est compatible GPL
[ ] Pas d'exécution de code à distance / pas de chargement de JS exécutable depuis un CDN ; inclure les
    ressources localement
[ ] Tout appel API tiers divulgué dans le readme "== External services ==" (quelles données, quand, URLs)
[ ] Pas de collecte/suivi de données sans consentement explicite (désactivé par défaut) ; pas de lien
    de crédit en front-end sauf consentement ; les notifications d'administration sont
    fermables et limitées à l'écran (pas de spam de notification)
[ ] Le slug/nom ne commence pas par une marque déposée que vous ne possédez pas (woocommerce-… / google-…)

README.TXT (references/readme-txt.md — valider avec le validateur de readme wp.org)
[ ] L'en-tête se parse : Contributors=noms d'utilisateurs wp.org, Tags<=5, Stable tag = version livrée réelle
[ ] Description courte <=150 caractères, texte brut ; le Changelog a une entrée pour la version du
    Stable tag
[ ] Les captures d'écran/bannière/icône vont dans SVN /assets/, PAS dans le zip

IA / ABILITIES / MCP (si le plugin enregistre des abilities, appelle un LLM, ou expose MCP)
[ ] Chaque wp_register_ability a un vrai permission_callback (cap au niveau objet), pas __return_true
[ ] Frontière de données : un outil ability/MCP retourne seulement ce que les capacités de l'utilisateur
    actuel permettent
[ ] L'entrée du modèle/agent est traitée comme non fiable ; les abilities destructives sont
    conditionnées par une confirmation
[ ] Le SDK LLM/IA est inclus (GPL) ; le fournisseur est divulgué dans == External services == ; les clés ne
    sont jamais journalisées
[ ] Le point de terminaison MCP authentifie (App Password/OAuth) ET exécute le permission_callback de
    chaque ability

SÉCURITÉ SUPPLÉMENTAIRE + CYCLE DE VIE
[ ] Pas de eval/shell/obfuscation/extract ; pas de var_dump/print_r/error_log laissés
[ ] Fichiers via WP_Filesystem uniquement dans uploads ; téléversements via wp_handle_upload + liste
    blanche MIME
[ ] Appels distants via wp_safe_remote_* (SSRF : bloquer les plages internes) + timeout + vérification
    de réponse
[ ] uninstall.php protégé par WP_UNINSTALL_PLUGIN ; supprime uniquement vos données préfixées ; jamais le
    contenu utilisateur

PAQUET + MÉTADONNÉES
[ ] Version synchronisée : en-tête Version du fichier principal, constante de version, readme Stable tag,
    Changelog
[ ] Les en-têtes Requires correspondent dans le fichier principal ET le readme.txt (WP / PHP / WC) — et toute
    constante MIN_* d'exécution qui verrouille l'activation
[ ] vendor/ est `composer install --no-dev` (pas de squizlabs/phpunit/phpcompatibility)
[ ] Le nom du dossier racine du zip == slug du plugin

Flux de travail

  1. Lisez les règles de la tâche (voir la Carte des références ci-dessus) — commencez par references/automated-scan.md + references/review-categories.md, puis l'analyse approfondie qui correspond au constat (prefixing.md / sanitization-escaping.md / enqueue.md / i18n.md) et references/packaging.md pour la construction.
  2. Construisez le zip propre — exécutez scripts/build-zip.sh (gère git archive, supprime les fichiers de développement + TOUS les fichiers dotfiles, installe vendor/ --no-dev, compresse avec le slug comme racine). Ne zippez jamais manuellement l'arborescence de travail ; c'est ainsi que les déchets de développement et les dotfiles s'infiltrent.
  3. Pré-vérifiez — exécutez scripts/preflight.sh <chemin-vers-le-zip-ou-dossier> : analyse les fichiers cachés, vérifie la cohérence version/en-tête/readme, exécute PHPCS si configuré. Corrigez jusqu'à ce que ce soit propre.
  4. Exécutez Plugin Check (PCP) — l'outil officiel qui exécute les vérifications automatisées du répertoire localement. wp plugin check <slug> --require=./wp-content/plugins/plugin-check/cli.php (ou Outils → Plugin Check). Corrigez chaque ERREUR, examinez chaque AVERTISSEMENT. Voir references/plugin-check.md pour les 31 vérifications, les indicateurs et quel chapitre de la compétence corrige chacun.
  5. Téléversez. Si le scan automatisé rejette → lisez le code exact, associez-le via data/plugin-check-errors.csv, corrigez, reconstruisez, retéléversez.
  6. Réponse à la revue manuelle — lorsque le relecteur envoie les problèmes par email, corrigez chacun partout (les exemples sont un échantillon — greppez toute l'arborescence, exécutez Plugin Check
    • PHPCS sur l'ensemble du plugin ; la même catégorie récurrente = rejet immédiat). Répondez ensuite point par point en référençant ce qui a changé. Voir references/review-categories.md pour les corrections canoniques + la formulation de réponse et references/real-review-lessons.md pour les commandes de balayage par catégorie et les pièges qui survivent à une première correction.

Pièges durement acquis (les plus coûteux)

  • .gitkeep fait échouer le scan automatisé. C'est un fichier caché. Supprimez chaque dotfile du paquet ; retirez .gitkeep de git pour que git archive ne le réajoute jamais.
  • Décalage de version requise. wp.org lit l'en-tête du fichier principal ET le readme.txt ; une constante MIN_WC/MIN_PHP d'exécution peut verrouiller l'activation séparément. Les trois doivent concorder, sinon un utilisateur avec une version trop basse installe avec succès puis rencontre des fonctionnalités cassées.
  • Les webhooks ne peuvent pas utiliser les nonces WP. Les relecteurs signalent "pas de nonce" sur les gestionnaires IPN — c'est un faux positif ; la réponse correcte est la vérification de la signature du fournisseur avec hash_equals(). Documentez-la avec un phpcs:ignore par ligne + raison.
  • json_decode n'est pas une validation. Utilisez toujours map_deep(sanitize_text_field) sur le résultat.
  • composer install (sans --no-dev) fait fuiter phpcs/phpunit dans vendor/ → paquet gonflé, signalé. Faites toujours --no-dev pour le zip livré.

Skills associés