> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Usa l'API mods

> Chiama l'API mods da un mod Claude Code per aggiungere comandi e strumenti, chiamare un modello, eseguire lavoro su un timer, inviare messaggi ad altre sessioni e accedere a file e rete.

L'API mods è l'insieme di metodi che un mod chiama per agire: aggiungere comandi e strumenti, chiamare un modello, eseguire lavoro tra gli eventi e accedere al file system, ai processi e alla rete. Ogni hook la riceve come primo argomento, `$`, con i metodi raggruppati in namespace come `$.ui` e `$.fs`. [Events](/docs/it/plugins/mods/events) decidono quando un hook viene eseguito, e l'API mods è ciò che l'hook chiama una volta che lo fa.

Costruisci il tuo [primo mod](/docs/it/plugins/mods/create) prima di iniziare qui. Per ogni metodo, vedi [mods API methods](/docs/it/plugins/mods/reference#mods-api-methods) o leggi [i tipi per la tua build](/docs/it/plugins/mods/create#get-the-types-for-your-build).

<h2 id="add-a-command-or-a-tool">
  Aggiungi un comando o uno strumento
</h2>

Un mod può aggiungere un comando per l'utente da eseguire e uno strumento per Claude da chiamare. Registra entrambi in un hook [`session.start`](/docs/it/plugins/mods/reference#session). Claude Code attende quell'hook prima del primo prompt, quindi ciò che registri è disponibile dal primo turno.

<h3 id="add-a-command">
  Aggiungi un comando
</h3>

Un comando è per l'utente. Registralo, quindi gestisci [`command.run`](/docs/it/plugins/mods/reference#commands-and-configuration) per il suo nome. Questo esempio aggiunge un comando `/standup` che accetta un numero facoltativo di giorni:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // Add /standup to the command list, with the description the user sees there
  await $.command.register({ name: 'standup', description: 'Summarize what changed today', argumentHint: '[days]' })
  return next(e)
})

// The matcher limits the hook to /standup, so other commands don't reach it
on('command.run', { command: 'standup' }, async ($, e) => {
  // e.args is the text typed after the command name, or an empty string
  return { text: 'Summary for the last ' + (e.args || '1') + ' day(s): ...' }
})
```

Dopo l'avvio della sessione, `/standup` appare con la sua descrizione nell'elenco che vedi quando digiti `/`. L'`argumentHint` viene visualizzato nel prompt dopo che digiti il comando e uno spazio, come in `/standup [days]`. Quando esegui `/standup 3`, il secondo hook restituisce `Summary for the last 3 day(s): ...`, e la trascrizione mostra quel testo dopo il nome del plugin. L'hook non chiama mai `next`, perché il comando non ha comportamento diverso dal tuo.

Il `text` che restituisci viene stampato nella trascrizione e Claude lo legge. Per non stampare nulla, come un comando che apre solo un [pane](/docs/it/plugins/mods/interface#pick-where-to-draw), restituisci `{}`. Per consentire al comando di essere eseguito mentre Claude sta lavorando, aggiungi `immediate: true` alla registrazione.

Scegli un nome che nessun comando integrato utilizza. Digita `/` in una sessione per vederli. `$.command.register` genera un'eccezione per un nome occupato, con un messaggio come `"/focus" refused: it is the built-in /focus"`. Un hook che genera un'eccezione viene saltato, quindi il resto del tuo hook `session.start` non viene eseguito nemmeno. Registra i comandi per ultimi in quell'hook, oppure avvolgi la chiamata in `try` e `catch`.

<h3 id="add-a-tool">
  Aggiungi uno strumento
</h3>

Uno strumento è per Claude. Registralo con un nome, una descrizione che Claude legge e uno JSON Schema per il suo input. Claude lo vede con un nome più lungo composto da `mcp__`, il nome del tuo plugin, due underscore e il nome che hai registrato. Gestisci le sue chiamate in un hook [`tool.call`](/docs/it/plugins/mods/events#guard-or-change-a-tool-call) filtrato a quel nome completo. Questo esempio, da un plugin denominato `my-mod`, registra `ticket`, quindi il nome completo è `mcp__my-mod__ticket`. Fornisce a Claude uno strumento che cerca un ticket in un issue tracker:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  await $.tool.register({
    name: 'ticket',
    // Claude decides when to call the tool from this description
    description: 'Look up a ticket by its id and return its title and status',
    // The arguments Claude has to send: one required string named id
    inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
  })
  return next(e)
})

