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.
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.
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.
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
Come funzionano gli Hooks
Gli hook sono comandi shell che vengono eseguiti automaticamente quando si verificano specifiche azioni di Cascade. Ogni hook:
- Riceve il contesto (i dettagli dell’azione in esecuzione) tramite JSON come input standard
- Esegue il tuo script - Python, Bash, Node.js o qualsiasi altro eseguibile
- 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.
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.
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 senza dover gestire file locali.
- macOS:
/Library/Application Support/Windsurf/hooks.json
- Linux/WSL:
/etc/windsurf/hooks.json
- Windows:
C:\ProgramData\Windsurf\hooks.json
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
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
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.
Ecco un esempio della struttura di base della configurazione degli hook:
{
"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.
Opzioni di configurazione
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. |
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 |
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
Cascade offre dodici eventi hook che coprono le azioni più importanti nel flusso di lavoro dell’agente.
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:
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:
{
"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.
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:
{
"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.
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:
{
"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"
}
]
}
}
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:
{
"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"
}
]
}
}
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:
{
"agent_action_name": "pre_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
Si attiva dopo che Cascade esegue un comando nel terminale.
Casi d’uso: registrare i risultati dei comandi, attivare azioni successive
JSON di input:
{
"agent_action_name": "post_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
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:
{
"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"
}
}
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:
{
"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"
}
}
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:
{
"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.
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:
{
"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 sono state attivate. Consulta l’esempio Tracking Triggered Rules per capire come analizzare l’utilizzo delle regole.
L’opzione di configurazione show_output non si applica a questo hook.
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.
post_cascade_response_with_transcript
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:
{
"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 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:
{"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 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/) |
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.
Si attiva dopo la creazione e la configurazione di un nuovo git worktree. 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:
{
"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"
}
}
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 |
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.
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.
Registrazione di tutte le azioni di Cascade
Monitora ogni azione eseguita da Cascade a fini di audit.
Configurazione:
{
"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):
#!/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.
Limitare l’accesso ai file
Impedisci a Cascade di leggere file al di fuori di una directory specifica.
configurazione:
{
"hooks": {
"pre_read_code": [
{
"command": "python3 /Users/yourname/hooks/block_read_access.py",
"show_output": true
}
]
}
}
Script (block_read_access.py):
#!/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.
Blocco dei comandi pericolosi
Impedisci a Cascade di eseguire comandi potenzialmente pericolosi.
Configurazione:
{
"hooks": {
"pre_run_command": [
{
"command": "python3 /Users/yourname/hooks/block_dangerous_commands.py",
"show_output": true
}
]
}
}
Script (block_dangerous_commands.py):
#!/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.
Blocco dei prompt che violano le policy
Impedisci agli utenti di inviare prompt che violano le policy dell’organizzazione.
Configurazione:
{
"hooks": {
"pre_user_prompt": [
{
"command": "python3 /Users/yourname/hooks/block_bad_prompts.py"
}
]
}
}
Script (block_bad_prompts.py):
#!/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.
Registrazione delle risposte di Cascade
Registra tutte le risposte di Cascade per verifiche di conformità o analisi.
Configurazione:
{
"hooks": {
"post_cascade_response": [
{
"command": "python3 /Users/yourname/hooks/log_cascade_response.py"
}
]
}
}
Script (log_cascade_response.py):
#!/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à.
Tracciamento delle regole attivate
Monitora quali regole vengono applicate durante le interazioni con Cascade, per l’osservabilità e le metriche.
Configurazione:
{
"hooks": {
"post_cascade_response": [
{
"command": "python3 /Users/yourname/hooks/track_rules.py"
}
]
}
}
Script (track_rules.py):
#!/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
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.
Formatta automaticamente i file di codice dopo che Cascade li ha modificati.
Configurazione:
{
"hooks": {
"post_write_code": [
{
"command": "bash /Users/yourname/hooks/format_code.sh",
"show_output": false
}
]
}
}
Script (format_code.sh):
#!/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.
Configurazione dei worktree
Copia i file dell’ambiente e installa le dipendenze quando viene creato un nuovo worktree.
Config (in .windsurf/hooks.json):
{
"hooks": {
"post_setup_worktree": [
{
"command": "bash $ROOT_WORKSPACE_PATH/hooks/setup_worktree.sh",
"show_output": true
}
]
}
}
Script (hooks/setup_worktree.sh):
#!/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.
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.
- 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.
- 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.
- 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.
- Inizia con il logging: inizia implementando un semplice hook di logging per comprendere il flusso dei dati.
- Usa
show_output: true: abilita l’output durante lo sviluppo per vedere cosa stanno facendo i tuoi hook.
- Testa il comportamento di blocco: verifica che il codice di uscita 2 blocchi correttamente le azioni nei pre-hook.
- Verifica tutti i percorsi del codice: testa nei tuoi script sia gli scenari di successo sia quelli di errore.
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:
- Cloud Dashboard - Configura gli hook tramite Team Settings nella dashboard di Devin Desktop
- 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.
Configurazione della Cloud Dashboard
Gli admin del team possono configurare i Cascade Hooks direttamente dalla dashboard di Devin Desktop.
Requisiti:
- piano Enterprise
- autorizzazione
TEAM_SETTINGS_UPDATE
Per configurare:
- Vai a Team Settings nella dashboard di Devin Desktop
- Individua la sezione Cascade Hooks
- Inserisci la configurazione degli hook in formato JSON
- 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.
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.
Distribuzione dei file a livello di sistema
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:
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.
MDM e gestione della configurazione
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
Dopo la distribuzione, verifica che gli hook siano installati correttamente:
# 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
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.
Hook del workspace per i progetti del team
Per convenzioni specifiche di progetto, i team possono usare hook a livello di workspace nel controllo di versione:
# 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.