Skip to content

Manuel de référence des plug-ins : packager sa configuration pour la distribuer

📚 Navigation de la série : L'article précédent 37 Checkpoints vous a appris comment sauvegarder et restaurer une session, afin de revenir en un clic au dernier point de sécurité en cas d'erreur. Cet article change de perspective — l'article 24 vous expliquait comment « utiliser les plug-ins des autres », tandis que celui-ci vous apprend à « concevoir vos propres plug-ins » : comment organiser l'arborescence, quel est le rôle de chaque champ du fichier plugin.json, quels composants packager, comment déclarer les dépendances et comment mettre en place un marketplace pour le partager avec votre équipe. C'est le guide de référence approfondi des plug-ins.

Exécutez la commande claude plugin details sur un plug-in, et observez ces chiffres dans le retour : ce plug-in consomme environ 180 tokens de manière permanente par session, et ses deux skills consomment respectivement 2400 et 1800 tokens supplémentaires lorsqu'ils sont déclenchés.

Ce petit plug-in, sous ses airs inoffensifs, occupe déjà une partie de l'espace de travail simplement en restant active sans rien faire. C'est à ce moment qu'on réalise : un plug-in n'est pas une boîte noire — il est constitué de plusieurs catégories de composants bien définis, et l'espace consommé, l'emplacement et le mode de déclenchement de chacun sont parfaitement documentés. C'est en maîtrisant cette structure que vous pourrez en concevoir par vous-même, et ce, de manière propre.

Dans l'article 24, nous avons vu comment utiliser les plug-ins des autres : ajouter un marketplace, installer un plug-in, appliquer les changements avec /reload-plugins, et vérifier la confiance avant installation. Cet article ne revient pas sur ces notions et s'attaque à un aspect plus complexe — la structure interne des plug-ins, leur développement et leur publication. En résumé, l'article 24 vous apprenait à « conduire », celui-ci vous apprend à « démonter le moteur et assembler votre propre véhicule ».

Cet article se comporte comme un « manuel de référence » et présente une densité d'information supérieure aux précédents. Vous n'avez pas besoin de tout mémoriser d'un coup. Suivez d'abord les étapes pour concevoir et publier un plug-in fonctionnel, et utilisez les tableaux de champs comme référence à consulter en cas de besoin.

À la fin de cet article, vous obtiendrez :

  • L'arborescence standard d'un plug-in, et la structure complète découlant de la règle d'or « seul plugin.json se place dans .claude-plugin/ »
  • Une vue d'ensemble des champs du manifeste plugin.json : champs obligatoires, métadonnées, chemins des composants, configurations utilisateur et dépendances, résumée sous forme de tableau
  • La localisation et les limites de chaque composant intégrable dans un plug-in (skill / command / agent / hook / MCP / LSP / monitor)
  • Pourquoi l'utilisation des variables de chemin comme ${CLAUDE_PLUGIN_ROOT} est obligatoire, et les conséquences de leur omission
  • Le flux complet pour créer un plug-in à partir de zéro, le tester localement, concevoir un marketplace et le distribuer à votre équipe, avec les commandes et résultats attendus
  • Les solutions aux deux pièges incontournables lors de la publication : la gestion des versions et les dépendances

01 Mettre en place la structure du plug-in : L'arborescence standard

Vous avez vu la structure minimale d'un plug-in à l'article 24 — un fichier plugin.json accompagné de quelques dossiers de composants. Pour concevoir un plug-in plus complet, il convient d'en appréhender la structure globale afin d'éviter les erreurs d'organisation.

Commençons par la conclusion : un plug-in est simplement un répertoire contenant un « fichier manifeste » définissant son identité, le reste des fichiers étant organisé par type de composant à la racine de ce répertoire.

Analogie : Un ensemble de briques LEGO. Une boîte de LEGO contient deux éléments — un livret d'instructions d'assemblage, décrivant le nom du modèle et la liste des pièces ; plusieurs sachets triés, regroupant les pièces par type (les roues d'un côté, les fenêtres de l'autre). Un plug-in suit cette même logique : plugin.json est le livret d'instructions, et les répertoires skills/, agents/ ou hooks/ sont les sachets triés. Le livret a son propre emplacement dédié, tandis que les pièces sont disposées autour — c'est le principe de la règle d'or présentée ci-dessous.

L'arborescence complète recommandée officiellement ressemble à ceci (les répertoires secondaires ont été omis pour se concentrer sur l'essentiel) :

text
my-plugin/
├── .claude-plugin/           # 元数据目录
│   └── plugin.json           # 清单(说明书)——只有它放这儿
├── skills/                   # Skills,每个一个 <名字>/SKILL.md
│   └── code-reviewer/
│       └── SKILL.md
├── commands/                 # Skills 的扁平 .md 写法(老形式)
│   └── status.md
├── agents/                   # Subagent 定义
│   └── security-reviewer.md
├── hooks/                    # Hook 配置
│   └── hooks.json
├── .mcp.json                 # MCP server 定义
├── .lsp.json                 # LSP server 配置
├── bin/                      # 加进 PATH 的可执行文件
├── scripts/                  # Hook 和工具脚本
└── settings.json             # 插件的默认设置

