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

# Hook di Cascade

> Esegui comandi shell personalizzati nei punti chiave del flusso di lavoro di Cascade per logging, controlli di sicurezza, convalida e governance aziendale con hook pre e post.

Gli hook di Cascade ti consentono di eseguire comandi shell personalizzati nei punti chiave del flusso di lavoro di Cascade. Questa potente funzionalità di estensione ti permette di registrare le operazioni, applicare barriere di sicurezza, eseguire controlli di convalida o integrarti con sistemi esterni.

<Note>
  Gli hook sono pensati per utenti esperti e team aziendali che necessitano di un controllo granulare sul comportamento di Cascade. Richiedono conoscenze di base di scripting shell.
</Note>

<div id="what-you-can-build">
  ## Cosa puoi creare
</div>

Hooks offrono un'ampia gamma di funzionalità di automazione e governance:

* **Logging e analisi**: Tieni traccia di ogni file letto, modifica al codice, comando eseguito, prompt dell'utente o risposta di Cascade ai fini della conformità e dell'analisi dell'utilizzo
* **Controlli di sicurezza**: Impedisci a Cascade di accedere a file sensibili, eseguire comandi pericolosi o elaborare prompt che violano le policy
* **Controllo qualità**: Esegui automaticamente linter, formatter o test dopo le modifiche al codice
* **Flussi di lavoro personalizzati**: Integrali con tracker di issue, sistemi di notifica o pipeline di distribuzione
* **Standardizzazione del team**: Applica standard di codifica e best practice in tutta l'organizzazione

<div id="how-hooks-work">
  ## Come funzionano gli Hooks
</div>

Gli hook sono comandi shell che vengono eseguiti automaticamente quando si verificano specifiche azioni di Cascade. Ogni hook:

