- Chiedi a Claude di scriverlo: descrivi quello che vuoi in una sessione di Claude Code
- Scrivilo tu stesso: segui il tutorial per imparare come funziona il codice di un mod. Non hai bisogno di Node.js, di un bundler o di un passo di build, perché Claude Code carica i file
.jse.tsdirettamente.
I mod richiedono Claude Code v2.1.287 o successivo. Nel tuo shell, esegui
claude --version per verificare. Per vedere se i mod possono caricarsi per te, vedi Verificare se i mod possono caricarsi.Chiedi a Claude un mod
Descrivi il mod che vuoi in una sessione interattiva di Claude Code, e Claude lo scrive. Claude lavora da una skill integrata denominataplugin-authoring, che gli dice dove scrivere il mod, quali eventi e metodi ha la tua versione e come il mod viene caricato. Claude può caricare la skill quando chiedi un mod, oppure puoi caricarla tu stesso eseguendo /plugin-authoring al prompt di Claude Code.
Il mod viene eseguito una volta che lo approvi, tranne nelle sessioni in cui un mod scritto da Claude non può caricarsi.
1
Descrivi il mod
Chiedi il mod con le tue parole, ad esempio
make a mod that shows the current git branch above the prompt. Claude scrive il mod in una directory propria nella cartella dei mod della sessione, che è ~/.claude/dev-mods/ seguita dall’ID della sessione. Il percorso completo di un mod è simile a ~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/.Nelle modalità di autorizzazione
default e acceptEdits, Claude Code chiede prima che Claude crei ciascuno dei file del mod, perché ~/.claude è un percorso protetto. Approva ogni file quando appare.2
Approva il mod
Quando Claude salva il primo file, Claude Code chiede se abilitare il ricaricamento a caldo per la sessione. Il ricaricamento a caldo esegue i mod scritti da Claude in questa sessione e raccoglie ogni modifica successiva.Scegli una di queste risposte:
- Abilita per questa sessione: i mod nella cartella dei mod della sessione si caricano quando il turno termina e si ricaricano alla fine di ogni turno che li modifica. La tua risposta dura per la sessione, anche dopo averla ripresa.
- Non ora: nulla si carica per ora. I file rimangono dove Claude li ha scritti e i mod si caricano la prossima volta che quella sessione inizia. Per impedire che un mod si carichi mai, elimina la sua directory.
3
Verifica che il mod sia stato caricato
Esegui
/plugin al prompt di Claude Code e premi Tab finché la scheda Installed non è selezionata. Elenca il mod e puoi disattivarlo lì.4
Prova il mod
Usa quello che hai chiesto. Per il prompt di esempio, il nome del ramo corrente appare sopra la casella del prompt. Se il mod non fa quello che volevi, dì a Claude cosa cambiare. Il mod si ricarica alla fine di ogni turno che modifica i suoi file, quindi puoi provare la modifica non appena Claude finisce.
Usa il mod in altre sessioni
Un mod scritto da Claude si carica solo nella sessione che lo ha creato, e Claude Code elimina la cartella dei mod di quella sessione una volta che è più vecchia dicleanupPeriodDays. Per mantenere il mod, copia la sua directory fuori dalla cartella dei mod in un posto tuo, come ~/mods/git-branch. Quindi scegli come caricarlo:
- In una sessione che avvii: nel tuo shell, esegui
claude --plugin-dir ~/mods/git-branch - Per altre persone: aggiungilo a un marketplace in modo che possano installarlo
Sessioni in cui un mod scritto da Claude non può caricarsi
Un mod scritto da Claude si carica solo dopo che lo approvi, in uno spazio di lavoro affidabile dove i mod possono essere eseguiti. In queste sessioni non si carica:- Nessuno è lì per approvare: la sessione non può mostrarti un prompt, come in un’esecuzione
claude -po in modalitàdontAsk - Lo spazio di lavoro non è affidabile: non hai accettato il prompt di fiducia per la directory
- I mod sono fermati: hai avviato con
--safe-modeo--bare, hai impostatodisableAllHooks, o le impostazioni gestite della tua organizzazione lo bloccano
Scrivi un mod tu stesso
In questo tutorial costruisci un mod denominatofirst-mod che conta le chiamate ai tool che Claude fa, mostra il conteggio accanto al spinner mentre Claude lavora e aggiunge un comando /tally che lo stampa. Quindi leggi le dichiarazioni di tipo che Claude Code scrive accanto al tuo mod ed esegui claude plugin validate. Insieme mostrano gli eventi e i metodi che la tua versione offre e cosa Claude Code legge dal tuo codice.
Questa registrazione mostra il mod finito. Lo spinner conta le chiamate ai tool, /tally stampa il conteggio e una modifica al codice ha effetto mentre la sessione è in esecuzione:
plugin.json: il manifest del pluginhooks.json: punta al tuo file di codiceregister.js: il tuo codice, chiamato modulo hooks
1
Crea la directory del plugin
Crea le due directory che contengono i file:
- Bash o Zsh
- PowerShell
2
Scrivi il manifest
Un mod è un plugin e un mod ha bisogno di un manifest. Il manifest di questo mod non ha campi speciali. Salva questo come
first-mod/.claude-plugin/plugin.json:first-mod/.claude-plugin/plugin.json
3
Dì a Claude Code dove si trova il tuo codice
Quando Claude Code carica un plugin, legge il
hooks/hooks.json del plugin. La chiave modules in quel file fornisce il percorso al tuo codice, e averlo è quello che rende il plugin un mod. Elenca un percorso, relativo a hooks.json. Qui punta a register.js, che scrivi nel passo successivo.Salva questo come first-mod/hooks/hooks.json:first-mod/hooks/hooks.json
4
Scrivi il codice
Questo file è il codice del mod, chiamato modulo hooks. Quando il mod si carica, Claude Code chiama la funzione Il file mantiene un conteggio in
register che il file esporta e le passa una funzione denominata on. Ogni chiamata a on registra un gestore di eventi, chiamato hook, per l’evento che nomina.Salva questo come first-mod/hooks/register.js:first-mod/hooks/register.js
calls e registra quattro hook:session.startviene eseguito quando la sessione inizia, prima del tuo primo prompt, e di nuovo ogni volta che il mod si ricarica. Aggiunge il comando/tallya Claude Code.tool.callviene eseguito ogni volta che Claude sta per usare un tool. Aggiunge uno acallse chiede a Claude Code di disegnare di nuovo l’interfaccia.command.runviene eseguito quando digiti/tally. Restituisce il testo da stampare.ui.renderviene eseguito ogni volta che Claude Code disegna lo spinner. Aggiunge il conteggio dopo la parola dello spinner.
5
Carica il mod
Avvia Claude Code con il flag
--plugin-dir, che carica una directory di plugin per una sessione senza installarla:6
Prova il mod
Chiedi a Claude di fare qualcosa che richieda alcuni tool call, come Se
list the files here and read the README. Mentre Claude lavora, la parola dello spinner è seguita da un conteggio che aumenta, come in Thinking · tool calls: 2…. Quando Claude finisce, digita /tally e premi Invio. La trascrizione mostra first-mod: Claude has made 2 tool calls since this mod loaded, con il tuo conteggio. Claude Code mette il nome del plugin davanti al testo del comando.Per verificare il comando senza una sessione interattiva, eseguilo in modalità non interattiva:/tally non è nell’elenco dei comandi, il modulo non è stato caricato. Vedi Scopri perché un mod non fa nulla.7
Cambia il codice mentre la sessione è in esecuzione
Lascia la sessione aperta. In Una riga nella trascrizione dice che
register.js, cambia ' · tool calls: ' in ' · tools used: ' nell’hook ui.render e salva. La riga evidenziata è quella che cambia:first-mod/hooks/register.js
first-mod si è ricaricato ed elenca i suoi hook, e lo spinner successivo usa il nuovo testo, come in Thinking · tools used: 1….Come funziona il mod di esempio
Ogni funzione che passi aon è un hook, che è un gestore di eventi. Claude Code passa a ogni hook gli stessi tre argomenti:
- L’API dei mod, denominata
$: ogni metodo che un mod può chiamare per raggiungere l’esterno, in namespace come$.uie$.command - L’evento, denominato
e: l’input dell’evento come dati semplici, come il nome e gli argomenti di una chiamata a un tool - Il gestore successivo, denominato
next: una funzione che passa l’evento agli altri mod e poi al comportamento proprio di Claude Code, e restituisce il risultato
first-mod gestiscono i loro eventi nei tre modi in cui un hook può:
- Osservare: l’hook
session.startregistra il comando e l’hooktool.callconta la chiamata e chiede un ridisegno. Entrambi restituiscononext(e), quindi la sessione inizia e il tool viene eseguito come al solito. - Rispondere: l’hook
command.runrestituisce il suo risultato e non chiama mainext. Il secondo argomento aon,{ command: 'tally' }, è un filtro, chiamato matcher, quindi l’hook viene eseguito solo per/tally. - Riscrivere: l’hook
ui.renderchiamanextcon una copia dieil cuisuffixcontiene il conteggio, quindi Claude Code disegna il suo spinner usuale con il tuo testo dopo la parola
--plugin-dir e ricarica a caldo il modulo hooks quando un file in essa cambia. Ogni ricaricamento esegue di nuovo register, quindi calls torna a 0 e /tally inizia a contare di nuovo. Per mantenere un valore tra i ricaricamenti, vedi Mantieni lo stato.
Continua a lavorare su un mod
Una volta che un mod si carica, puoi far cambiare a Claude il mod, verificare il tuo codice rispetto alle definizioni di tipo per la tua versione, elencare gli eventi e le chiamate che Claude Code trova in esso e testarlo.Cambia un mod con Claude
Per cambiare un mod che hai già, avvia la sessione con--plugin-dir puntato alla directory del mod, in modo che quello che Claude scrive si carichi nella stessa sessione:
add a /tally-reset command to this mod that sets the tally back to zero. Claude modifica il modulo hooks, esegue claude plugin validate e corregge quello che segnala. Una directory che carichi con --plugin-dir è un percorso protetto, quindi nelle modalità default e acceptEdits ti viene chiesto di approvare ogni modifica di Claude al mod. La tabella dei percorsi protetti fornisce il risultato per le altre modalità di autorizzazione.
I file che Claude salva durante il suo turno si ricaricano quando il turno termina, quindi puoi provare /tally-reset non appena Claude finisce.
Ottieni le definizioni di tipo per la tua versione
Ogni volta che Claude Code carica o ricarica un mod da una directory che passi a--plugin-dir, o un mod scritto da Claude per te, scrive file di dichiarazione TypeScript, che terminano in .d.ts, in .claude-plugin/types/ dentro la directory del mod. Descrivono gli eventi esatti, i metodi dell’API dei mod e gli elementi nelle superfici della versione di Claude Code che stai eseguendo, quindi il tuo editor può completare automaticamente e controllare il tipo dei tuoi hook. Per sfogliare le dichiarazioni online, leggi mods/types/claude-code.d.ts nel repository di Claude Code, la cui prima riga nomina la versione che l’ha scritto. La directory contiene questi file:
Se il tuo mod non ha un suo
tsconfig.json, Claude Code ne aggiunge uno alla radice del mod che estende quello generato, quindi il tuo editor e tsc -p ./first-mod controllano il tipo del mod senza ulteriore configurazione.
Gli eventi e i metodi possono cambiare tra le versioni, quindi affidati a questi file rispetto a qualsiasi pagina, inclusa questa, quando non sono d’accordo.
claude-code/index.d.ts è il riferimento più completo per la tua build, con un commento e un esempio per ogni metodo dell’API dei mod. Per cercare qualcosa, cerca il file per il suo nome, come 'tool.call'.
Verifica cosa Claude Code legge dal tuo mod
Per vedere il tuo mod nel modo in cui Claude Code lo vede, senza eseguire il tuo codice o avviare una sessione, usaclaude plugin validate. Controlla il manifest ed esegue la stessa analisi statica sul sorgente del modulo hooks che Claude Code esegue quando carica un mod. Nel tuo shell, eseguilo sulla directory del mod:
first-mod, l’output include queste righe.
hooks: elenca gli eventi che il tuo modulo aggancia, ciascuno con il suo filtro tra parentesi graffe. La riga calls: elenca ogni metodo dell’API dei mod che chiama. Un modulo che legge o imposta variabili di ambiente ottiene anche righe env reads: e env writes:, e uno che usa $.state ottiene state reads: e state writes:.
Se un evento che intendevi agganciare manca dalla prima riga, Claude Code non chiamerà nemmeno quell’hook. La causa usuale è un nome di evento scritto male, che il comando segnala come un errore come "tool.calls" is not an event.
Segui queste regole in modo che l’analisi statica possa trovare ogni hook e chiamata:
- Scrivi ogni chiamata all’API dei mod per intero:
$, il namespace, quindi il metodo, come in$.store.get('notes'). Puoi passare$a una funzione dichiarata al livello superiore dello stesso file, e per una tua funzione denominataloadNotes, la rigacalls:legge quindi$.store.get (via loadNotes). Passare$a un metodo, una funzione definita dentro l’hook, o una funzione che importi da un altro dei tuoi file non supera la convalida. Le funzionireadeupdateche$.stateusa sono le importazioni che possono prenderlo. Non assegnare$o uno dei suoi namespace a una variabile, destrutturarlo o indicizzarlo con un nome calcolato.const ui = $.uifallisce con$.ui is used as a value. - Scrivi il nome dell’evento in ogni chiamata
oncome un letterale di stringa, come in'tool.call'. Una variabile, o un ciclo su un elenco di nomi, fallisce conthe event name passed to on() is not a string literal. - Dentro
register, non dichiarare una seconda variabile o parametro denominatoon. La convalida fallisce con"on" is declared again (shadowed). - Importa solo da file dentro la directory del plugin, per percorso relativo. L’unica importazione nuda consentita è
claude-code, per i tipi e alcuni helper. - Usa dichiarazioni
importin cima al file, come inimport { name } from './file.js'. Unimport()dinamico fallisce cona dynamic import(); a hooks module imports its own files with an import declaration. - Scrivi ogni file come un modulo ES, con
importe nonrequire. Il riferimento elenca le estensioni di file che Claude Code carica.
Testa il mod
Puoi scrivere test automatizzati per un mod ed eseguirli dal tuo shell conclaude plugin test, senza sessione, accesso o rete. Un test solleva gli eventi che i tuoi hook gestiscono e verifica cosa hanno fatto gli hook.
Questo test solleva due tool call, esegue /tally e verifica che la risposta conti entrambi. Salvalo come first-mod/tests/first-mod.test.ts:
first-mod/tests/first-mod.test.ts
first-mod:
Condividi il tuo mod
Un mod è un plugin, quindi lo versioni nel manifest e le persone lo installano e aggiornano con i comandi/plugin. Per darlo ad altre persone, aggiungilo a un marketplace.
Prima di farlo, controlla il name del plugin: claude plugin validate fallisce un nome che sembra uno dei propri di Anthropic, come uno che inizia con claude-. Gli eventi e i metodi possono cambiare tra le versioni, quindi il tuo README è il posto per dire quale versione di Claude Code hai testato.
Continua a sviluppare rispetto alla directory con --plugin-dir, non rispetto a una copia installata. Claude Code memorizza nella cache un plugin installato per versione, quindi le tue modifiche non raggiungono la copia installata finché non aumenti la versione e installi di nuovo.
Prossimi passi
- Disegna nell’interfaccia: apri un riquadro, disegna sopra il prompt e aggiungi pulsanti e campi di testo
- Reagisci agli eventi: aggancia le chiamate ai tool, i prompt e i turni
- Usa l’API dei mod: aggiungi comandi e tool, chiama un modello ed esegui lavoro su un timer
- Testa un mod: stub quello che Claude Code risponderebbe, e testa timer e disegni
- Risolvi i problemi di un mod: i motivi per cui un mod non fa nulla e il log di debug
- Leggi il sorgente dei mod integrati: plugin completi, ciascuno con il suo modulo hooks e test