Voici une règle d'or mise en évidence officiellement par un avertissement, que les débutants enfreignent fréquemment, retenez-la bien :

.claude-plugin/ 目录包含 plugin.json 文件。所有其他目录(commands/、agents/、skills/、output-styles/、themes/、monitors/、hooks/)必须在 plugin 根目录,而不是在 .claude-plugin/ 内。

En clair : le dossier .claude-plugin/ doit contenir uniquement le fichier plugin.json et rien d'autre, les dossiers comme skills/, agents/ ou hooks/ se plaçant à l'extérieur, au même niveau que lui. Cette difficulté a déjà été évoquée à l'article 24 — lors du premier packaging, on a tendance à insérer le dossier skills/ dans .claude-plugin/, ce qui permet au plug-in de se charger mais empêche les skills de s'afficher, obligeant à chercher l'erreur d'arborescence. Gardez en tête l'analogie des LEGO : le livret d'instructions reste dans sa boîte dédiée, les briques sont disposées tout autour.

Un autre point à ne pas négliger, précisé officiellement : le fichier CLAUDE.md situé à la racine du plug-in n'est pas chargé dans le contexte du projet. Si un plug-in doit transmettre des instructions à Claude, il doit passer par ses composants (skill, agent, hook) et non par l'ajout d'un fichier CLAUDE.md à sa racine. Cela diffère du fichier CLAUDE.md au niveau projet abordé à l'article 18.

💡 En résumé : Un plug-in se compose d'un manifeste (.claude-plugin/plugin.json) et de répertoires dédiés aux composants à sa racine. La règle d'or est simple — le dossier .claude-plugin/ ne contient que le fichier plugin.json, tous les autres répertoires se placent à la racine.


02 plugin.json:这份「清单」每个字段管什么

Une fois l'arborescence validée, analysons le fichier manifeste — plugin.json. Il définit l'identité ainsi que les paramètres du plug-in et constitue son élément central.

先记一个反直觉但很省心的事实:清单是可选的。 Selon la documentation officielle, si vous omettez le fichier plugin.json, Claude Code recherche automatiquement les composants dans les répertoires par défaut (skills/, agents/, etc.) et déduit le nom du plug-in à partir de celui du répertoire. Ce manifeste n'est requis que pour définir des métadonnées ou personnaliser les chemins d'accès aux composants. Toutefois, sa présence est indispensable pour toute distribution officielle. Nous allons donc détailler sa configuration.

Analogie : Une déclaration de douane. Un envoi de marchandises à l'export s'accompagne d'un formulaire de déclaration indiquant la désignation, l'expéditeur, le numéro de lot ainsi que le contenu détaillé. Les services douaniers (Claude Code) s'appuient sur ce document pour effectuer les contrôles, l'enregistrement et l'affectation. Le fichier plugin.json constitue le formulaire de déclaration du plug-in : le nom, l'auteur, la version et la liste des composants intégrés y sont définis sur ce seul document.

Le seul champ obligatoire

Si vous créez ce fichier manifeste, un seul champ est requis :

ChampTypeDescription
namestringIdentifiant unique, écrit en kebab-case (lettres minuscules et tirets), sans espaces

Pourquoi le champ name est-il essentiel ? Car il définit le préfixe d'espace de noms (namespace) des composants. Si un plug-in nommé plugin-dev contient un agent nommé agent-creator, ce dernier apparaîtra dans l'interface sous la forme plugin-dev:agent-creator ; l'appel de son skill s'effectuera par /plugin-dev:xxx. Ce mécanisme d'espace de noms évite les conflits de nommage — vous pouvez installer une dizaine de plug-ins sans que leurs composants respectifs n'entrent en collision.

Champs de métadonnées (décrivant le rôle du plug-in)

Ces champs n'altèrent pas le comportement technique mais sont recommandés pour la publication afin d'informer les utilisateurs :

ChampDescription
displayNameNom lisible affiché dans l'interface, acceptant espaces et majuscules ; utilise name par défaut s'il est omis
versionNuméro de version sémantique (semver). Sa configuration implique que les utilisateurs ne recevront les mises à jour que si vous incrémentez ce numéro (voir section 08 pour ce piège)
descriptionDescription concise présentant l'objet du plug-in, affichée lors de la recherche et de l'installation
authorCoordonnées de l'auteur (name / email / url)
homepage / repository / licenseURL de la documentation / URL du dépôt de code / Type de licence
keywordsMots-clés facilitant la découverte du plug-in

Champs d'emplacement des composants (indiquant leur localisation)

Par défaut, les composants sont recherchés dans les répertoires standards skills/ ou agents/, vous n'avez donc pas à renseigner ces champs. Ils ne sont requis que pour utiliser des chemins personnalisés :

ChampCible pointée
skillsRépertoires de skills additionnels (ajoutés au répertoire skills/ par défaut)
commands / agents / outputStylesChemins personnalisés (remplaçant les dossiers par défaut)
hooks / mcpServers / lspServersEmplacement du fichier de configuration, ou configuration directement déclarée en ligne
dependenciesListe des dépendances vers d'autres plug-ins (détaillé à la section 08)