1. **Riceve il contesto** (i dettagli dell'azione in esecuzione) tramite JSON come input standard
2. **Esegue il tuo script** - Python, Bash, Node.js o qualsiasi altro eseguibile
3. **Restituisce un risultato** tramite il codice di uscita e i flussi di output

Per i **pre-hook** (eseguiti prima di un'azione), il tuo script può **bloccare l'azione** terminando con il codice di uscita `2`. Questo rende i pre-hook ideali per implementare policy di sicurezza o controllo di convalida.

<div id="configuration">
  ## Configurazione
</div>

Gli hook si configurano in file JSON che possono essere collocati a tre livelli diversi. Cascade carica e unisce gli hook da tutte queste posizioni, offrendo ai team flessibilità nel modo in cui distribuiscono e gestiscono le configurazioni degli hook.

<div id="system-level">
  #### A livello di sistema
</div>

Gli hook a livello di sistema sono ideali per applicare policy valide per l'intera organizzazione su macchine di sviluppo condivise. Ad esempio, puoi usarli per imporre policy di sicurezza, requisiti di conformità o flussi di lavoro obbligatori per la revisione del codice. I team Enterprise possono anche configurare gli hook tramite la [dashboard cloud](#cloud-dashboard-configuration) senza dover gestire file locali.

* **macOS**: `/Library/Application Support/Windsurf/hooks.json`
* **Linux/WSL**: `/etc/windsurf/hooks.json`
* **Windows**: `C:\ProgramData\Windsurf\hooks.json`

<div id="user-level">
  #### A livello utente
</div>

Gli hook a livello utente sono ideali per preferenze personali e flussi di lavoro opzionali.

* **Devin Desktop IDE**: `~/.codeium/windsurf/hooks.json`
* **Plugin JetBrains**: `~/.codeium/hooks.json`

<div id="workspace-level">
  #### A livello di workspace
</div>

Gli hook a livello di workspace consentono ai team di tenere sotto controllo di versione le policy specifiche del progetto insieme al codice. Possono includere regole di convalida personalizzate, integrazioni specifiche del progetto o flussi di lavoro specifici del team.

* **Posizione**: `.windsurf/hooks.json` nella radice del workspace

<Note>
  Gli hook di tutte e tre le posizioni vengono **combinati**. Se lo stesso evento hook è configurato in più posizioni, tutti gli hook verranno eseguiti nell'ordine seguente: sistema → utente → workspace.
</Note>

<div id="basic-structure">
  ### Struttura di base
</div>

Ecco un esempio della struttura di base della configurazione degli hook:

```json theme={null}
{
  "hooks": {
    "pre_read_code": [
      {
        "command": "python3 /path/to/your/script.py",
        "powershell": "python3 C:\\path\\to\\your\\script.py",
        "show_output": true
      }
    ],
    "post_write_code": [
      {
        "command": "python3 /path/to/another/script.py",
        "show_output": true
      }
    ]
  }
}
```

In questo esempio, `pre_read_code` specifica sia un comando per macOS/Linux sia un comando PowerShell per Windows. L'hook `post_write_code` specifica solo `command`, quindi verrà eseguito su macOS/Linux e su Windows userà PowerShell come soluzione di fallback.

<div id="configuration-options">
  ### Opzioni di configurazione
</div>

Ogni hook accetta i seguenti parametri:

| Parametro           | Tipo    | Descrizione                                                                                                                                             |
| ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `command`           | string  | Il comando shell da eseguire su **macOS/Linux** (eseguito tramite `bash -c`). Deve essere specificato almeno uno tra `command` e `powershell`.          |
| `powershell`        | string  | Facoltativo. Il comando da eseguire su **Windows** (eseguito tramite `powershell -Command`). Se omesso su Windows, `command` viene usato come fallback. |
| `show_output`       | boolean | Indica se visualizzare l'output stdout/stderr dell'hook nella UI di Cascade rivolta all'utente. Utile per il debug.                                     |
| `working_directory` | string  | Facoltativo. La directory da cui eseguire il comando. Per impostazione predefinita, è la radice del workspace.                                          |

<div id="cross-platform-behavior">
  #### Comportamento multipiattaforma
</div>

I campi `command` e `powershell` consentono di definire, in un'unica configurazione, comandi appropriati per ciascuna piattaforma. Questo è utile per i team con parchi macchine misti macOS/Linux e Windows.

| Piattaforma | `command` impostato | `powershell` impostato | Risultato                                                 |
| ----------- | :-----------------: | :--------------------: | --------------------------------------------------------- |
| macOS/Linux |          ✓          |       (ignorato)       | Esegue `command` tramite `bash -c`                        |
| macOS/Linux |          ✗          |            ✓           | L'hook viene ignorato senza alcun avviso                  |
| Windows     |          ✓          |            ✗           | Usa `command` come fallback tramite `powershell -Command` |
| Windows     |          ✗          |            ✓           | Esegue `powershell` tramite `powershell -Command`         |
| Windows     |          ✓          |            ✓           | Esegue `powershell` tramite `powershell -Command`         |
| Qualsiasi   |          ✗          |            ✗           | Errore di convalida                                       |

<Note>
  **Informazioni sul parametro `working_directory`:**

  * Nei workspace multi-repo, il valore predefinito è la radice del repo su cui si sta lavorando
  * I percorsi relativi vengono risolti a partire dalla posizione predefinita (workspace o radice del repo)
  * I percorsi assoluti sono supportati
  * L'uso di `~` per espandere la home directory non è supportato
</Note>

<div id="hook-events">
  ## Eventi hook
</div>

Cascade offre dodici eventi hook che coprono le azioni più importanti nel flusso di lavoro dell'agente.

<div id="common-input-structure">
  ### Struttura di input comune
</div>

Tutti gli hook ricevono un oggetto JSON con i seguenti campi comuni:

| Campo               | Tipo   | Descrizione                                                                                                                                                                                                                                                                                                                                                   |
| ------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent_action_name` | string | Il nome dell'evento hook (ad es. "pre\_read\_code", "post\_write\_code")                                                                                                                                                                                                                                                                                      |
| `trajectory_id`     | string | Identificatore univoco dell'intera conversazione Cascade                                                                                                                                                                                                                                                                                                      |
| `execution_id`      | string | Identificatore univoco del singolo turno dell'agente                                                                                                                                                                                                                                                                                                          |
| `timestamp`         | string | Timestamp ISO 8601 che indica quando è stato attivato l'hook                                                                                                                                                                                                                                                                                                  |
| `model_name`        | string | Nome leggibile del modello associato a questa invocazione dell'hook (ad es. "Claude Sonnet 4", "GPT 4.1"). È la stessa etichetta mostrata nel selettore dei modelli di Cascade. Il valore può cambiare nel tempo man mano che Devin Desktop aggiorna i nomi visualizzati dei modelli. È impostato su "Unknown" quando non è possibile determinare il modello. |
| `tool_info`         | object | Informazioni specifiche dell'evento (variano in base al tipo di hook)                                                                                                                                                                                                                                                                                         |

Negli esempi seguenti, i campi comuni sono omessi per brevità. Esistono dodici tipi principali di eventi hook:

<div id="pre_read_code">
  ### pre\_read\_code
</div>

Si attiva **prima** che Cascade legga un file di codice. Può bloccare l'azione se l'hook termina con il codice 2.

**Casi d'uso**: limitare l'accesso ai file, registrare le operazioni di lettura, verificare le autorizzazioni

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "pre_read_code",
  "tool_info": {
    "file_path": "/Users/yourname/project/file.py"
  }
}
```

Questo `file_path` può essere il percorso di una directory quando Cascade legge una directory in modo ricorsivo.

<div id="post_read_code">
  ### post\_read\_code
</div>

Si attiva **dopo** che Cascade ha letto correttamente un file di codice.

**Casi d'uso**: registrare le letture riuscite, monitorare gli schemi di accesso ai file

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_read_code",
  "tool_info": {
    "file_path": "/Users/yourname/project/file.py"
  }
}
```

Questo `file_path` può essere il percorso di una directory quando Cascade legge una directory in modo ricorsivo.

<div id="pre_write_code">
  ### pre\_write\_code
</div>

Si attiva **prima** che Cascade scriva o modifichi un file di codice. Può bloccare l'azione se l'hook termina con il codice 2.

**Casi d'uso**: impedire modifiche ai file protetti, eseguire il backup dei file prima delle modifiche

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "pre_write_code",
  "tool_info": {
    "file_path": "/Users/yourname/project/file.py",
    "edits": [
      {
        "old_string": "def old_function():\n    pass",
        "new_string": "def new_function():\n    return True"
      }
    ]
  }
}
```

<div id="post_write_code">
  ### post\_write\_code
</div>

Attivato **dopo** che Cascade scrive o modifica un file di codice.

**Casi d'uso**: Run di linter, formatter o test; registra le modifiche al codice

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_write_code",
  "tool_info": {
    "file_path": "/Users/yourname/project/file.py",
    "edits": [
      {
        "old_string": "import os",
        "new_string": "import os\nimport sys"
      }
    ]
  }
}
```

<div id="pre_run_command">
  ### pre\_run\_command
</div>

Si attiva **prima** che Cascade esegua un comando nel terminale. Può bloccare l'action se l'hook termina con il codice 2.

**Casi d'uso**: Bloccare comandi pericolosi, registrare tutte le esecuzioni dei comandi, aggiungere controlli di sicurezza

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "pre_run_command",
  "tool_info": {
    "command_line": "npm install package-name",
    "cwd": "/Users/yourname/project"
  }
}
```