// The full tool name is mcp__, the plugin's name, and the registered name
on('tool.call', { tool: 'mcp__my-mod__ticket' }, async ($, e) => {
  // The tool's arguments are fields of e, so the id is e.id
  const response = await $.http.fetch('https://tickets.example.com/api/' + encodeURIComponent(e.id))
  // Return a result either way, so Claude learns when the lookup failed
  return { result: response.ok ? response.text : 'Lookup failed with status ' + response.status }
})
```

Quando chiedi informazioni su un ticket, Claude può chiamare `mcp__my-mod__ticket` con il suo id. Il secondo hook recupera il ticket e restituisce il corpo della risposta, che Claude legge come risultato dello strumento. Quando il server risponde con uno stato di errore, Claude legge `Lookup failed with status` e il numero.

<h2 id="call-a-model">
  Chiama un modello
</h2>

Un mod può fare una domanda a un modello di sua iniziativa, al di fuori della conversazione, per un piccolo lavoro come ordinare o riassumere un pezzo di testo. `$.model.complete` invia un prompt a un modello con le credenziali della tua sessione e si risolve nella risposta. Non ha cronologia della conversazione.

Questo hook risponde a un comando `/triage`, [registrato come comando](#add-a-command), chiedendo a un piccolo modello di etichettare il testo digitato dopo di esso:

```javascript theme={null}
on('command.run', { command: 'triage' }, async ($, e) => {
  const r = await $.model.complete({
    model: 'haiku',
    // The system prompt sets the job, and the prompt carries the text to label
    system: 'Reply with one word: bug, feature, or question.',
    prompt: e.args,
    // One word needs few tokens, and the call gives up after 15 seconds
    maxTokens: 20,
    timeoutMs: 15000,
  })
  // r.text exists only when the model answered, so check r.isAnswered first
  const label = r.isAnswered ? r.text.trim() : 'unknown'
  return { text: 'Label: ' + label }
})
```

Quando esegui `/triage the export button does nothing`, il mod invia quel testo al modello e stampa la sua risposta, come `Label: bug`. La conversazione di Claude non fa parte della richiesta. Quando il modello non risponde, l'etichetta è `unknown`.

Un errore dell'API Claude non rifiuta la chiamata, quindi controlla `r.isAnswered` e leggi `r.reason` quando è `false`. La chiamata rifiuta solo per una richiesta che Claude Code non invierà, come un modello che la tua organizzazione blocca. [I tipi per la tua build](/docs/it/plugins/mods/create#get-the-types-for-your-build) elencano le altre opzioni, come `effort`, e i [limiti](/docs/it/plugins/mods/reference#limits) forniscono il valore predefinito di `maxTokens`.

`$.model.fork({ prompt })` pone una domanda sulla conversazione corrente, con lo stesso modello e prompt di sistema, quindi l'API Claude serve la maggior parte da prompt caching.

Queste chiamate utilizzano il piano o la chiave API dell'utente.

<h2 id="run-work-in-the-background">
  Esegui lavoro in background
</h2>

Il lavoro che sopravvive a un evento, come controllare qualcosa una volta al minuto, viene eseguito su un timer che avvii da `session.start`. Un hook stesso viene eseguito per un evento e ha un limite di tempo di 10 secondi del suo tempo di esecuzione. Il tempo trascorso in attesa di `next` o di una chiamata all'API mods non conta, tranne un `$.clock.sleep`. `$.clock.every` e `$.clock.after` prendono il posto di `setInterval` e `setTimeout`, con il ritardo in millisecondi per primo: `$.clock.after(5000, fn)` chiama `fn` una volta, cinque secondi da ora. Ognuno restituisce un timer con un metodo `cancel()`, e `await $.clock.now()` fornisce l'ora in millisecondi.

Questo hook cerca i controlli di una pull request una volta al minuto e mostra il risultato sotto il prompt. `summarize` è una funzione tua che trasforma l'output JSON del comando in poche parole:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // Call the function every 60,000 milliseconds, starting one minute from now
  $.clock.every(60_000, async () => {
    const status = await $.process.run(['gh', 'pr', 'checks', '--json', 'state'])
    // Replace the line under the prompt with the latest summary
    $.ui.status('checks: ' + summarize(status.stdout))
  })
  // Return without waiting for the timer, so the session starts right away
  return next(e)
})
```

