4 4
5# Reagire agli eventi con un mod5# Reagire agli eventi con un mod
6 6
7> Gestire gli eventi di Claude Code da un mod: osservare, riscrivere o rispondere alle chiamate di strumenti, ai prompt e ai turni, filtrare quali eventi un hook gestisce e pianificare per altri mod.7> Gestisci gli eventi di Claude Code da un mod: osserva, riscrivi o rispondi a chiamate agli strumenti, prompt e turni, filtra quali eventi gestisce un hook e pianifica in vista di altri mod.
8 8
9Un hook è un gestore di eventi: una funzione che Claude Code esegue quando si verifica un evento denominato. Claude Code genera un evento in ogni punto in cui sta per agire, ad esempio quando esegue uno strumento, invia un prompt, invia una richiesta al modello o avvia o termina una sessione. Il vostro hook viene eseguito prima che Claude Code agisca, quindi può osservare l'evento, riscriverlo o rispondere al suo posto. Registrate un hook con [`on(eventName, handler)`](/docs/it/plugins/mods/reference#the-hook-function).9Un hook è un gestore di eventi: una funzione che Claude Code esegue quando si verifica un evento con un determinato nome. Claude Code genera un evento in ogni punto in cui sta per agire, ad esempio quando esegue uno strumento, invia un prompt, invia una richiesta al modello oppure avvia o termina una sessione. Il tuo hook viene eseguito prima che Claude Code agisca, quindi può osservare l'evento, riscriverlo o rispondere al posto di Claude Code. Registri un hook con [`on(eventName, handler)`](/docs/it/plugins/mods/reference#the-hook-function).
10 10
11Costruite il vostro [primo mod](/docs/it/plugins/mods/create) prima di iniziare qui. Per ogni evento e i suoi campi esatti, consultate il [riferimento](/docs/it/plugins/mods/reference#events) o leggete [i tipi per la vostra build](/docs/it/plugins/mods/create#get-the-types-for-your-build).11Crea il tuo [primo mod](/docs/it/plugins/mods/create) prima di iniziare da qui. Per ogni evento e i relativi campi esatti, consulta il [riferimento](/docs/it/plugins/mods/reference#events) oppure leggi [i tipi per la tua build](/docs/it/plugins/mods/create#get-the-types-for-your-build).
12 12
13<h2 id="how-a-hook-handles-an-event">13<h2 id="how-a-hook-handles-an-event">
14 Come un hook gestisce un evento14 Come un hook gestisce un evento
15</h2>15</h2>
16 16
17Un hook si trova tra un evento e ciò che Claude Code farebbe al riguardo, quindi può osservare l'evento, riscriverlo o rispondere da solo. Riceve tre argomenti: l'[API dei mods](/docs/it/plugins/mods/api) come `$`, l'evento come `e` e il gestore successivo come `next`. I gestori di un evento formano una catena middleware. `next(e)` chiama il gestore successivo, che è un hook di un altro mod o, alla fine della catena, il comportamento proprio di Claude Code, e si risolve nel risultato. Ciò che il vostro hook fa con `next` decide quale dei tre fa.17Un hook si colloca tra un evento e ciò che Claude Code farebbe in risposta, quindi può osservare l'evento, riscriverlo o rispondere direttamente. Riceve tre argomenti: l'[API dei mod](/docs/it/plugins/mods/api) come `$`, l'evento come `e` e il gestore successivo come `next`. I gestori di un evento formano una catena middleware. `next(e)` chiama il gestore successivo, che è l'hook di un altro mod oppure, alla fine della catena, il comportamento nativo di Claude Code, e si risolve nel risultato. Ciò che il tuo hook fa con `next` determina quale delle tre azioni compie.
18 18
19<h3 id="observe-an-event">19<h3 id="observe-an-event">
20 Osservare un evento20 Osservare un evento
21</h3>21</h3>
22 22
23Per osservare un evento senza modificarlo, fate il vostro lavoro e restituite `next(e)`. Questo hook registra ogni strumento che Claude sta per utilizzare:23Per osservare un evento senza modificarlo, esegui il tuo lavoro e restituisci `next(e)`. Questo hook registra nel log ogni strumento che Claude sta per usare:
24 24
25```javascript theme={null}25```javascript theme={null}
26on('tool.call', async ($, e, next) => {26on('tool.call', async ($, e, next) => {
27 // Viene eseguito prima che lo strumento venga eseguito27 // Runs before the tool does
28 $.ui.log('Claude is about to use ' + e.tool)28 $.ui.log('Claude is about to use ' + e.tool)
29 // Passa l'evento invariato29 // Pass the event on unchanged
30 return next(e)30 return next(e)
31})31})
32```32```
33 33
34Prima di ogni esecuzione dello strumento, una riga attenuata come `● my-mod: Claude is about to use Bash` appare nella trascrizione, dove `my-mod` è il nome del vostro plugin. Lo strumento viene eseguito come farebbe senza il mod.34Prima dell'esecuzione di ogni strumento, nella trascrizione compare una riga attenuata come `● my-mod: Claude is about to use Bash`, dove `my-mod` è il nome del tuo plugin. Lo strumento viene eseguito come farebbe senza il mod.
35 35
36Per agire dopo l'evento, `await next(e)`, fate il vostro lavoro e restituite il risultato. Questo hook registra ogni strumento dopo che è stato eseguito:36Per agire dopo l'evento, esegui `await next(e)`, svolgi il tuo lavoro e restituisci il risultato. Questo hook registra nel log ogni strumento dopo la sua esecuzione:
37 37
38```javascript theme={null}38```javascript theme={null}
39on('tool.call', async ($, e, next) => {39on('tool.call', async ($, e, next) => {
40 // Lascia che lo strumento venga eseguito e attendi il suo risultato40 // Let the tool run, and wait for its result
41 const result = await next(e)41 const result = await next(e)
42 // Viene eseguito dopo che lo strumento è stato eseguito42 // Runs after the tool does
43 $.ui.log(e.tool + ' finished')43 $.ui.log(e.tool + ' finished')
44 // Restituisci il risultato invariato44 // Give the result back unchanged
45 return result45 return result
46})46})
47```47```
48 48
49La riga ora appare dopo che ogni strumento termina. Claude legge lo stesso risultato in entrambi i casi, perché l'hook restituisce ciò a cui `next(e)` si è risolto.49Ora la riga compare dopo il termine di ogni strumento. Claude legge lo stesso risultato in entrambi i casi, perché l'hook restituisce ciò in cui si è risolto `next(e)`.
50 50
51<h3 id="rewrite-an-event">51<h3 id="rewrite-an-event">
52 Riscrivere un evento52 Riscrivere un evento
53</h3>53</h3>
54 54
55Per modificare ciò su cui Claude Code agisce, ad esempio il testo di un prompt, chiamate `next` con una copia modificata dell'evento. L'evento stesso è immutabile: è congelato a ogni profondità e l'assegnazione a un campo genera un errore. Questo hook taglia ogni prompt prima che venga inviato:55Per cambiare ciò su cui Claude Code agisce, come il testo di un prompt, chiama `next` con una copia modificata dell'evento. L'evento stesso è immutabile: è congelato in profondità e l'assegnazione a un campo genera un'eccezione. Questo hook rimuove gli spazi iniziali e finali da ogni prompt prima che venga inviato:
56 56
57```javascript theme={null}57```javascript theme={null}
58on('prompt.submit', async ($, e, next) => {58on('prompt.submit', async ($, e, next) => {
59 // Passa una copia dell'evento con il suo testo modificato59 // Pass on a copy of the event with its text changed
60 return next({ ...e, text: e.text.trim() })60 return next({ ...e, text: e.text.trim() })
61})61})
62```62```
63 63
64I gestori successivi e Claude Code ricevono il prompt tagliato e non vedono mai l'originale. Potete anche modificare il risultato: `await next(e)`, quindi restituite una copia del risultato con un campo sostituito.64I gestori successivi e Claude Code ricevono il prompt ripulito e non vedono mai l'originale. Puoi anche modificare il risultato: esegui `await next(e)`, poi restituisci una copia del risultato con un campo sostituito.
65 65
66<h3 id="answer-an-event">66<h3 id="answer-an-event">
67 Rispondere a un evento67 Rispondere a un evento
68</h3>68</h3>
69 69
70Per gestire un evento da soli, restituite un risultato senza chiamare `next`. Questo cortocircuita la catena, quindi i mod successivi e il comportamento proprio di Claude Code non vengono eseguiti. Questo hook rifiuta ogni comando Bash:70Per gestire tu stesso un evento, restituisci un risultato senza chiamare `next`. In questo modo interrompi la catena, quindi i mod successivi e il comportamento nativo di Claude Code non vengono eseguiti. Questo hook rifiuta ogni comando Bash:
71 71
72```javascript theme={null}72```javascript theme={null}
73on('tool.call', { tool: 'Bash' }, async () => {73on('tool.call', { tool: 'Bash' }, async () => {
74 // Nessuna chiamata a next, quindi il comando non viene mai eseguito74 // No call to next, so the command never runs
75 return { deny: 'Bash is turned off in this project. Use the file tools.' }75 return { deny: 'Bash is turned off in this project. Use the file tools.' }
76})76})
77```77```
78 78
79Quando Claude prova un comando Bash, il comando non viene eseguito e Claude legge il testo `deny` come risultato dello strumento. Ogni evento ha la sua forma di risultato, che il [riferimento degli eventi](/docs/it/plugins/mods/reference#events) elenca.79Quando Claude prova un comando Bash, il comando non viene eseguito e Claude legge il testo di `deny` come risultato dello strumento. Ogni evento ha una propria forma del risultato, elencata nel [riferimento degli eventi](/docs/it/plugins/mods/reference#events).
80 80
81<h3 id="filter-which-events-a-hook-handles">81<h3 id="filter-which-events-a-hook-handles">
82 Filtrare quali eventi un hook gestisce82 Filtrare gli eventi gestiti da un hook
83</h3>83</h3>
84 84
85Per eseguire un hook solo per alcuni eventi, passate un filtro come secondo argomento a `on`. Claude Code chiama il filtro un matcher. È un oggetto i cui campi vengono confrontati con quelli dell'evento e l'hook viene eseguito solo quando ogni campo corrisponde. Un campo può essere un valore, un array di valori consentiti o un'espressione regolare.85Per eseguire un hook solo per alcuni eventi, passa un filtro come secondo argomento a `on`. Claude Code chiama questo filtro matcher. È un oggetto i cui campi vengono confrontati con quelli dell'evento, e l'hook viene eseguito solo quando tutti i campi corrispondono. Un campo può essere un valore, un array di valori consentiti o un'espressione regolare.
86 86
87Ogni riga in questo esempio registra la stessa funzione, `hook`, per un insieme più ristretto di chiamate di strumenti:87Ogni riga di questo esempio registra la stessa funzione, `hook`, per un insieme più ristretto di chiamate agli strumenti:
88 88
89```javascript theme={null}89```javascript theme={null}
90// Una stringa corrisponde a un valore: solo chiamate Bash90// A string matches one value: Bash calls only
91on('tool.call', { tool: 'Bash' }, hook)91on('tool.call', { tool: 'Bash' }, hook)
92// Un array corrisponde a qualsiasi valore in esso: chiamate Edit e Write92// An array matches any value in it: Edit calls and Write calls
93on('tool.call', { tool: ['Edit', 'Write'] }, hook)93on('tool.call', { tool: ['Edit', 'Write'] }, hook)
94// Un'espressione regolare corrisponde per pattern: ogni strumento di un server MCP94// A regular expression matches by pattern: every tool of one MCP server
95on('tool.call', { tool: /^mcp__github__/ }, hook)95on('tool.call', { tool: /^mcp__github__/ }, hook)
96```96```
97 97
98`hook` viene eseguito una volta per una chiamata Bash, Edit o Write e una volta per una chiamata a uno strumento il cui nome inizia con `mcp__github__`. Una chiamata a qualsiasi altro strumento, come Read, non corrisponde a nessuno dei tre, quindi `hook` non viene eseguito per essa.98`hook` viene eseguita una volta per una chiamata a Bash, Edit o Write, e una volta per una chiamata a uno strumento il cui nome inizia con `mcp__github__`. Una chiamata a qualsiasi altro strumento, come Read, non corrisponde a nessuno dei tre, quindi `hook` non viene eseguita.
99 99
100Il nome dell'evento può essere un wildcard. `'classic.*'` corrisponde a ogni [evento hook delle impostazioni](#hook-the-settings-hook-events). `'*'` corrisponde a ogni evento tranne gli [eventi di telemetria](/docs/it/plugins/mods/reference#telemetry), che potete agganciare per nome o come `'telemetry.*'`.100Il nome dell'evento può essere un carattere jolly. `'classic.*'` corrisponde a ogni [evento degli hook delle impostazioni](#hook-the-settings-hook-events). `'*'` corrisponde a ogni evento tranne gli [eventi di telemetria](/docs/it/plugins/mods/reference#telemetry), che richiedono il proprio nome e un filtro `{ to: 'collector' }`.
101 101
102Registrate ogni evento una volta per matcher. Se chiamate `on` due volte per `session.start` senza un matcher, il modulo non si carica con `on("session.start") is registered twice without a matcher`. Mettete tutto ciò che il vostro mod fa all'inizio della sessione in un hook.102Registra ogni evento una sola volta per matcher. Se chiami `on` due volte per `session.start` senza matcher, il caricamento del modulo fallisce con `on("session.start") is registered twice without a matcher`. Inserisci tutto ciò che il tuo mod fa all'avvio della sessione in un unico hook.
103 103
104<h2 id="hook-what-claude-is-doing">104<h2 id="hook-what-claude-is-doing">
105 Agganciare ciò che Claude sta facendo105 Agganciarsi a ciò che Claude sta facendo
106</h2>106</h2>
107 107
108Agganciate questi eventi per vedere o modificare una chiamata di strumento, un prompt o un turno mentre accade. Per ogni evento e ciò che un hook può restituire, consultate il [riferimento degli eventi](/docs/it/plugins/mods/reference#events).108Gestisci questi eventi per vedere o modificare una chiamata a uno strumento, un prompt o un turno mentre avviene. Per ogni evento e per ciò che un hook può restituire, consulta il [riferimento degli eventi](/docs/it/plugins/mods/reference#events).
109 109
110<h3 id="guard-or-change-a-tool-call">110<h3 id="guard-or-change-a-tool-call">
111 Proteggere o modificare una chiamata di strumento111 Proteggere o modificare una chiamata a uno strumento
112</h3>112</h3>
113 113
114Un hook `tool.call` vede ogni strumento che Claude sta per utilizzare, quindi può rifiutare la chiamata, modificare i suoi argomenti o lasciarla passare. `tool.call` si attiva quando Claude Code sta per eseguire uno strumento, incluse le chiamate che un subagent effettua e le chiamate agli strumenti MCP. `e.tool` è il nome dello strumento e gli argomenti dello strumento sono campi di `e`, come `e.command` per Bash. Quando chiamate `next(e)`, Claude Code esegue il controllo delle autorizzazioni e quindi lo strumento.114Un hook `tool.call` vede ogni strumento che Claude sta per usare, quindi può rifiutare la chiamata, modificarne gli argomenti o lasciarla passare. `tool.call` si attiva quando Claude Code sta per eseguire uno strumento, incluse le chiamate effettuate da un subagent e le chiamate agli strumenti MCP. `e.tool` è il nome dello strumento e gli argomenti dello strumento sono campi di `e`, come `e.command` per Bash. Quando chiami `next(e)`, Claude Code esegue il controllo dei permessi e poi lo strumento.
115 115
116Questo hook rifiuta un comando Bash che fa un force-push e dice a Claude perché:116Questo hook rifiuta un comando Bash che esegue un force push e spiega a Claude il motivo:
117 117
118```javascript theme={null}118```javascript theme={null}
119// Il matcher limita l'hook alle chiamate Bash, quindi e.command è il comando della shell119// The matcher limits the hook to Bash calls, so e.command is the shell command
120on('tool.call', { tool: 'Bash' }, async ($, e, next) => {120on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
121 if (/git push .*--force/.test(e.command)) {121 if (/git push .*--force/.test(e.command)) {
122 // Restituire senza chiamare next risponde all'evento, quindi il comando non viene mai eseguito122 // Returning without calling next answers the event, so the command never runs
123 return { deny: 'Force pushes are not allowed in this repository. Push to a new branch instead.' }123 return { deny: 'Force pushes are not allowed in this repository. Push to a new branch instead.' }
124 }124 }
125 // Ogni altro comando va al controllo delle autorizzazioni e poi a Bash125 // Every other command goes on to the permission check and then to Bash
126 return next(e)126 return next(e)
127})127})
128```128```
129 129
130Quando Claude prova `git push --force`, il comando non viene eseguito e non appare alcun prompt di autorizzazione, perché l'hook non chiama mai `next`. Claude legge il testo `deny` come risultato dello strumento, quindi scrivilo come un'istruzione su cui Claude può agire. Ogni altro comando Bash viene eseguito come farebbe senza il mod.130Quando Claude prova `git push --force`, il comando non viene eseguito e non compare alcuna richiesta di permesso, perché l'hook non chiama mai `next`. Claude legge il testo di `deny` come risultato dello strumento, quindi scrivilo come un'istruzione su cui Claude possa agire. Ogni altro comando Bash viene eseguito come farebbe senza il mod.
131 131
132Per agire dopo che uno strumento è stato eseguito, `await next(e)`, fate il vostro lavoro e restituite ciò che `next` vi ha dato. Questo hook registra ogni file `.mdx` che Claude modifica, con [`$.ui.log`](/docs/it/plugins/mods/api#show-something-without-starting-a-turn), che aggiunge una riga attenuata alla trascrizione che Claude non legge:132Per agire dopo che uno strumento è stato eseguito, usa `await next(e)`, svolgi il tuo lavoro e restituisci ciò che `next` ti ha dato. Questo hook registra ogni file `.mdx` che Claude modifica, con [`$.ui.log`](/docs/it/plugins/mods/api#show-something-without-starting-a-turn), che aggiunge alla trascrizione una riga attenuata che Claude non legge:
133 133
134```javascript theme={null}134```javascript theme={null}
135on('tool.call', { tool: ['Edit', 'Write'] }, async ($, e, next) => {135on('tool.call', { tool: ['Edit', 'Write'] }, async ($, e, next) => {
136 // Attendi il controllo delle autorizzazioni e lo strumento, e mantieni ciò che hanno prodotto136 // Wait for the permission check and the tool, and keep what they produced
137 const result = await next(e)137 const result = await next(e)
138 // Una chiamata rifiutata torna come { deny }, e una fallita ha isError impostato138 // A refused call comes back as { deny }, and a failed one has isError set
139 const changed = !result.deny && !result.isError139 const changed = !result.deny && !result.isError
140 if (changed && e.file_path.endsWith('.mdx')) $.ui.log('Claude changed ' + e.file_path)140 if (changed && e.file_path.endsWith('.mdx')) $.ui.log('Claude changed ' + e.file_path)
141 // Restituisci il risultato come è arrivato, quindi Claude legge ciò che lo strumento ha restituito141 // Return the result as it came, so Claude reads what the tool returned
142 return result142 return result
143})143})
144```144```
145 145
146Dopo che Claude modifica o scrive un file `.mdx`, una riga attenuata nella trascrizione nomina il file. Nulla viene registrato per un altro tipo di file o per una chiamata che è stata rifiutata o non è riuscita. La vista di Claude della chiamata non cambia, perché l'hook restituisce il risultato che ha ricevuto.146Dopo che Claude modifica o scrive un file `.mdx`, una riga attenuata nella trascrizione indica il nome del file. Non viene registrato nulla per un altro tipo di file, né per una chiamata rifiutata o non riuscita. La visione che Claude ha della chiamata non cambia, perché l'hook restituisce il risultato che ha ricevuto.
147 147
148Per modificare una chiamata, passate argomenti modificati a `next`. Per riprovare una chiamata, chiamate `next(e)` di nuovo: un hook che vede `isError` sul primo risultato può eseguire lo strumento una seconda volta e restituire quel risultato. Per rispondere a una chiamata da soli, restituite un oggetto con un campo `result`, come `{ result: 'Skipped by my-mod' }`, senza chiamare `next`. Quando lo fate, non appare alcun prompt di autorizzazione e lo strumento non viene eseguito, quindi il risultato che restituite è tutto ciò che Claude apprende su ciò che è accaduto.148Per modificare una chiamata, passa argomenti modificati a `next`. Per riprovare una chiamata, chiama di nuovo `next(e)`: un hook che vede `isError` nel primo risultato può eseguire lo strumento una seconda volta e restituire quel risultato. Per rispondere tu stesso a una chiamata, restituisci un oggetto con un campo `result`, come `{ result: 'Skipped by my-mod' }`, senza chiamare `next`. In questo caso non compare alcuna richiesta di permesso e lo strumento non viene eseguito, quindi il risultato che restituisci è tutto ciò che Claude sa di quanto è accaduto.
149 149
150Gli hook nelle [impostazioni gestite](/docs/it/server-managed-settings) della vostra organizzazione vengono eseguiti prima di qualsiasi hook `tool.call` di un mod, e un blocco da uno di essi è definitivo.150Gli hook nelle [impostazioni gestite](/docs/it/server-managed-settings) della tua organizzazione vengono eseguiti prima dell'hook `tool.call` di qualsiasi mod, e un blocco da parte di uno di essi è definitivo.
151 151
152<h4 id="hold-a-tool-call-until-the-user-decides">152<h4 id="hold-a-tool-call-until-the-user-decides">
153 Tenere una chiamata di strumento in sospeso fino a quando l'utente decide153 Trattenere una chiamata a uno strumento finché l'utente non decide
154</h4>154</h4>
155 155
156Un hook può mettere in pausa una chiamata di strumento e chiedere all'utente cosa fare prima che proceda. Un hook `tool.call` può `await` prima di chiamare `next` o restituire, e la chiamata dello strumento rimane in sospeso fino ad allora. Per porre la domanda all'utente, chiamate `$.ui.ask`. Mostra la vostra domanda sopra un elenco numerato delle vostre opzioni, nella finestra di dialogo che Claude usa per chiedervi qualcosa, e si risolve nell'etichetta che l'utente sceglie. Dopo le vostre opzioni, la finestra di dialogo aggiunge una riga per digitare una risposta diversa e una riga **Chat about this**.156Un hook può mettere in pausa una chiamata a uno strumento e chiedere all'utente cosa fare prima che proceda. Un hook `tool.call` può usare `await` prima di chiamare `next` o di restituire un valore, e la chiamata allo strumento resta in sospeso fino ad allora. Per porre la domanda all'utente, chiama `$.ui.ask`. Mostra la tua domanda sopra un elenco numerato delle tue opzioni, nella finestra di dialogo che Claude usa per chiederti qualcosa, e si risolve nell'etichetta scelta dall'utente. Dopo le tue opzioni, la finestra di dialogo aggiunge una riga per digitare una risposta diversa e una riga **Chat about this**.
157 157
158Il pattern `RISKY` in questo esempio corrisponde a `rm -r`, `rm -rf`, `git reset --hard` e `git push` con `--force`, e manca altre ortografie come `git push -f`. Questo modulo chiede prima di eseguire un comando Bash che corrisponde al pattern:158Il pattern `RISKY` in questo esempio corrisponde a `rm -r`, `rm -rf`, `git reset --hard` e `git push` con `--force`, e non coglie altre forme come `git push -f`. Questo modulo chiede conferma prima di eseguire un comando Bash che corrisponde al pattern:
159 159
160```javascript theme={null}160```javascript theme={null}
161const RISKY = /\brm\s+-rf?\b|\bgit\s+reset\s+--hard\b|\bgit\s+push\b.*--force/161const RISKY = /\brm\s+-rf?\b|\bgit\s+reset\s+--hard\b|\bgit\s+push\b.*--force/
162 162
163export function register(on) {163export function register(on) {
164 on('tool.call', { tool: 'Bash' }, async ($, e, next) => {164 on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
165 // Lascia passare ogni altro comando senza una domanda165 // Let every other command through without a question
166 if (!RISKY.test(e.command)) return next(e)166 if (!RISKY.test(e.command)) return next(e)
167 // Inizia dalla risposta sicura, quindi una domanda a cui nessuno risponde rifiuta il comando167 // Start from the safe answer, so a question nobody answers refuses the command
168 let answer = 'Refuse'168 let answer = 'Refuse'
169 try {169 try {
170 // La chiamata dello strumento attende qui fino a quando l'utente sceglie una delle due etichette170 // The tool call waits here until the user picks one of the two labels
171 answer = await $.ui.ask('Run this command? ' + e.command, ['Run it', 'Refuse'])171 answer = await $.ui.ask('Run this command? ' + e.command, ['Run it', 'Refuse'])
172 } catch {172 } catch {
173 // L'utente ha chiuso la domanda, o questo è un'esecuzione claude -p senza nessuno a cui chiedere173 // The user dismissed the question, or this is a claude -p run with nobody to ask
174 }174 }
175 if (answer !== 'Run it') {175 if (answer !== 'Run it') {
176 // Rispondi senza chiamare next, quindi il comando non viene eseguito176 // Answer without calling next, so the command doesn't run
177 return { deny: 'The user declined this command. Ask before trying a different approach.' }177 return { deny: 'The user declined this command. Ask before trying a different approach.' }
178 }178 }
179 return next(e)179 return next(e)
181}181}
182```182```
183 183
184Quando Claude prova un comando come `rm -rf build`, la domanda appare con il comando in essa, e il comando attende la risposta:184Quando Claude prova un comando come `rm -rf build`, compare la domanda con il comando al suo interno, e il comando attende la risposta:
185 185
186* **L'utente sceglie Run it**: l'hook chiama `next(e)` e il solito controllo delle autorizzazioni viene comunque eseguito dopo186* **L'utente sceglie Run it**: l'hook chiama `next(e)`, e il consueto controllo dei permessi viene comunque eseguito dopo
187* **L'utente sceglie Refuse**: il comando non viene eseguito e Claude legge il testo `deny`187* **L'utente sceglie Refuse**: il comando non viene eseguito e Claude legge il testo di `deny`
188* **L'utente digita una risposta**: `$.ui.ask` si risolve nel testo digitato. L'hook lo confronta con `Run it`, quindi qualsiasi altro testo rifiuta il comando.188* **L'utente digita una risposta**: `$.ui.ask` si risolve nel testo digitato. L'hook lo confronta con `Run it`, quindi qualsiasi altro testo rifiuta il comando.
189* **Nessuno risponde**: `$.ui.ask` rifiuta quando l'utente chiude la domanda o sceglie **Chat about this**, e in un'esecuzione `claude -p`, quindi il blocco `catch` lascia la risposta a `Refuse`189* **Nessuno risponde**: `$.ui.ask` viene rifiutata quando l'utente chiude la domanda o sceglie **Chat about this**, e in un'esecuzione `claude -p`, quindi il blocco `catch` lascia la risposta a `Refuse`
190 190
191Mantenete l'attesa all'interno di una chiamata API dei mods come `$.ui.ask`, perché quel tempo non conta rispetto al [limite di tempo di 10 secondi](/docs/it/plugins/mods/reference#limits) dell'hook. Il tempo trascorso in attesa di una promessa propria conta. Claude Code salta un hook che scade, quindi il comando tenuto in sospeso verrebbe eseguito.191Mantieni l'attesa all'interno di una chiamata all'API dei mod come `$.ui.ask`, perché quel tempo non viene conteggiato nel [limite di tempo](/docs/it/plugins/mods/reference#limits) dell'hook. Il tempo trascorso in attesa di una tua promise invece viene conteggiato. Claude Code salta un hook che va in timeout, quindi il comando trattenuto verrebbe eseguito.
192
193<h4 id="approve-or-refuse-a-tool-call-before-the-user-is-asked">
194 Approvare o rifiutare una chiamata a uno strumento prima che venga chiesto all'utente
195</h4>
196
197Per decidere se una chiamata a uno strumento può essere eseguita, gestisci [`tool.check`](/docs/it/plugins/mods/reference#tools), l'evento in cui Claude Code prende questa decisione. Si attiva dopo che le regole di permesso e gli hook delle impostazioni hanno deciso, e `next(e)` si risolve nella loro decisione: `allow`, `ask` o `deny`. Il tuo hook restituisce quella decisione o una diversa. `e.input` contiene gli argomenti dello strumento, come `command` per Bash.
198
199Per un comando o un percorso fisso, usa una [regola di permesso](/docs/it/permissions#permission-rule-syntax) come `Bash(npm test)`, che non richiede codice. Gestisci `tool.check` quando la decisione dipende da ciò che è vero in quel momento, come il branch Git corrente o un valore registrato da un altro hook.
200
201Questo hook rifiuta `git push` mentre il branch corrente è `main`:
202
203```javascript theme={null}
204on('tool.check', { tool: 'Bash' }, async ($, e, next) => {
205 // What the permission rules and settings hooks decided: 'allow', 'ask', or 'deny'
206 const decided = await next(e)
207 if (!e.input.command.includes('git push')) return decided
208 const branch = await $.process.run(['git', 'branch', '--show-current'])
209 if (branch.stdout.trim() !== 'main') return decided
210 return { decision: 'deny', reason: 'Push from a branch other than main' }
211})
212```
213
214Su `main`, l'hook restituisce `deny`, anche quando una regola consente `git push`. Su un altro branch, e per altri comandi, la chiamata riceve la decisione che riceverebbe senza il mod.
215
216L'hook confronta il testo del comando, quindi consideralo un promemoria per Claude. Per bloccare i push su `main` per tutti, proteggi il branch sul tuo host Git.
217
218Un hook può restituire `allow`, `ask` o `deny`, quindi può anche approvare una chiamata bloccata da un hook `PreToolUse` al di fuori delle impostazioni gestite. [Estendere i permessi con gli hook](/docs/it/permissions#extend-permissions-with-hooks) elenca quali decisioni prevalgono su un mod.
192 219
193<h3 id="rewrite-or-add-to-a-prompt">220<h3 id="rewrite-or-add-to-a-prompt">
194 Riscrivere o aggiungere a un prompt221 Riscrivere o integrare un prompt
195</h3>222</h3>
196 223
197Un hook `prompt.submit` vede ogni prompt prima che il turno inizi, quindi può riscrivere il testo o aggiungervi. `e.text` è ciò che è stato digitato.224Un hook `prompt.submit` vede ogni prompt prima che inizi il turno, quindi può riscriverne il testo o aggiungervi qualcosa. `e.text` è ciò che è stato digitato.
198 225
199| Per fare questo | Restituite questo |226| Per fare questo | Restituisci questo |
200| :- | :- |227| :- | :- |
201| Riscrivere il prompt. Il messaggio nella trascrizione mostra il nuovo testo. | `next({ ...e, text: newText })` |228| Riscrivere il prompt. Il messaggio nella trascrizione mostra il nuovo testo. | `next({ ...e, text: newText })` |
202| Aggiungere testo che solo Claude legge, dopo il prompt | `next({ ...e, context: [...(e.context ?? []), extraText] })` |229| Aggiungere testo, dopo il prompt, che solo Claude legge | `next({ ...e, context: [...(e.context ?? []), extraText] })` |
203| Impedire che il prompt venga inviato | `{ drop: 'the reason' }` |230| Impedire l'invio del prompt | `{ drop: 'the reason' }` |
204 231
205Questo hook aggiunge il nome del ramo corrente per Claude ogni volta che un prompt menziona una pull request:232Questo hook aggiunge per Claude il nome del branch corrente ogni volta che un prompt menziona una pull request:
206 233
207```javascript theme={null}234```javascript theme={null}
208on('prompt.submit', async ($, e, next) => {235on('prompt.submit', async ($, e, next) => {
209 // Passa un prompt che non menziona una pull request così com'è236 // Pass on a prompt that doesn't mention a pull request as it is
210 if (!/\bPR\b|pull request/i.test(e.text)) return next(e)237 if (!/\bPR\b|pull request/i.test(e.text)) return next(e)
211 const git = await $.process.run(['git', 'branch', '--show-current'])238 const git = await $.process.run(['git', 'branch', '--show-current'])
212 // Al di fuori di un repository git il comando fallisce, quindi non c'è ramo da aggiungere239 // Outside a git repository the command fails, so there's no branch to add
213 if (git.exitCode !== 0) return next(e)240 if (git.exitCode !== 0) return next(e)
214 // Mantieni qualsiasi contesto che un hook precedente ha aggiunto e aggiungi un'altra riga per Claude241 // Keep any context an earlier hook added, and add one more line for Claude
215 return next({ ...e, context: [...(e.context ?? []), 'Current branch: ' + git.stdout.trim()] })242 return next({ ...e, context: [...(e.context ?? []), 'Current branch: ' + git.stdout.trim()] })
216})243})
217```244```
218 245
219Quando inviate un prompt come `open a PR for this change`, il vostro messaggio appare uguale nella trascrizione e Claude legge anche una riga come `Current branch: feature/auth` dopo di esso. Un prompt che non menziona una pull request passa invariato e `git` non viene eseguito.246Quando invii un prompt come `open a PR for this change`, il tuo messaggio appare invariato nella trascrizione, e Claude legge anche una riga come `Current branch: feature/auth` dopo di esso. Un prompt che non menziona una pull request passa invariato, e `git` non viene eseguito.
220 247
221[Altri eventi](/docs/it/plugins/mods/reference#prompts-and-what-claude-reads) coprono il resto di ciò che Claude legge: `prompt.section` per ogni sezione del prompt di sistema, `prompt.context` per il contesto inviato con il primo messaggio e `skill.prompt` per il testo di una skill. Il testo da questi hook che cambia tra le richieste [invalida la cache del prompt](/docs/it/prompt-caching).248[Altri eventi](/docs/it/plugins/mods/reference#prompts-and-what-claude-reads) coprono il resto di ciò che Claude legge: `prompt.section` per ogni sezione del prompt di sistema, `prompt.context` per il contesto inviato con il primo messaggio e `skill.prompt` per il testo di una skill. Il testo di questi hook che cambia tra una richiesta e l'altra [invalida la cache dei prompt](/docs/it/prompt-caching).
222 249
223<h3 id="follow-a-turn">250<h3 id="follow-a-turn">
224 Seguire un turno251 Seguire un turno
225</h3>252</h3>
226 253
227Un turno è tutto ciò che Claude fa in risposta a un prompt. Agganciate `turn.start`, `turn.step` e `turn.complete` per seguirne uno:254Un turno è tutto ciò che Claude fa in risposta a un prompt. Gestisci `turn.start`, `turn.step` e `turn.complete` per seguirne uno:
228 255
229| Evento | Quando si attiva | Cosa può fare un hook |256| Evento | Quando si attiva | Cosa può fare un hook |
230| :- | :- | :- |257| :- | :- | :- |
231| `turn.start` | Un turno inizia | Osservare. `e.turnId` identifica il turno negli altri due eventi. |258| `turn.start` | Inizia un turno | Osservare. `e.turnId` identifica il turno negli altri due eventi. |
232| `turn.step` | Claude Code sta per inviare una richiesta al modello. Un turno con chiamate di strumenti ne ha diverse. `e.agentId` è impostato per una richiesta di un subagent. | Leggere l'utilizzo dei token di ogni richiesta, inviarlo a un modello diverso con `next({ ...e, model })` o rispondere senza chiamare il modello |259| `turn.step` | Claude Code sta per inviare una richiesta al modello. Un turno con chiamate agli strumenti ne ha diverse. `e.agentId` è impostato per la richiesta di un subagent. | Leggere l'utilizzo di token di ogni richiesta, inviarla a un modello diverso con `next({ ...e, model })`, o rispondere senza chiamare il modello |
233| `turn.complete` | Il turno è terminato, incluso un turno che l'utente ha interrotto, dove `e.isAborted` è `true`. `e.answer` è il testo finale di Claude, `e.durationMs` quanto tempo ha impiegato e `e.usage` i totali dei token del turno. Un turno di un subagent lo attiva con `e.agentId` impostato. | Osservare, o restituire un oggetto con un campo `text`, come `{ text: 'Done in 12 seconds' }`, per mostrare una riga sotto la risposta |260| `turn.complete` | Il turno è terminato, incluso un turno interrotto dall'utente, nel qual caso `e.isAborted` è `true`. `e.answer` è il testo finale di Claude, `e.durationMs` quanto tempo ha richiesto ed `e.usage` i totali di token del turno. Il turno di un subagent lo attiva con `e.agentId` impostato. | Osservare, o restituire un oggetto con un campo `text`, come `{ text: 'Done in 12 seconds' }`, per mostrare una riga sotto la risposta |
234 261
235Scrivete un hook `turn.step` come generatore asincrono, perché l'evento trasmette. `yield* next(e)` inoltra la risposta mentre trasmette e si valuta nel risultato finito. Questo hook registra quanto di ogni richiesta il Claude API ha servito dalla [cache del prompt](/docs/it/prompt-caching):262Scrivi un hook `turn.step` come generatore asincrono, perché l'evento è in streaming. `yield* next(e)` inoltra la risposta mentre arriva in streaming e restituisce il risultato finale. Questo hook registra quanto di ogni richiesta la Claude API ha servito dalla [cache dei prompt](/docs/it/prompt-caching):
236 263
237```javascript theme={null}264```javascript theme={null}
238// function* rende l'hook un generatore, che può passare la risposta pezzo per pezzo265// function* makes the hook a generator, which can pass the response on piece by piece
239on('turn.step', async function* ($, e, next) {266on('turn.step', async function* ($, e, next) {
240 // Invia la richiesta, inoltra ogni pezzo mentre arriva e mantieni il risultato finito267 // Send the request, forward each piece as it arrives, and keep the finished result
241 const result = yield* next(e)268 const result = yield* next(e)
242 // Salta un risultato che non riporta conteggi di token269 // Skip a result that reports no token counts
243 if (result.usage) {270 if (result.usage) {
244 $.ui.log('cache read ' + result.usage.cache_read_input_tokens + ' · wrote ' + result.usage.cache_creation_input_tokens)271 $.ui.log('cache read ' + result.usage.cache_read_input_tokens + ' · wrote ' + result.usage.cache_creation_input_tokens)
245 }272 }
246 // Restituisci il risultato invariato, quindi il turno continua come al solito273 // Return the result unchanged, so the turn continues as usual
247 return result274 return result
248})275})
249```276```
250 277
251La risposta di Claude trasmette allo schermo come farebbe senza il mod. Dopo che ogni richiesta termina, una riga attenuata nella trascrizione fornisce il numero di token letti dalla cache e il numero scritto in essa. Un turno con chiamate di strumenti ha diverse richieste, quindi aggiunge diverse righe.278La risposta di Claude viene mostrata sullo schermo in streaming come accade senza il mod. Al termine di ogni richiesta, una riga attenuata nella trascrizione indica il numero di token letti dalla cache e il numero di quelli scritti in essa. Un turno con chiamate agli strumenti ha diverse richieste, quindi aggiunge diverse righe.
252 279
253`result.usage` contiene i quattro conteggi di token che il Claude API riporta per una richiesta, più il `model` che ha risposto: `input_tokens`, `output_tokens`, `cache_read_input_tokens` e `cache_creation_input_tokens`. L'hook viene eseguito anche per le richieste dei subagent, quindi controllate `e.agentId` quando volete solo la conversazione principale.280`result.usage` contiene i conteggi di token che la Claude API riporta per una richiesta, più il `model` che ha risposto: `input_tokens`, `output_tokens`, `cache_read_input_tokens` e `cache_creation_input_tokens`. L'hook viene eseguito anche per le richieste dei subagent, quindi controlla `e.agentId` quando vuoi solo la conversazione principale.
254 281
255<h3 id="hook-the-settings-hook-events">282<h3 id="hook-the-settings-hook-events">
256 Agganciare gli eventi hook delle impostazioni283 Gestire gli eventi degli hook delle impostazioni
257</h3>284</h3>
258 285
259Gli hook delle impostazioni sono gli hook di comando, HTTP, prompt e agente che configurate nei file delle impostazioni. Ogni [evento hook delle impostazioni](/docs/it/hooks#hook-events), come `Stop`, `SessionEnd` o `PostToolUse`, è anche un evento denominato `classic.` seguito dal nome dell'evento hook delle impostazioni, come `classic.Stop`. `e` è il JSON che un hook delle impostazioni riceve su stdin, incluso `transcript_path`.286Gli hook delle impostazioni sono gli hook di comando, HTTP, prompt e agente che configuri nei file di impostazioni. Ogni [evento degli hook delle impostazioni](/docs/it/hooks#hook-events), come `Stop`, `SessionEnd` o `PostToolUse`, è anche un evento denominato `classic.` seguito dal nome dell'evento dell'hook delle impostazioni, come `classic.Stop`. `e` è il JSON che un hook delle impostazioni riceve su stdin, incluso `transcript_path`.
260 287
261Questo hook usa `Stop`, che si attiva quando Claude finisce di rispondere, per registrare dove viene salvata la trascrizione della sessione:288Questo hook usa `Stop`, che si attiva quando Claude termina di rispondere, per registrare dove viene salvata la trascrizione della sessione:
262 289
263```javascript theme={null}290```javascript theme={null}
264on('classic.Stop', async ($, e, next) => {291on('classic.Stop', async ($, e, next) => {
265 // e ha gli stessi campi che un hook Stop in un file di impostazioni legge da stdin292 // e has the same fields a Stop hook in a settings file reads from stdin
266 $.ui.log('Transcript saved at ' + e.transcript_path)293 $.ui.log('Transcript saved at ' + e.transcript_path)
267 // Passa l'evento, quindi gli hook Stop nei vostri file di impostazioni vengono comunque eseguiti294 // Pass the event on, so Stop hooks in your settings files still run
268 return next(e)295 return next(e)
269})296})
270```297```
271 298
272Ogni volta che Claude finisce di rispondere, una riga attenuata nella trascrizione fornisce il percorso del file di trascrizione. L'hook restituisce `next(e)`, quindi osserva l'evento e non cambia nulla su come il turno termina.299Ogni volta che Claude termina di rispondere, una riga attenuata nella trascrizione indica il percorso del file della trascrizione. L'hook restituisce `next(e)`, quindi osserva l'evento e non modifica nulla del modo in cui termina il turno.
273 300
274<h2 id="run-alongside-other-mods">301<h2 id="run-alongside-other-mods">
275 Eseguire insieme ad altri mod302 Eseguire insieme ad altri mod
276</h2>303</h2>
277 304
278Diversi mod possono agganciare lo stesso evento e uno qualsiasi di essi può fallire. Se il vostro mod blocca le chiamate di strumenti, controllate la sua posizione nella catena e cosa accade quando il suo hook fallisce.305Più mod possono gestire lo stesso evento e ognuno di essi può fallire. Se il tuo mod blocca le chiamate agli strumenti, controlla la sua posizione nella catena e cosa succede quando il suo hook fallisce.
279 306
280<h3 id="the-order-mods-run-in">307<h3 id="the-order-mods-run-in">
281 L'ordine in cui i mod vengono eseguiti308 L'ordine in cui vengono eseguiti i mod
282</h3>309</h3>
283 310
284Gli hook sullo stesso evento formano una catena middleware. Ogni `next` di un mod chiama l'hook del mod seguente e l'ultimo `next` raggiunge il comportamento proprio di Claude Code. Il primo mod è il più esterno: vede l'evento prima degli altri e il risultato dopo di loro, e decide se gli altri vengono eseguiti. Un mod successivo non può impedire a uno precedente di vedere un evento.311Gli hook sullo stesso evento formano un'unica catena middleware. Il `next` di ciascun mod chiama l'hook del mod successivo, e l'ultimo `next` raggiunge il comportamento proprio di Claude Code. Il primo mod è il più esterno: vede l'evento prima degli altri e il risultato dopo di loro, e decide se gli altri vengono eseguiti o meno. Un mod successivo non può impedire a uno precedente di vedere un evento.
285 312
286Claude Code ordina la catena in base a dove proviene ogni mod:313Claude Code ordina la catena in base alla provenienza di ciascun mod:
287 314
2881. La guardia incorporata `sec-default@builtin`, un mod incorporato in Claude Code che `/plugin` elenca come `cc-plugin-sec-default`, dove [si carica](/docs/it/plugins/mods/admin#know-what-happens-by-default), i mod che la vostra organizzazione elenca in [`prependPlugins`](/docs/it/plugins/mods/admin#install-your-organizations-mods) e quindi qualsiasi altro mod che conta come della vostra organizzazione e non è in `appendPlugins`3151. La protezione integrata `sec-default@builtin`, un mod integrato in Claude Code che `/plugin` elenca come `cc-plugin-sec-default`, dove [viene caricata](/docs/it/plugins/mods/admin#know-what-happens-by-default), i mod che la tua organizzazione elenca in [`prependPlugins`](/docs/it/plugins/mods/admin#install-your-organizations-mods), e poi qualsiasi altro mod che conta come della tua organizzazione e non è in `appendPlugins`
2892. I mod che installate3162. I mod che installi tu
2903. I mod che la vostra organizzazione elenca in `appendPlugins`3173. I mod che la tua organizzazione elenca in `appendPlugins`
2914. Altri mod incorporati in Claude Code3184. Gli altri mod integrati in Claude Code
292 319
293Tra i mod che installate, un mod viene eseguito prima dei mod che elenca sotto `dependencies` nel suo manifesto. All'interno di un modulo, gli hook vengono eseguiti nell'ordine in cui `register` ha chiamato `on`.320Tra i mod che installi, un mod viene eseguito prima dei mod che elenca sotto `dependencies` nel suo manifest. All'interno di un modulo, gli hook vengono eseguiti nell'ordine in cui `register` ha chiamato `on`.
294 321
295<h4 id="where-settings-hooks-run-in-the-order">322<h4 id="where-settings-hooks-run-in-the-order">
296 Dove gli hook delle impostazioni vengono eseguiti nell'ordine323 Dove vengono eseguiti gli hook delle impostazioni nell'ordine
297</h4>324</h4>
298 325
299Gli hook `PreToolUse` configurati nei file delle impostazioni vengono anche eseguiti durante una chiamata di strumento, in punti fissi nella catena dei mod:326Anche gli hook `PreToolUse` configurati nei file di impostazioni vengono eseguiti durante una chiamata a uno strumento, in punti fissi della catena di mod:
300 327
301* **Hook `PreToolUse` dalle impostazioni gestite**: vengono eseguiti prima dell'hook `tool.call` del primo mod, e un blocco da uno di essi è definitivo, quindi nessun mod vede la chiamata.328* **Hook `PreToolUse` dalle impostazioni gestite**: vengono eseguiti prima dell'hook `tool.call` del primo mod, e un blocco da parte di uno di essi è definitivo, quindi nessun mod vede la chiamata.
302* **Hook `PreToolUse` da ogni altro file di impostazioni e da `hooks/hooks.json` dei plugin**: vengono eseguiti dopo che l'ultimo mod chiama `next`, come parte del comportamento proprio di Claude Code. Un mod che risponde a `tool.call` senza chiamare `next` li impedisce di eseguire e un mod che chiama `next` vede la loro decisione nel risultato che restituisce.329* **Hook `PreToolUse` da ogni altro file di impostazioni e da `hooks/hooks.json` dei plugin**: vengono eseguiti dopo che l'ultimo mod ha chiamato `next`, come parte del comportamento proprio di Claude Code. Un mod che risponde a `tool.call` senza chiamare `next` ne impedisce l'esecuzione, e un mod che chiama `next` vede la loro decisione nel risultato che restituisce.
303 330
304[`tool.check`](/docs/it/plugins/mods/reference#tools) è l'evento in cui Claude Code decide se una chiamata di strumento può essere eseguita. Si attiva dopo quegli hook e le regole di autorizzazione hanno deciso e `next(e)` si risolve nella loro decisione. Un hook su `tool.check` può restituire una decisione diversa, come `{ decision: 'allow' }`, quindi può approvare una chiamata che un hook nel secondo gruppo ha bloccato. [Estendere le autorizzazioni con gli hook](/docs/it/permissions#extend-permissions-with-hooks) elenca quali decisioni prevalgono su un mod.331[`tool.check`](#approve-or-refuse-a-tool-call-before-the-user-is-asked) si attiva dopo che quegli hook e le regole di permesso hanno deciso, quindi un hook su di esso può approvare una chiamata che un hook del secondo gruppo ha bloccato.
305 332
306<h3 id="handle-a-hook-that-fails">333<h3 id="handle-a-hook-that-fails">
307 Gestire un hook che fallisce334 Gestire un hook che fallisce
308</h3>335</h3>
309 336
310Un hook che fallisce non interrompe la sessione e potete decidere cosa accade invece. Quando un hook senza un gestore `.catch` genera un errore, scade o restituisce un risultato di forma sbagliata, ciò che accade dopo dipende dal fatto che abbia chiamato `next`:337Un hook che fallisce non interrompe la sessione, e puoi decidere cosa succede al suo posto. Quando un hook senza un gestore `.catch` genera un'eccezione, va in timeout o restituisce un risultato con la forma sbagliata, ciò che succede dopo dipende dal fatto che abbia chiamato `next`:
311 338
312* **Ha fallito prima di chiamare `next`**: Claude Code lo salta e il gestore successivo viene eseguito al suo posto339* **È fallito prima di chiamare `next`**: Claude Code lo salta, e il gestore successivo viene eseguito al suo posto
313* **Ha fallito dopo che `next` si è risolto**: quel risultato rimane e nulla viene eseguito una seconda volta340* **È fallito dopo che `next` è stato risolto**: quel risultato rimane valido, e nulla viene eseguito una seconda volta
314 341
315Una riga nomina il mod, l'evento e il motivo, come `my-mod: tool.call hook skipped: threw Error: boom`. Dove lo leggete dipende dalla sessione, come [Scoprire perché un mod non fa nulla](/docs/it/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing) elenca. Un hook `ui.render` il cui disegno non convalida viene segnalato diversamente, come [Costruire un albero da elementi](/docs/it/plugins/mods/interface#build-a-tree-from-elements) descrive.342Una riga indica il mod, l'evento e il motivo, ad esempio `my-mod: tool.call hook skipped: threw Error: boom`. Dove la leggi dipende dalla sessione, come elencato in [Scoprire perché un mod non fa nulla](/docs/it/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing). Un hook `ui.render` il cui disegno non supera la validazione viene segnalato in modo diverso, come descritto in [Costruire un albero a partire dagli elementi](/docs/it/plugins/mods/interface#build-a-tree-from-elements).
316 343
317Per fare in modo che un hook che blocca le chiamate fallisca in modo sicuro, aggiungete un gestore di errore `.catch` che risponda al suo posto. Qui, `guard` è la vostra funzione hook:344Per fare in modo che un hook che blocca le chiamate fallisca in modo chiuso, aggiungi un gestore di errori `.catch` che risponda al suo posto. Qui, `guard` è la tua funzione hook:
318 345
319```javascript theme={null}346```javascript theme={null}
320// on restituisce una registrazione e .catch allega un gestore a quel singolo hook347// on returns a registration, and .catch attaches a handler to that one hook
321on('tool.call', { tool: 'Bash' }, guard).catch(async ($, e, next) => {348on('tool.call', { tool: 'Bash' }, guard).catch(async ($, e, next) => {
322 // next.error.kind è 'throw' o 'timeout', che dice come guard ha fallito349 // next.error.kind is 'throw' or 'timeout', which says how guard failed
323 return { deny: 'The command guard failed, so this command was not run: ' + next.error.kind }350 return { deny: 'The command guard failed, so this command was not run: ' + next.error.kind }
324})351})
325```352```
326 353
327Mentre `guard` funziona, il gestore non viene mai eseguito. Quando `guard` genera un errore o scade su una chiamata Bash, Claude Code chiama il gestore con lo stesso evento. Il gestore restituisce `{ deny }`, quindi il comando non viene eseguito e Claude legge il testo con `throw` o `timeout` alla fine. Senza il gestore, Claude Code salterebbe `guard` ed eseguirebbe il comando. Il gestore ha [un secondo](/docs/it/plugins/mods/reference#limits) per rispondere.354Finché `guard` funziona, il gestore non viene mai eseguito. Quando `guard` genera un'eccezione o va in timeout su una chiamata Bash, Claude Code chiama il gestore con lo stesso evento. Il gestore restituisce `{ deny }`, quindi il comando non viene eseguito, e Claude legge il testo con `throw` o `timeout` alla fine. Senza il gestore, Claude Code salterebbe `guard` ed eseguirebbe il comando. Il gestore ha un proprio [limite di tempo](/docs/it/plugins/mods/reference#limits) più breve.
328 355
329<h2 id="next-steps">356<h2 id="next-steps">
330 Passaggi successivi357 Passaggi successivi
331</h2>358</h2>
332 359
333* [Usare l'API dei mods](/docs/it/plugins/mods/api): aggiungere comandi e strumenti, chiamare un modello ed eseguire lavoro su un timer360* [Usa l'API dei mod](/docs/it/plugins/mods/api): aggiungi comandi e strumenti, chiama un modello ed esegui attività a intervalli regolari
334* [Disegnare nell'interfaccia](/docs/it/plugins/mods/interface): mostrare ciò che i vostri hook raccolgono in un riquadro o sopra il prompt361* [Disegna nell'interfaccia](/docs/it/plugins/mods/interface): mostra ciò che i tuoi hook raccolgono in un riquadro o sopra il prompt
335* [Testare un mod](/docs/it/plugins/mods/test): generare uno qualsiasi di questi eventi da un test362* [Testa un mod](/docs/it/plugins/mods/test): attiva uno qualsiasi di questi eventi da un test
336* [Riferimento dei mods](/docs/it/plugins/mods/reference): ogni evento, ogni metodo dell'API dei mods e i limiti363* [Riferimento dei mod](/docs/it/plugins/mods/reference): ogni evento, ogni metodo dell'API dei mod e i limiti