Voici un détail important à surveiller, faisant l'objet de règles d'association de chemins spécifiques : certains champs écrasent la configuration par défaut, tandis que d'autres s'y ajoutent.

  • Remplacement de la configuration par défaut : commands, agents, outputStyles. Déclarer le champ commands désactive la scrutation du répertoire commands/ par défaut. Pour conserver le répertoire standard tout en ajoutant d'autres chemins, vous devez tous les lister explicitement : "commands": ["./commands/", "./extras/"].
  • Ajout à la configuration par défaut : skills. Le dossier skills/ standard est toujours scruté, les répertoires supplémentaires listés dans le champ skills s'ajoutant simplement à la configuration par défaut.

C'est un piège classique : ajouter "agents": ["./extra-agents/reviewer.md"] à un plug-in dans le but d'ajouter un nouvel agent peut faire disparaître les deux agents présents dans le répertoire agents/ par défaut, car la clé agents effectue un remplacement. Il convient de lister les trois fichiers dans le tableau de configuration. Consultez cette règle en cas de doute pour éviter les surprises.

Voici un exemple de manifeste complet incluant des métadonnées :

json
{
  "name": "deployment-tools",
  "displayName": "Deployment Tools",
  "version": "1.2.0",
  "description": "Deployment automation tools",
  "author": { "name": "Dev Team", "email": "dev@company.com" },
  "license": "MIT",
  "keywords": ["deployment", "ci-cd"]
}

💡 En résumé : Le fichier plugin.json constitue la déclaration d'exportation du plug-in. Le seul champ requis est name (qui définit l'espace de noms). Faites bien la distinction entre les champs de type « remplacement » (commands/agents) et ceux de type « ajout » (skills), sous peine de voir des composants disparaître.


03 插件能打包哪些组件:七类零件认全

Cette section présente les notions les plus importantes de cet article — les sept types de composants qu'un plug-in peut embarquer. Détaillons la localisation et les contraintes de chaque type de composant officiellement pris en charge, complétant l'introduction de l'article 24.

Analogie : Les casiers de rangement de pièces LEGO, contenant chacun une catégorie précise. Les roues dans un casier, les vitres dans un autre — le tri facilite l'assemblage. L'organisation des composants segue cette même structure :