La sessione inizia come al solito. Un minuto dopo, una riga appare sotto il prompt con un `⚠`, il nome del mod e poi `checks:` e il tuo riassunto. Viene sostituito una volta al minuto dopo. Il callback del timer viene eseguito al di fuori di qualsiasi evento, quindi continua a funzionare tra i turni e non ne avvia uno. Se il callback genera un'eccezione, l'errore va al [debug log](/docs/it/plugins/mods/troubleshoot#read-the-debug-log) e il timer viene eseguito di nuovo all'intervallo successivo.

<h3 id="show-something-without-starting-a-turn">
  Mostra qualcosa senza avviare un turno
</h3>

Un lavoro in background può mostrare all'utente qualcosa senza avviare un turno. Ognuna di queste chiamate mette il testo in un posto diverso:

| Chiamata | Cosa vede l'utente |
| :- | :- |
| `$.ui.status(text)` | Una riga sotto il prompt che rimane fino a quando non la cambi. Inizia con `⚠` e il nome del mod, come in `⚠ my-mod: checks: 3 passing`. |
| `$.ui.toast(text)` | Una piccola casella in alto a destra, con il nome del mod sopra il testo, che scompare dopo pochi secondi |
| `$.ui.log(text)` | Una riga attenuata nella trascrizione che Claude non legge. Inizia con `●` e il nome del mod, come in `● my-mod: build finished`. |

<h3 id="start-a-turn-from-a-background-job">
  Avvia un turno da un lavoro in background
</h3>

Quando un lavoro in background trova qualcosa che ha bisogno dell'attenzione di Claude, può avviare un turno inviando un prompt con `$.prompt.submit({ text })`. Claude legge il testo dopo una frase che nomina il tuo mod come mittente. Per inviarlo come parole proprie dell'utente, senza quella frase, aggiungi `asUser: true`. La chiamata attende fino a quando la sessione è inattiva e quindi avvia un nuovo turno. Si risolve quando quel turno inizia, quindi non `await` in un handler che viene eseguito mentre Claude sta lavorando.

<h3 id="stop-background-work">
  Interrompi il lavoro in background
</h3>

Il lavoro in background si interrompe in due modi. I timer si interrompono quando il modulo viene ricaricato. Per il lavoro di lunga durata all'interno di un hook, [`next.signal`](/docs/it/plugins/mods/reference#the-hook-function) è un `AbortSignal` che si interrompe quando l'evento che il tuo hook sta gestendo viene abbandonato, ad esempio quando l'utente interrompe, quindi passalo a qualsiasi cosa di lunga durata.

<h2 id="send-and-receive-messages-between-sessions">
  Invia e ricevi messaggi tra sessioni
</h2>

Un mod può inviare un messaggio in testo semplice a un'altra delle tue sessioni o a uno dei subagent di questa sessione e osservare i messaggi che arrivano e partono. `$.session.send({ to, text })` ne invia uno, la stessa consegna che lo strumento SendMessage effettua. `to` è `{ sessionId }` per una sessione, `{ agentId }` per un subagent da `$.agent.list()`, o l'indirizzo stringa da cui proviene un messaggio ricevuto. La chiamata si risolve una volta che il messaggio è in coda, con `{ isDelivered: true }`. Quando nulla è stato consegnato si risolve con `{ isDelivered: false, reason }`, e `reason` spiega perché.

Questo hook risponde a un comando `/ping`, [registrato come comando](#add-a-command), chiedendo alla sessione il cui id digiti dopo di esso uno stato:

```javascript theme={null}
on('command.run', { command: 'ping' }, async ($, e) => {
  // e.args is the session id typed after /ping
  const sent = await $.session.send({ to: { sessionId: e.args }, text: 'Status? One line.' })
  // The call resolves either way, so check isDelivered to learn what happened
  if (!sent.isDelivered) $.ui.toast('Not delivered: ' + sent.reason)
  // An empty result prints nothing in this session's transcript
  return {}
})
```

Quando il messaggio è in coda, nulla appare nella tua sessione e Claude dell'altra sessione legge `Status? One line.` Quando nulla è stato consegnato, una piccola casella in alto a destra fornisce il motivo e scompare dopo pochi secondi.

Due eventi consentono a un mod di osservare i messaggi. Restituisci `next(e)` da entrambi per passare ogni messaggio invariato:

| Evento | Si attiva quando | Campi utili |
| :- | :- | :- |
| `session.receive` | Un messaggio arriva per questa sessione, prima che Claude lo legga | `e.text` e `e.origin.kind`, come `peer` o `peer-send-message` per un'altra sessione o agente, `task-notification` o `scheduled-trigger`. Restituisci `{ consumed: reason }` per impedirlo a Claude. |
| `session.send` | Un messaggio sta per partire, dallo strumento SendMessage o da un mod | `e.to`, `e.text` e `e.origin.kind`, che è `model` o `plugin` |

Una sessione impostata per [rifiutare messaggi in entrata](/docs/it/cross-session-messaging#control-inbound-messages) rifiuta un messaggio prima che `session.receive` si attivi, quindi un hook non lo vede mai. Un messaggio che è in sospeso per la tua approvazione raggiunge prima l'hook, quindi un mod può leggere un messaggio che non hai ancora approvato. Il `next(e)` dell'hook rifiuta quando il messaggio non viene consegnato.

Il nome del mittente su un messaggio ricevuto è quello che il mittente ha scritto, quindi non basare una decisione su di esso.

<h2 id="reach-files-processes-and-the-network">
  Accedi a file, processi e rete
</h2>

Un mod accede al file system, ai processi e alla rete attraverso l'API mods, con le stesse autorizzazioni dell'utente che esegue Claude Code. Il modulo hooks stesso non ha API Node.js, nessun timer globale come `setTimeout` e nessun accesso di rete o file proprio. Le API JavaScript standard e web come `URL`, `TextEncoder`, `AbortController` e `crypto.subtle` sono disponibili. Ogni namespace di seguito copre un tipo di accesso:

| Namespace | Cosa fa |
| :- | :- |
| `$.fs` | `read(path)`, `write(path, text)`, `exists(path)`, `stat(path)` e `list(path)` funzionano su file e directory |
| `$.process` | `run(['git', 'status'])` avvia un comando e si risolve quando esce. `spawn` trasmette l'output di un comando di lunga durata. |
| `$.http` | `fetch(url, init)` su `http` o `https`. Si risolve in `{ status, ok, headers, text }` una volta che il corpo è stato letto. |
| `$.store` | Un archivio chiave-valore JSON del tuo plugin, mantenuto tra le sessioni |
| `$.env` | `get` e `set` variabili di ambiente. Scrivi il nome come una stringa letterale. |
| `$.settings` | `read` cosa contengono i file di impostazioni e la politica gestita |
| `$.session` | `messages()` restituisce la trascrizione come un elenco di `{ role, text, toolUses }`. Anche la directory di lavoro, il modello e altro. [`usage()`](/docs/it/plugins/mods/reference#mods-api-methods) restituisce l'uso della finestra di contesto e i limiti del piano. |
| `$.mcp` | `call` uno strumento su un server MCP connesso |

File e processi hanno poche regole proprie:

* **Percorsi**: un percorso relativo è sotto la directory di lavoro della sessione
* **`$.fs.list`**: restituisce le voci di una directory come `{ name, kind, size, isLink }` e non scende nelle sottodirectory
* **`$.process.run`**: accetta un elenco di argomenti e non utilizza shell. Si risolve in `{ exitCode, stdout, stderr }` indipendentemente dal codice di uscita. Rifiuta se il programma non può avviarsi o è ancora in esecuzione al timeout, che è 30 secondi per impostazione predefinita, quindi avvolgilo in `try` e `catch`.

Ognuna di queste chiamate è essa stessa un evento, denominato per il suo namespace e metodo senza il `$.`, come `fs.read` per `$.fs.read`. Un mod [precedente nella catena](/docs/it/plugins/mods/events#the-order-mods-run-in) può osservare, riscrivere o rifiutare la tua chiamata, che è come un'organizzazione limita ciò che i mod raggiungono.

<h2 id="next-steps">
  Passaggi successivi
</h2>

* [Reagisci agli eventi](/docs/it/plugins/mods/events): hook tool calls, prompts e turns
* [Disegna nell'interfaccia](/docs/it/plugins/mods/interface): mostra ciò che il tuo mod raccoglie in un pane o sopra il prompt
* [Testa un mod](/docs/it/plugins/mods/test): stub qualsiasi di queste chiamate in un test
* [Mods reference](/docs/it/plugins/mods/reference): ogni evento, ogni metodo dell'API mods e i limiti
