4 4
5# Creare un mod5# Creare un mod
6 6
7> Fai scrivere a Claude un mod di Claude Code da una descrizione, oppure scrivi tu stesso uno che conta le chiamate ai tool e aggiunge un comando. Impara il ciclo di ricaricamento e convalida.7> Chiedi a Claude di scrivere un mod di Claude Code a partire da una descrizione, oppure scrivine uno tu che conta le chiamate agli strumenti e aggiunge un comando. Impara il ciclo di ricaricamento e convalida.
8 8
9Un mod è un [plugin](/docs/it/plugins/overview) di Claude Code con un file di ingresso, chiamato modulo hooks: un file JavaScript o TypeScript le cui funzioni Claude Code chiama quando accadono eventi. Ci sono due modi per crearne uno:9Un mod è un [plugin](/docs/it/plugins/overview) di Claude Code con un file di ingresso, chiamato modulo degli hook: un file JavaScript o TypeScript le cui funzioni vengono chiamate da Claude Code quando si verificano degli eventi. Per crearne uno:
10 10
11* **Chiedi a Claude di scriverlo**: [descrivi quello che vuoi](#ask-claude-for-a-mod) in una sessione di Claude Code11* **Chiedi a Claude di scriverlo**: [descrivi ciò che vuoi](#ask-claude-for-a-mod) in una sessione di Claude Code
12* **Scrivilo tu stesso**: [segui il tutorial](#write-a-mod-yourself) 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 `.js` e `.ts` direttamente.12* **Scrivilo tu**: [segui il tutorial](#write-a-mod-yourself) per imparare come funziona il codice di un mod. Non ti servono Node.js, un bundler o un passaggio di build, perché Claude Code carica direttamente i file `.js` e `.ts`.
13 13
14Se non hai ancora deciso se un mod è lo strumento giusto, leggi prima il [confronto nella panoramica](/docs/it/plugins/mods/overview#compare-mods-settings-hooks-skills-and-mcp-servers).14Se non hai ancora deciso se un mod è lo strumento giusto, leggi prima il [confronto nella panoramica](/docs/it/plugins/mods/overview#compare-mods-settings-hooks-skills-and-mcp-servers).
15 15
16<Note>16<Note>
17 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](/docs/it/plugins/mods/troubleshoot#check-whether-mods-can-load).17 I mod richiedono Claude Code v2.1.287 o versioni successive. Nella tua shell, esegui `claude --version` per verificarlo. Per capire se i mod possono essere caricati nel tuo caso, consulta [Verificare se i mod possono essere caricati](/docs/it/plugins/mods/troubleshoot#check-whether-mods-can-load).
18</Note>18</Note>
19 19
20<h2 id="ask-claude-for-a-mod">20<h2 id="ask-claude-for-a-mod">
21 Chiedi a Claude un mod21 Chiedi a Claude un mod
22</h2>22</h2>
23 23
24Descrivi il mod che vuoi in una sessione interattiva di Claude Code, e Claude lo scrive. Claude lavora da una [skill](/docs/it/skills) integrata denominata `plugin-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.24Descrivi il mod che desideri in una sessione interattiva di Claude Code e Claude lo scrive. Claude lavora a partire da una [skill](/docs/it/skills) integrata chiamata `plugin-authoring`, che gli indica dove scrivere il mod, quali eventi e metodi ha la tua versione e come viene caricato il mod. Claude può caricare la skill quando chiedi un mod, oppure puoi caricarla tu stesso eseguendo `/plugin-authoring` nel prompt di Claude Code.
25 25
26Il mod viene eseguito una volta che lo approvi, tranne nelle [sessioni in cui un mod scritto da Claude non può caricarsi](#sessions-that-skip-the-approval).26Il mod viene eseguito una volta che lo approvi, tranne nelle [sessioni in cui un mod scritto da Claude non può essere caricato](#sessions-that-skip-the-approval).
27 27
28<Steps>28<Steps>
29 <Step title="Descrivi il mod">29 <Step title="Descrivi il mod">
30 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/`.30 Chiedi il mod con parole tue, ad esempio `make a mod that shows the current git branch above the prompt`. Claude scrive il mod in una propria directory all'interno della 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/`.
31 31
32 <Note>32 <Note>
33 Nelle [modalità di autorizzazione](/docs/it/permission-modes#protected-paths) `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.33 Nelle [modalità di permesso](/docs/it/permission-modes#protected-paths) `default` e `acceptEdits`, Claude Code chiede conferma prima che Claude crei ciascuno dei file del mod, perché `~/.claude` è un percorso protetto. Approva ogni file man mano che viene proposto.
34 </Note>34 </Note>
35 </Step>35 </Step>
36 36
37 <Step title="Approva il mod">37 <Step title="Approva il mod">
38 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.38 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 che Claude scrive in questa sessione e recepisce ogni modifica successiva.
39 39
40 Scegli una di queste risposte:40 Scegli una di queste risposte:
41 41
42 * **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.42 * **Enable for this session**: i mod nella cartella dei mod della sessione vengono caricati al termine del turno e ricaricati alla fine di ogni turno che li modifica. La tua risposta vale per tutta la sessione, anche dopo averla ripresa.
43 * **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.43 * **Not now**: per ora non viene caricato nulla. I file restano dove Claude li ha scritti e i mod vengono caricati al successivo avvio di quella sessione. Per impedire che un mod venga mai caricato, elimina la sua directory.
44 </Step>44 </Step>
45 45
46 <Step title="Verifica che il mod sia stato caricato">46 <Step title="Verifica che il mod sia stato caricato">
47 Esegui `/plugin` al prompt di Claude Code e premi Tab finché la scheda **Installed** non è selezionata. Elenca il mod e puoi disattivarlo lì.47 Esegui `/plugin` nel prompt di Claude Code e premi Tab finché non è selezionata la scheda **Installed**. Questa elenca il mod, e da lì puoi disattivarlo.
48 </Step>48 </Step>
49 49
50 <Step title="Prova il mod">50 <Step title="Prova il mod">
51 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.51 Usa ciò che hai chiesto. Per il prompt di esempio, il nome del branch corrente appare sopra la casella del prompt. Se il mod non fa ciò che volevi, di' a Claude cosa cambiare. Il mod si ricarica alla fine di ogni turno che ne modifica i file, quindi puoi provare la modifica non appena Claude termina.
52 </Step>52 </Step>
53</Steps>53</Steps>
54 54
55<h3 id="use-the-mod-in-other-sessions">55<h3 id="use-the-mod-in-other-sessions">
56 Usa il mod in altre sessioni56 Usare il mod in altre sessioni
57</h3>57</h3>
58 58
59Un 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 di [`cleanupPeriodDays`](/docs/it/settings-reference#cleanupperioddays). 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:59Un mod scritto da Claude viene caricato solo nella sessione che l'ha creato, e Claude Code elimina la cartella dei mod di quella sessione una volta che supera [`cleanupPeriodDays`](/docs/it/settings-reference#cleanupperioddays). Per conservare il mod, copia la sua directory fuori dalla cartella dei mod in una posizione tua, come `~/mods/git-branch`. Poi scegli come caricarlo:
60 60
61* **In una sessione che avvii**: nel tuo shell, esegui `claude --plugin-dir ~/mods/git-branch`61* **In una sessione che avvii tu**: nella tua shell, esegui `claude --plugin-dir ~/mods/git-branch`
62* **Per altre persone**: [aggiungilo a un marketplace](#share-your-mod) in modo che possano installarlo62* **Per altre persone**: [aggiungilo a un marketplace](#share-your-mod) in modo che possano installarlo
63 63
64<h3 id="sessions-that-skip-the-approval">64<h3 id="sessions-that-skip-the-approval">
65 Sessioni in cui un mod scritto da Claude non può caricarsi65 Sessioni in cui un mod scritto da Claude non può essere caricato
66</h3>66</h3>
67 67
68Un 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:68Un mod scritto da Claude viene caricato solo dopo che lo hai approvato, in un workspace attendibile in cui i mod possono essere eseguiti. In queste sessioni non viene caricato:
69 69
70* **Nessuno è lì per approvare**: la sessione non può mostrarti un prompt, come in un'esecuzione `claude -p` o in modalità [`dontAsk`](/docs/it/permission-modes)70* **Nessuno è presente per approvare**: la sessione non può mostrarti una richiesta di conferma, come in un'esecuzione `claude -p` o in [modalità `dontAsk`](/docs/it/permission-modes)
71* **Lo spazio di lavoro non è affidabile**: non hai accettato il prompt di fiducia per la directory71* **Il workspace non è attendibile**: non hai accettato la richiesta di attendibilità per la directory
72* **I mod sono fermati**: hai avviato con `--safe-mode` o `--bare`, hai impostato `disableAllHooks`, o le [impostazioni gestite](/docs/it/plugins/mods/admin#choose-how-much-to-allow) della tua organizzazione lo bloccano72* **I mod sono disabilitati**: hai avviato con `--safe-mode` o `--bare`, hai impostato `disableAllHooks`, oppure le [impostazioni gestite della tua organizzazione lo bloccano](/docs/it/plugins/mods/admin#choose-how-much-to-allow)
73 73
74<h2 id="write-a-mod-yourself">74<h2 id="write-a-mod-yourself">
75 Scrivi un mod tu stesso75 Scrivi un mod da solo
76</h2>76</h2>
77 77
78In questo tutorial costruisci un mod denominato `first-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.78In questo tutorial crei un mod chiamato `first-mod` che conta le chiamate agli strumenti effettuate da Claude, mostra il conteggio accanto allo spinner mentre Claude lavora e aggiunge un comando `/tally` che lo stampa. Poi leggi le dichiarazioni di tipo che Claude Code scrive accanto al tuo mod ed esegui `claude plugin validate`. Insieme ti mostrano gli eventi e i metodi offerti dalla tua versione e cosa Claude Code legge dal tuo codice.
79 79
80Questa 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:80Questa registrazione mostra il mod finito. Lo spinner conta le chiamate agli strumenti, `/tally` stampa il conteggio e una modifica al codice ha effetto mentre la sessione è in esecuzione:
81 81
82<Frame>82<Frame>
83 <video autoPlay muted loop playsInline controls className="w-full dark:hidden" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-light.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=eb561134afa90375777408453ba51c77" aria-label="In a Claude Code session, the prompt 'list the files here and read the README' is typed and sent. The spinner reads 'Thinking · tool calls: 1' and the count rises as Claude works. The /tally command prints 'first-mod: Claude has made 3 tool calls since this mod loaded'. A line says first-mod reloaded and lists its four hooks. On the next prompt the spinner reads 'Thinking · tools used: 1'." data-path="images/mods-first-mod-light.mp4" />83 <video autoPlay muted loop playsInline controls className="w-full dark:hidden" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-light.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=eb561134afa90375777408453ba51c77" aria-label="In una sessione di Claude Code, il prompt 'list the files here and read the README' viene digitato e inviato. Lo spinner mostra 'Thinking · tool calls: 1' e il conteggio aumenta mentre Claude lavora. Il comando /tally stampa 'first-mod: Claude has made 3 tool calls since this mod loaded'. Una riga indica che first-mod è stato ricaricato ed elenca i suoi quattro hook. Al prompt successivo lo spinner mostra 'Thinking · tools used: 1'." data-path="images/mods-first-mod-light.mp4" />
84 84
85 <video autoPlay muted loop playsInline controls className="w-full hidden dark:block" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-dark.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=09779dadc7ef66c2b1e2da0c2e31ac72" aria-label="In a Claude Code session, the prompt 'list the files here and read the README' is typed and sent. The spinner reads 'Thinking · tool calls: 1' and the count rises as Claude works. The /tally command prints 'first-mod: Claude has made 3 tool calls since this mod loaded'. A line says first-mod reloaded and lists its four hooks. On the next prompt the spinner reads 'Thinking · tools used: 1'." data-path="images/mods-first-mod-dark.mp4" />85 <video autoPlay muted loop playsInline controls className="w-full hidden dark:block" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-dark.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=09779dadc7ef66c2b1e2da0c2e31ac72" aria-label="In una sessione di Claude Code, il prompt 'list the files here and read the README' viene digitato e inviato. Lo spinner mostra 'Thinking · tool calls: 1' e il conteggio aumenta mentre Claude lavora. Il comando /tally stampa 'first-mod: Claude has made 3 tool calls since this mod loaded'. Una riga indica che first-mod è stato ricaricato ed elenca i suoi quattro hook. Al prompt successivo lo spinner mostra 'Thinking · tools used: 1'." data-path="images/mods-first-mod-dark.mp4" />
86</Frame>86</Frame>
87 87
88Scrivi tre file:88Scrivi tre file:
98 98
99* **`plugin.json`**: il [manifest](/docs/it/plugins/manifest-reference) del plugin99* **`plugin.json`**: il [manifest](/docs/it/plugins/manifest-reference) del plugin
100* **`hooks.json`**: [punta al tuo file di codice](/docs/it/plugins/mods/reference#files)100* **`hooks.json`**: [punta al tuo file di codice](/docs/it/plugins/mods/reference#files)
101* **`register.js`**: il tuo codice, chiamato modulo hooks101* **`register.js`**: il tuo codice, chiamato modulo degli hook
102 102
103<Steps>103<Steps>
104 <Step title="Crea la directory del plugin">104 <Step title="Crea la directory del plugin">
120 </Step>120 </Step>
121 121
122 <Step title="Scrivi il manifest">122 <Step title="Scrivi il manifest">
123 Un mod è un plugin e un mod ha bisogno di un [manifest](/docs/it/plugins/manifest-reference). Il manifest di questo mod non ha campi speciali. Salva questo come `first-mod/.claude-plugin/plugin.json`:123 Un mod è un plugin, e un mod ha bisogno di un [manifest](/docs/it/plugins/manifest-reference). Il manifest di questo mod non ha campi speciali. Salva questo come `first-mod/.claude-plugin/plugin.json`:
124 124
125 ```json first-mod/.claude-plugin/plugin.json theme={null}125 ```json first-mod/.claude-plugin/plugin.json theme={null}
126 {126 {
132 ```132 ```
133 </Step>133 </Step>
134 134
135 <Step title="Dì a Claude Code dove si trova il tuo codice">135 <Step title="Indica a Claude Code dove si trova il tuo codice">
136 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.136 Quando Claude Code carica un plugin, legge il file `hooks/hooks.json` del plugin. La chiave `modules` in quel file fornisce il percorso del tuo codice, ed è la sua presenza a rendere il plugin un mod. Elenca un percorso, relativo a `hooks.json`. Qui punta a `register.js`, che scrivi nel passaggio successivo.
137 137
138 Salva questo come `first-mod/hooks/hooks.json`:138 Salva questo come `first-mod/hooks/hooks.json`:
139 139
146 </Step>146 </Step>
147 147
148 <Step title="Scrivi il codice">148 <Step title="Scrivi il codice">
149 Questo file è il codice del mod, chiamato modulo hooks. Quando il mod si carica, Claude Code chiama la funzione `register` che il file esporta e le passa una funzione denominata [`on`](/docs/it/plugins/mods/reference#the-hook-function). Ogni chiamata a `on` registra un gestore di eventi, chiamato hook, per l'evento che nomina.149 Questo file è il codice del mod, chiamato modulo degli hook. Quando il mod viene caricato, Claude Code chiama la funzione `register` esportata dal file e le passa una funzione chiamata [`on`](/docs/it/plugins/mods/reference#the-hook-function). Ogni chiamata a `on` registra un gestore di eventi, chiamato hook, per l'evento che nomina.
150 150
151 Salva questo come `first-mod/hooks/register.js`:151 Salva questo come `first-mod/hooks/register.js`:
152 152
190 }190 }
191 ```191 ```
192 192
193 Il file mantiene un conteggio in `calls` e registra quattro hook:193 Il file tiene un conteggio in `calls` e registra quattro hook:
194 194
195 * **[`session.start`](/docs/it/plugins/mods/reference#session)** viene eseguito quando la sessione inizia, prima del tuo primo prompt, e di nuovo ogni volta che il mod si ricarica. Aggiunge il comando `/tally` a Claude Code.195 * **[`session.start`](/docs/it/plugins/mods/reference#session)** viene eseguito all'avvio della sessione, prima del tuo primo prompt, e di nuovo ogni volta che il mod viene ricaricato. Aggiunge il comando `/tally` a Claude Code.
196 * **[`tool.call`](/docs/it/plugins/mods/reference#tools)** viene eseguito ogni volta che Claude sta per usare un tool. Aggiunge uno a `calls` e chiede a Claude Code di disegnare di nuovo l'interfaccia.196 * **[`tool.call`](/docs/it/plugins/mods/reference#tools)** viene eseguito ogni volta che Claude sta per usare uno strumento. Aggiunge uno a `calls` e chiede a Claude Code di ridisegnare l'interfaccia.
197 * **[`command.run`](/docs/it/plugins/mods/reference#commands-and-configuration)** viene eseguito quando digiti `/tally`. Restituisce il testo da stampare.197 * **[`command.run`](/docs/it/plugins/mods/reference#commands-and-configuration)** viene eseguito quando digiti `/tally`. Restituisce il testo da stampare.
198 * **[`ui.render`](/docs/it/plugins/mods/reference#interface)** viene eseguito ogni volta che Claude Code disegna lo spinner. Aggiunge il conteggio dopo la parola dello spinner.198 * **[`ui.render`](/docs/it/plugins/mods/reference#interface)** viene eseguito ogni volta che Claude Code disegna lo spinner. Aggiunge il conteggio dopo la parola dello spinner.
199 199
200 [Come funziona il mod di esempio](#how-the-example-mod-works) spiega i tre argomenti che ogni hook accetta e cosa ciascuno restituisce.200 [Come funziona il mod di esempio](#how-the-example-mod-works) spiega i tre argomenti che ogni hook riceve e cosa restituisce ciascuno.
201 </Step>201 </Step>
202 202
203 <Step title="Carica il mod">203 <Step title="Carica il mod">
209 </Step>209 </Step>
210 210
211 <Step title="Prova il mod">211 <Step title="Prova il mod">
212 Chiedi a Claude di fare qualcosa che richieda alcuni tool call, come `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.212 Chiedi a Claude di fare qualcosa che richieda alcune chiamate agli strumenti, come `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 antepone il nome del plugin al testo del comando.
213 213
214 Per verificare il comando senza una sessione interattiva, eseguilo in modalità non interattiva:214 Per verificare il comando senza una sessione interattiva, eseguilo in modalità non interattiva:
215 215
221 first-mod: Claude has made 0 tool calls since this mod loaded221 first-mod: Claude has made 0 tool calls since this mod loaded
222 ```222 ```
223 223
224 Se `/tally` non è nell'elenco dei comandi, il modulo non è stato caricato. Vedi [Scopri perché un mod non fa nulla](/docs/it/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing).224 Se `/tally` non è nell'elenco dei comandi, il modulo non è stato caricato. Consulta [Scopri perché un mod non fa nulla](/docs/it/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing).
225 </Step>225 </Step>
226 226
227 <Step title="Cambia il codice mentre la sessione è in esecuzione">227 <Step title="Modifica il codice mentre la sessione è in esecuzione">
228 Lascia la sessione aperta. In `register.js`, cambia `' · tool calls: '` in `' · tools used: '` nell'hook `ui.render` e salva. La riga evidenziata è quella che cambia:228 Lascia aperta la sessione. In `register.js`, cambia `' · tool calls: '` in `' · tools used: '` nell'hook `ui.render` e salva. La riga evidenziata è quella che cambia:
229 229
230 ```javascript first-mod/hooks/register.js {4} theme={null}230 ```javascript first-mod/hooks/register.js {4} theme={null}
231 // Runs each time Claude Code draws the spinner231 // Runs each time Claude Code draws the spinner
235 })235 })
236 ```236 ```
237 237
238 Una riga nella trascrizione dice che `first-mod` si è ricaricato ed elenca i suoi hook, e lo spinner successivo usa il nuovo testo, come in `Thinking · tools used: 1…`.238 Una riga nella trascrizione indica che `first-mod` è stato ricaricato ed elenca i suoi hook, e lo spinner successivo usa il nuovo testo, come in `Thinking · tools used: 1…`.
239 </Step>239 </Step>
240</Steps>240</Steps>
241 241
243 Come funziona il mod di esempio243 Come funziona il mod di esempio
244</h3>244</h3>
245 245
246Ogni funzione che passi a `on` è un hook, che è un gestore di eventi. Claude Code passa a ogni hook gli stessi tre argomenti:246Ogni funzione che passi a `on` è un hook, ovvero un gestore di eventi. Claude Code passa a ogni hook gli stessi tre argomenti:
247 247
248* **L'API dei mod**, denominata `$`: ogni metodo che un mod può chiamare per raggiungere l'esterno, in [namespace](/docs/it/plugins/mods/reference#mods-api-methods) come `$.ui` e `$.command`248* **L'API dei mod**, chiamata `$`: ogni metodo che un mod può chiamare per raggiungere l'esterno, organizzato in [namespace](/docs/it/plugins/mods/reference#mods-api-methods) come `$.ui` e `$.command`
249* **L'evento**, denominato `e`: l'[input dell'evento](/docs/it/plugins/mods/reference#events) come dati semplici, come il nome e gli argomenti di una chiamata a un tool249* **L'evento**, chiamato `e`: l'[input dell'evento](/docs/it/plugins/mods/reference#events) come dati semplici, ad esempio il nome e gli argomenti di una chiamata a uno strumento
250* **Il gestore successivo**, denominato [`next`](/docs/it/plugins/mods/events#how-a-hook-handles-an-event): una funzione che passa l'evento agli altri mod e poi al comportamento proprio di Claude Code, e restituisce il risultato250* **Il gestore successivo**, chiamato [`next`](/docs/it/plugins/mods/events#how-a-hook-handles-an-event): una funzione che passa l'evento agli altri mod e poi al comportamento proprio di Claude Code, e restituisce il risultato
251 251
252Gli hook in `first-mod` gestiscono i loro eventi nei tre modi in cui un hook può:252Gli hook in `first-mod` gestiscono i loro eventi in questi modi:
253 253
254* **Osservare**: l'hook `session.start` registra il comando e l'hook `tool.call` conta la chiamata e chiede un ridisegno. Entrambi restituiscono `next(e)`, quindi la sessione inizia e il tool viene eseguito come al solito.254* **Osservare**: l'hook `session.start` registra il comando e l'hook `tool.call` conta la chiamata e richiede un ridisegno. Entrambi restituiscono `next(e)`, quindi la sessione si avvia e lo strumento viene eseguito come di consueto.
255* **Rispondere**: l'hook `command.run` restituisce il suo risultato e non chiama mai `next`. Il secondo argomento a `on`, `{ command: 'tally' }`, è un filtro, chiamato [matcher](/docs/it/plugins/mods/events#filter-which-events-a-hook-handles), quindi l'hook viene eseguito solo per `/tally`.255* **Rispondere**: l'hook `command.run` restituisce il proprio risultato e non chiama mai `next`. Il secondo argomento di `on`, `{ command: 'tally' }`, è un filtro, chiamato [matcher](/docs/it/plugins/mods/events#filter-which-events-a-hook-handles), quindi l'hook viene eseguito solo per `/tally`.
256* **Riscrivere**: l'hook `ui.render` chiama `next` con una copia di `e` il cui `suffix` contiene il conteggio, quindi Claude Code disegna il suo spinner usuale con il tuo testo dopo la parola256* **Riscrivere**: l'hook `ui.render` chiama `next` con una copia di `e` il cui `suffix` contiene il conteggio, così Claude Code disegna il suo consueto spinner con il tuo testo dopo la parola
257 257
258Claude Code osserva una directory caricata con `--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](/docs/it/plugins/mods/interface#keep-state).258Claude Code osserva una directory caricata con `--plugin-dir` e ricarica a caldo il modulo degli hook quando un file al suo interno cambia. Ogni ricaricamento esegue di nuovo `register`, quindi `calls` si azzera a `0` e `/tally` ricomincia a contare. Per mantenere un valore tra i ricaricamenti, consulta [Mantieni lo stato](/docs/it/plugins/mods/interface#keep-state).
259 259
260<h2 id="keep-working-on-a-mod">260<h2 id="keep-working-on-a-mod">
261 Continua a lavorare su un mod261 Continua a lavorare su un mod
262</h2>262</h2>
263 263
264Una 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.264Una volta caricato un mod, puoi chiedere a Claude di modificarlo, verificare il tuo codice rispetto alle definizioni dei tipi per la tua versione, elencare gli eventi e le chiamate che Claude Code vi trova e testarlo.
265 265
266<h3 id="change-a-mod-with-claude">266<h3 id="change-a-mod-with-claude">
267 Cambia un mod con Claude267 Modifica un mod con Claude
268</h3>268</h3>
269 269
270Per 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:270Per modificare un mod che hai già, avvia la sessione con `--plugin-dir` che punta alla directory del mod, in modo che ciò che Claude scrive venga caricato nella stessa sessione:
271 271
272```bash theme={null}272```bash theme={null}
273claude --plugin-dir ./first-mod273claude --plugin-dir ./first-mod
274```274```
275 275
276Quindi chiedi il cambiamento, ad esempio `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](/docs/it/permission-modes#protected-paths), 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.276Poi chiedi la modifica, ad esempio `add a /tally-reset command to this mod that sets the tally back to zero`. Claude modifica il modulo degli hook, esegue `claude plugin validate` e corregge ciò che viene segnalato. Una directory che carichi con `--plugin-dir` è un [percorso protetto](/docs/it/permission-modes#protected-paths), quindi nelle modalità `default` e `acceptEdits` ti viene chiesto di approvare ogni modifica di Claude al mod. La tabella dei percorsi protetti indica il risultato per le altre modalità di permesso.
277 277
278I file che Claude salva durante il suo turno si ricaricano quando il turno termina, quindi puoi provare `/tally-reset` non appena Claude finisce.278I file che Claude salva durante il suo turno vengono ricaricati al termine del turno, quindi puoi provare `/tally-reset` non appena Claude ha finito.
279 279
280<h3 id="get-the-types-for-your-build">280<h3 id="get-the-types-for-your-build">
281 Ottieni le definizioni di tipo per la tua versione281 Ottieni le definizioni dei tipi per la tua versione
282</h3>282</h3>
283 283
284Ogni 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](#ask-claude-for-a-mod), 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`](https://github.com/anthropics/claude-code/blob/main/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:284Ogni volta che Claude Code carica o ricarica un mod da una directory che passi a `--plugin-dir`, oppure un mod [che Claude ha scritto per te](#ask-claude-for-a-mod), scrive dei file di dichiarazione TypeScript, con estensione `.d.ts`, in `.claude-plugin/types/` all'interno della directory del mod. Questi descrivono esattamente gli eventi, i metodi dell'API dei mod e gli elementi presenti nella versione di Claude Code che stai eseguendo, così il tuo editor può completare automaticamente e verificare i tipi dei tuoi hook. Per consultare le dichiarazioni online, leggi [`mods/types/claude-code.d.ts`](https://github.com/anthropics/claude-code/blob/main/mods/types/claude-code.d.ts) nel repository di Claude Code, la cui prima riga indica la versione che lo ha scritto. La directory contiene questi file:
285 285
286| Percorso | Cosa dichiara |286| Percorso | Cosa dichiara |
287| :- | :- |287| :- | :- |
288| `claude-code/index.d.ts` | Ogni evento e il suo input e risultato, ogni namespace e metodo dell'API dei mod, e gli elementi che ogni superficie può disegnare |288| `claude-code/index.d.ts` | Ogni evento con il suo input e il suo risultato, ogni namespace e metodo dell'API dei mod e gli elementi che ogni superficie può disegnare |
289| `claude-code-tools/index.d.ts` | Gli input e i risultati dei tool integrati, in modo che il controllo `e.tool === 'Bash'` restringa `e` |289| `claude-code-tools/index.d.ts` | Gli input e i risultati degli strumenti integrati, in modo che la verifica `e.tool === 'Bash'` restringa il tipo di `e` |
290| `claude-code-mcp/index.d.ts` | Gli input dei tool MCP che erano connessi l'ultima volta che hai salvato un file nel mod |290| `claude-code-mcp/index.d.ts` | Gli input degli strumenti MCP che erano connessi l'ultima volta che hai salvato un file nel mod |
291| `index.d.ts` in una directory denominata per un plugin | Quello che quel plugin aggiunge all'API dei mod. C'è una directory per ogni plugin che il tuo `plugin.json` elenca sotto `dependencies`. |291| `index.d.ts` in una directory con il nome di un plugin | Ciò che quel plugin aggiunge all'API dei mod. C'è una directory per ogni plugin che il tuo `plugin.json` elenca in `dependencies`. |
292| `tsconfig.json` | Opzioni del compilatore che si adattano a un modulo hooks |292| `tsconfig.json` | Opzioni del compilatore adatte a un modulo degli hook |
293 293
294Se 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.294Se il tuo mod non ha un proprio `tsconfig.json`, Claude Code ne aggiunge uno nella radice del mod che estende quello generato, così il tuo editor e `tsc -p ./first-mod` verificano i tipi del mod senza ulteriore configurazione.
295 295
296Gli 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.296Gli eventi e i metodi possono cambiare da una release all'altra, quindi in caso di discrepanza fidati di questi file piuttosto che di qualsiasi pagina, inclusa questa.
297 297
298`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'`.298`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 nel file il suo nome, ad esempio `'tool.call'`.
299 299
300<h3 id="check-what-claude-code-reads-from-your-mod">300<h3 id="check-what-claude-code-reads-from-your-mod">
301 Verifica cosa Claude Code legge dal tuo mod301 Verifica cosa legge Claude Code dal tuo mod
302</h3>302</h3>
303 303
304Per vedere il tuo mod nel modo in cui Claude Code lo vede, senza eseguire il tuo codice o avviare una sessione, usa `claude 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:304Per vedere il tuo mod come lo vede Claude Code, senza eseguire il tuo codice né avviare una sessione, usa `claude plugin validate`. Il comando controlla il manifest ed esegue sul sorgente del modulo degli hook la stessa analisi statica che Claude Code esegue quando carica un mod. Nella tua shell, eseguilo sulla directory del mod:
305 305
306```bash theme={null}306```bash theme={null}
307claude plugin validate ./first-mod307claude plugin validate ./first-mod
316✔ Validation passed316✔ Validation passed
317```317```
318 318
319La riga `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`](/docs/it/plugins/mods/interface#keep-state) ottiene `state reads:` e `state writes:`.319La riga `hooks:` elenca gli eventi a cui il tuo modulo si 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 d'ambiente ottiene anche le righe `env reads:` e `env writes:`, e uno che usa [`$.state`](/docs/it/plugins/mods/interface#keep-state) ottiene `state reads:` e `state writes:`.
320 320
321Se 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`.321Se un evento che intendevi gestire manca dalla prima riga, nemmeno Claude Code chiamerà quell'hook. La causa più comune è un nome di evento scritto in modo errato, che il comando segnala con un errore come `"tool.calls" is not an event`.
322 322
323Segui queste regole in modo che l'analisi statica possa trovare ogni hook e chiamata:323Segui queste regole affinché l'analisi statica possa trovare ogni hook e ogni chiamata:
324 324
325* 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 denominata `loadNotes`, la riga `calls:` 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 funzioni `read` e `update` che [`$.state`](/docs/it/plugins/mods/interface#keep-state) usa 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 = $.ui` fallisce con `$.ui is used as a value`.325* Scrivi ogni chiamata all'API dei mod per intero: `$`, il namespace, poi il metodo, come in `$.store.get('notes')`. Puoi passare `$` a una funzione dichiarata al livello superiore dello stesso file e, per una tua funzione chiamata `loadNotes`, la riga `calls:` riporterà quindi `$.store.get (via loadNotes)`. Passare `$` a un metodo, a una funzione definita all'interno dell'hook o a una funzione che importi da un altro dei tuoi file non supera la validazione. Le funzioni `read` e `update` che [`$.state`](/docs/it/plugins/mods/interface#keep-state) usa sono gli import che possono riceverlo. Non assegnare `$` o uno dei suoi namespace a una variabile, non destrutturarlo e non indicizzarlo con un nome calcolato. `const ui = $.ui` fallisce con `$.ui is used as a value`.
326* Scrivi il nome dell'evento in ogni chiamata `on` come un letterale di stringa, come in `'tool.call'`. Una variabile, o un ciclo su un elenco di nomi, fallisce con `the event name passed to on() is not a string literal`.326* Scrivi il nome dell'evento in ogni chiamata `on` come stringa letterale, ad esempio `'tool.call'`. Una variabile, o un ciclo su un elenco di nomi, fallisce con `the event name passed to on() is not a string literal`.
327* Dentro `register`, non dichiarare una seconda variabile o parametro denominato `on`. La convalida fallisce con `"on" is declared again (shadowed)`.327* All'interno di `register`, non dichiarare una seconda variabile o un secondo parametro chiamato `on`. La validazione fallisce con `"on" is declared again (shadowed)`.
328* 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.328* Importa solo da file all'interno della directory del plugin, tramite percorso relativo. L'unico import senza percorso consentito è `claude-code`, per i tipi e alcune funzioni di supporto.
329* Usa dichiarazioni `import` in cima al file, come in `import { name } from './file.js'`. Un `import()` dinamico fallisce con `a dynamic import(); a hooks module imports its own files with an import declaration`.329* Usa dichiarazioni `import` all'inizio del file, come in `import { name } from './file.js'`. Un `import()` dinamico fallisce con `a dynamic import(); a hooks module imports its own files with an import declaration`.
330* Scrivi ogni file come un modulo ES, con `import` e non `require`. Il [riferimento](/docs/it/plugins/mods/reference#files) elenca le estensioni di file che Claude Code carica.330* Scrivi ogni file come modulo ES, con `import` e non `require`. Il [riferimento](/docs/it/plugins/mods/reference#files) elenca le estensioni di file che Claude Code carica.
331 331
332<h3 id="test-the-mod">332<h3 id="test-the-mod">
333 Testa il mod333 Testa il mod
334</h3>334</h3>
335 335
336Puoi scrivere test automatizzati per un mod ed eseguirli dal tuo shell con `claude plugin test`, senza sessione, accesso o rete. Un test solleva gli eventi che i tuoi hook gestiscono e verifica cosa hanno fatto gli hook.336Puoi scrivere test automatizzati per un mod ed eseguirli dalla tua shell con `claude plugin test`, senza sessione, accesso o rete. Un test attiva gli eventi gestiti dai tuoi hook e verifica cosa hanno fatto gli hook.
337 337
338Questo test solleva due tool call, esegue `/tally` e verifica che la risposta conti entrambi. Salvalo come `first-mod/tests/first-mod.test.ts`:338Questo test attiva due chiamate agli strumenti, esegue `/tally` e verifica che la risposta le conti entrambe. Salvalo come `first-mod/tests/first-mod.test.ts`:
339 339
340```typescript first-mod/tests/first-mod.test.ts theme={null}340```typescript first-mod/tests/first-mod.test.ts theme={null}
341import { expect, test } from 'claude-code/testing'341import { expect, test } from 'claude-code/testing'
344 // Answer each tool call in Claude Code's place, so no tool runs344 // Answer each tool call in Claude Code's place, so no tool runs
345 on('tool.call', () => ({ result: 'ok' }))345 on('tool.call', () => ({ result: 'ok' }))
346 346
347 // Raise two tool calls, which the mod's tool.call hook counts347 // Fire two tool calls, which the mod's tool.call hook counts
348 await $.tool.call({ tool: 'Bash', command: 'ls' })348 await $.tool.call({ tool: 'Bash', command: 'ls' })
349 await $.tool.call({ tool: 'Read', file_path: 'README.md' })349 await $.tool.call({ tool: 'Read', file_path: 'README.md' })
350 350
354})354})
355```355```
356 356
357Nel tuo shell, esegui i test dalla directory `first-mod`:357Nella tua shell, esegui i test dalla directory `first-mod`:
358 358
359```bash theme={null}359```bash theme={null}
360claude plugin test360claude plugin test
361```361```
362 362
363L'output nomina ogni test e se è passato, con tempi che variano da esecuzione a esecuzione:363L'output indica ogni test e se è stato superato, con tempi che variano da un'esecuzione all'altra:
364 364
365```text theme={null}365```text theme={null}
366tests/first-mod.test.ts:366tests/first-mod.test.ts:
371Ran 1 test across 1 file. [0.19s]371Ran 1 test across 1 file. [0.19s]
372```372```
373 373
374[Testa un mod](/docs/it/plugins/mods/test) copre lo stub di una chiamata a un modello o dello store, e il test di timer e disegni.374[Testa un mod](/docs/it/plugins/mods/test) spiega come simulare una chiamata al modello o lo store e come testare timer e disegni.
375 375
376<h2 id="share-your-mod">376<h2 id="share-your-mod">
377 Condividi il tuo mod377 Condividi il tuo mod
378</h2>378</h2>
379 379
380Un 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](/docs/it/plugins/publish).380Un mod è un plugin, quindi ne gestisci la versione nel manifest e le persone lo installano e lo aggiornano con i comandi `/plugin`. Per renderlo disponibile ad altre persone, [aggiungilo a un marketplace](/docs/it/plugins/publish).
381 381
382Prima di farlo, controlla il `name` del plugin: `claude plugin validate` fallisce un nome che [sembra uno dei propri di Anthropic](/docs/it/plugins/manifest-reference#name), 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.382Prima di farlo, controlla il `name` del plugin: `claude plugin validate` rifiuta un nome che [sembra uno di quelli di Anthropic](/docs/it/plugins/manifest-reference#name), come uno che inizia con `claude-`. Gli eventi e i metodi possono cambiare tra una release e l'altra, quindi il tuo README è il posto giusto per indicare con quale versione di Claude Code l'hai testato.
383 383
384Continua 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.384Continua a sviluppare sulla directory con `--plugin-dir`, non su una copia installata. Claude Code memorizza nella cache un plugin installato in base alla versione, quindi le tue modifiche non raggiungono la copia installata finché non incrementi la versione e lo installi di nuovo.
385 385
386<h2 id="next-steps">386<h2 id="next-steps">
387 Prossimi passi387 Passaggi successivi
388</h2>388</h2>
389 389
390* [Disegna nell'interfaccia](/docs/it/plugins/mods/interface): apri un riquadro, disegna sopra il prompt e aggiungi pulsanti e campi di testo390* [Disegna nell'interfaccia](/docs/it/plugins/mods/interface): apri un riquadro, disegna sopra il prompt e aggiungi pulsanti e campi di testo
391* [Reagisci agli eventi](/docs/it/plugins/mods/events): aggancia le chiamate ai tool, i prompt e i turni391* [Reagisci agli eventi](/docs/it/plugins/mods/events): intercetta le chiamate agli strumenti, i prompt e i turni
392* [Usa l'API dei mod](/docs/it/plugins/mods/api): aggiungi comandi e tool, chiama un modello ed esegui lavoro su un timer392* [Usa l'API dei mod](/docs/it/plugins/mods/api): aggiungi comandi e strumenti, chiama un modello ed esegui operazioni a intervalli regolari
393* [Testa un mod](/docs/it/plugins/mods/test): stub quello che Claude Code risponderebbe, e testa timer e disegni393* [Testa un mod](/docs/it/plugins/mods/test): simula le risposte di Claude Code e testa timer e disegni
394* [Risolvi i problemi di un mod](/docs/it/plugins/mods/troubleshoot): i motivi per cui un mod non fa nulla e il log di debug394* [Risolvi i problemi di un mod](/docs/it/plugins/mods/troubleshoot): i motivi per cui un mod non fa nulla e il log di debug
395* [Leggi il sorgente dei mod integrati](/docs/it/plugins/mods/overview#read-the-source-of-built-in-mods): plugin completi, ciascuno con il suo modulo hooks e test395* [Leggi il codice sorgente dei mod integrati](/docs/it/plugins/mods/overview#read-the-source-of-built-in-mods): plugin completi, ciascuno con il proprio modulo degli hook e i propri test