Tutoriel Claude Code Mods : créer, tester et installer votre premier mod, avec 15 exemples de la communauté
Mis à jour le

Un mod Claude Code est un plugin composé de fonctions JavaScript ou TypeScript qui s’exécutent à l’intérieur de Claude Code. Un mod peut dessiner un panneau ou une ligne au-dessus du prompt, ajouter une commande slash qui s’exécute instantanément, et bloquer ou réécrire un appel d’outil avant son exécution. Les mods sont arrivés dans Claude Code 2.1.287 le 1er octobre 2026, et ils sont activés par défaut.
Choisissez le point d’entrée le plus rapide :
| Vous voulez | Faites ceci |
|---|---|
| Obtenir un mod sans écrire de code | Décrivez-le dans une session, par exemple « crée un mod qui affiche la durée de chaque tour ». Claude l’écrit et vous demande une seule fois d’activer le rechargement à chaud |
| Installer le mod de quelqu’un d’autre | /plugin install <name>@<marketplace> dans une session du terminal, ou claude plugin install <name>@<marketplace> dans votre shell |
| Charger un dossier pendant le développement | claude --plugin-dir ./my-mod |
| Essayer l’agent annexe intégré | /plugin enable cc-plugin-you-should-know@builtin |
Vérifiez d’abord votre version. claude --version doit afficher 2.1.287 ou une version ultérieure. L’application Desktop embarque sa propre copie de Claude Code, et les mods y fonctionnent à partir de 2.1.286. Tapez /status dans l’onglet Code pour savoir laquelle vous avez.
Ce que j’ai testé. Le 7 octobre 2026, j’ai créé trois mods sur Claude Code 2.1.293, dans l’onglet Code de l’application Desktop sous macOS : un garde-fou pour les commandes, un compteur de tours au-dessus du prompt et une commande
/pyenvpour le travail en Python. Les trois passentclaude plugin validateainsi que 8 tests automatisés exécutés avecclaude plugin test. J’ai aussi fait tourner le garde-fou en direct dans une session, avec le rechargement à chaud activé. Les sections sur la communauté s’appuient sur environ 50 articles japonais publiés sur Zenn, Qiita et note.com du 1er au 7 octobre, sur la documentation officielle des mods (opens in a new tab) et sur les données du scan du catalogue awesome-claude-code-mods (opens in a new tab) du 6 octobre.
- Tutoriel Claude Code Mods : créer, tester et installer votre premier mod, avec 15 exemples de la communauté
- GPT Image 2.5 : guide d'utilisation, Flare ou Sunburst et tarifs API
- Comment utiliser DeepSeek Harness : installation, configuration et premier agent
- Runcell Science : l'alternative open source à Claude Science pour la recherche
- Empêcher un Mac de se mettre en veille : capot fermé, Codex et Claude Code
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot : quelle stack d’agents IA choisir en 2026 ?
- Comment Claude Code analyse un notebook Jupyter en Data Science : capacités réelles et limites
- Claude Code routines : triggers, cron jobs et automatisation d’agents IA
- Claude Code Desktop : activer le mode Bypass permissions
- Comment Créer Deux Agents Python avec le Protocole A2A de Google - Tutoriel Étape par Étape
- Top 10 bibliothèques de visualisation de données en Python en pleine croissance en 2025
Ce qu’est un mod, et quand utiliser autre chose
Avant les mods, vous étendiez Claude Code depuis l’extérieur, avec des settings hooks, des skills, un script de barre d’état (status line) ou un serveur MCP. La différence tient à l’endroit où le code s’exécute. Un settings hook est un script que Claude Code lance depuis l’extérieur. Les fonctions d’un mod s’exécutent dans le processus même de Claude Code : un mod peut donc dessiner dans l’interface, ce qu’aucune des autres options ne permet.
La page de présentation officielle les compare à peu près ainsi :
| Mod | Settings hook | Skill | Serveur MCP | |
|---|---|---|---|---|
| Ce que c’est | Des fonctions JS ou TS dans un plugin | Une commande shell, un appel HTTP ou un prompt dans settings.json | Un fichier SKILL.md d’instructions | Un processus externe qui fournit des outils à Claude |
| Peut dessiner dans l’interface | Oui | Non | Non | Non |
| Ce qu’il peut modifier | Appels d’outils, prompts, commandes, tours, l’interface | Si un appel a lieu, ses arguments et son résultat, du contexte supplémentaire | Ce que Claude sait et fait | Les outils dont Claude dispose |
| À choisir quand | Vous voulez un panneau, un bandeau, une commande instantanée, ou réécrire un événement | Vous avez déjà un script qui bloque ou journalise | Vous collez sans cesse les mêmes instructions | Claude doit accéder à un système externe |
Un piège de vocabulaire à connaître. Dans les pages sur les mods, « hook » désigne une fonction de mod, et l’ancien type s’appelle « settings hook ». Les settings hooks fonctionnent toujours et ne sont pas dépréciés. Un même plugin peut contenir à la fois un mod, un skill et un serveur MCP.
Où les mods fonctionnent
Les hooks s’exécutent presque partout. L’interface d’un mod, elle, ne s’affiche que dans le terminal et dans l’application Desktop.
| Où vous lancez Claude Code | Hooks exécutés | Interface du mod affichée |
|---|---|---|
claude dans un terminal, y compris les terminaux d’éditeur et JetBrains | Oui | Oui |
| Application Desktop, onglet Code | Oui | Oui, sauf les éléments réservés au terminal |
| Application Desktop, session WSL | Non | Non |
| Panneau de chat de l’extension VS Code | Oui | Non |
claude -p et l’Agent SDK | Oui | Non |
| Sessions cloud | Oui, si le plugin arrive jusqu’à la session | Non |
Ce tableau vient de la page de présentation officielle. Concrètement, un mod garde-fou vous protège toujours dans VS Code et dans claude -p, alors qu’un compteur n’a nulle part où s’afficher.
Méfiez-vous des deux copies de Claude Code. Plusieurs auteurs japonais ont obtenu des erreurs validate déroutantes parce qu’un ancien CLI pour terminal, installé avec Homebrew (les versions 2.1.226 et 2.1.234 dans leurs comptes rendus), cohabitait avec la version 2.1.286 embarquée dans l’application Desktop. Vérifiez la version partout où vous utilisez Claude Code.
Comment un mod est organisé
Un petit mod tient en trois fichiers :
safe-shell/
├── .claude-plugin/
│ └── plugin.json name, version, description
└── hooks/
├── hooks.json { "modules": ["./register.ts"] }
└── register.ts your coderegister.ts exporte une seule fonction, register(on). Chaque appel on(event, matcher, hook) ajoute un hook, et chaque hook reçoit les trois mêmes arguments.
$est le moteur. Tout ce qui se trouve hors de votre propre code passe par lui :$.ui.toast,$.process.run,$.state,$.model.complete.eest l’événement, par exemple la commande Bash que Claude s’apprête à exécuter.next(e)transmet l’événement aux autres mods, puis à Claude Code. Si votre hook retourne sans l’appeler, il répond lui-même. Appeleznext({ ...e, command }), et vous changez ce qui se passe.
Le module n’a accès ni à Node ni au DOM. C’est cette limite qui permet à Claude Code de lister tout ce qu’un mod appelle avant de l’exécuter. Essayez sur n’importe quel dossier de mod :
claude plugin validate ./safe-shellMod 1 : un garde-fou qui bloque les commandes destructrices
Si vous utilisez Claude en mode auto ou avec bypass permissions, rien ne l’arrête avant un git reset --hard. Ce mod refuse trois types de commandes shell et tient les fichiers .env à l’écart de la conversation.
import type { Register } from 'claude-code'
// Shell commands an agent should never run without a human typing them.
const BLOCKED: { pattern: RegExp; reason: string }[] = [
{
pattern: /\brm\s+-[a-zA-Z]*[rR][a-zA-Z]*\s+(\/|~|\$HOME)\/?\*?(\s|$)/,
reason: 'recursive delete of / or the home folder',
},
{
pattern: /\bgit\s+push\b.*(--force\b|--force-with-lease\b|\s-f\b).*\b(main|master)\b/,
reason: 'force push to main or master',
},
{
pattern: /\bgit\s+reset\s+--hard\b/,
reason: 'git reset --hard throws away uncommitted work',
},
]
// .env, .env.local, config/.env.production ... but not .env.example.
const isSecretEnvFile = (path: string) =>
/(^|\/)\.env(\.[^/]+)?$/.test(path) && !/\.(example|sample|template)$/.test(path)
export const register: Register = on => {
on('tool.call', { tool: 'Bash' }, ($, e, next) => {
const hit = BLOCKED.find(rule => rule.pattern.test(e.command))
if (hit === undefined) {
return next(e)
}
$.ui.toast(`safe-shell blocked: ${hit.reason}`)
return { deny: `safe-shell: blocked (${hit.reason}). Ask the user to run it themselves.` }
}).catch(($, e, next) =>
// Fail closed: if the guard itself breaks, refuse instead of letting the command through.
next.called ? next(e) : { deny: 'safe-shell: the guard failed, so the command was not run.' },
)
for (const tool of ['Read', 'Edit', 'Write'] as const) {
on('tool.call', { tool }, ($, e, next) =>
isSecretEnvFile(e.file_path)
? { deny: `safe-shell: ${e.file_path} holds secrets and stays out of the conversation.` }
: next(e),
).catch(($, e, next) =>
next.called ? next(e) : { deny: 'safe-shell: the guard failed, so the file was not touched.' },
)
}
}Deux détails comptent plus que les expressions régulières.
Le garde-fou décide avant d’appeler next. Dès que next s’exécute, la commande a déjà été lancée. Un deny renvoyé après coup n’annule rien.
Le .catch le fait échouer en mode fermé (fail closed). Un hook qui lève une exception, ou qui dépasse son budget de 10 secondes, est ignoré, et un garde-fou ignoré laisse passer la commande. Le gestionnaire next.called ? next(e) : deny refuse à la place. validate signale chaque hook capable de bloquer un appel (gating hook) et indique s’il a un .catch. C’est la première chose à vérifier sur le garde-fou de quelqu’un d’autre :
❯ ./register.ts hooks: tool.call{tool=Bash}, tool.call{tool=Read|Edit|Write}
❯ ./register.ts gating hook with .catch: tool.call{tool=Bash}
❯ ./register.ts gating hook with .catch: tool.call{tool=Read|Edit|Write}
❯ ./register.ts calls: $.ui.toast
✔ Validation passedLe tester sans session
claude plugin test exécute les fichiers *.test.ts d’un mod contre le moteur, sans session, sans authentification et sans réseau. Le kit de test n’a rien sous votre mod : chaque test enregistre donc des hooks de substitution pour tout ce que le mod transmet :
import { expect, test } from 'claude-code/testing'
const ran = { stdout: 'ran', stderr: '', interrupted: false }
test('blocks rm -rf on the home folder', async ($, on) => {
on('tool.call', { tool: 'Bash' }, () => ({ result: ran }))
const answer = await $.tool.call({ tool: 'Bash', command: 'rm -rf ~' })
expect(answer.deny).toContain('recursive delete')
})
test('lets ordinary commands through', async ($, on) => {
on('tool.call', { tool: 'Bash' }, () => ({ result: ran }))
const answer = await $.tool.call({ tool: 'Bash', command: 'rm -rf ./build && python -m pytest -q' })
expect(answer.deny).toBeUndefined()
})Le fichier complet contient quatre tests :
(pass) blocks rm -rf on the home folder [16.23ms]
(pass) blocks a force push to main [7.73ms]
(pass) lets ordinary commands through [7.22ms]
(pass) keeps .env out of Read but allows .env.example [9.40ms]
4 pass
0 failMon premier lancement a échoué avec on("tool.call") after the test first called $. Enregistrez les substituts en haut de chaque test, avant le premier appel à $.
Ce qui s’est passé en session réelle
Avec le rechargement à chaud activé, j’ai demandé à Claude d’exécuter echo "the words git reset --hard inside an echo". Le garde-fou a refusé la commande avec « blocked (git reset --hard throws away uncommitted work) », et une notification toast s’est affichée. Or cette commande était inoffensive. La recherche de motifs ne distingue pas une commande d’un texte qui la mentionne, et elle rate aussi une commande cachée dans une variable, un script ou un alias. Les auteurs japonais qui ont publié des garde-fous similaires, comme rafi-guard, delete-guard et board-guard, signalent ces deux problèmes.
Considérez un mod garde-fou comme un second filet de sécurité. Tout ce qui ne doit jamais arriver a aussi sa place dans une règle de permission deny. Attention aussi au sens inverse. La documentation officielle indique que, sur une machine personnelle sans paramètres gérés (managed settings), un mod peut approuver un appel qu’une règle deny refuse. Les mods ne tournent pas dans une sandbox. Ils s’exécutent avec vos permissions.
Mod 2 : un compteur au-dessus du prompt
Le bandeau au-dessus du prompt et le panneau latéral sont les endroits où les mods dessinent le plus. Dans le scan du catalogue du 6 octobre, 41 % des mods dessinent dans le bandeau et 40 % ouvrent un panneau. Celui-ci affiche la durée du dernier tour, ses appels d’outils et ses tokens, avec un bouton Hide.
Les valeurs que lit un affichage vont dans $.state, et chacune est déclarée dans un petit fichier de types :
// types/index.d.ts, named in plugin.json as "types": "./types/index.d.ts"
export type TurnStats = {
seconds: number
tools: number
inputTokens: number
outputTokens: number
model: string | null
}
declare module 'claude-code' {
interface PluginState {
'turn-meter': { last: TurnStats | null; isHidden: boolean }
}
}Les hooks comptent les appels d’outils, lisent durationMs et usage dans turn.complete, puis dessinent le bandeau :
import { atom, read, update } from 'claude-code'
import type { Register } from 'claude-code'
import type { TurnStats } from '../types'
const last = atom({ plugin: 'turn-meter', key: 'last' } as const, null)
const isHidden = atom({ plugin: 'turn-meter', key: 'isHidden' } as const, false)
const formatTokens = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n))
export const register: Register = on => {
let tools = 0
on('prompt.submit', ($, e, next) => {
tools = 0
return next(e)
})
on('tool.call', ($, e, next) => {
// Count the main conversation's calls; subagents carry an agentId.
if (e.agentId === undefined) tools += 1
return next(e)
})
on('turn.complete', async ($, e, next) => {
if (e.agentId !== undefined) return next(e)
const usage = e.usage
const stats: TurnStats = {
seconds: Math.round(e.durationMs / 1000),
tools,
inputTokens: usage
? usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens
: 0,
outputTokens: usage?.output_tokens ?? 0,
model: usage?.model ?? null,
}
await update($, last, () => stats)
if (stats.seconds > 120) $.ui.toast(`That turn took ${stats.seconds}s`)
return next(e)
})
on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
const stats = await read($, last)
if (e.props.hasSurvey || stats === null || (await read($, isHidden))) return next(e)
const { Box, Button, Text } = $.ui.resolve(e)
const model = stats.model === null ? '' : ` · ${stats.model}`
// The band is shared by every mod: keep what the mods beneath drew, then add a row.
const below = await next(e)
return (
<Box flexDirection="column">
{below}
<Box>
<Text dimColor>
{`Last turn: ${stats.seconds}s · ${stats.tools} tool calls · ${formatTokens(stats.inputTokens)} in / ${formatTokens(stats.outputTokens)} out${model} `}
</Text>
<Button key="hide" label="Hide" onPress={() => update($, isHidden, () => true)} />
</Box>
</Box>
)
})
}Dans le test, sur les surfaces terminal et Desktop, le bandeau affiche :
Last turn: 42s · 0 tool calls · 18.2k in / 800 out · claude-opus-5-5 [ Hide ]Trois choses que j’ai apprises en le construisant :
- Gardez les valeurs affichées dans
$.state, pas dans des variables du module. Un rechargement à chaud relanceregisteret réinitialise vos variables, alors que$.statesurvit./clearrepart de zéro : si une valeur doit y survivre, écrivez-la dans$.storesursession.end. - Le bandeau est partagé. Appelez
next(e)et placez son résultat dans votreBox, sinon vous masquez la ligne de tous les autres mods. Un auteur sur note.com a perdu l’un de ses bandeaux, masqué par un autre mod, avant de comprendre ce point. - Les éléments
Textne conservent pas dekey. Dans les tests, retrouvez-les par leur contenu :ui.find({ type: 'Text', text: /Last turn/ }).
Mod 3 : /pyenv, quand Claude lance le mauvais Python
J’ai cherché des mods pour la data science et j’ai trouvé un manque. Sur les 2 690 mods du scan du 6 octobre, aucun ne mentionne Jupyter, pandas, DataFrames, Polars, venv ou conda dans son nom ou sa description.
Le problème derrière ce mod est courant en analyse de données. L’outil Bash de Claude exécute le premier python3 trouvé dans votre PATH, et ce n’est souvent pas l’environnement de votre projet. Voici ce que la sonde a affiché sur ma machine :
python: /Users/<you>/.local/bin/python3 (3.14.2)
env: none (system or tool-managed Python)
pandas: 3.0.1
numpy: 2.4.2
polars: not installed
matplotlib: 3.11.0
pygwalker: not installedAucun environnement virtuel n’était actif : un pip install lancé par Claude serait donc allé dans un interpréteur global.
La commande /pyenv lance cette sonde et répond en deux parties. text est la ligne que vous voyez. context est une note que seul le modèle lit : les appels Bash suivants de Claude savent ainsi quel interpréteur est utilisé, sans nouveau prompt de votre part.
import type { Register } from 'claude-code'
// Reads package versions from metadata instead of importing them, so it stays fast.
const PROBE = `
import os, sys
from importlib.metadata import PackageNotFoundError, version
env = os.environ.get("VIRTUAL_ENV") or os.environ.get("CONDA_PREFIX") or "none (system or tool-managed Python)"
print(f"python: {sys.executable} ({sys.version.split()[0]})")
print(f"env: {env}")
for name in ("pandas", "numpy", "polars", "matplotlib", "pygwalker"):
try:
print(f"{name}: {version(name)}")
except PackageNotFoundError:
print(f"{name}: not installed")
`
export const register: Register = on => {
on('session.start', async ($, e, next) => {
await $.command.register({
name: 'pyenv',
description: "Show which Python, environment and data packages this session's shell uses",
})
return next(e)
})
on('command.run', { command: 'pyenv' }, async $ => {
try {
const probe = await $.process.run(['python3', '-c', PROBE], { timeoutMs: 15_000 })
if (probe.exitCode !== 0) {
return { text: `pyenv: python3 exited with ${probe.exitCode}: ${probe.stderr.trim().slice(0, 300)}` }
}
const report = probe.stdout.trim()
// `text` is the row you see; `context` is a note only the model reads.
return {
text: report,
context: [`Python environment of this session's shell, from /pyenv:\n${report}`],
}
} catch (error) {
return { text: `pyenv: could not run python3 (${String(error).slice(0, 200)})` }
}
})
}La commande slash d’un mod exécute votre fonction immédiatement, sans tour du modèle, même pendant que Claude travaille. $.process.run prend une liste d’arguments, sans shell, et s’interrompt au bout de 30 secondes sauf si vous définissez timeoutMs.
$.process.run voit-il le même PATH que l’outil Bash de Claude ? Un auteur de la communauté a constaté que le node de nvm manquait dans les processus d’un mod. J’ai donc vérifié avec un mod sonde temporaire. Dans ma session Desktop, un simple $.process.run obtenait exactement le PATH de l’outil Bash et le même python3. Passer par un shell de connexion, zsh -lc, donnait la mauvaise réponse : la sonde tombait sur le Python 3.10.9 de python.org, car un shell de connexion non interactif ignore ~/.zshrc, où se trouvent la plupart des ajouts au PATH. Gardez l’appel simple. Si un résultat vous semble faux sur votre machine, comparez-le avec !which python3 tapé dans le prompt de Claude Code.
Les tests ont révélé un autre piège. Les appels sur $, comme $.process.run et $.command.register, ont eux aussi besoin de substituts, et un substitut d’appel $ répond { value: ... }. Si vous renvoyez le résultat brut, le kit le refuse.
Si l’essentiel de vos analyses se fait dans des notebooks plutôt que dans des scripts, cette approche a ses limites : Claude Code modifie les fichiers .ipynb comme du JSON et ne voit jamais le kernel en cours d’exécution. RunCell (opens in a new tab) est un agent pour notebooks qui exécute les cellules et lit directement leurs sorties : il convient mieux à ce type de travail.
Laisser Claude écrire le mod
Vous n’êtes pas obligé d’écrire tout cela à la main. Il suffit de demander dans une session, par exemple « crée un mod qui affiche ma consommation sur 5 heures au-dessus du prompt ». Claude charge le skill intégré plugin-authoring et écrit les fichiers dans ~/.claude/dev-mods/<session-id>/. Le premier fichier déclenche une seule question, « Enable hot reloading for this session? ». Une fois que vous acceptez, chaque modification se recharge à la fin du tour de Claude. C’est ainsi que les trois mods ci-dessus ont été construits et chargés.
Ce qu’ajoutent la documentation et la communauté :
- Copiez le dossier dans un emplacement permanent. Des auteurs sur Qiita et Zenn signalent que les dossiers dev-mods sont nettoyés avec les anciennes sessions au bout d’environ 30 jours.
- Développez avec
claude --plugin-dir ./my-mod. Un mod installé exécute une copie en cache : modifier son dossier ne change rien tant que vous ne mettez pas le plugin à jour. - L’application Desktop n’accepte aucun flag. Définissez
CLAUDE_CODE_PLUGIN_DIRSdans le blocenvde~/.claude/settings.json. Les paramètres du projet sont ignorés pour ce réglage. - Lancez
/plugin. Une ligne grisée comme1 mod active · safe-shellconfirme que le mod est chargé. - Démarrez avec
claude --debugpendant le développement. Le journal de débogage nomme chaque hook ignoré et chaque affichage refusé par le moteur.
15 mods de la communauté à étudier
Le catalogue awesome-claude-code-mods (opens in a new tab), qui compte 316 étoiles, a analysé 2 690 mods publics dans 1 265 dépôts le 6 octobre, cinq jours après le lancement. Les données de ce scan montrent ce que les gens construisent :
- 68 % ajoutent une commande slash
- 53 % interceptent des appels d’outils
- 41 % dessinent au-dessus du prompt, 40 % ouvrent un panneau
- 40 % lancent des processus, 12 % appellent un modèle, 11 % utilisent le réseau
Ces 15 mods montrent l’étendue des possibilités. Les étoiles sont celles du 7 octobre 2026.
| Mod | Ce qu’il fait | Étoiles | À lire pour |
|---|---|---|---|
| terminal-browser (opens in a new tab) | Un navigateur web à côté de la conversation, pour les sites, les aperçus HTML locaux et les pull requests | 3 695 | Le panneau le plus ambitieux à ce jour |
| claude-image-view (opens in a new tab) | Des miniatures des images collées au-dessus du prompt, au lieu de [Image #1] | 160 | L’affichage d’images dans le terminal |
| hamzafer/claude-code-mods (opens in a new tab) | Un ensemble : barre de contexte, garde-fou de rayon d’impact, aperçu Markdown, tableau de bord des sous-agents | 138 | Plusieurs types de mods dans un seul dépôt |
| claude-auto-handoff (opens in a new tab) | Transmet une longue session à une nouvelle session avec un résumé structuré | 60 | La gestion du contexte |
| prismantis (opens in a new tab) | Des réponses thématisées : tableaux, code, graphiques en art ASCII, texte de droite à gauche | 49 | Le restylage des messages de Claude lui-même |
| cc-arcade (opens in a new tab) | Neuf jeux au-dessus du prompt, mis en pause quand Claude a terminé | 41 | L’animation avec une horloge de frames |
| jev-permission-gate (opens in a new tab) | Un modèle de décision Jev juge les appels d’outils en mode auto | 28 | Une section confidentialité soignée : il envoie vos trois derniers messages, jusqu’à 1 500 caractères chacun, à l’API de TypeSafe |
| prompt-rail (opens in a new tab) | Un rail de vos anciens prompts : survolez pour lire, cliquez pour y revenir | 22 | La pièce maîtresse de la revue japonaise de mods la plus appréciée sur Zenn |
| claude-paste-view (opens in a new tab) | Un aperçu des images collées et des longs textes collés | 18 | Un code court et lisible |
| claude-gfm-render (opens in a new tab) | Alertes GitHub, listes de tâches et Mermaid dans les réponses, en art ASCII ou en SVG | 14 | Un affichage différent selon la surface |
| claude_qamods (opens in a new tab) | qa-guide explique les questions et les options de Claude dans un panneau latéral | 10 | L’amélioration d’une boîte de dialogue intégrée |
| CC-Usage-Band (opens in a new tab) | Limites sur 5 heures et sur 7 jours, contexte et taux de succès du cache au-dessus du prompt | 10 | Le type de mod le plus courant : un compteur |
| harness-scope (opens in a new tab) | Des profils par dépôt qui masquent les skills, agents et règles globaux | 1 | L’auteur a mesuré une liste de skills passée de 98 entrées à 49 |
| touch-map (opens in a new tab) | Montre quels fichiers Claude a listés, lus, modifiés ou créés | 0 | Son auteur a constaté que Claude avait touché 125 fichiers sur 304 pendant une exploration avant refactoring |
| claude-mods-router (opens in a new tab) | Oriente chaque prompt vers un niveau d’effort avec $.model.classify | 0 | Son article sur Qiita (26 likes) note que changer de modèle casse le cache de prompt |
Anthropic publie aussi trois exemples dans claude-code-playground (opens in a new tab) : token-weather, blast-radius et replay-theater. Le code source des mods intégrés, dont /diff, se trouve dans le dépôt claude-code (opens in a new tab).
Les bonnes pratiques adoptées par la communauté
Pendant la première semaine, les auteurs japonais ont publié à eux seuls environ 50 articles avec des mods fonctionnels, des mesures et des retours d’échec. Voici les habitudes qui revenaient le plus souvent.
- Lisez un mod avant de l’installer. Clonez-le, lancez
claude plugin validateet lisez les ligneshooks:etcalls:. Lisez le code source partout où apparaissent$.process,$.http,$.fs.write,$.env.getou$.model. Relancez la validation après chaque mise à jour. Une validation réussie signifie que le moteur peut charger le code, pas que ce code est sûr. - Les garde-fous décident avant
nextet échouent en mode fermé. Les mods qui se contentent d’observer doivent échouer en mode ouvert avec.catch(($, e, next) => next(e)), pour qu’un bug dans un compteur ne bloque jamais votre travail. - Attendez à l’intérieur des appels
$. Un hook dispose de 10 secondes de temps propre. Un$.process.runou un$.ui.asken cours ne compte pas dans ce budget, mais vos propres promesses, si. - Ne stockez jamais
$et ne le déstructurez pas. Passez-le uniquement à des fonctions déclarées au niveau supérieur du fichier. Plusieurs auteurs avaient des mods qui échouaient au chargement sans aucun message, jusqu’à ce qu’ils corrigent ce point. - Attention au cache de prompt. Changer de modèle en cours de session, ou modifier le prompt système entre deux requêtes, invalide le cache.
- Adaptez le code selon
e.surface.Svgne s’affiche que dans l’application Desktop.RasteretImagene s’affichent que dans le terminal. - Figez une version pour un usage en équipe. L’API est en accès anticipé et change d’une version à l’autre. Cinq des six versions publiées après le lancement, de 2.1.288 à 2.1.293, ont modifié ou corrigé le comportement des mods.
Le masquage des secrets est le contre-exemple à retenir. Un auteur sur note.com a créé un mod qui remplaçait les clés API dans la sortie des outils avant que Claude ne les voie. Claude a tout de même affiché les valeurs brutes en déboguant une modification ratée avec od -c, et un Write sur le fichier entier a enregistré les valeurs de remplacement à la place des vraies clés. Seule une règle de permission deny sur le fichier a tenu. Un mod qui change ce qu’affiche l’écran ne cache rien au modèle.
Problèmes courants
| Symptôme | Cause probable | Solution |
|---|---|---|
/plugin ne liste pas le mod | Dossier non approuvé, --safe-mode, --bare ou disableAllHooks | Approuvez le dossier et redémarrez sans le flag |
hooks modules are turned off in this process | Anthropic a désactivé à distance les mods installés | Rien à changer en local. Mettez à jour, car 2.1.289 et 2.1.290 ont corrigé deux cas où les mods restaient désactivés |
validate échoue avec « expected record, received undefined » | Un ancien CLI placé plus tôt dans votre PATH | Lancez claude --version et mettez à jour |
| Un hook est ignoré sans erreur visible | Il a levé une exception, par exemple en appelant $.plugin.name(), qui est une propriété | Lancez claude --debug et lisez la ligne qui signale le hook ignoré |
| Un panneau ne s’ouvre jamais | Un panneau qui s’ouvre sans que vous le demandiez attend 144 colonnes, ne se place à côté de la conversation qu’en disposition plein écran, et /diff peut le recouvrir | Élargissez la fenêtre, essayez la disposition plein écran, fermez /diff |
| Ça fonctionne dans le terminal mais pas dans Desktop | Desktop embarque sa propre version, et certains éléments sont réservés au terminal | Vérifiez /status dans l’onglet Code et adaptez le code selon e.surface |
Aucune interface de mod dans VS Code ou claude -p | Ces surfaces n’affichent rien | Rabattez-vous sur une ligne dans la conversation ou sur le texte d’une commande |
| Un test échoue avec « nothing beneath the plugins answers » | Le kit de test n’a pas de moteur | Ajoutez des hooks de substitution, et répondez aux appels $ avec { value } |
Partager votre mod
Placez un marketplace.json à côté de plugin.json, dans .claude-plugin/ :
{
"name": "my-mods",
"owner": { "name": "you" },
"plugins": [{ "name": "safe-shell", "source": "./" }]
}Poussez le dossier sur GitHub. N’importe qui peut ensuite l’installer depuis une session du terminal :
/plugin install safe-shell --marketplace you/safe-shellDans l’application Desktop, passez par + puis Plugins puis Add plugin, dans les sessions locales et SSH. Si vous ajoutez le topic claude-code-mod au dépôt, le catalogue de la communauté le repère en général dans les quelques heures qui suivent votre prochain push.
FAQ
Guides liés
- Claude Code Desktop : activer le mode Bypass permissions
- Claude Code routines : triggers, cron jobs et automatisation d’agents IA
- Construire un agent IA type Claude Code avec Claude Agent SDK (TypeScript)
- Utiliser OpenCode : démarrage rapide, 7 conseils pratiques et quand ajouter Oh My OpenCode
- Guide d’utilisation de Codex : démarrage, 5 tips, et best practices