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.
Os Hooks do Cascade permitem executar comandos shell personalizados em pontos-chave do fluxo de trabalho do Cascade. Esse poderoso recurso de extensibilidade permite registrar operações, aplicar guardrails, executar verificações de validação ou integrar-se a sistemas externos.
Os hooks foram projetados para usuários avançados e equipes corporativas que precisam de controle detalhado sobre o comportamento do Cascade. Eles exigem conhecimento básico de shell scripting.
Hooks desbloqueiam uma ampla gama de recursos de automação e governança:
- Logging & Analytics: Monitore cada arquivo lido, alteração de código, comando executado, prompt do usuário ou resposta do Cascade para fins de conformidade e análise de uso
- Security Controls: Impeça o Cascade de acessar arquivos sensíveis, executar comandos perigosos ou processar prompts que violem políticas
- Quality Assurance: Execute linters, formatadores ou testes automaticamente após modificações no código
- Custom Workflows: Integre com rastreadores de problemas, sistemas de notificação ou pipelines de deployment
- Team Standardization: Garanta padrões de código e boas práticas em toda a sua organização
Hooks são comandos de shell executados automaticamente quando determinadas ações do Cascade ocorrem. Cada hook:
- Recebe o contexto (detalhes sobre a ação em execução) via JSON na entrada padrão
- Executa seu script - Python, Bash, Node.js ou qualquer executável
- Retorna um resultado por meio do código de saída e dos fluxos de saída
Para pre-hooks (executados antes de uma ação), seu script pode bloquear a ação encerrando com o código de saída 2. Isso torna os pre-hooks ideais para implementar políticas de segurança ou verificações.
Hooks são configurados em arquivos JSON que podem ser colocados em três níveis diferentes. O Cascade carrega e mescla, em cascata, os hooks de todos esses locais, dando às equipes flexibilidade para distribuir e gerenciar as configurações de hooks.
Hooks no nível do sistema são ideais para políticas válidas para toda a organização em máquinas de desenvolvimento compartilhadas. Por exemplo, você pode usá-los para aplicar políticas de segurança, requisitos de conformidade ou fluxos obrigatórios de revisão de código. As equipes Enterprise também podem configurar hooks pelo dashboard na nuvem sem precisar gerenciar arquivos locais.
- macOS:
/Library/Application Support/Windsurf/hooks.json
- Linux/WSL:
/etc/windsurf/hooks.json
- Windows:
C:\ProgramData\Windsurf\hooks.json
Os hooks no nível de usuário são ideais para preferências pessoais e workflows opcionais.
- Devin Desktop IDE:
~/.codeium/windsurf/hooks.json
- Plugin JetBrains:
~/.codeium/hooks.json
Os hooks no nível do workspace permitem que as equipes mantenham políticas específicas do projeto sob controle de versão junto com seu código. Eles podem incluir regras de validação personalizadas, integrações específicas do projeto ou workflows específicos da equipe.
- Localização:
.windsurf/hooks.json na raiz do seu workspace
Os hooks dos três locais são mesclados. Se o mesmo evento de hook estiver configurado em vários locais, todos os hooks serão executados em ordem: system → user → workspace.
Veja um exemplo da estrutura básica da configuração de hooks:
{
"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
}
]
}
}
Neste exemplo, pre_read_code especifica tanto um comando para macOS/Linux quanto um comando do Windows PowerShell. O hook post_write_code especifica apenas command, então será executado em macOS/Linux e, no Windows, usará o PowerShell como alternativa.
Cada hook aceita os seguintes parâmetros:
| Parâmetro | Tipo | Descrição |
|---|
command | string | O comando de shell a ser executado no macOS/Linux (via bash -c). É necessário especificar pelo menos um entre command e powershell. |
powershell | string | Opcional. O comando a ser executado no Windows (via powershell -Command). Se for omitido no Windows, command será usado como fallback. |
show_output | boolean | Indica se a saída stdout/stderr do hook deve ser exibida na UI do Cascade voltada ao usuário. Útil para depuração. |
working_directory | string | Opcional. O diretório a partir do qual o comando será executado. O padrão é a raiz do seu workspace. |
Os campos command e powershell permitem definir comandos apropriados para cada plataforma em uma única configuração. Isso é útil para equipes com ambientes mistos de macOS/Linux e Windows.
| Plataforma | command set | powershell set | Resultado |
|---|
| macOS/Linux | ✓ | (ignorado) | Executa command via bash -c |
| macOS/Linux | ✗ | ✓ | O hook é ignorado sem aviso |
| Windows | ✓ | ✗ | Usa command como alternativa via powershell -Command |
| Windows | ✗ | ✓ | Executa powershell via powershell -Command |
| Windows | ✓ | ✓ | Executa powershell via powershell -Command |
| Qualquer | ✗ | ✗ | Erro de validação |
Sobre o parâmetro working_directory:
- Em workspaces com vários repositórios, o padrão é a raiz do repo que está sendo usado no momento
- Os caminhos relativos são resolvidos a partir do local padrão (workspace ou raiz do repo)
- Há suporte a caminhos absolutos
- Não há suporte ao uso de
~ para expandir o diretório home
O Cascade oferece doze eventos de hook que abrangem as ações mais importantes no fluxo de trabalho do agente.
Todos os hooks recebem um objeto JSON com os seguintes campos comuns:
| Campo | Tipo | Descrição |
|---|
agent_action_name | string | O nome do evento do hook (por exemplo, “pre_read_code”, “post_write_code”) |
trajectory_id | string | Identificador exclusivo da conversa completa no Cascade |
execution_id | string | Identificador exclusivo de uma única interação do agente |
timestamp | string | Timestamp ISO 8601 de quando o hook foi acionado |
model_name | string | Nome legível do modelo associado a esta invocação do hook (por exemplo, “Claude Sonnet 4”, “GPT 4.1”). Este é o mesmo rótulo exibido no seletor de modelos do Cascade. O valor pode mudar ao longo do tempo à medida que o Devin Desktop atualiza os nomes de exibição dos modelos. Definido como “Unknown” quando não for possível determinar o modelo. |
tool_info | object | Informações específicas do evento (variam conforme o tipo de hook) |
Nos exemplos a seguir, os campos comuns foram omitidos por brevidade. Há doze tipos principais de eventos de hook:
É acionado antes de o Cascade ler um arquivo de código. Isso pode bloquear a ação se o hook retornar o código 2.
Casos de uso: Restringir o acesso a arquivos, registrar operações de leitura, verificar permissões
JSON de entrada:
{
"agent_action_name": "pre_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Este file_path pode ser o caminho de um diretório quando o Cascade lê um diretório recursivamente.
É acionado após o Cascade ler um arquivo de código com sucesso.
Casos de uso: Registrar leituras bem-sucedidas, acompanhar padrões de acesso a arquivos
JSON de entrada:
{
"agent_action_name": "post_read_code",
"tool_info": {
"file_path": "/Users/yourname/project/file.py"
}
}
Este file_path pode ser um caminho para um diretório quando o Cascade lê um diretório de forma recursiva.
Acionado antes de o Cascade escrever ou modificar um arquivo de código. Isso pode bloquear a ação se o hook for encerrado com o código 2.
Casos de uso: Impedir modificações em arquivos protegidos, fazer backup dos arquivos antes das alterações
JSON de entrada:
{
"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"
}
]
}
}
Acionado após o Cascade escrever ou modificar um arquivo de código.
Casos de uso: Executar linters, formatadores ou testes; registrar alterações no 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"
}
]
}
}
Acionado antes de o Cascade executar um comando no terminal. Isso pode bloquear a ação se o hook for encerrado com o código 2.
Casos de uso: Bloquear comandos perigosos, registrar todas as execuções de comandos, adicionar verificações de segurança
JSON de entrada:
{
"agent_action_name": "pre_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
É acionado após o Cascade executar um comando de terminal.
Casos de uso: Registrar resultados de comandos, acionar ações subsequentes
JSON de entrada:
{
"agent_action_name": "post_run_command",
"tool_info": {
"command_line": "npm install package-name",
"cwd": "/Users/yourname/project"
}
}
Acionado antes de o Cascade invocar uma ferramenta do MCP (Model Context Protocol). Isso pode bloquear a ação se o hook for encerrado com o código 2.
Casos de uso: Registrar o uso de ferramentas MCP, restringir quais ferramentas MCP podem ser usadas
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": "Bug report",
"body": "Description of the bug here"
},
"mcp_tool_name": "create_issue"
}
}
Acionado após o Cascade invocar com sucesso uma ferramenta MCP.
Casos de uso: Registrar operações MCP, acompanhar o uso da API, ver os resultados do 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"
}
}
Acionado antes que o Cascade processe o texto do prompt de um usuário. Isso pode bloquear a ação se o hook terminar com o código 2.
Casos de uso: Registrar todos os prompts dos usuários para auditoria; bloquear prompts potencialmente prejudiciais ou que violem políticas
JSON de entrada:
{
"agent_action_name": "pre_user_prompt",
"tool_info": {
"user_prompt": "can you run the echo hello command"
}
}
A opção de configuração show_output não se aplica a este hook.
Acionado de forma assíncrona após o Cascade concluir uma resposta a um prompt do usuário. Este hook recebe a resposta completa do Cascade desde a última mensagem do usuário.
Casos de uso: Registrar todas as respostas do Cascade para auditoria, analisar padrões de resposta, enviar respostas para sistemas externos para revisão de conformidade
JSON de entrada:
{
"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."
}
}
O campo response contém o conteúdo em markdown da resposta do Cascade desde a última entrada do usuário. Isso inclui respostas do planner, ações de ferramentas (leituras e gravações de arquivos, além de comandos) e quaisquer outras etapas executadas pelo Cascade. Também inclui informações sobre quais regras foram acionadas. Consulte o exemplo Rastreamento de regras acionadas para ver como analisar o uso de regras.
A opção de configuração show_output não se aplica a este hook.
O conteúdo de response é derivado de dados de trajetória e pode conter informações confidenciais da sua base de código ou das suas conversas. Trate esses dados de acordo com as políticas de segurança e privacidade da sua organização.
post_cascade_response_with_transcript
Acionado de forma assíncrona depois que o Cascade conclui uma resposta ao prompt de um usuário, semelhante a post_cascade_response. Em vez de fornecer um resumo em markdown inline, este hook grava a transcrição completa da conversa (desde o início da conversa) em um arquivo JSONL local e fornece o caminho do arquivo.
Casos de uso: registro de auditoria e conformidade do Enterprise, rastreamento de contribuições geradas por IA, envio de transcrições para ferramentas externas de observabilidade ou análises
JSON de entrada:
{
"agent_action_name": "post_cascade_response_with_transcript",
"tool_info": {
"transcript_path": "/Users/yourname/.windsurf/transcripts/{trajectory_id}.jsonl"
}
}
O transcript_path aponta para um arquivo JSONL em ~/.windsurf/transcripts/{trajectory_id}.jsonl. Cada linha é um objeto JSON que representa uma única etapa da conversa, com os campos type e status, além de dados específicos da etapa. Por exemplo:
{"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"}
A transcrição inclui dados detalhados do cliente, como conteúdo de arquivos, saídas de comandos, argumentos de ferramentas, resultados de pesquisa e regras aplicadas. Observe que a estrutura exata de cada etapa pode mudar em versões futuras, portanto, crie qualquer consumidor de hook para ser resiliente.
Os arquivos de transcrição são gravados com permissões 0600. O Devin Desktop limita automaticamente o diretório de transcrições a 100 arquivos, removendo os mais antigos com base na data de modificação.
A opção de configuração show_output não se aplica a este hook.
Esta tabela mostra as principais diferenças entre os hooks post_cascade_response e post_cascade_response_with_transcript:
| post_cascade_response | post_cascade_response_with_transcript |
|---|
| Escopo dos dados | Apenas as etapas desde a última entrada do usuário | Toda a conversa desde o início |
| Formato | Resumo em Markdown em tool_info.response | Arquivo JSONL estruturado em tool_info.transcript_path |
| Nível de detalhe | Resumo condensado, legível por humanos | Dados detalhados, legíveis por máquina (conteúdo de arquivos, saídas de comandos etc.) |
| Entrega | Inline, via JSON na stdin | Arquivo em disco (~/.windsurf/transcripts/) |
Os arquivos de transcrição conterão informações confidenciais da sua base de código, incluindo conteúdo de arquivos, saídas de comandos e histórico da conversa. Trate esses arquivos de acordo com as políticas de segurança e privacidade da sua organização.
Acionado após a criação e configuração de um novo git worktree. O hook é executado dentro do novo diretório worktree.
Casos de uso: Copiar arquivos .env ou outros arquivos não rastreados para o worktree, instalar dependências, executar scripts de configuração
Variáveis de ambiente:
| Variável | Descrição |
|---|
$ROOT_WORKSPACE_PATH | O caminho absoluto para o workspace original. Use-o para acessar arquivos ou executar comandos em relação ao repositório original. |
JSON de entrada:
{
"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"
}
}
Seus scripts de hook comunicam os resultados por meio de códigos de saída:
| Código de saída | Significado | Efeito |
|---|
0 | Sucesso | A ação prossegue normalmente |
2 | Erro bloqueante | O agente Cascade verá a mensagem de erro na stderr. Para pre-hooks, isso bloqueia a ação. |
| Qualquer outro | Erro | A ação prossegue normalmente |
Somente pre-hooks (pre_user_prompt, pre_read_code, pre_write_code, pre_run_command, pre_mcp_tool_use) podem bloquear ações usando o código de saída 2. Post-hooks não podem bloquear, pois a ação já ocorreu.
Lembre-se de que o usuário pode ver qualquer saída padrão e erro padrão gerados pelos hooks na UI do Cascade se show_output estiver definido como true.
Registro de todas as ações do Cascade
Acompanhe todas as ações realizadas pelo Cascade para fins de auditoria.
Config:
{
"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():
# Lê os dados JSON da entrada padrão (stdin)
input_data = sys.stdin.read()
# Faz o parse do JSON
try:
data = json.loads(input_data)
# Grava o JSON formatado no arquivo
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()
Este script adiciona cada invocação de hook a um arquivo de log, criando uma trilha de auditoria de todas as ações do Cascade. Você pode transformar os dados de entrada ou executar lógica personalizada como preferir.
Restringir o acesso a arquivos
Impeça que o Cascade leia arquivos fora de um diretório específico.
Configuração:
{
"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():
# Lê os dados JSON da entrada padrão (stdin)
input_data = sys.stdin.read()
# Analisa o 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) # Código de saída 2 bloqueia a ação
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 o Cascade tenta ler um arquivo fora do diretório permitido, esse hook bloqueia a operação e exibe uma mensagem de erro.
Bloqueio de comandos perigosos
Impeça o Cascade de executar comandos potencialmente perigosos.
Config:
{
"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():
# Lê os dados JSON da entrada padrão (stdin)
input_data = sys.stdin.read()
# Faz o parse do 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) # Código de saída 2 bloqueia o 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()
Este hook faz uma varredura nos comandos em busca de padrões perigosos e os bloqueia antes da execução.
Bloqueio de prompts que violam políticas
Impede que os usuários enviem prompts que violem as políticas organizacionais.
Config:
{
"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():
# Lê os dados JSON da entrada padrão (stdin)
input_data = sys.stdin.read()
# Faz o parse do 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) # Código de saída 2 bloqueia o prompt
except json.JSONDecodeError as e:
print(f"Error parsing JSON: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Este hook examina os prompts do usuário antes do processamento e bloqueia os que contêm padrões proibidos. Quando um prompt é bloqueado, o usuário vê uma mensagem de erro na UI do Cascade.
Registro das respostas do Cascade
Registre todas as respostas do Cascade para auditoria de conformidade ou análises.
Configuração:
{
"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():
# Lê os dados JSON da entrada padrão (stdin)
input_data = sys.stdin.read()
# Faz o parse do 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 em arquivo
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()
Esse hook registra cada resposta do Cascade em um arquivo, criando uma trilha de auditoria de todo o conteúdo gerado por IA. Você pode expandi-lo para enviar dados a sistemas externos de logs, bancos de dados ou plataformas de conformidade.
Monitorando Regras acionadas
Acompanhe quais regras foram aplicadas durante as interações no Cascade para observabilidade e métricas.
Configuração:
{
"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:
"""
Analisa as regras acionadas a partir da resposta do Cascade.
As regras aparecem como: - (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())
# Registrar em arquivo
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()
Tipos de regras:
Always On - regras sempre incluídas
Model Decision - regras cujas descrições foram mostradas ao modelo para aplicação condicional
Manual - regras explicitamente mencionadas com @ na entrada do usuário
Global - regras globais de global_rules.md
Glob - regras acionadas pelo acesso a arquivos que correspondem a padrões glob
Isso rastreia quais regras foram apresentadas ao modelo ou acionadas pelo acesso a arquivos, mas não indica se o modelo realmente seguiu uma regra. regras que já foram mostradas recentemente na conversa são deduplicadas e podem não aparecer novamente até mais tarde.
Formate automaticamente os arquivos de código depois que o Cascade os modificar.
Configuração:
{
"hooks": {
"post_write_code": [
{
"command": "bash /Users/yourname/hooks/format_code.sh",
"show_output": false
}
]
}
}
Script (format_code.sh):
#!/bin/bash
# Lê JSON da entrada padrão
input=$(cat)
# Extrai o caminho do arquivo usando jq
file_path=$(echo "$input" | jq -r '.tool_info.file_path')
# Formata com base na extensão do arquivo
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
Este hook executa automaticamente o formatador adequado com base no tipo de arquivo após cada edição.
Copie os arquivos de ambiente e instale as dependências quando uma nova worktree for criada.
Configuração (em .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
# Copiar arquivos de ambiente do workspace original
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
# Instalar dependências
if [ -f "package.json" ]; then
npm install
echo "Installed npm dependencies"
fi
exit 0
Este hook garante que cada worktree tenha a configuração de ambiente necessária e que as dependências sejam instaladas automaticamente.
Use Cascade Hooks por sua conta e risco: Hooks executam comandos de shell automaticamente com todas as permissões da sua conta de usuário. Você é totalmente responsável pelo código que configurar. Hooks mal projetados ou maliciosos podem modificar arquivos, excluir dados, expor credenciais ou comprometer seu sistema.
- Valide todos os dados de entrada: Nunca confie no JSON de entrada sem validá-lo, especialmente em caminhos de arquivos e comandos.
- Use caminhos absolutos: Sempre use caminhos absolutos nas configurações de hook para evitar ambiguidades.
- Proteja dados sensíveis: Evite registrar em log informações sensíveis, como Chaves de API ou credenciais.
- Revise as permissões: Garanta que seus scripts de hook tenham as permissões apropriadas no sistema de arquivos.
- Audite antes da implantação: Revise cada comando e script de hook antes de adicioná-los à sua configuração.
- Teste de forma isolada: Execute Hooks em um ambiente de teste antes de habilitá-los na sua máquina principal de desenvolvimento.
- Mantenha os hooks rápidos: Hooks lentos afetam a capacidade de resposta do Cascade. Procure manter o tempo de execução abaixo de 100 ms.
- Use operações assíncronas: Para hooks não bloqueantes, considere registrar logs em uma fila ou banco de dados de forma assíncrona.
- Filtre logo no início: Verifique o tipo de ação no começo do script para evitar processamento desnecessário.
- Sempre valide o JSON: Use blocos try-catch para lidar com entradas inválidas sem causar falhas.
- Registre os erros corretamente: Grave os erros em
stderr para que fiquem visíveis quando show_output estiver ativado.
- Falhe com segurança: Se o seu hook encontrar um erro, avalie se ele deve bloquear a ação ou permitir que ela continue.
- Comece com logging: Comece implementando um hook simples de logging para entender o fluxo de dados.
- Use
show_output: true: Ative a saída durante o desenvolvimento para ver o que seus hooks estão fazendo.
- Teste o comportamento de bloqueio: Verifique se o código de saída 2 bloqueia corretamente as ações em pre-hooks.
- Verifique todos os fluxos de execução: Teste tanto os cenários de sucesso quanto os de falha nos seus scripts.
As organizações Enterprise precisam impor políticas de segurança, requisitos de conformidade e padrões de desenvolvimento que usuários individuais não podem burlar. O Hooks do Cascade oferece suporte a dois métodos de distribuição Enterprise:
- dashboard na nuvem - Configure hooks por meio de Configurações da equipe no dashboard do Devin Desktop
- Arquivos em nível de sistema - Implante hooks por meio de ferramentas de MDM ou de gerenciamento de configurações
Os dois métodos podem ser usados em conjunto — hooks de todas as fontes são combinados e executados em ordem.
Configuração do Dashboard na Nuvem
Os admins da equipe podem configurar os Hooks do Cascade diretamente no dashboard do Devin Desktop.
Requisitos:
- plano Enterprise
- permissão
TEAM_SETTINGS_UPDATE
Para configurar:
- Acesse Configurações da equipe no dashboard do Devin Desktop
- Localize a seção Hooks do Cascade
- Insira a configuração dos hooks no formato JSON
- Salve suas alterações
Os hooks configurados pelo dashboard são distribuídos automaticamente para todos os membros da equipe e carregados quando o Devin Desktop é iniciado. Os hooks configurados na nuvem são carregados primeiro, seguidos pelos hooks no nível do sistema, do usuário e do workspace.
Quando várias configurações de equipe são mescladas, os hooks são combinados por GitHub Action em vez de serem sobrescritos. Isso significa que os hooks de todas as configurações de equipe aplicáveis serão executados juntos.
Implantação de arquivos em nível de sistema
Para organizações que preferem configuração por arquivo ou precisam que os hooks funcionem offline, implante a configuração obrigatória de hooks.json nestes locais específicos de cada sistema operacional:
macOS:
/Library/Application Support/Windsurf/hooks.json
Linux/WSL:
Windows:
C:\ProgramData\Windsurf\hooks.json
Coloque seus scripts de hook no diretório de sistema correspondente (por exemplo, /usr/local/share/windsurf-hooks/ em sistemas Unix).
Hooks em nível de sistema têm precedência sobre hooks de usuário e de workspace, e não podem ser desativados por usuários finais sem permissões de root.
MDM e gerenciamento de configuração
As equipes de TI corporativa podem implantar hooks no nível do sistema usando ferramentas padrão:
Gerenciamento de Dispositivos Móveis (MDM)
- Jamf Pro (macOS) - Implante por meio de perfis de configuração ou scripts
- Microsoft Intune (Windows/macOS) - Use scripts do PowerShell ou políticas de implantação
- Workspace ONE, Google Endpoint Management e outras soluções de MDM
Gerenciamento de configuração
- Ansible, Puppet, Chef, SaltStack - Use a automação de infraestrutura existente
- Scripts de implantação personalizados - Scripts de shell, PowerShell ou a ferramenta de sua preferência
Após a implantação, verifique se os hooks foram instalados corretamente:
# Verificar se os hooks do sistema estão presentes
ls -la /etc/windsurf/hooks.json # Linux
ls -la "/Library/Application Support/Windsurf/hooks.json" # macOS
# Testar a execução do hook (a saída do hook deve aparecer no Cascade)
# Peça a um desenvolvedor para acionar a ação relevante no Cascade
# Verificar se os usuários não podem modificar os hooks do sistema
sudo chown root:root /etc/windsurf/hooks.json
sudo chmod 644 /etc/windsurf/hooks.json
Importante: Os hooks em nível de sistema são de responsabilidade exclusiva da sua equipe de TI ou de segurança. O Devin Desktop não implanta nem gerencia arquivos em caminhos de sistema. Garanta que suas equipes internas cuidem da implantação, das atualizações e da conformidade de acordo com as políticas da sua organização.
Hooks de workspace para projetos do Team
Para convenções específicas de cada projeto, as equipes podem usar hooks em nível de workspace no controle de versão:
# Adicione ao seu repositório
.windsurf/
├── hooks.json
└── scripts/
└── format-check.py
# Faça commit no git
git add .windsurf/
git commit -m "Add workspace hooks for code formatting"
Isso permite que as equipes padronizem as práticas de desenvolvimento. Mantenha as políticas essenciais para a segurança no nível da nuvem ou do sistema e evite versionar informações sensíveis.