Los Hooks de Cascade te permiten ejecutar comandos de shell personalizados en puntos clave del flujo de trabajo de Cascade. Esta potente capacidad de extensibilidad te permite registrar operaciones, aplicar controles, ejecutar validaciones o integrarte con sistemas externos.
Versión beta: Los Hooks de Cascade están actualmente en beta y en desarrollo activo. Las funciones y las API pueden cambiar. Comunícate con Windsurf Support para enviar comentarios o informar errores.
Los Hooks están diseñados para usuarios avanzados y equipos Enterprise que necesitan un control de grano fino sobre el comportamiento de Cascade. Requieren conocimientos básicos de scripting en shell.
Los hooks habilitan una amplia gama de capacidades de automatización y gobernanza:
- Registro y Analytics: Haz seguimiento de cada archivo leído, cambio de código o comando ejecutado por Cascade para fines de cumplimiento y análisis de uso
- Controles de seguridad: Evita que Cascade acceda a archivos sensibles o ejecute comandos peligrosos
- Aseguramiento de la calidad: Ejecuta linters, formatters o pruebas automáticamente después de modificaciones de código
- Flujos de trabajo personalizados: Integra con rastreadores de incidencias, sistemas de notificaciones o pipelines de despliegue
- Estandarización del equipo: Aplica estándares de codificación y mejores prácticas en toda tu organización
Los hooks son comandos de shell que se ejecutan automáticamente cuando se producen acciones específicas de Cascade. Cada hook:
- Recibe contexto (detalles sobre la acción que se está realizando) en formato JSON por la entrada estándar
- Ejecuta tu script: Python, Bash, Node.js o cualquier ejecutable
- Devuelve un resultado mediante el código de salida y los flujos de salida
En el caso de los pre-hooks (ejecutados antes de una acción), tu script puede bloquear la acción saliendo con el código de salida 2. Esto hace que los pre-hooks sean ideales para implementar políticas de seguridad o comprobaciones de validación.
Los hooks se configuran en archivos JSON que pueden ubicarse en tres niveles diferentes. Cascade carga y fusiona los hooks de todas las ubicaciones, lo que ofrece a los equipos flexibilidad para distribuir y administrar las configuraciones de hooks.
Los hooks a nivel de sistema son ideales para definir políticas de toda la organización en máquinas de desarrollo compartidas. Por ejemplo, puedes usarlos para aplicar políticas de seguridad, requisitos de cumplimiento o flujos de trabajo obligatorios de revisión de código.
- macOS:
/Library/Application Support/Windsurf/hooks.json
- Linux/WSL:
/etc/windsurf/hooks.json
- Windows:
C:\ProgramData\Windsurf\hooks.json
Los hooks a nivel de usuario son ideales para preferencias personales y flujos de trabajo opcionales.
- Ubicación:
~/.codeium/windsurf/hooks.json
Los hooks a nivel de workspace permiten a los equipos llevar el control de versiones de políticas específicas del proyecto junto con su código. Pueden incluir reglas de validación personalizadas, integraciones específicas del proyecto o flujos de trabajo específicos del equipo.
- Ubicación:
.windsurf/hooks.json en la raíz de tu workspace
Los hooks de las tres ubicaciones se combinan. Si el mismo evento de hook está configurado en varias ubicaciones, todos los hooks se ejecutarán en este orden: sistema → usuario → workspace.
Este es un ejemplo de la estructura básica de la configuración de hooks:
{
"hooks": {
"pre_read_code": [
{
"command": "python3 /path/to/your/script.py",
"show_output": true
}
],
"post_write_code": [
{
"command": "python3 /path/to/another/script.py",
"show_output": true
}
]
}
}
Opciones de configuración
Cada hook acepta los siguientes parámetros:
| Parámetro | Tipo | Descripción |
command | string | El comando de shell que se ejecutará. Puede ser cualquier ejecutable válido con argumentos. |
show_output | boolean | Si se debe mostrar la salida stdout/stderr del hook en la interfaz de Cascade visible para el usuario. Útil para depuración. |
working_directory | string | Opcional. El directorio desde el cual ejecutar el comando. De forma predeterminada, es la raíz de tu workspace. |
Cascade ofrece ocho eventos de hooks que cubren las acciones más críticas en el flujo de trabajo del agente.
Todos los hooks reciben un objeto JSON con los siguientes campos comunes:
| Campo | Tipo | Descripción |
agent_action_name | string | Nombre del evento del hook (p. ej., “pre_read_code”, “post_write_code”) |
trajectory_id | string | Identificador único de la conversación global de Cascade |
execution_id | string | Identificador único del turno del agente |
timestamp | string | Marca de tiempo en formato ISO 8601 cuando se activó el hook |
tool_info | object | Información específica del evento (varía según el tipo de hook) |
En los siguientes ejemplos, se omiten los campos comunes por brevedad. Hay ocho tipos principales de eventos de hook:
pre_read_code
Se activa antes de que Cascade lea un archivo de código. Puede bloquear la acción si el hook finaliza con el código 2.
Casos de uso: Restringir el acceso a archivos, registrar operaciones de lectura, verificar permisos
JSON de entrada:
{
"agent_action_name": "pre_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Este file_path puede ser una ruta de directorio cuando Cascade lee un directorio de forma recursiva.
post_read_code
Se activa después de que Cascade lea correctamente un archivo de código.
Casos de uso: Registrar lecturas correctas, rastrear patrones de acceso a archivos
JSON de entrada:
{
"agent_action_name": "post_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Este file_path puede ser una ruta de directorio cuando Cascade lee un directorio de manera recursiva.
pre_write_code
Se activa antes de que Cascade escriba o modifique un archivo de código. Esto puede bloquear la acción si el hook termina con el código 2.
Casos de uso: Evitar modificaciones en archivos protegidos, hacer copias de seguridad de archivos antes de aplicar cambios
Entrada 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"
}
]
}
}
post_write_code
Se activa después de que Cascade escribe o modifica un archivo de código.
Casos de uso: Ejecutar linters, formateadores o pruebas; registrar cambios de código
JSON de entrada:
{
"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"
}
]
}
}
pre_run_command
Se activa antes de que Cascade ejecute un comando en la terminal. Esto puede bloquear la acción si el hook termina con el código 2.
Casos de uso: Bloquear comandos peligrosos, registrar todas las ejecuciones de comandos, añadir comprobaciones de seguridad
JSON de entrada:
{
"agent_action_name": "pre_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
post_run_command
Se activa después de que Cascade ejecuta un comando en la terminal.
Casos de uso: Registrar los resultados del comando, activar acciones posteriores
JSON de entrada:
{
"agent_action_name": "post_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
Se activa antes de que Cascade invoque una herramienta MCP (Model Context Protocol). Puede bloquear la acción si el hook finaliza con el código 2.
Casos de uso: Registrar el uso de MCP, restringir qué herramientas MCP pueden utilizarse
JSON de entrada:
{
"agent_action_name": "pre_mcp_tool_use",
"tool_info": {
"mcp_server_name": "github",
"mcp_tool_arguments": {
"owner": "code-owner",
"repo": "my-cool-repo",
"title": "Informe de error",
"body": "Descripción del error aquí"
},
"mcp_tool_name": "create_issue"
}
}
post_mcp_tool_use
Se activa después de que Cascade invoque con éxito una herramienta MCP.
Casos de uso: Registrar operaciones de MCP, rastrear el uso de la API, ver resultados de MCP
JSON de entrada:
{
"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"
}
}
Tus scripts de hooks comunican resultados mediante códigos de salida:
| Código de salida | Significado | Efecto |
0 | Éxito | La acción continúa con normalidad |
2 | Error bloqueante | El agente de Cascade verá el mensaje de error desde stderr. En los pre-hooks, esto bloquea la acción. |
| Cualquier otro | Error | La acción continúa con normalidad |
Solo los pre-hooks (pre_read_code, pre_write_code, pre_run_command, pre_mcp_tool_use) pueden bloquear acciones usando el código de salida 2. Los post-hooks no pueden bloquear, ya que la acción ya se realizó.
Ten en cuenta que el usuario puede ver cualquier salida estándar y error estándar generados por los hooks en la interfaz de Cascade si show_output es true.
Registro de todas las acciones de Cascade
Realiza un seguimiento de cada acción que Cascade lleva a cabo con fines de auditoría.
Configuración (~/.codeium/windsurf/hooks.json):
{
"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
}
]
}
}
Script (log_input.py):
#!/usr/bin/env python3
import sys
import json
def main():
# Leer los datos JSON desde stdin
input_data = sys.stdin.read()
# Parsear el JSON
try:
data = json.loads(input_data)
# Escribir JSON formateado en el archivo
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 al parsear JSON: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Este script anexa cada invocación del hook a un archivo de registro, creando un rastro de auditoría de todas las acciones de Cascade. Puedes transformar los datos de entrada o implementar lógica personalizada según lo consideres adecuado.
Restringir el acceso a archivos
Evita que Cascade lea archivos fuera de un directorio específico.
Configuración (~/.codeium/windsurf/hooks.json):
{
"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():
# Leer los datos JSON desde stdin
input_data = sys.stdin.read()
# Analizar el 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"Acceso denegado: Cascade solo tiene permitido leer archivos en {ALLOWED_PREFIX}", file=sys.stderr)
sys.exit(2) # El código de salida 2 bloquea la acción
print(f"Acceso concedido: {file_path}", file=sys.stdout)
except json.JSONDecodeError as e:
print(f"Error al analizar JSON: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Cuando Cascade intenta leer un archivo fuera del directorio permitido, este gancho bloquea la operación y muestra un mensaje de error.
Bloquear comandos peligrosos
Evita que Cascade ejecute comandos potencialmente peligrosos.
Configuración (~/.codeium/windsurf/hooks.json):
{
"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():
# Leer los datos JSON desde stdin
input_data = sys.stdin.read()
# Analizar el 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"Comando bloqueado: '{dangerous_cmd}' no está permitido por razones de seguridad.", file=sys.stderr)
sys.exit(2) # El código de salida 2 bloquea el comando
print(f"Comando aprobado: {command}", file=sys.stdout)
except json.JSONDecodeError as e:
print(f"Error al analizar JSON: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Este hook escanea los comandos en busca de patrones peligrosos y los bloquea antes de su ejecución.
Formatea automáticamente los archivos de código después de que Cascade los modifique.
Configuración (~/.codeium/windsurf/hooks.json):
{
"hooks": {
"post_write_code": [
{
"command": "bash /Users/yourname/hooks/format_code.sh",
"show_output": false
}
]
}
}
Script (format_code.sh):
#!/bin/bash
# Leer JSON desde stdin
input=$(cat)
# Extraer ruta de archivo usando jq
file_path=$(echo "$input" | jq -r '.tool_info.file_path')
# Formatear según extensión de archivo
if [[ "$file_path" == *.py ]]; then
black "$file_path" 2>&1
echo "Archivo Python formateado: $file_path"
elif [[ "$file_path" == *.js ]] || [[ "$file_path" == *.ts ]]; then
prettier --write "$file_path" 2>&1
echo "Archivo JS/TS formateado: $file_path"
elif [[ "$file_path" == *.go ]]; then
gofmt -w "$file_path" 2>&1
echo "Archivo Go formateado: $file_path"
fi
exit 0
Este hook ejecuta automáticamente el formateador correspondiente según el tipo de archivo tras cada edición.
Use Cascade Hooks at Your Own Risk: Los hooks ejecutan comandos de shell automáticamente con todos los permisos de su cuenta de usuario. Usted es completamente responsable del código que configure. Los hooks mal diseñados o maliciosos pueden modificar archivos, eliminar datos, exponer credenciales o comprometer su sistema.
- Valide todas las entradas: Nunca confíe en el JSON de entrada sin validarlo, especialmente en lo referente a rutas de archivos y comandos.
- Use rutas absolutas: Utilice siempre rutas absolutas en la configuración de sus hooks para evitar ambigüedades.
- Proteja los datos sensibles: Evite registrar información sensible, como claves de API o credenciales.
- Revise los permisos: Asegúrese de que sus scripts de hooks tengan los permisos adecuados en el sistema de archivos.
- Audite antes del despliegue: Revise cada comando y script de hook antes de añadirlo a su configuración.
- Pruebe en aislamiento: Ejecute los hooks en un entorno de pruebas antes de habilitarlos en su máquina principal de desarrollo.
- Mantén los hooks rápidos: Los hooks lentos afectarán la capacidad de respuesta de Cascade. Procura tiempos de ejecución inferiores a 100 ms.
- Usa operaciones asíncronas: Para hooks no bloqueantes, considera enviar registros a una cola o base de datos de manera asíncrona.
- Filtra cuanto antes: Verifica el tipo de acción al inicio de tu script para evitar procesamiento innecesario.
- Valida siempre el JSON: Usa bloques try-catch para manejar entradas malformadas de forma adecuada.
- Registra los errores correctamente: Escribe los errores en
stderr para que sean visibles cuando show_output esté habilitado.
- Falla de forma segura: Si tu hook encuentra un error, considera si debe bloquear la acción o permitir que continúe.
- Empieza con registros: Implementa primero un hook simple de logging para comprender el flujo de datos.
- Usa
show_output: true: Habilita la salida durante el desarrollo para ver qué hacen tus hooks.
- Prueba el comportamiento de bloqueo: Verifica que el código de salida 2 bloquee correctamente las acciones en los pre-hooks.
- Verifica todas las rutas de código: Prueba tanto los casos de éxito como los de error en tus scripts.
Distribución para Enterprise
Las organizaciones Enterprise deben aplicar políticas de seguridad, requisitos de cumplimiento y estándares de desarrollo que los usuarios individuales no puedan eludir. Cascade Hooks admite esto mediante una configuración a nivel del sistema, que tiene prioridad y no puede deshabilitarse por los usuarios finales sin permisos de root.
Implemente su configuración obligatoria hooks.json en estas ubicaciones específicas del sistema operativo:
macOS:
/Library/Application Support/Windsurf/hooks.json
Linux/WSL:
Windows:
C:\ProgramData\Windsurf\hooks.json
Coloca tus scripts de hooks en un directorio de sistema correspondiente (p. ej., /usr/local/share/windsurf-hooks/ en sistemas Unix).
Métodos de implementación
Los equipos de TI de Enterprise pueden desplegar hooks a nivel del sistema utilizando herramientas y flujos de trabajo estándar:
Mobile Device Management (MDM)
- Jamf Pro (macOS) - Despliegue mediante perfiles de configuración o scripts
- Microsoft Intune (Windows/macOS) - Use scripts de PowerShell o despliegue de políticas
- Workspace ONE, Google Endpoint Management y otras soluciones MDM
Gestión de configuración
- Ansible, Puppet, Chef, SaltStack - Use su automatización de infraestructura existente
- Scripts de despliegue personalizados - Scripts de shell, PowerShell o sus herramientas preferidas
Después del despliegue, verifica que los hooks estén correctamente instalados y no puedan ser evadidos:
# Verificar que los hooks del sistema estén presentes
ls -la /etc/windsurf/hooks.json # Linux
ls -la "/Library/Application Support/Windsurf/hooks.json" # macOS
# Probar la ejecución del hook (debería ver la salida del hook en Cascade)
# Pida a un desarrollador que active la acción correspondiente de Cascade
# Verificar que los usuarios no puedan modificar los hooks del sistema
sudo chown root:root /etc/windsurf/hooks.json
sudo chmod 644 /etc/windsurf/hooks.json
Importante: Los hooks a nivel de sistema son gestionados íntegramente por tu equipo de TI o de seguridad. Windsurf no despliega ni administra archivos en rutas del sistema. Asegúrate de que tus equipos internos se encarguen del despliegue, las actualizaciones y el cumplimiento conforme a las políticas de tu organización.
Hooks de workspace para proyectos en equipo
Para convenciones específicas del proyecto, los equipos pueden usar hooks a nivel de workspace en el control de versiones:
# Agregar a tu repositorio
.windsurf/
├── hooks.json
└── scripts/
└── format-check.py
# Hacer commit en git
git add .windsurf/
git commit -m "Agregar hooks de workspace para formateo de código"
Esto permite estandarizar las prácticas de desarrollo en los equipos. Asegúrate de mantener las políticas críticas de seguridad a nivel del sistema y de no subir ni registrar información sensible en el control de versiones.