<div id="post_run_command">
  ### post\_run\_command
</div>

Si attiva **dopo** che Cascade esegue un comando nel terminale.

**Casi d'uso**: registrare i risultati dei comandi, attivare azioni successive

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_run_command",
  "tool_info": {
    "command_line": "npm install package-name",
    "cwd": "/Users/yourname/project"
  }
}
```

<div id="pre_mcp_tool_use">
  ### pre\_mcp\_tool\_use
</div>

Si attiva **prima** che Cascade invochi uno strumento MCP (Model Context Protocol). Può bloccare l'azione se l'hook termina con il codice 2.

**Casi d'uso**: Registrare l'utilizzo degli strumenti MCP, limitare quali strumenti MCP possono essere usati

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "pre_mcp_tool_use",
  "tool_info": {
    "mcp_server_name": "github",
    "mcp_tool_arguments": {
      "owner": "code-owner",
      "repo": "my-cool-repo",
      "title": "Bug report",
      "body": "Description of the bug here"
    },
    "mcp_tool_name": "create_issue"
  }
}
```

<div id="post_mcp_tool_use">
  ### post\_mcp\_tool\_use
</div>

Si attiva **dopo** che Cascade invoca con successo uno strumento MCP.

**Casi d'uso**: Registrare le operazioni MCP, monitorare l'utilizzo dell'API, visualizzare i risultati MCP

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_mcp_tool_use",
  "tool_info": {
    "mcp_result": "...",
    "mcp_server_name": "github",
    "mcp_tool_arguments": {
      "owner": "code-owner",
      "perPage": 1,
      "repo": "my-cool-repo",
      "sha": "main"
    },
    "mcp_tool_name": "list_commits"
  }
}
```

<div id="pre_user_prompt">
  ### pre\_user\_prompt
</div>

Attivato **prima** che Cascade elabori il testo del prompt di un utente. Questo può bloccare l'azione se l'hook termina con il codice 2.

**Casi d'uso**: registrare tutti i prompt degli utenti a fini di audit, bloccare prompt potenzialmente dannosi o in violazione delle policy

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "pre_user_prompt",
  "tool_info": {
    "user_prompt": "can you run the echo hello command"
  }
}
```

L'opzione di configurazione `show_output` non è applicabile a questo hook.

<div id="post_cascade_response">
  ### post\_cascade\_response
</div>

Attivato in modo asincrono **dopo** che Cascade ha completato una risposta al prompt di un utente. Questo hook riceve l'intera risposta di Cascade successiva all'ultimo input dell'utente.

**Casi d'uso**: Registrare tutte le risposte di Cascade a fini di audit, analizzare i pattern delle risposte, inviare le risposte a sistemi esterni per la revisione della conformità

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_cascade_response",
  "tool_info": {
    "response": "### Planner Response\n\nI'll help you create that file.\n\n*Created file `/path/to/file.py`*\n\n### Planner Response\n\nThe file has been created successfully."
  }
}
```

Il campo `response` contiene il contenuto in formato Markdown della risposta di Cascade dall'ultimo input dell'utente. Include le risposte del planner, le azioni degli strumenti (letture e scritture di file, comandi) e qualsiasi altro passaggio eseguito da Cascade. Include anche informazioni su quali [regole](/it/desktop/cascade/memories) sono state attivate. Consulta l'esempio [Tracking Triggered Rules](#tracking-triggered-rules) per capire come analizzare l'utilizzo delle regole.

L'opzione di configurazione `show_output` non si applica a questo hook.

<Warning>
  Il contenuto di `response` è derivato dai dati della traiettoria e può contenere informazioni sensibili provenienti dalla tua codebase o dalle tue conversazioni. Gestisci questi dati in conformità con le politiche di sicurezza e privacy della tua organizzazione.
</Warning>

<div id="post_cascade_response_with_transcript">
  ### post\_cascade\_response\_with\_transcript
</div>

Attivato in modo asincrono **dopo** che Cascade ha completato una risposta al prompt dell'utente, in modo simile a `post_cascade_response`. Invece di fornire un riepilogo markdown inline, questo hook scrive la trascrizione completa della conversazione (dall'inizio della conversazione) in un file JSONL locale e ne fornisce il percorso.

**Casi d'uso**: registrazione per audit e conformità in ambito Enterprise, monitoraggio dei contributi generati dall'IA, invio delle trascrizioni a strumenti esterni di osservabilità o analisi

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_cascade_response_with_transcript",
  "tool_info": {
    "transcript_path": "/Users/yourname/.windsurf/transcripts/{trajectory_id}.jsonl"
  }
}
```

