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.
Cascade Hooks ermöglichen es Ihnen, benutzerdefinierte Shell-Befehle an zentralen Stellen in Cascades Workflow auszuführen. Mit dieser leistungsstarken Erweiterungsfunktion können Sie Vorgänge protokollieren, Guardrails durchsetzen, Validierungsprüfungen ausführen oder externe Systeme integrieren.
Hooks sind für fortgeschrittene Nutzer und Enterprise-Teams konzipiert, die eine granulare Kontrolle über das Verhalten von Cascade benötigen. Sie erfordern grundlegende Kenntnisse im Shell-Scripting.
Was Sie damit umsetzen können
Hooks ermöglichen ein breites Spektrum an Automatisierungs- und Governance-Funktionen:
- Protokollierung & Analysen: Erfassen Sie jede gelesene Datei, jede Codeänderung, jeden ausgeführten Befehl, jeden Nutzer-Prompt und jede Cascade-Antwort für Compliance- und Nutzungsanalysen
- Sicherheitskontrollen: Verhindern Sie, dass Cascade auf sensible Dateien zugreift, gefährliche Befehle ausführt oder gegen Richtlinien verstoßende Prompts verarbeitet
- Qualitätssicherung: Führen Sie Linter, Formatter oder Tests nach Codeänderungen automatisch aus
- Benutzerdefinierte Workflows: Integrieren Sie Issue-Tracker, Benachrichtigungssysteme oder Deployment-Pipelines
- Standardisierung im Team: Setzen Sie Coding-Standards und Best Practices in Ihrer Organisation durch
Hooks sind Shell-Befehle, die automatisch ausgeführt werden, wenn bestimmte Cascade-Aktionen ausgelöst werden. Jeder Hook:
- Erhält Kontextinformationen (Details zur ausgeführten Aktion) über JSON als Standardeingabe
- Führt Ihr Skript aus – Python, Bash, Node.js oder jedes andere ausführbare Programm
- Gibt ein Ergebnis zurück über den Exit-Code und die Ausgabeströme
Bei Pre-Hooks (die vor einer Aktion ausgeführt werden) kann Ihr Skript die Aktion blockieren, indem es sich mit dem Exit-Code 2 beendet. Dadurch eignen sich Pre-Hooks ideal für die Umsetzung von Sicherheitsrichtlinien oder Validierungen.
Hooks werden in JSON-Dateien konfiguriert, die auf drei verschiedenen Ebenen abgelegt werden können. Cascade lädt und zusammenführt Hooks aus allen Speicherorten und gibt Teams so die Flexibilität, Hook-Konfigurationen zu verteilen und zu verwalten.
Hooks auf Systemebene eignen sich besonders für organisationsweite Richtlinien, die auf gemeinsam genutzten Entwicklungsrechnern durchgesetzt werden. Zum Beispiel können Sie damit Sicherheitsrichtlinien, Compliance-Anforderungen oder verpflichtende Code-Review-Workflows erzwingen. Enterprise-Teams können Hooks auch über das Cloud-Dashboard konfigurieren, ohne lokale Dateien verwalten zu müssen.
- macOS:
/Library/Application Support/Windsurf/hooks.json
- Linux/WSL:
/etc/windsurf/hooks.json
- Windows:
C:\ProgramData\Windsurf\hooks.json
Hooks auf Nutzerebene eignen sich ideal für persönliche Einstellungen und optionale Workflows.
- Devin Desktop IDE:
~/.codeium/windsurf/hooks.json
- JetBrains-Plugin:
~/.codeium/hooks.json
Hooks auf Workspace-Ebene ermöglichen es Teams, projektspezifische Richtlinien zusammen mit ihrem Code unter Versionskontrolle zu verwalten. Sie können benutzerdefinierte Validierungsregeln, projektspezifische Integrationen oder teamspezifische Workflows umfassen.
- Ort:
.windsurf/hooks.json im Workspace-Stammverzeichnis
Hooks aus allen drei Orten werden zusammengeführt. Wenn dasselbe Hook-Ereignis an mehreren Orten konfiguriert ist, werden alle Hooks in der folgenden Reihenfolge ausgeführt: System → Nutzer → Workspace.
Hier ist ein Beispiel für die Grundstruktur der Hooks-Konfiguration:
{
"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 diesem Beispiel gibt pre_read_code sowohl einen Befehl für macOS/Linux als auch einen Windows-PowerShell-Befehl an. Der Hook post_write_code gibt nur command an und wird daher unter macOS/Linux ausgeführt; unter Windows wird stattdessen PowerShell verwendet.
Jeder Hook akzeptiert die folgenden Parameter:
| Parameter | Typ | Beschreibung |
|---|
command | string | Der Shell-Befehl, der unter macOS/Linux ausgeführt wird (über bash -c). Mindestens einer von command oder powershell muss angegeben sein. |
powershell | string | Optional. Der Befehl, der unter Windows ausgeführt wird (über powershell -Command). Wenn er unter Windows nicht angegeben ist, wird command als Fallback verwendet. |
show_output | boolean | Ob die stdout-/stderr-Ausgabe des Hooks in der Cascade UI für Nutzer angezeigt wird. Nützlich für das Debugging. |
working_directory | string | Optional. Das Verzeichnis, aus dem der Befehl ausgeführt wird. Standardmäßig wird Ihr Workspace-Stammverzeichnis verwendet. |
Mit den Feldern command und powershell können Sie in einer einzigen Konfiguration plattformspezifische Befehle definieren. Das ist nützlich für Teams mit gemischten macOS-/Linux- und Windows-Umgebungen.
| Plattform | command gesetzt | powershell gesetzt | Ergebnis |
|---|
| macOS/Linux | ✓ | (ignoriert) | Führt command über bash -c aus |
| macOS/Linux | ✗ | ✓ | Hook wird stillschweigend übersprungen |
| Windows | ✓ | ✗ | Fällt auf command über powershell -Command zurück |
| Windows | ✗ | ✓ | Führt powershell über powershell -Command aus |
| Windows | ✓ | ✓ | Führt powershell über powershell -Command aus |
| Beliebig | ✗ | ✗ | Validierungsfehler |
Zum Parameter working_directory:
- In Workspaces mit mehreren Repos ist das Standardverzeichnis das Stammverzeichnis des Repos, an dem gerade gearbeitet wird
- Relative Pfade beziehen sich auf den Standardspeicherort (Workspace- oder Repo-Stammverzeichnis)
- Absolute Pfade werden unterstützt
- Die Auflösung von
~ zum Home-Verzeichnis wird nicht unterstützt
Cascade bietet zwölf Hook-Ereignisse, die die wichtigsten Aktionen im Agent-Workflow abdecken.
Alle Hooks erhalten ein JSON-Objekt mit den folgenden gemeinsamen Feldern:
| Field | Type | Description |
|---|
agent_action_name | string | Der Name des Hook-Ereignisses (z. B. “pre_read_code”, “post_write_code”) |
trajectory_id | string | Eindeutige Kennung für die gesamte Cascade-Unterhaltung |
execution_id | string | Eindeutige Kennung für den einzelnen Agent-Durchlauf |
timestamp | string | ISO-8601-Zeitstempel der Auslösung des Hooks |
model_name | string | Menschenlesbarer Name des Modells, das mit diesem Hook-Aufruf verknüpft ist (z. B. “Claude Sonnet 4”, “GPT 4.1”). Dies ist dieselbe Bezeichnung, die auch im Cascade-Modellauswahlfeld angezeigt wird. Der Wert kann sich im Laufe der Zeit ändern, wenn Devin Desktop die angezeigten Modellnamen aktualisiert. Ist auf “Unknown” gesetzt, wenn das Modell nicht ermittelt werden kann. |
tool_info | object | Ereignisspezifische Informationen (variieren je nach Hook-Typ) |
In den folgenden Beispielen werden die gemeinsamen Felder der Kürze halber weggelassen. Es gibt zwölf Haupttypen von Hook-Ereignissen:
Wird vor dem Lesen einer Code-Datei durch Cascade ausgelöst. Dies kann die Aktion blockieren, wenn der Hook mit Code 2 endet.
Anwendungsfälle: Dateizugriff einschränken, Lesevorgänge protokollieren, Berechtigungen prüfen
Eingabe-JSON:
{
"agent_action_name": "pre_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Dieser file_path kann auch ein Verzeichnispfad sein, wenn Cascade ein Verzeichnis rekursiv einliest.
Wird nachdem Cascade eine Codedatei erfolgreich gelesen hat, ausgelöst.
Anwendungsfälle: Erfolgreiche Lesevorgänge protokollieren, Dateizugriffsmuster erfassen
Eingabe-JSON:
{
"agent_action_name": "post_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Dieser file_path kann ein Verzeichnispfad sein, wenn Cascade ein Verzeichnis rekursiv einliest.
Wird bevor Cascade eine Code-Datei schreibt oder ändert ausgelöst. Dies kann den Vorgang blockieren, wenn der Hook mit Code 2 beendet wird.
Anwendungsfälle: Änderungen an geschützten Dateien verhindern, Dateien vor Änderungen sichern
Eingabe-JSON:
{
"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"
}
]
}
}
Wird nach dem Schreiben oder Ändern einer Codedatei durch Cascade ausgelöst.
Anwendungsfälle: Linter, Formatter oder Tests ausführen; Codeänderungen protokollieren
Eingabe-JSON:
{
"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"
}
]
}
}
Wird vor der Ausführung eines Terminalbefehls durch Cascade ausgelöst. Dadurch kann die Ausführung blockiert werden, wenn der Hook mit Code 2 beendet wird.
Anwendungsfälle: Gefährliche Befehle blockieren, alle Befehlsausführungen protokollieren, Sicherheitsprüfungen hinzufügen
Eingabe-JSON:
{
"agent_action_name": "pre_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
Wird nachdem Cascade einen Terminalbefehl ausgeführt hat, ausgelöst.
Anwendungsfälle: Befehlsergebnisse protokollieren, Folgeaktionen auslösen
Eingabe-JSON:
{
"agent_action_name": "post_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
Wird ausgelöst, bevor Cascade ein MCP-Tool (Model Context Protocol) aufruft. Dies kann die Aktion blockieren, wenn der Hook mit Code 2 beendet wird.
Anwendungsfälle: MCP-Nutzung protokollieren, einschränken, welche MCP-Tools verwendet werden können
Eingabe-JSON:
{
"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"
}
}
Wird nachdem Cascade ein MCP-Tool erfolgreich aufgerufen hat, ausgelöst.
Anwendungsfälle: MCP-Operationen protokollieren, API-Nutzung nachverfolgen, MCP-Ergebnisse anzeigen
Eingabe-JSON:
{
"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"
}
}
Wird vor der Verarbeitung des Texts eines Nutzer-Prompts durch Cascade ausgelöst. Dadurch kann die Aktion blockiert werden, wenn der Hook mit Code 2 beendet wird.
Anwendungsfälle: Alle Nutzer-Prompts zu Audit-Zwecken protokollieren, potenziell schädliche oder gegen Richtlinien verstoßende Prompts blockieren
Eingabe-JSON:
{
"agent_action_name": "pre_user_prompt",
"tool_info": {
"user_prompt": "can you run the echo hello command"
}
}
Die Konfigurationsoption show_output gilt nicht für diesen Hook.
Wird asynchron nachdem ausgelöst, dass Cascade eine Antwort auf den Prompt eines Nutzers fertiggestellt hat. Dieser Hook erhält die vollständige Cascade-Antwort seit der letzten Nutzereingabe.
Anwendungsfälle: Alle Cascade-Antworten zur Auditierung protokollieren, Antwortmuster analysieren, Antworten zur Compliance-Prüfung an externe Systeme senden
Eingabe-JSON:
{
"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."
}
}
Das Feld response enthält den in Markdown formatierten Inhalt von Cascades Antwort seit der letzten Nutzereingabe. Dazu gehören Antworten des Planners, Tool-Aktionen (Dateilesevorgänge, Schreibvorgänge, Befehle) sowie alle anderen Schritte, die Cascade ausgeführt hat. Es enthält außerdem Informationen darüber, welche Regeln ausgelöst wurden. Im Beispiel Tracking Triggered Rules sehen Sie, wie Sie die Nutzung von Regeln auswerten.
Die Konfigurationsoption show_output gilt nicht für diesen Hook.
Der Inhalt von response wird aus Verlaufsdaten abgeleitet und kann sensible Informationen aus Ihrer Codebasis oder Ihren Unterhaltungen enthalten. Behandeln Sie diese Daten gemäß den Sicherheits- und Datenschutzrichtlinien Ihrer Organisation.
post_cascade_response_with_transcript
Wird asynchron nachdem Cascade eine Antwort auf den Prompt eines Nutzers fertiggestellt hat ausgelöst, ähnlich wie post_cascade_response. Statt inline eine Markdown-Zusammenfassung bereitzustellen, schreibt dieser Hook das vollständige Transkript der Unterhaltung (vom Beginn der Unterhaltung an) in eine lokale JSONL-Datei und gibt den Dateipfad zurück.
Anwendungsfälle: Audit- und Compliance-Protokollierung für Enterprise, Nachverfolgung KI-generierter Beiträge, Einspeisung von Transkripten in externe Observability- oder Analytics-Tools
Eingabe-JSON:
{
"agent_action_name": "post_cascade_response_with_transcript",
"tool_info": {
"transcript_path": "/Users/yourname/.windsurf/transcripts/{trajectory_id}.jsonl"
}
}
Der transcript_path verweist auf eine JSONL-Datei unter ~/.windsurf/transcripts/{trajectory_id}.jsonl. Jede Zeile ist ein JSON-Objekt, das einen einzelnen Schritt in der Unterhaltung darstellt, mit den Feldern type und status sowie schrittspezifischen Daten. Zum Beispiel:
{"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"}
Das Transkript enthält detaillierte, kundeneigene Daten wie Dateiinhalte, Befehlsausgaben, Tool-Argumente, Suchergebnisse und angewendete Regeln. Bitte beachten Sie, dass sich die genaue Struktur der einzelnen Schritte in künftigen Versionen ändern kann. Implementieren Sie Consumer für diese Hooks daher so, dass sie gegenüber Änderungen robust sind.
Transkriptdateien werden mit den Berechtigungen 0600 geschrieben. Devin Desktop begrenzt das Transkriptverzeichnis automatisch auf 100 Dateien und entfernt die ältesten anhand des Änderungszeitpunkts.
Die Konfigurationsoption show_output gilt nicht für diesen Hook.
Diese Tabelle zeigt die wichtigsten Unterschiede zwischen den Hooks post_cascade_response und post_cascade_response_with_transcript:
| post_cascade_response | post_cascade_response_with_transcript |
|---|
| Datenumfang | Nur die Schritte seit der letzten Nutzereingabe | Die gesamte Unterhaltung ab dem Anfang |
| Format | Markdown-Zusammenfassung in tool_info.response | Strukturierte JSONL-Datei unter tool_info.transcript_path |
| Detailgrad | Verdichtete, menschenlesbare Zusammenfassung | Detaillierte, maschinenlesbare Daten (Dateiinhalte, Befehlsausgabe usw.) |
| Bereitstellung | Inline über stdin-JSON | Datei auf dem Datenträger (~/.windsurf/transcripts/) |
Transkriptdateien enthalten sensible Informationen aus Ihrer Codebase, darunter Dateiinhalte, Befehlsausgaben und den Verlauf der Unterhaltung. Behandeln Sie diese Dateien gemäß den Sicherheits- und Datenschutzrichtlinien Ihrer Organisation.
Wird ausgelöst, nachdem ein neuer Git-Worktree erstellt und konfiguriert wurde. Der Hook wird im Verzeichnis des neuen Worktree ausgeführt.
Anwendungsfälle: .env-Dateien oder andere nicht versionierte Dateien in den Worktree kopieren, Abhängigkeiten installieren, Setup-Skripte ausführen
Umgebungsvariablen:
| Variable | Beschreibung |
|---|
$ROOT_WORKSPACE_PATH | Der absolute Pfad zum ursprünglichen Workspace. Verwenden Sie diesen, um auf Dateien zuzugreifen oder Befehle relativ zum ursprünglichen Repository auszuführen. |
Eingabe-JSON:
{
"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"
}
}
Ihre Hook-Skripte übermitteln Ergebnisse über Exit-Codes:
| Exit Code | Bedeutung | Auswirkung |
|---|
0 | Erfolg | Aktion wird normal fortgesetzt |
2 | Blockierender Fehler | Der Cascade-Agent sieht die Fehlermeldung aus stderr. Bei Pre-Hooks blockiert dies die Aktion. |
| Jeder andere | Fehler | Aktion wird normal fortgesetzt |
Nur Pre-Hooks (pre_user_prompt, pre_read_code, pre_write_code, pre_run_command, pre_mcp_tool_use) können Aktionen mit Exit-Code 2 blockieren. Post-Hooks können nicht blockieren, da die Aktion bereits schon stattgefunden hat.
Beachten Sie, dass der Nutzer jede von Hooks erzeugte Standardausgabe und Standardfehlerausgabe in der Cascade-UI sehen kann, wenn show_output auf true gesetzt ist.
Beispielhafte Anwendungsfälle
Protokollierung aller Cascade-Aktionen
Erfassen Sie zu Audit-Zwecken jede Aktion, die Cascade ausführt.
Konfiguration:
{
"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"
}
]
}
}
Skript (log_input.py):
#!/usr/bin/env python3
import sys
import json
def main():
# JSON-Daten von stdin lesen
input_data = sys.stdin.read()
# JSON parsen
try:
data = json.loads(input_data)
# Formatiertes JSON in Datei schreiben
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()
Dieses Skript fügt jeden Hook-Aufruf einer Protokolldatei hinzu und erstellt so einen Audit-Trail aller Cascade-Aktionen. Sie können die Eingabedaten nach Bedarf umwandeln oder benutzerdefinierte Logik ausführen.
Dateizugriff einschränken
Verhindern Sie, dass Cascade Dateien außerhalb eines bestimmten Verzeichnisses lesen kann.
Konfiguration:
{
"hooks": {
"pre_read_code": [
{
"command": "python3 /Users/yourname/hooks/block_read_access.py",
"show_output": true
}
]
}
}
Skript (block_read_access.py):
#!/usr/bin/env python3
import sys
import json
ALLOWED_PREFIX = "/Users/yourname/my-project/"
def main():
# JSON-Daten von stdin lesen
input_data = sys.stdin.read()
# JSON parsen
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) # Exit-Code 2 blockiert die Aktion
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()
Wenn Cascade versucht, eine Datei außerhalb des erlaubten Verzeichnisses zu lesen, blockiert dieser Hook den Vorgang und zeigt eine Fehlermeldung an.
Gefährliche Befehle blockieren
Verhindern Sie, dass Cascade potenziell gefährliche Befehle ausführt.
Konfiguration:
{
"hooks": {
"pre_run_command": [
{
"command": "python3 /Users/yourname/hooks/block_dangerous_commands.py",
"show_output": true
}
]
}
}
Skript (block_dangerous_commands.py):
#!/usr/bin/env python3
import sys
import json
DANGEROUS_COMMANDS = ["rm -rf", "sudo rm", "format", "del /f"]
def main():
# JSON-Daten von stdin lesen
input_data = sys.stdin.read()
# JSON parsen
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) # Exit-Code 2 blockiert den Befehl
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()
Dieser Hook prüft Befehle auf gefährliche Muster und blockiert sie vor der Ausführung.
Blockieren von Prompts, die gegen Richtlinien verstoßen
Verhindern Sie, dass Nutzer Prompts einreichen, die gegen die Richtlinien ihrer Organisation verstoßen.
Konfiguration:
{
"hooks": {
"pre_user_prompt": [
{
"command": "python3 /Users/yourname/hooks/block_bad_prompts.py"
}
]
}
}
Skript (block_bad_prompts.py):
#!/usr/bin/env python3
import sys
import json
BLOCKED_PATTERNS = [
"something dangerous",
"bypass security",
"ignore previous instructions"
]
def main():
# JSON-Daten von stdin lesen
input_data = sys.stdin.read()
# JSON parsen
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) # Exit-Code 2 blockiert den Prompt
except json.JSONDecodeError as e:
print(f"Error parsing JSON: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Dieser Hook prüft Nutzer-Prompts, bevor sie verarbeitet werden, und blockiert alle, die verbotene Muster enthalten. Wenn ein Prompt blockiert wird, wird dem Nutzer in der Cascade-UI eine Fehlermeldung angezeigt.
Protokollierung von Cascade-Antworten
Erfassen Sie alle Cascade-Antworten für Compliance-Audits oder Analysezwecke.
Konfiguration:
{
"hooks": {
"post_cascade_response": [
{
"command": "python3 /Users/yourname/hooks/log_cascade_response.py"
}
]
}
}
Skript (log_cascade_response.py):
#!/usr/bin/env python3
import sys
import json
from datetime import datetime
def main():
# JSON-Daten von stdin lesen
input_data = sys.stdin.read()
# JSON parsen
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())
# In Datei protokollieren
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()
Dieser Hook protokolliert jede Cascade-Antwort in einer Datei und erstellt so einen Audit-Trail aller KI-generierten Inhalte. Sie können dies erweitern, um Daten an externe Logging-Systeme, Datenbanken oder Compliance-Plattformen zu senden.
Nachverfolgen ausgelöster Regeln
Verfolgen Sie, welche Regeln während Cascade-Interaktionen angewendet wurden, um Beobachtbarkeit und Metriken zu verbessern.
Konfiguration:
{
"hooks": {
"post_cascade_response": [
{
"command": "python3 /Users/yourname/hooks/track_rules.py"
}
]
}
}
Skript (track_rules.py):
#!/usr/bin/env python3
import sys
import json
import re
from datetime import datetime
def extract_triggered_rules(response: str) -> dict:
"""
Ausgelöste Regeln aus der Cascade-Antwort parsen.
Regeln erscheinen als: - (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())
# In Datei protokollieren
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()
Regeltypen:
Always On - Regeln, die immer einbezogen werden
Model Decision - Regeln, deren Beschreibungen dem Modell zur bedingten Anwendung angezeigt wurden
Manual - Regeln, die in der Nutzereingabe explizit mit @ erwähnt wurden
Global - Globale Regeln aus global_rules.md
Glob - Regeln, die durch Dateizugriffe ausgelöst werden, die mit Glob-Mustern übereinstimmen
Dies erfasst, welche Regeln dem Modell präsentiert oder durch Dateizugriff ausgelöst wurden, gibt jedoch nicht an, ob das Modell eine Regel tatsächlich befolgt hat. Regeln, die in der Unterhaltung vor Kurzem bereits angezeigt wurden, werden dedupliziert und erscheinen möglicherweise erst später erneut.
Code-Dateien automatisch formatieren, nachdem Cascade sie geändert hat.
Konfiguration:
{
"hooks": {
"post_write_code": [
{
"command": "bash /Users/yourname/hooks/format_code.sh",
"show_output": false
}
]
}
}
Skript (format_code.sh):
#!/bin/bash
# JSON von stdin lesen
input=$(cat)
# Dateipfad mit jq extrahieren
file_path=$(echo "$input" | jq -r '.tool_info.file_path')
# Formatierung anhand der Dateiendung
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
Dieser Hook führt nach jeder Bearbeitung automatisch je nach Dateityp den passenden Formatter aus.
Kopieren Sie Umgebungsdateien und installieren Sie Abhängigkeiten, sobald ein neuer Worktree erstellt wird.
Konfiguration (in .windsurf/hooks.json):
{
"hooks": {
"post_setup_worktree": [
{
"command": "bash $ROOT_WORKSPACE_PATH/hooks/setup_worktree.sh",
"show_output": true
}
]
}
}
Skript (hooks/setup_worktree.sh):
#!/bin/bash
# Environment-Dateien aus dem ursprünglichen Workspace kopieren
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
# Dependencies installieren
if [ -f "package.json" ]; then
npm install
echo "Installed npm dependencies"
fi
exit 0
Dieser Hook stellt sicher, dass für jeden Worktree die erforderliche Umgebungskonfiguration vorhanden ist und Abhängigkeiten automatisch installiert werden.
Verwenden Sie Cascade Hooks auf eigenes Risiko: Hooks führen Shell-Befehle automatisch mit den vollständigen Berechtigungen Ihres Nutzerkontos aus. Sie tragen die volle Verantwortung für den Code, den Sie konfigurieren. Schlecht konzipierte oder bösartige Hooks können Dateien ändern, Daten löschen, Zugangsdaten offenlegen oder Ihr System kompromittieren.
- Alle Eingaben validieren: Vertrauen Sie Eingabe-JSON niemals, ohne sie zu validieren, insbesondere bei Dateipfaden und Befehlen.
- Absolute Pfade verwenden: Verwenden Sie in Ihren Hook-Konfigurationen immer absolute Pfade, um Unklarheiten zu vermeiden.
- Sensible Daten schützen: Vermeiden Sie das Protokollieren sensibler Informationen wie API-Schlüsseln oder Zugangsdaten.
- Berechtigungen überprüfen: Stellen Sie sicher, dass Ihre Hook-Skripte über geeignete Dateisystemberechtigungen verfügen.
- Vor dem Deployment prüfen: Überprüfen Sie jeden Hook-Befehl und jedes Skript, bevor Sie sie zu Ihrer Konfiguration hinzufügen.
- Isoliert testen: Führen Sie Hooks in einer Testumgebung aus, bevor Sie sie auf Ihrem primären Entwicklungsrechner aktivieren.
- Hooks schnell halten: Langsame Hooks beeinträchtigen die Reaktionsfähigkeit von Cascade. Ziel sollten Ausführungszeiten von unter 100 ms sein.
- Asynchrone Vorgänge verwenden: Bei nicht blockierenden Hooks sollten Sie die Protokollierung asynchron in eine Warteschlange oder Datenbank schreiben.
- Früh filtern: Prüfen Sie den Aktionstyp direkt zu Beginn Ihres Skripts, um unnötige Verarbeitung zu vermeiden.
- JSON immer prüfen: Verwende Try-Catch-Blöcke, um fehlerhafte Eingaben robust zu behandeln.
- Fehler korrekt protokollieren: Schreibe Fehler in
stderr, damit sie sichtbar sind, wenn show_output aktiviert ist.
- Sicher fehlschlagen: Wenn dein Hook auf einen Fehler stößt, überlege, ob er die Aktion blockieren oder fortfahren lassen sollte.
- Beginnen Sie mit Logging: Implementieren Sie zunächst einen einfachen Logging-Hook, um den Datenfluss besser zu verstehen.
- Verwenden Sie
show_output: true: Aktivieren Sie während der Entwicklung die Ausgabe, damit Sie sehen, was Ihre Hooks tun.
- Testen Sie das Blockierverhalten: Stellen Sie sicher, dass Exit-Code 2 in Pre-Hooks Aktionen ordnungsgemäß blockiert.
- Prüfen Sie alle Codepfade: Testen Sie in Ihren Skripten sowohl Erfolgs- als auch Fehlerszenarien.
Verteilung in Enterprise-Umgebungen
Enterprise-Organisationen müssen Sicherheitsrichtlinien, Compliance-Anforderungen und Entwicklungsstandards durchsetzen, die einzelne Nutzer nicht umgehen können. Cascade Hooks unterstützt zwei Verteilungsmethoden für Enterprise-Umgebungen:
- Cloud-Dashboard - Konfigurieren Sie Hooks über Team Settings im Devin Desktop-Dashboard
- Dateien auf Systemebene - Stellen Sie Hooks über MDM oder Konfigurationsmanagement-Tools bereit
Beide Methoden können zusammen verwendet werden — Hooks aus allen Quellen werden kombiniert und nacheinander ausgeführt.
Konfiguration im Cloud-Dashboard
Team-Admins können Cascade Hooks direkt im Devin Desktop-Dashboard konfigurieren.
Anforderungen:
- Enterprise-Plan
- Berechtigung
TEAM_SETTINGS_UPDATE
So konfigurieren Sie Cascade Hooks:
- Navigieren Sie im Devin Desktop-Dashboard zu Team Settings
- Suchen Sie den Abschnitt Cascade Hooks
- Geben Sie Ihre Hook-Konfiguration im JSON-Format ein
- Speichern Sie Ihre Änderungen
Über das Dashboard konfigurierte Hooks werden automatisch an alle Teammitglieder verteilt und beim Start von Devin Desktop geladen. In der Cloud konfigurierte Hooks werden zuerst geladen, danach Hooks auf System-, Nutzer- und Workspace-Ebene.
Wenn mehrere Team-Konfigurationen zusammengeführt werden, werden Hooks pro Aktion kombiniert, statt überschrieben zu werden. Das bedeutet, dass Hooks aus allen zutreffenden Team-Konfigurationen gemeinsam ausgeführt werden.
Bereitstellung von Dateien auf Systemebene
Für Organisationen, die eine dateibasierte Konfiguration bevorzugen oder Hooks offline nutzen müssen, stellen Sie die obligatorische hooks.json-Konfiguration an diesen betriebssystemspezifischen Speicherorten bereit:
macOS:
/Library/Application Support/Windsurf/hooks.json
Linux/WSL:
Windows:
C:\ProgramData\Windsurf\hooks.json
Legen Sie Ihre Hook-Skripte in einem entsprechenden Systemverzeichnis ab (z. B. /usr/local/share/windsurf-hooks/ auf Unix-Systemen).
Hooks auf Systemebene haben Vorrang vor Nutzer- und Workspace-Hooks und können von Endnutzern ohne Root-Rechte nicht deaktiviert werden.
MDM und Konfigurationsmanagement
Enterprise-IT-Teams können Hooks auf Systemebene mit Standardtools bereitstellen:
Mobile Device Management (MDM)
- Jamf Pro (macOS) - Bereitstellung über Konfigurationsprofile oder Skripte
- Microsoft Intune (Windows/macOS) - Bereitstellung per PowerShell-Skripten oder Richtlinien
- Workspace ONE, Google Endpoint Management und andere MDM-Lösungen
Konfigurationsmanagement
- Ansible, Puppet, Chef, SaltStack - Nutzen Sie Ihre bestehende Infrastrukturautomatisierung
- Benutzerdefinierte Bereitstellungsskripte - Shell-Skripte, PowerShell oder andere Tools Ihrer Wahl
Überprüfung und Auditierung
Stellen Sie nach der Bereitstellung sicher, dass die Hooks ordnungsgemäß installiert sind:
# System-Hooks auf Vorhandensein prüfen
ls -la /etc/windsurf/hooks.json # Linux
ls -la "/Library/Application Support/Windsurf/hooks.json" # macOS
# Hook-Ausführung testen (Hook-Ausgabe sollte in Cascade sichtbar sein)
# Einen Entwickler die entsprechende Cascade-Aktion auslösen lassen
# Sicherstellen, dass Nutzer System-Hooks nicht ändern können
sudo chown root:root /etc/windsurf/hooks.json
sudo chmod 644 /etc/windsurf/hooks.json
Wichtig: Hooks auf Systemebene werden vollständig von Ihrem IT- oder Sicherheitsteam verwaltet. Devin Desktop legt keine Dateien in systemweiten Pfaden ab und verwaltet sie dort auch nicht. Stellen Sie sicher, dass Ihre internen Teams Bereitstellung, Updates und Compliance gemäß den Richtlinien Ihrer Organisation übernehmen.
Workspace-Hooks für Team-Projekte
Für projektspezifische Konventionen können Teams Workspace-Hooks in der Versionsverwaltung verwenden:
# Zum Repository hinzufügen
.windsurf/
├── hooks.json
└── scripts/
└── format-check.py
# In git committen
git add .windsurf/
git commit -m "Add workspace hooks for code formatting"
Dies ermöglicht es Teams, Entwicklungspraktiken zu standardisieren. Belassen Sie sicherheitskritische Richtlinien auf Cloud- oder Systemebene und vermeiden Sie, vertrauliche Informationen in die Versionsverwaltung zu übernehmen.