ComposantEmplacementFonction principaleDéclencheur
Skillsskills/<nom>/SKILL.mdCompétences spécialisées appelables (article 26)Saisie de /nom-du-plugin:nom-du-skill ou exécution automatique par Claude
Commandscommands/*.mdAncienne syntaxe simplifiée des skills, préférer l'usage de skillsIdentique aux skills
Agentsagents/*.mdSous-agent (subagent) spécialisé (article 23)Affiché dans la commande /agents, affecté par Claude ou sélectionné manuellement
Hookshooks/hooks.jsonActions automatisées liées aux événements (article 33)Exécution automatique lors des événements du cycle de vie
MCP servers.mcp.jsonConnexion à des services tiers (article 22)Démarrage automatique à l'activation, outils intégrés au catalogue d'outils
LSP servers.lsp.jsonAnalyse de code en temps réel (navigation, références)Utilisation automatique lors du traitement du code, nécessite un serveur de langage tiers
Monitorsmonitors/monitors.jsonSurveillance d'événements en tâche de fond, notification de ClaudeDémarrage automatique à l'activation du plug-in (expérimental)

Voici quelques précisions importantes sur les limites définies officiellement pour certains composants :

Les privilèges des agents sont restreints au sein des plug-ins. C'est un aspect essentiel. La documentation officielle précise : pour des raisons de sécurité, les agents déclarés par un plug-in ne prennent pas en charge les champs de frontmatter hooks, mcpServers et permissionMode. En d'autres termes, un sous-agent fourni par un plug-in ne peut pas configurer de hook de manière autonome, démarrer de serveur MCP ni modifier les règles d'autorisation — évitant ainsi qu'un plug-in altère vos droits d'accès en arrière-plan. Les champs autorisés comprennent name, description, model, effort, maxTurns, tools, disallowedTools, skills, memory, background et isolation (l'unique valeur valide pour isolation étant "worktree").

Les hooks peuvent s'associer à de très nombreux événements. Les hooks intégrés aux plug-ins partagent les mêmes événements de cycle de vie que vos hooks personnels (article 33) — de SessionStart (ouverture de session), PreToolUse (avant appel d'outil, avec possibilité de blocage), PostToolUse (après exécution réussie), jusqu'à Stop (fin de réponse) et SessionEnd (fermeture de session), parmi une trentaine répertoriés officiellement. Les débutants n'ont pas à les mémoriser tous, retenez simplement que presque chaque étape peut accueillir une action automatique, comme détaillé à l'article 33.

Les types d'actions des hooks dépassent le simple cadre des scripts. Outre l'action classique command (exécution d'une commande shell), on trouve les types http (transmission de l'événement à une URL externe), mcp_tool (appel d'un outil MCP), prompt (évaluation d'une consigne par le modèle) et agent (exécution d'un agent de validation).

Le composant Monitors est expérimental. Il permet de surveiller des fichiers journaux ou des indicateurs d'état en tâche de fond et de transmettre les nouvelles lignes à Claude sous forme de notification, sans intervention manuelle. Ce mécanisme étant expérimental, son architecture est susceptible d'évoluer ; il s'exécute uniquement dans les sessions interactives et requiert Claude Code v2.1.105 ou supérieur. Les débutants doivent simplement en connaître l'existence.

Deux autres composants secondaires sont utiles à connaître : les fichiers exécutables du répertoire bin/ sont ajoutés au chemin de recherche PATH de l'outil Bash à l'activation du plug-in et peuvent être invoqués comme des commandes standard ; le fichier settings.json définit les configurations par défaut du plug-in, bien qu'il ne supporte actuellement que les clés agent et subagentStatusLine — définir la clé agent permet par exemple d'affecter un agent personnalisé comme thread principal à l'activation, modifiant le comportement par défaut de l'interface.

💡 En résumé : Un plug-in peut intégrer sept types de composants — skill / command / agent / hook / MCP / LSP / monitor, disposant chacun d'un emplacement propre. Retenez deux restrictions clés : les privilèges des agents de plug-ins sont restreints (pas de hooks, MCP ni permissionMode) et le composant monitor reste expérimental.


04 ${CLAUDE_PLUGIN_ROOT}:为什么路径必须用变量,不能写死

Cette section fait l'objet d'un chapitre dédié car elle représente la source d'erreurs la plus fréquente lors de la création de plug-ins, bien que le principe en soit très simple.

Considérons un exemple : un hook de votre plug-in doit exécuter scripts/format.sh, ou un serveur MCP requiert node server.js. Si vous configurez le chemin absolu /Users/votre-nom/my-plugin/scripts/format.shla commande échouera sur toute autre machine où cette arborescence n'existe pas, et même sur votre poste, l'emplacement change à chaque mise à jour du cache du plug-in.

Pour résoudre cette difficulté, le système propose trois variables de chemin qui sont substituées automatiquement dans les commandes de hooks, les configurations MCP/LSP et le contenu des skills ou agents :

VariableCible de substitutionUsage
${CLAUDE_PLUGIN_ROOT}Chemin absolu du répertoire d'installation du plug-inRéférencer les scripts, exécutables et configurations intégrés
${CLAUDE_PLUGIN_DATA}Répertoire persistant des données du plug-in (conservé après mise à jour)Stocker les dossiers node_modules, les caches et les fichiers d'état à conserver
${CLAUDE_PROJECT_DIR}Chemin absolu du répertoire racine du projet actifRéférencer les scripts et configurations du projet

Analogie : La mention « voir l'annexe à la fin de ce document » plutôt que « voir page 87 ». Dans un dossier contenant des feuilles volantes réorganisées régulièrement, indiquer « voir page 87 » provoquera des erreurs dès que l'ordre des pages changera ; utiliser un repère relatif à l'emplacement du document est plus fiable. La variable ${CLAUDE_PLUGIN_ROOT} joue ce rôle de repère d'emplacement — quel que soit le dossier d'installation du plug-in ou sa version active, elle pointe systématiquement vers son répertoire racine.

L'écriture recommandée pour référencer un script interne dans la configuration ressemble à ceci (les guillemets évitent les erreurs si les chemins contiennent des espaces) :

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/format-code.sh"
          }
        ]
      }
    ]
  }
}

La documentation officielle insiste sur une règle importante à retenir :

当 plugin 更新时,此路径会更改。前一个版本的目录在更新后约七天内保留在磁盘上以进行清理,但应将其视为临时的,不要在此处写入状态。

En d'autres termes : le dossier ${CLAUDE_PLUGIN_ROOT} est temporaire, n'y écrivez pas de données persistantes (comme les dépendances installées ou les fichiers de cache). Ces dernières doivent être enregistrées dans ${CLAUDE_PLUGIN_DATA}, car ce répertoire de données est préservé lors des mises à jour. Une erreur courante consiste à installer le dossier node_modules dans ROOT, ce qui supprime les dépendances à la mise à jour suivante. Utilisez ROOT pour les fichiers intégrés, et DATA pour les états à conserver pour éviter les désagréments.

Un autre point d'attention est détaillé dans la section sur le cache des plug-ins : un plug-in installé ne peut pas faire référence à des fichiers situés en dehors de son arborescence. L'utilisation de chemins relatifs comme ../shared-utils échouera après installation, car l'intégralité du répertoire du plug-in est copiée dans le cache (~/.claude/plugins/cache) et les fichiers externes ne sont pas importés. Le partage de ressources entre plug-ins requiert l'usage de liens symboliques, ce qui constitue un sujet avancé ; pour débuter, évitez simplement les références en dehors du répertoire du plug-in.

💡 En résumé : Les références de chemins au sein d'un plug-in doivent obligatoirement utiliser les variables comme ${CLAUDE_PLUGIN_ROOT} au lieu de chemins absolus en dur (qui changent à chaque mise à jour). Utilisez ROOT pour les scripts intégrés, DATA pour les fichiers d'état, et ne référencez aucun fichier externe au répertoire du plug-in.


05 动手:从零造一个能跑的插件,再本地测

Après la théorie, passons à la pratique. Nous allons créer un plug-in minimal complet, le charger localement et exécuter son skill — cet exercice ne requiert aucune configuration complexe et peut être suivi étape par étape. Nous allons concevoir le plug-in my-greeter incluant une compétence d'accueil.

Étape 1 : Initialisez l'arborescence à l'aide de la commande officielle

La méthode la plus rapide consiste à s'appuyer sur la commande plugin init qui se charge de structurer les répertoires :

bash
claude plugin init my-greeter --with skills

L'option --with skills génère également un sous-répertoire d'exemple. Cette commande crée le fichier manifeste .claude-plugin/plugin.json ainsi qu'un fichier de démarrage SKILL.md sous le chemin ~/.claude/skills/my-greeter/.

Résultat attendu : Le terminal confirme la création de l'arborescence et indique le répertoire cible ~/.claude/skills/my-greeter/.

Il s'agit d'une facilité d'utilisation prévue par le système : tout sous-répertoire de ~/.claude/skills/ contenant un fichier manifeste plugin.json est automatiquement chargé sous la désignation my-greeter@skills-dir à la session suivante, sans nécessiter d'installation ni de marketplace. Cette méthode appelée « plug-in de répertoire de skills » constitue l'approche la plus simple pour le développement de plug-ins personnels.

Étape 2 : Examinez les fichiers générés

Affichez l'arborescence (en utilisant un chemin absolu) :

bash
ls -R ~/.claude/skills/my-greeter

Résultat attendu : Vous devez voir le fichier .claude-plugin/plugin.json et le répertoire skills/ (ou un fichier SKILL.md). Vérifiez que plugin.json se trouve bien dans le sous-dossier .claude-plugin/ et que le skill est à l'extérieur — illustrant concrètement la règle d'or de la section 01.

Étape 3 : Rédigez votre premier skill

Ouvrez (ou créez) le fichier ~/.claude/skills/my-greeter/skills/hello/SKILL.md et saisissez-y ce contenu :

markdown
---
description: Saluer l'utilisateur sur un ton chaleureux
---

# Hello Skill

Saluer chaleureusement l'utilisateur nommé « $ARGUMENTS », demander comment l'aider aujourd'hui. Adopter un ton amical et encourageant.

La variable $ARGUMENTS sert de paramètre de substitution — elle capture tout texte saisi après le nom du skill. C'est la syntaxe standard pour passer des paramètres à un skill (comme abordé aux articles 26 et 27).

Étape 4 : Chargez le plug-in localement

Il n'est pas nécessaire de configurer un marketplace durant la phase de développement, l'option --plugin-dir permet de cibler directement le répertoire local :

bash
claude --plugin-dir ~/.claude/skills/my-greeter

Résultat attendu : Claude Code démarre normalement. Saisissez la commande /help pour vérifier que le skill apparaît bien sous l'espace de noms du plug-in.

Étape 5 : Exécutez le skill pour observer son comportement

Les skills intégrés par plug-in requièrent l'usage de leur espace de noms, l'appel s'effectue ainsi (en ajoutant un nom en argument) :

text
/my-greeter:hello Walter

Résultat attendu : Claude vous répond sur un ton chaleureux en s'adressant à « Walter ». Le fait qu'il suive la description et les consignes fournies confirme le bon enregistrement et le fonctionnement du skill du plug-in.

Étape 6 : Modifiez le skill et utilisez le rechargement à chaud

Modifiez le contenu du fichier SKILL.md (par exemple en ajoutant des emojis ou en changeant la langue de salutation), puis, sans redémarrer la session, lancez la commande suivante dans Claude Code :

text
/reload-plugins

Résultat attendu : Lancez à nouveau /my-greeter:hello Walter pour vérifier la prise en compte immédiate des modifications.

⚠️ Une distinction à noter : les modifications appliquées à SKILL.md sont prises en compte immédiatement au cours de la session active ; en revanche, modifier des hooks, des fichiers .mcp.json ou des définitions sous agents/ requiert de lancer /reload-plugins ou de redémarrer la session. Pensez à recharger la configuration si un changement apporté à un hook ne semble pas réagir.

Ces six étapes décrivent le cycle de développement de base d'un plug-in : « Initialisation de l'arborescence → Écriture des composants → Chargement local → Appel de test → Rechargement à chaud ». Les développements futurs suivront ce même flux, seul le nom de composants variera.

💡 En résumé : L'initialisation avec plugin init, le chargement avec --plugin-dir et le rechargement avec /reload-plugins constituent les commandes fondamentales du flux de développement ; le stockage sous ~/.claude/skills/ offre de plus un chargement automatique sans installation préalable.


06 把插件发出去:建一个市场

Pour un usage strictement personnel, utiliser le répertoire ~/.claude/skills/ ou l'option --plugin-dir est suffisant. Cependant, la distribution auprès d'une équipe ou de la communauté requiert la création d'un marketplace — après avoir été client à l'article 24, découvrons comment configurer un marketplace.

Distinguons deux concepts proches mais bien distincts, faisant l'objet d'une clarification dans la documentation :

ConceptDéfinitionEmplacement de configuration
Source du marketplace (marketplace source)Emplacement du manifeste d'indexation (marketplace.json)Déclaré lors de la commande /plugin marketplace add ou dans la configuration
Source du plug-in (plugin source)Emplacement de téléchargement du plug-in lui-mêmeDéfini par le champ source de chaque entrée dans marketplace.json

Analogie : Le magasin par rapport au fournisseur de chaque produit. La « source du marketplace » correspond à l'adresse de la boutique et à la localisation de son catalogue ; la « source du plug-in » désigne le lieu de fabrication et d'expédition de chaque article. Ces deux localisations peuvent différer — le catalogue d'indexation peut être stocké sur le dépôt A, tandis qu'un plug-in spécifique est téléchargé depuis le dépôt B.

Un marketplace s'appuie sur un fichier central : le manifeste .claude-plugin/marketplace.json situé à la racine du dépôt. Il renseigne le nom du marketplace, son propriétaire et la liste des plug-ins référencés. En voici une version minimale :

json
{
  "name": "my-plugins",
  "owner": { "name": "Your Name" },
  "plugins": [
    {
      "name": "my-greeter",
      "source": "./plugins/my-greeter",
      "description": "A friendly greeting plugin"
    }
  ]
}

Chaque entrée de la liste de plug-ins requiert au minimum les clés name et source (renseignant le chemin d'accès). Le champ source prend en charge différents types de localisations :

Type de source du plug-inSyntaxeCas d'usage recommandé
Chemin relatif"./plugins/my-greeter"Le plug-in est stocké au sein du même dépôt (usage le plus courant)
github{ "source": "github", "repo": "owner/repo" }Le plug-in est hébergé sur un dépôt GitHub externe
git-subdirClés url et pathLe plug-in se situe dans un sous-répertoire d'un dépôt multi-projets (monorepo) pour optimiser les téléchargements
npm{ "source": "npm", "package": "@org/plugin" }Le plug-in est distribué sous forme de paquet npm

Pratique : Intégrez le plug-in de la section 05 dans un marketplace local. En supposant que vous ayez configuré le répertoire my-marketplace/ avec l'arborescence requise (.claude-plugin/marketplace.json + plugins/my-greeter/), saisissez dans Claude Code :

text
/plugin marketplace add ./my-marketplace
/plugin install my-greeter@my-plugins

Résultat attendu : Le premier message confirme l'ajout du marketplace ; le second lance l'installation. L'appel /my-greeter:hello est alors opérationnel — ce flux correspond à la procédure d'installation standard vue à l'article 24, le plug-in étant ici le vôtre.

Il est recommandé de valider la configuration avant publication à l'aide de la commande dédiée :

bash
claude plugin validate ./my-marketplace

Résultat attendu : L'outil valide le schéma du fichier marketplace.json, l'absence de doublons dans les noms, la conformité des chemins (absence de .. interdit) et la cohérence des versions. Cibler le dossier du marketplace valide uniquement le fichier marketplace.json ; valider les métadonnées (frontmatter) des skills et agents requiert de cibler le sous-dossier du plug-in (claude plugin validate ./my-marketplace/plugins/my-greeter).

Pour le partager avec votre équipe, publiez le dépôt du marketplace sur GitHub ; vos collaborateurs pourront l'importer à l'aide de la commande /plugin marketplace add owner/repo. Pour automatiser l'installation auprès de vos collaborateurs, vous pouvez déclarer le paramètre extraKnownMarketplaces dans le fichier .claude/settings.json du projet. Une invite d'installation leur sera présentée lorsqu'ils accepteront les conditions d'accès du répertoire de travail. Cette approche relève de l'administration d'équipe, sachez qu'elle existe.

💡 En résumé : La distribution s'appuie sur un marketplace — création de .claude-plugin/marketplace.json à la racine listant les plug-ins et déclarations de source (chemins relatifs, github, npm, etc.). Distinguez la « source du marketplace » (où se trouve le catalogue d'indexation) de la « source du plug-in » (d'où est téléchargé le paquet) ; utilisez claude plugin validate avant publication.


07 一组对照:自用、本地测、正式发布,三条路别走错

L'erreur la plus fréquente lors de la création de plug-ins ne concerne pas le code lui-même, mais le choix du mode de distribution — comme mettre en place un marketplace complet pour de simples tests personnels, ou tenter d'utiliser l'option --plugin-dir (locale) pour un déploiement d'équipe. Ce tableau résume les trois approches :

Contexte d'usageApproche recommandéeCommandeCaractéristiques
Usage strictement personnel, itérations rapidesPlug-in de répertoire de skillsPlacé sous ~/.claude/skills/<nom>/ (avec plugin.json)Chargement automatique, sans installation ni indexation, prise en compte immédiate des modifications de SKILL.md
Phase de développement, tests locauxOption --plugin-dirclaude --plugin-dir ./my-pluginChargement direct sans installation ; supporte le chargement de répertoires multiples ou d'archives .zip
Distribution d'équipe ou publiqueMarketplacemarketplace.json + /plugin installGestion des versions, mises à jour automatisées, partageabilité

Quelques détails d'utilisation pratiques :

L'option --plugin-dir est idéale pour le développement, mais sa portée est limitée à la session en cours. Le plug-in est chargé au démarrage mais la configuration n'est pas enregistrée pour les sessions suivantes. L'avantage est la propreté des tests : fermer la session efface toute trace du chargement. Pendant le développement, il est conseillé de conserver une session ouverte avec --plugin-dir et d'appeler /reload-plugins après chaque modification, ce qui évite les réinstallations répétées via le catalogue d'indexation. De plus, le chemin local fourni à --plugin-dir surcharge temporairement un plug-in de même nom déjà installé via le marketplace — vous permettant de tester des modifications locales sans devoir désinstaller la version publiée.

Le répertoire de skills présente une particularité de portée. Placé sous ~/.claude/skills/ (niveau utilisateur), le plug-in est disponible pour tous les projets ; toutefois, s'il est placé sous le répertoire de projet .claude/skills/ (niveau projet), la documentation officielle indique qu'il est recherché uniquement depuis le répertoire de démarrage de Claude Code, et non en remontant vers la racine du dépôt comme pour un skill classique. Lancer la session depuis un sous-dossier peut donc ignorer le plug-in — veillez à démarrer la session depuis la racine du dépôt, ou appelez la commande /reload-plugins.

Éteignez la configuration d'un marketplace dès le début. C'est un cas typique de sur-ingénierie. La recommandation officielle est pragmatique : commencez par des répertoires locaux ou l'option --plugin-dir pour valider votre code, puis organisez-le sous forme de plug-in publiable sur un marketplace une fois stabilisé. Un composant requiert généralement de nombreuses itérations avec --plugin-dir avant de fonctionner correctement ; imposer le cycle de commit et d'indexation du catalogue d'indexation à ce stade compliquerait inutilement la tâche.

💡 En résumé : Choisissez le bon mode de distribution — dossier personnel ~/.claude/skills/ pour l'usage propre, option --plugin-dir pour la phase de test, et marketplace uniquement pour la publication. L'option --plugin-dir est limitée à la session en cours (ce qui garantit sa propreté) ; assurez-vous de stabiliser le plug-in avec les deux premières méthodes avant de le distribuer.


08 发布绕不开的两个坑:版本管理与依赖

La gestion des versions et des dépendances constituent deux sources d'erreurs fréquentes lors du déploiement, mises en avant par des avertissements dans la documentation officielle. Détaillons ces aspects.

Piège 1 : L'incrémentation de version obligatoire pour pousser les mises à jour

C'est un comportement très contre-intuitif à appréhender. Comment Claude Code identifie-t-il la présence d'une nouvelle version d'un plug-in ? Il consulte les informations dans cet ordre de priorité :

  1. La clé version dans le fichier plugin.json
  2. La clé version déclarée dans le catalogue du marketplace
  3. En l'absence de ces deux informations, le hachage SHA du commit git

La documentation officielle met en garde sur ce point :

设置 version 会固定 plugin。如果 plugin.json 声明 "version": "1.0.0",推送新提交而不改变该字符串对现有用户没有任何作用,因为 Claude Code 看到相同的版本并保留缓存副本。

En clair : dès lors que le champ "version": "1.0.0" est déclaré, pousser des commits de mise à jour sur votre dépôt ne suffit pas — pour les utilisateurs, le numéro de version n'ayant pas changé, la commande /plugin update renverra « déjà à jour » et le cache local ne sera pas actualisé. Vous devez obligatoirement incrémenter le numéro de version à chaque publication (1.0.1, 1.1.0, etc.).

Le système propose donc deux stratégies de gestion des versions :

StratégieMéthodeComportement de mise à jourCas d'usage recommandé
Version expliciteConfigurer le champ version dans plugin.json et l'incrémenter manuellementLes utilisateurs reçoivent la mise à jour uniquement lors du changement de versionPlug-ins officiels suivant un cycle de publication stable
Version par commit git (SHA)Ne pas renseigner le champ version, confier le suivi à gitChaque commit poussé constitue une nouvelle version, récupérée automatiquementPlug-ins d'équipe, internes ou en phase d'itérations rapides

Autre piège à éviter : ne déclarez pas la clé version simultanément dans plugin.json et dans le catalogue du marketplace. La documentation officielle indique que la valeur présente dans plugin.json écrase en silence celle du catalogue du marketplace ; modifier la version dans marketplace.json restera sans effet si elle est bloquée par un numéro obsolète dans le fichier plugin.json interne.

C'est une erreur classique : configurer "version": "1.0.0" pour un plug-in d'équipe interne, puis pousser des correctifs ; les collègues signaleront que les modifications ne s'appliquent pas. On a tendance à accuser l'indexation du catalogue, alors qu'en réalité le numéro de version n'ayant pas changé, Claude Code considère qu'il n'y a pas de mise à jour. Pour les plug-ins internes, omettez le champ version pour vous appuyer sur les hachages SHA de git ; chaque commit permettra une mise à jour immédiate. Règle générale : évitez de renseigner le champ version pour les plug-ins internes à cycle rapide, réservez-le aux versions officielles et pensez à l'incrémenter à chaque publication.

Piège 2 : La déclaration des dépendances

Si un plug-in A requiert la présence d'un plug-in B pour fonctionner, déclarez cette association via la clé dependencies :

json
{
  "name": "my-plugin",
  "dependencies": [
    "helper-lib",
    { "name": "secrets-vault", "version": "~2.1.0" }
  ]
}

Une fois déclarées, les dépendances sont installées et activées automatiquement par Claude Code lors de l'installation ou de l'activation de votre plug-in. Les contraintes de version s'expriment selon la syntaxe semver (comme ~2.1.0) pour éviter qu'une mise à jour majeure d'une dépendance ne rende votre plug-in instable. Lors de la désinstallation, la commande claude plugin uninstall --prune supprime automatiquement les dépendances devenues orphelines (installées automatiquement mais n'étant plus requises par aucun plug-in actif) ; les plug-ins que vous avez installés manuellement ne sont jamais impactés par le nettoyage de type prune.

Analogie : La liste des pièces complémentaires requises. La notice de montage d'un meuble indique en bas de page « nécessite l'achat d'un sachet de vis M4 (version 2.1) ». L'assemblage n'est possible qu'une fois les accessoires réunis. La clé dependencies constitue cette liste d'accessoires : elle indique l'identifiant et la version des ressources requises pour que Claude Code se charge de les importer automatiquement.

💡 En résumé : Évitez deux pièges lors du déploiement — si le champ version est renseigné, vous devez impérativement l'incrémenter à chaque publication pour que les mises à jour soient récupérées (pour des cycles rapides, préférez le suivi par SHA en omettant ce champ) ; utilisez dependencies pour lier d'autres plug-ins avec des contraintes de version semver facultatives afin d'automatiser leur installation.


09 Résumé

Cet article a détaillé la transition de l'utilisation des plug-ins vers leur création et leur publication — un plug-in est comparable à une boîte de LEGO : un livret d'instructions (plugin.json) en définit l'identité, et des sachets triés (répertoires de composants) en contiennent les pièces ; l'ensemble pouvant être packagé et partagé.

Synthétisons les points clés à retenir :

ObjectifPoint clé
ArborescenceLe sous-dossier .claude-plugin/ contient uniquement plugin.json, tous les composants se plaçant à la racine
Champs du manifesteSeule la clé name est obligatoire (définit l'espace de noms) ; les chemins de composants se divisent en « remplacement » (agents/commands) et « ajout » (skills)
Composants supportésSept types : skill/command/agent/hook/MCP/LSP/monitor ; les privilèges des agents intégrés sont restreints (pas de hooks, MCP ni permissionMode)
Déclaration des cheminsUtilisation obligatoire des variables comme ${CLAUDE_PLUGIN_ROOT} sans chemins absolus en dur ni références en dehors de l'arborescence ; stockage d'état dans DATA (et non ROOT)
Cycle de développementInitialisation avec plugin init → chargement avec --plugin-dir → rechargement à chaud avec /reload-plugins
PublicationCréation de marketplace.json, distinction entre source du marketplace et source du plug-in, validation avec claude plugin validate
Pièges classiquesObligation d'incrémenter le champ version à chaque modification ; déclaration des liaisons via le champ dependencies

Vous êtes désormais en mesure de : analyser l'organisation d'un plug-in, structurer un paquet fonctionnel à partir de zéro, effectuer des tests locaux avec --plugin-dir, et concevoir un marketplace de distribution pour votre équipe ; vous comprenez également l'importance d'utiliser la variable ${CLAUDE_PLUGIN_ROOT} et comment contourner le piège du cache lié à l'incrémentation de version. Après l'intégration des plug-ins tiers vue à l'article 24, vous disposez des compétences pour concevoir vos propres extensions — regroupez vos configurations personnalisées sous forme de paquet publiable au lieu de devoir copier celles des autres.

La chaîne d'apprentissage « Extension + Configuration + Distribution » de Claude Code est désormais complète. Du fichier CLAUDE.md de l'article 18, en passant par le protocole MCP de l'article 22, les sous-agents de l'article 23, jusqu'aux extensions des articles 24 et 38 — vous maîtrisez non seulement l'utilisation de ces technologies, mais aussi leur assemblage, leur packaging et leur distribution auprès d'autres développeurs.


L'article suivant, 39 « 实战入门 » (Mise en pratique), marque une transition. Les chapitres précédents présentaient chaque fonctionnalité de manière isolée. Il convient désormais d'assembler ces éléments au sein d'un flux de travail complet : nous nous concentrerons sur la réalisation d'un besoin concret, de la phase de cadrage jusqu'à sa livraison, pour observer comment coordonner les outils appris. Pensez-y : chaque commande ou technique vous est familière individuellement, mais comment allez-vous les enchaîner face à un cas réel ?


Lectures recommandées