Il `transcript_path` punta a un file [JSONL](https://jsonlines.org/) in `~/.windsurf/transcripts/{trajectory_id}.jsonl`. Ogni riga contiene un oggetto JSON che rappresenta un singolo passaggio della conversazione, con i campi `type` e `status`, oltre ai dati specifici del passaggio. Ad esempio:

```jsonl theme={null}
{"status":"done","type":"user_input","user_input":{"rules_applied":{"always_on":["my-rule.md"]},"user_response":"create a hello world file"}}
{"planner_response":{"response":"I'll create a hello world file for you."},"status":"done","type":"planner_response"}
{"code_action":{"new_content":"print('hello world')\n","path":"/path/to/file.py"},"status":"done","type":"code_action"}
{"planner_response":{"response":"I created the file for you."},"status":"done","type":"planner_response"}
```

La trascrizione include dati dettagliati di proprietà del cliente, come contenuti dei file, output dei comandi, argomenti dei tool, risultati di ricerca e [regole](/it/desktop/cascade/memories) applicate. Nota che la struttura esatta di ogni passaggio potrebbe cambiare nelle versioni future, quindi assicurati che gli eventuali consumer degli hook siano robusti a queste variazioni.

I file di trascrizione vengono scritti con autorizzazioni `0600`. Devin Desktop limita automaticamente la directory delle trascrizioni a 100 file, eliminando i più vecchi in base alla data di modifica.

L'opzione di configurazione `show_output` non si applica a questo hook.

Questa tabella mostra le principali differenze tra gli hook `post_cascade_response` e `post_cascade_response_with_transcript`:

|                          | `post_cascade_response`                            | `post_cascade_response_with_transcript`                                                  |
| ------------------------ | -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Ambito dei dati**      | Solo i passaggi dall'ultimo input dell'utente      | L'intera conversazione dall'inizio                                                       |
| **Formato**              | Riepilogo Markdown in `tool_info.response`         | File JSONL strutturato in `tool_info.transcript_path`                                    |
| **Livello di dettaglio** | Riepilogo condensato, leggibile dagli esseri umani | Dati dettagliati leggibili dalla macchina (contenuti dei file, output dei comandi, ecc.) |
| **Consegna**             | Inline tramite JSON su stdin                       | File su disco (`~/.windsurf/transcripts/`)                                               |

<Warning>
  I file di trascrizione conterranno informazioni sensibili della tua codebase, inclusi contenuti dei file, output dei comandi e cronologia della conversazione. Gestisci questi file in conformità con le policy di sicurezza e privacy della tua organizzazione.
</Warning>

<div id="post_setup_worktree">
  ### post\_setup\_worktree
</div>

Si attiva **dopo** la creazione e la configurazione di un nuovo [git worktree](./worktrees). L'hook viene eseguito all'interno della directory del nuovo **worktree**.

**Casi d'uso**: Copiare file `.env` o altri file non tracciati nel worktree, installare dipendenze, eseguire script di setup

**Variabili d'ambiente**:

| Variabile              | Descrizione                                                                                                                   |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `$ROOT_WORKSPACE_PATH` | Il percorso assoluto del workspace originale. Usalo per accedere ai file o eseguire comandi relativi al repository originale. |

**JSON di input**:

```json theme={null}
{
  "agent_action_name": "post_setup_worktree",
  "tool_info": {
    "worktree_path": "/Users/me/.windsurf/worktrees/my-repo/abmy-repo-c123",
    "root_workspace_path": "/Users/me/projects/my-repo"
  }
}
```

<div id="exit-codes">
  ## Codici di uscita
</div>

I tuoi script hook comunicano i risultati tramite i codici di uscita:

| Codice di uscita | Significato      | Effetto                                                                                             |
| ---------------- | ---------------- | --------------------------------------------------------------------------------------------------- |
| `0`              | Successo         | L'action procede normalmente                                                                        |
| `2`              | Errore bloccante | L'agent Cascade vedrà il messaggio di errore da stderr. Per i pre-hook, questo **blocca** l'action. |
| Qualsiasi altro  | Errore           | L'action procede normalmente                                                                        |

<Warning>
  Solo i **pre-hook** (pre\_user\_prompt, pre\_read\_code, pre\_write\_code, pre\_run\_command, pre\_mcp\_tool\_use) possono bloccare le action usando il codice di uscita 2. I post-hook non possono bloccare l'esecuzione, perché l'action è già avvenuta.
</Warning>

Tieni presente che, se `show_output` è true, l'utente può vedere nella UI di Cascade qualsiasi output standard o errore standard generato da un hook.

<div id="example-use-cases">
  ## Esempi di casi d'uso
</div>

<div id="logging-all-cascade-actions">
  ### Registrazione di tutte le azioni di Cascade
</div>

Monitora ogni azione eseguita da Cascade a fini di audit.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "post_read_code": [
      {
        "command": "python3 /Users/yourname/hooks/log_input.py",
        "show_output": true
      }
    ],
    "post_write_code": [
      {
        "command": "python3 /Users/yourname/hooks/log_input.py",
        "show_output": true
      }
    ],
    "post_run_command": [
      {
        "command": "python3 /Users/yourname/hooks/log_input.py",
        "show_output": true
      }
    ],
    "post_mcp_tool_use": [
      {
        "command": "python3 /Users/yourname/hooks/log_input.py",
        "show_output": true
      }
    ],
    "post_cascade_response": [
      {
        "command": "python3 /Users/yourname/hooks/log_input.py"
      }
    ]
  }
}
```

**Script** (`log_input.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json

