wp-pack
Zip/package WordPress (plugin ou thème). Se charge : (1) après modification de .php/.css/.js/.html/.twig/block.json/theme.json dans un projet WP (header 'Plugin Name:' ou 'Theme Name:' détecté), (2) dès qu'un zip/package WP est envisagé — mots-clés 'zip le plugin WP', 'package WordPress', 'zipper le thème', 'prépare pour prod WP', 'build du plugin WP'. Flow : détection type et slug → bump version (patch pour fix, minor pour feature) → zip via node hooks/wp-pack.js (jamais de Compress-Archive/zip -r inline, jamais de script .ps1/.sh temporaire). Ne se charge PAS : projet non-WordPress, review ou audit read-only, fichiers hors scope WP.
WP Pack — Packaging WordPress
Ce skill s'active :
- Automatiquement quand Claude termine une modification de code (fichiers PHP, CSS, JS, HTML, templates) et qu'un projet WordPress est détecté — avec ou sans commande codebloom
- Sur demande quand l'utilisateur demande de packager, zipper ou préparer pour distribution
Le zip est TOUJOURS généré automatiquement après une modification ou un ajout de code. Ne JAMAIS demander "Tu veux le zip ?" — le faire directement.
Étape 1 — Détection auto : Plugin ou Thème
1a. Type et fichier principal
| Type | Détection |
|---|---|
| Plugin | Fichier PHP contenant Plugin Name: dans le header |
| Thème | style.css contenant Theme Name: dans le header |
Chercher d'abord à la racine. Si rien trouvé → chercher dans les sous-dossiers directs (1 niveau).
1b. Slug (CRITIQUE)
Le slug détermine le nom du dossier racine dans le zip. Un mauvais slug = deux plugins sur le site WordPress.
Déterminer le slug dans cet ordre de priorité :
Text Domain:dans le header du fichier principal (source la plus fiable)- Nom du fichier PHP principal sans extension (ex:
adn-tag.php→adn-tag) - Dernier recours : nom du dossier contenant le fichier principal
RÈGLE ABSOLUE : le slug dans le zip doit être identique à celui déjà installé sur le site WordPress. Ne JAMAIS inventer, transformer ou dériver un slug autrement (pas de conversion . → -, pas de slugification du nom du plugin, etc.).
RÈGLE STRUCTURE : le dossier racine dans le zip doit toujours être {slug}/. Ne JAMAIS changer la structure interne du zip (pas de dossier racine renommé, pas de fichiers déplacés, pas de réorganisation). Un changement de structure = double plugin dans WordPress à l'activation.
1c. Structure
| Structure | Détection | Dossier source |
|---|---|---|
| Racine | Le fichier principal est à la racine du projet | . (racine) |
| Sous-dossier | Le fichier principal est dans un sous-dossier | Le sous-dossier |
Afficher avant de continuer :
Type : Plugin / Thème
Slug : {slug}
Source : {chemin du dossier source}
Étape 2 — Bump de version
Lire la version actuelle
Chercher la version dans le fichier principal détecté à l'étape 1.
Déterminer l'incrément
| Type de changement | Bump | Exemple |
|---|---|---|
| Nouvelle feature / fonctionnalité | minor (0.X.0) | 1.2.3 → 1.3.0 |
| Correction / refactoring / nettoyage | patch (0.0.X) | 1.2.3 → 1.2.4 |
| Breaking change explicite | major (X.0.0) | 1.2.3 → 2.0.0 |
| Demande directe de l'utilisateur | demander | patch / minor / major / custom |
Règles semver :
- major (X.0.0) : remet minor et patch à 0
- minor (0.X.0) : remet patch à 0
- patch (0.0.X) : incrémente seulement
Quand le bump est auto-déterminé : afficher la version choisie et enchaîner directement.
Fichiers à mettre à jour
Mettre à jour seulement les fichiers qui existent :
| Type | Fichiers | Champ |
|---|---|---|
| Plugin | PHP principal | Version: dans le header |
| Plugin | readme.txt | Stable tag: |
| Plugin | PHP principal ou includes | define('..._VERSION', '...') ou const VERSION = '...' |
| Thème | style.css | Version: dans le header |
| Thème | functions.php | define('..._VERSION', '...') ou const VERSION = '...' |
| Thème | readme.txt (si existe) | Stable tag: |
Étape 3 — Anciens zips (géré automatiquement)
Ne lancer aucune commande rm / Remove-Item / del manuelle. Le script wp-pack.js supprime lui-même, via fs.unlinkSync, tous les anciens {slug}.zip et {slug}-*.zip présents dans le dossier source, le dossier parent, et le dossier de sortie, avant de créer le nouveau zip. Passer directement à l'étape 4.
Étape 4 — Créer le zip
Utiliser le script wp-pack.js du plugin. Ne JAMAIS écrire de commande zip/PowerShell inline, et ne JAMAIS créer de script temporaire (build-zip.sh, package.ps1, etc.).
❌ Anti-patterns stricts — ne JAMAIS faire
# Interdit — rm + Compress-Archive inline (trigger un prompt de permission + bypass des exclusions du script)
cd "..." && rm -f {slug}.zip && powershell.exe -Command "Compress-Archive -Path '{slug}' -DestinationPath '{slug}.zip' -Force"
# Interdit — zip unix inline
cd "..." && rm -f {slug}.zip && zip -r {slug}.zip {slug}/
# Interdit — script temporaire
echo "..." > build-zip.ps1 && powershell.exe -File build-zip.ps1
Ces commandes :
- Déclenchent un prompt de permission sur
rm - Ne respectent pas les exclusions (
.git,node_modules,*.md,.claude/, etc.) - Ne nettoient pas les anciens zips du dossier parent / output
- Ne garantissent pas que le dossier racine du zip =
{slug}/
✅ Commande unique et obligatoire
node "${CLAUDE_PLUGIN_ROOT}/hooks/wp-pack.js" --source "{chemin_dossier_source}" --slug "{slug}" --output "{chemin_output}/{slug}.zip"
Arguments :
--source: chemin absolu du dossier contenant le code plugin/thème (racine ou sous-dossier)--slug: le slug détecté à l'étape 1b (détermine le nom du dossier racine dans le zip)--output: chemin absolu du zip de sortie
Emplacement du zip :
- Structure racine → le zip va dans le dossier source :
{source}/{slug}.zip - Structure sous-dossier → le zip va dans le dossier parent (racine projet) :
{parent}/{slug}.zip
Le script gère automatiquement :
- Windows : PowerShell
Compress-Archivevia fichier .ps1 temporaire (pas de problème d'échappement) - macOS/Linux : commande
zip - Renommage du dossier : si le dossier source a un nom différent du slug, le zip contient quand même
{slug}/comme racine - Exclusions :
.git,node_modules,*.md,.claude/,plans/,*.zip, etc. (liste complète dans le script) readme.txtest toujours inclus (ce n'est pas un.md)
Étape 5 — Vérification
Contenu du zip
Lister le contenu résumé et vérifier :
- Présence du fichier principal (PHP header ou
style.css) - Absence de fichiers dev (
.git/,node_modules/,.env) - Dossier racine dans le zip = slug
Résumé
Type : Plugin / Thème
Slug : {slug}
Version : {version} (depuis {ancienne-version})
Zip : {slug}.zip ({taille})
Fichiers : {nombre} fichiers
Cas particuliers
vendor/ (Composer)
- Si
composer.jsonexiste avec une sectionautoload→vendor/est inclus automatiquement - Si
vendor/n'existe pas maiscomposer.jsona un autoload → signaler : "vendor/ manquant — lancercomposer install --no-dev"
Build step détecté
- Si
package.jsoncontient des scriptsbuild,compile, oudist→ signaler : "Build step détecté — vérifier que les assets sont à jour"
Traductions (languages/)
- Toujours inclues si le dossier existe
Pas de readme.txt
- Ne pas en créer
- Signaler uniquement si plugin destiné à WordPress.org
Comportement
- TOUJOURS zipper après une modification ou un ajout de code dans un projet WordPress — ne JAMAIS demander "Tu veux le zip ?", le faire directement
- Utiliser
wp-pack.js— ne JAMAIS écrire de commandes zip/PowerShell inline, ne JAMAIS créer de scripts (build-zip.sh,package.ps1, etc.) - Auto-bumper la version selon le type de changement (minor pour feature, patch pour fix/refactoring)
- Toujours bumper — chaque zip inclut un bump de version (étapes 2→5), y compris depuis
/push. Raison : forcer le cache-busting CSS/JS côté WordPress - Enchaîner sans interruption : suppression → zip → vérification
- Signaler les anomalies (vendor manquant, build step, taille > 10 MB) sans bloquer
- Ne pas modifier la structure du projet
- Ne pas créer de
readme.txt,LICENSE, ou autres fichiers manquants