def main():
    # Leggi i dati JSON da stdin
    input_data = sys.stdin.read()
    
    # Analizza il JSON
    try:
        data = json.loads(input_data)
        
        # Scrivi il JSON formattato su file
        with open("/Users/yourname/hooks/input.txt", "a") as f:
            f.write('\n' + '='*80 + '\n')
            f.write(json.dumps(data, indent=2, separators=(',', ': ')))
            f.write('\n')
    
        print(json.dumps(data, indent=2))
    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

Questo script aggiunge ogni invocazione di hook a un file di log, creando una traccia di controllo di tutte le azioni di Cascade. Puoi trasformare i dati di input o applicare una logica personalizzata, come ritieni opportuno.

<div id="restricting-file-access">
  ### Limitare l'accesso ai file
</div>

Impedisci a Cascade di leggere file al di fuori di una directory specifica.

**configurazione**:

```json theme={null}
{
  "hooks": {
    "pre_read_code": [
      {
        "command": "python3 /Users/yourname/hooks/block_read_access.py",
        "show_output": true
      }
    ]
  }
}
```

**Script** (`block_read_access.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json

ALLOWED_PREFIX = "/Users/yourname/my-project/"

def main():
    # Leggi i dati JSON da stdin
    input_data = sys.stdin.read()

    # Analizza il JSON
    try:
        data = json.loads(input_data)

        if data.get("agent_action_name") == "pre_read_code":
            tool_info = data.get("tool_info", {})
            file_path = tool_info.get("file_path", "")
            
            if not file_path.startswith(ALLOWED_PREFIX):
                print(f"Access denied: Cascade is only allowed to read files under {ALLOWED_PREFIX}", file=sys.stderr)
                sys.exit(2)  # Il codice di uscita 2 blocca l'action
            
            print(f"Access granted: {file_path}", file=sys.stdout)

    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

Quando Cascade tenta di leggere un file al di fuori della directory consentita, questo hook blocca l'operazione e visualizza un messaggio di errore.

<div id="blocking-dangerous-commands">
  ### Blocco dei comandi pericolosi
</div>

Impedisci a Cascade di eseguire comandi potenzialmente pericolosi.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "pre_run_command": [
      {
        "command": "python3 /Users/yourname/hooks/block_dangerous_commands.py",
        "show_output": true
      }
    ]
  }
}
```

**Script** (`block_dangerous_commands.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json

DANGEROUS_COMMANDS = ["rm -rf", "sudo rm", "format", "del /f"]

def main():
    # Leggi i dati JSON da stdin
    input_data = sys.stdin.read()

    # Analizza il JSON
    try:
        data = json.loads(input_data)

        if data.get("agent_action_name") == "pre_run_command":
            tool_info = data.get("tool_info", {})
            command = tool_info.get("command_line", "")

            for dangerous_cmd in DANGEROUS_COMMANDS:
                if dangerous_cmd in command:
                    print(f"Command blocked: '{dangerous_cmd}' is not allowed for safety reasons.", file=sys.stderr)
                    sys.exit(2)  # Il codice di uscita 2 blocca il comando
            
            print(f"Command approved: {command}", file=sys.stdout)

    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

Questo hook analizza i comandi per individuare pattern pericolosi e li blocca prima dell'esecuzione.

<div id="blocking-policy-violating-prompts">
  ### Blocco dei prompt che violano le policy
</div>

Impedisci agli utenti di inviare prompt che violano le policy dell'organizzazione.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "pre_user_prompt": [
      {
        "command": "python3 /Users/yourname/hooks/block_bad_prompts.py"
      }
    ]
  }
}
```

**Script** (`block_bad_prompts.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json

BLOCKED_PATTERNS = [
    "something dangerous",
    "bypass security",
    "ignore previous instructions"
]

def main():
    # Leggi i dati JSON da stdin
    input_data = sys.stdin.read()

    # Analizza il JSON
    try:
        data = json.loads(input_data)

        if data.get("agent_action_name") == "pre_user_prompt":
            tool_info = data.get("tool_info", {})
            user_prompt = tool_info.get("user_prompt", "").lower()

            for pattern in BLOCKED_PATTERNS:
                if pattern in user_prompt:
                    print(f"Prompt blocked: Contains prohibited content. The user cannot ask the agent to do bad things.", file=sys.stderr)
                    sys.exit(2)  # Il codice di uscita 2 blocca il prompt

    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

Questo hook esamina i prompt dell'utente prima che vengano elaborati e blocca quelli che contengono pattern non consentiti. Quando un prompt viene bloccato, l'utente vede un messaggio di errore nella UI di Cascade.

<div id="logging-cascade-responses">
  ### Registrazione delle risposte di Cascade
</div>

Registra tutte le risposte di Cascade per verifiche di conformità o analisi.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "post_cascade_response": [
      {
        "command": "python3 /Users/yourname/hooks/log_cascade_response.py"
      }
    ]
  }
}
```

**Script** (`log_cascade_response.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json
from datetime import datetime

def main():
    # Leggi i dati JSON da stdin
    input_data = sys.stdin.read()

    # Analizza il JSON
    try:
        data = json.loads(input_data)

        if data.get("agent_action_name") == "post_cascade_response":
            tool_info = data.get("tool_info", {})
            cascade_response = tool_info.get("response", "")
            trajectory_id = data.get("trajectory_id", "unknown")
            timestamp = data.get("timestamp", datetime.now().isoformat())

            # Registra su file
            with open("/Users/yourname/hooks/cascade_responses.log", "a") as f:
                f.write(f"\n{'='*80}\n")
                f.write(f"Timestamp: {timestamp}\n")
                f.write(f"Trajectory ID: {trajectory_id}\n")
                f.write(f"Response:\n{cascade_response}\n")

            print(f"Logged Cascade response for trajectory {trajectory_id}")

    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

Questo hook registra ogni risposta di Cascade in un file, creando una traccia di controllo di tutti i contenuti generati dall'IA. Puoi estenderlo per inviare i dati a sistemi di logging esterni, database o piattaforme di conformità.

<div id="tracking-triggered-rules">
  ### Tracciamento delle regole attivate
</div>

Monitora quali [regole](/it/desktop/cascade/memories) vengono applicate durante le interazioni con Cascade, per l'osservabilità e le metriche.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "post_cascade_response": [
      {
        "command": "python3 /Users/yourname/hooks/track_rules.py"
      }
    ]
  }
}
```

**Script** (`track_rules.py`):

```python theme={null}
#!/usr/bin/env python3

import sys
import json
import re
from datetime import datetime

def extract_triggered_rules(response: str) -> dict:
    """
    Parse triggered rules from the Cascade response.
    Rules appear as: - (Rule-Type) Triggered Rule: rule-filename.md
    """
    pattern = r"- \(([^)]+)\) Triggered Rule: (.+?)(?:\s*$)"
    rules = {}

    for match in re.finditer(pattern, response, re.MULTILINE):
        rule_type, rule_name = match.groups()
        if rule_type not in rules:
            rules[rule_type] = []
        rules[rule_type].append(rule_name)

    return rules

def main():
    input_data = sys.stdin.read()

    try:
        data = json.loads(input_data)

        if data.get("agent_action_name") == "post_cascade_response":
            response = data.get("tool_info", {}).get("response", "")
            trajectory_id = data.get("trajectory_id", "unknown")
            timestamp = data.get("timestamp", datetime.now().isoformat())

            rules = extract_triggered_rules(response)
            total_rules = sum(len(v) for v in rules.values())

            # Scrivi nel file di log
            with open("/Users/yourname/hooks/rules_usage.log", "a") as f:
                f.write(f"\n{'='*60}\n")
                f.write(f"Timestamp: {timestamp}\n")
                f.write(f"Trajectory: {trajectory_id}\n")
                f.write(f"Total rules triggered: {total_rules}\n")
                for rule_type, rule_list in rules.items():
                    if rule_list:
                        f.write(f"  {rule_type}: {', '.join(rule_list)}\n")

            print(f"Tracked {total_rules} triggered rules")

    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
```

**Tipi di regole:**

* `Always On` - Regole sempre incluse
* `Model Decision` - Regole le cui descrizioni sono state mostrate al modello per un'applicazione condizionale
* `Manual` - Regole menzionate esplicitamente con @ nell'input dell'utente
* `Global` - Regole globali da `global_rules.md`
* `Glob` - Regole attivate dall'accesso a file che corrispondono a pattern glob

<Note>
  Questo tiene traccia di quali regole sono state *presentate* al modello o *attivate* dall'accesso ai file, ma non indica se il modello abbia effettivamente *seguito* una regola. Le regole già mostrate di recente nella conversazione vengono deduplicate e potrebbero non comparire di nuovo fino a più avanti.
</Note>

<div id="running-code-formatters-after-edits">
  ### Eseguire i formattatori del codice dopo le modifiche
</div>

Formatta automaticamente i file di codice dopo che Cascade li ha modificati.

**Configurazione**:

```json theme={null}
{
  "hooks": {
    "post_write_code": [
      {
        "command": "bash /Users/yourname/hooks/format_code.sh",
        "show_output": false
      }
    ]
  }
}
```

**Script** (`format_code.sh`):

```bash theme={null}
#!/bin/bash

# Leggi JSON da stdin
input=$(cat)

# Estrai il percorso del file usando jq
file_path=$(echo "$input" | jq -r '.tool_info.file_path')

# Formatta in base all'estensione del file
if [[ "$file_path" == *.py ]]; then
    black "$file_path" 2>&1
    echo "Formatted Python file: $file_path"
elif [[ "$file_path" == *.js ]] || [[ "$file_path" == *.ts ]]; then
    prettier --write "$file_path" 2>&1
    echo "Formatted JS/TS file: $file_path"
elif [[ "$file_path" == *.go ]]; then
    gofmt -w "$file_path" 2>&1
    echo "Formatted Go file: $file_path"
fi

exit 0
```

Questo hook applica automaticamente il formatter appropriato in base al tipo di file dopo ogni modifica.

<div id="setting-up-worktrees">
  ### Configurazione dei worktree
</div>

Copia i file dell'ambiente e installa le dipendenze quando viene creato un nuovo worktree.

**Config** (in `.windsurf/hooks.json`):

```json theme={null}
{
  "hooks": {
    "post_setup_worktree": [
      {
        "command": "bash $ROOT_WORKSPACE_PATH/hooks/setup_worktree.sh",
        "show_output": true
      }
    ]
  }
}
```

**Script** (`hooks/setup_worktree.sh`):

```bash theme={null}
#!/bin/bash

# Copia i file environment dal workspace originale
if [ -f "$ROOT_WORKSPACE_PATH/.env" ]; then
    cp "$ROOT_WORKSPACE_PATH/.env" .env
    echo "Copied .env file"
fi

if [ -f "$ROOT_WORKSPACE_PATH/.env.local" ]; then
    cp "$ROOT_WORKSPACE_PATH/.env.local" .env.local
    echo "Copied .env.local file"
fi

# Installa le dependencies
if [ -f "package.json" ]; then
    npm install
    echo "Installed npm dependencies"
fi

exit 0
```

Questo hook garantisce che ogni worktree disponga automaticamente della configurazione dell'ambiente necessaria e delle dipendenze richieste.

<div id="best-practices">
  ## Buone pratiche
</div>

<div id="security">
  ### Sicurezza
</div>

<Warning>
  **Usa Cascade Hooks a tuo rischio e pericolo**: gli hook eseguono automaticamente comandi shell con tutte le autorizzazioni del tuo account utente. Sei interamente responsabile del codice che configuri. Hook progettati male o dannosi possono modificare file, eliminare dati, esporre credenziali o compromettere il sistema.
</Warning>

* **Convalida tutti gli input**: non fidarti mai dell'input JSON senza prima convalidarlo, soprattutto per quanto riguarda i percorsi dei file e i comandi.
* **Usa percorsi assoluti**: usa sempre percorsi assoluti nelle configurazioni degli hook per evitare ambiguità.
* **Proteggi i dati sensibili**: evita di registrare informazioni sensibili come API key o credenziali.
* **Verifica le autorizzazioni**: assicurati che gli script degli hook abbiano autorizzazioni del file system appropriate.
* **Controlla prima della distribuzione**: controlla ogni comando e script degli hook prima di aggiungerli alla configurazione.
* **Testa in isolamento**: esegui gli hook in un ambiente di test prima di abilitarli sulla macchina di sviluppo principale.

<div id="performance-considerations">
  ### Considerazioni sulle prestazioni
</div>

* **Mantieni gli hook veloci**: gli hook lenti riducono la reattività di Cascade. Punta a tempi di esecuzione inferiori a 100 ms.
* **Usa operazioni asincrone**: per hook non bloccanti, valuta la possibilità di inviare i log a una coda o a un database in modo asincrono.
* **Filtra subito**: verifica il tipo di action all'inizio dello script per evitare elaborazioni non necessarie.

<div id="error-handling">
  ### Gestione degli errori
</div>

* **Verifica sempre il JSON**: Usa blocchi try-catch per gestire correttamente input non validi.
* **Registra correttamente gli errori**: Scrivi gli errori su `stderr` in modo che siano visibili quando `show_output` è abilitato.
* **Gestisci gli errori in modo sicuro**: Se il tuo hook incontra un errore, valuta se debba bloccare l'action o consentirle di proseguire.

<div id="testing-your-hooks">
  ### Test dei tuoi hook
</div>

1. **Inizia con il logging**: inizia implementando un semplice hook di logging per comprendere il flusso dei dati.
2. **Usa `show_output: true`**: abilita l'output durante lo sviluppo per vedere cosa stanno facendo i tuoi hook.
3. **Testa il comportamento di blocco**: verifica che il codice di uscita 2 blocchi correttamente le azioni nei pre-hook.
4. **Verifica tutti i percorsi del codice**: testa nei tuoi script sia gli scenari di successo sia quelli di errore.

<div id="enterprise-distribution">
  ## Distribuzione Enterprise
</div>

Le organizzazioni Enterprise devono applicare policy di sicurezza, requisiti di conformità e standard di sviluppo che i singoli utenti non possono aggirare. Cascade Hooks supporta due metodi di distribuzione Enterprise:

1. **Cloud Dashboard** - Configura gli hook tramite Team Settings nella dashboard di Devin Desktop
2. **File a livello di sistema** - Distribuisci gli hook tramite MDM o strumenti di gestione della configurazione

Entrambi i metodi possono essere usati insieme — gli hook da tutte le origini vengono combinati ed eseguiti in ordine.

<div id="cloud-dashboard-configuration">
  ### Configurazione della Cloud Dashboard
</div>

Gli admin del team possono configurare i Cascade Hooks direttamente dalla dashboard di Devin Desktop.

**Requisiti:**

* piano Enterprise
* autorizzazione `TEAM_SETTINGS_UPDATE`

**Per configurare:**

1. Vai a **Team Settings** nella dashboard di Devin Desktop
2. Individua la sezione **Cascade Hooks**
3. Inserisci la configurazione degli hook in formato JSON
4. Salva le modifiche

Gli hook configurati tramite la dashboard vengono distribuiti automaticamente a tutti i membri del team e caricati all'avvio di Devin Desktop. Gli hook configurati nel cloud vengono caricati per primi, seguiti da quelli a livello di sistema, utente e workspace.

<Note>
  Quando vengono unite più configurazioni del team, gli hook vengono combinati per action anziché essere sovrascritti. Ciò significa che gli hook di tutte le configurazioni del team applicabili verranno eseguiti insieme.
</Note>

<div id="system-level-file-deployment">
  ### Distribuzione dei file a livello di sistema
</div>

Per le organizzazioni che preferiscono una configurazione basata su file o hanno bisogno che gli hook funzionino offline, distribuisci la configurazione obbligatoria `hooks.json` nelle seguenti posizioni specifiche del sistema operativo:

**macOS:**

```
/Library/Application Support/Windsurf/hooks.json
```

**Linux/WSL:**

```
/etc/windsurf/hooks.json
```

**Windows:**

```
C:\ProgramData\Windsurf\hooks.json
```

Colloca gli script hook nella directory di sistema corrispondente (ad es. `/usr/local/share/windsurf-hooks/` sui sistemi Unix).

Gli hook a livello di sistema hanno la precedenza su quelli dell'utente e del workspace e non possono essere disabilitati dagli utenti finali senza autorizzazioni di root.

<div id="mdm-and-configuration-management">
  #### MDM e gestione della configurazione
</div>

I team IT Enterprise possono distribuire hook a livello di sistema utilizzando strumenti standard:

**Mobile Device Management (MDM)**

* **Jamf Pro** (macOS) - Distribuzione tramite profili di configurazione o script
* **Microsoft Intune** (Windows/macOS) - Usa script PowerShell o la distribuzione tramite criteri
* **Workspace ONE**, **Google Endpoint Management** e altre soluzioni MDM

**Gestione della configurazione**

* **Ansible**, **Puppet**, **Chef**, **SaltStack** - Usa l'automazione dell'infrastruttura esistente
* **Script di distribuzione personalizzati** - Script shell, PowerShell o gli strumenti che preferisci

<div id="verification-and-auditing">
  #### Verifica e audit
</div>

Dopo la distribuzione, verifica che gli hook siano installati correttamente:

```bash theme={null}
# Verifica che gli hook di sistema siano presenti
ls -la /etc/windsurf/hooks.json  # Linux
ls -la "/Library/Application Support/Windsurf/hooks.json"  # macOS

# Testa l'esecuzione degli hook (l'output degli hook dovrebbe essere visibile in Cascade)
# Chiedi a uno sviluppatore di attivare l'action pertinente di Cascade

# Verifica che gli utenti non possano modificare gli hook di sistema
sudo chown root:root /etc/windsurf/hooks.json
sudo chmod 644 /etc/windsurf/hooks.json
```

<Note>
  **Importante**: Gli hook a livello di sistema sono gestiti interamente dal team IT o di sicurezza. Devin Desktop non distribuisce né gestisce file nei percorsi di sistema. Assicurati che i team interni si occupino della distribuzione, degli aggiornamenti e della conformità in base alle policy della tua organizzazione.
</Note>

<div id="workspace-hooks-for-team-projects">
  ### Hook del workspace per i progetti del team
</div>

Per convenzioni specifiche di progetto, i team possono usare hook a livello di workspace nel controllo di versione:

```bash theme={null}
# Aggiungi al tuo repository
.windsurf/
├── hooks.json
└── scripts/
    └── format-check.py

# Esegui il commit su git
git add .windsurf/
git commit -m "Add workspace hooks for code formatting"
```

Questo consente ai team di standardizzare le pratiche di sviluppo. Mantieni le policy critiche per la sicurezza a livello di cloud o di sistema ed evita di archiviare informazioni sensibili nel sistema di controllo versione.

<div id="additional-resources">
  ## Risorse aggiuntive
</div>

* **Integrazione MCP**: Scopri di più sul [Model Context Protocol in Devin Desktop](/it/desktop/cascade/mcp)
* **Flussi di lavoro**: Scopri come combinare gli hook con i [flussi di lavoro di Cascade](/it/desktop/cascade/workflows)
* **Analisi**: Monitora l'utilizzo di Cascade con [Analisi del team](/it/desktop/accounts/analytics)
