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

# Hooks do Cascade

> Execute comandos de shell personalizados em pontos-chave do fluxo de trabalho do Cascade para registro em log, controles de segurança, validação e governança corporativa, com hooks de pré e pós-execução.

Os Hooks do Cascade permitem executar comandos de shell personalizados em pontos-chave do fluxo de trabalho do Cascade. Esse poderoso recurso de extensibilidade possibilita registrar operações, aplicar controles (guardrails), executar verificações de validação ou integrar-se a sistemas externos.

<Note>
  Os Hooks foram projetados para usuários avançados e equipes Enterprise que precisam de controle granular sobre o comportamento do Cascade. Eles exigem conhecimento básico de shell scripting.
</Note>

<div id="what-you-can-build">
  ## O que você pode construir
</div>

Hooks desbloqueiam uma ampla gama de recursos de automação e governança:

* **Registro e Analytics**: Acompanhe cada arquivo lido, alteração de código, comando executado, prompt de usuário enviado ao Cascade ou resposta do Cascade para fins de conformidade e análise de uso
* **Controles de segurança**: Impeça o Cascade de acessar arquivos sensíveis, executar comandos perigosos ou processar prompts que violem políticas
* **Garantia de qualidade**: Execute linters, formatadores ou testes automaticamente após modificações no código
* **Fluxos de trabalho personalizados**: Integre com rastreadores de issues, sistemas de notificação ou pipelines de deploy
* **Padronização da equipe**: Faça cumprir padrões de codificação e melhores práticas em toda a organização

<div id="how-hooks-work">
  ## Como os Hooks Funcionam
</div>

Hooks são comandos de shell que são executados automaticamente quando ações específicas do Cascade ocorrem. Cada hook:

1. **Recebe contexto** (detalhes sobre a ação em execução) via JSON na entrada padrão
2. **Executa seu script** — Python, Bash, Node.js ou qualquer executável
3. **Retorna um resultado** por meio de código de saída e fluxos de saída

Para **pré-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 pré-hooks ideais para implementar políticas de segurança ou validações.

<div id="configuration">
  ## Configuração
</div>

Os hooks são configurados em arquivos JSON que podem ser colocados em três níveis diferentes. O Cascade carrega e combina os hooks de todos os locais, dando às equipes flexibilidade para distribuir e gerenciar as configurações de hooks.

<div id="system-level">
  #### Nível do sistema
</div>

Hooks em nível de sistema são ideais para políticas organizacionais aplicadas em máquinas de desenvolvimento compartilhadas. Por exemplo, você pode usá-los para impor políticas de segurança, requisitos de conformidade ou fluxos de trabalho obrigatórios de revisão de código. Equipes Enterprise também podem configurar hooks por meio do [cloud dashboard](#cloud-dashboard-configuration) sem precisar gerenciar arquivos locais.

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

<div id="user-level">
  #### Nível do usuário
</div>

Hooks no nível do usuário são ideais para preferências pessoais e fluxos de trabalho opcionais.

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

<div id="workspace-level">
  #### Nível de workspace
</div>

Hooks no nível de workspace permitem que as equipes versionem políticas específicas do projeto junto com o código. Eles podem incluir regras de validação personalizadas, integrações específicas do projeto ou fluxos de trabalho específicos da equipe.

* **Local**: `.windsurf/hooks.json` na raiz do seu workspace

<Note>
  Hooks de todas as três origens são **mesclados**. Se o mesmo evento de hook estiver configurado em várias origens, todos os hooks serão executados na seguinte ordem: sistema → usuário → workspace.
</Note>

<div id="basic-structure">
  ### Estrutura básica
</div>

Veja um exemplo da estrutura básica da configuração de hooks:

```json theme={null}
{
  "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
      }
    ]
  }
}
```

<div id="configuration-options">
  ### Opções de configuração
</div>

Cada hook aceita os seguintes parâmetros:

| Parâmetro           | Tipo    | Descrição                                                                                                             |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| `command`           | string  | O comando de shell a ser executado. Pode ser qualquer executável válido com argumentos.                               |
| `show_output`       | boolean | Define se a saída stdout/stderr do hook será exibida na interface 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. Por padrão, é a raiz do seu workspace.               |

<Note>
  **Sobre o parâmetro `working_directory`:**

  * Em workspaces com múltiplos repositórios, o padrão é a raiz do repositório em que você está trabalhando no momento
  * Caminhos relativos são resolvidos em relação à localização padrão (raiz do workspace ou do repositório)
  * Caminhos absolutos são suportados
  * Não há suporte ao uso de `~` para expansão do diretório home
</Note>

<div id="hook-events">
  ## Eventos de Hook
</div>

O Cascade oferece doze eventos de hook que abrangem as ações mais críticas no fluxo de trabalho do agente.

<div id="common-input-structure">
  ### Estrutura comum de entrada
</div>

Todos os hooks recebem um objeto JSON com os seguintes campos comuns:

| Campo               | Tipo   | Descrição                                                                      |
| ------------------- | ------ | ------------------------------------------------------------------------------ |
| `agent_action_name` | string | Nome do evento do hook (por exemplo, "pre\_read\_code", "post\_write\_code")   |
| `trajectory_id`     | string | Identificador exclusivo da conversa geral do Cascade                           |
| `execution_id`      | string | Identificador exclusivo da única interação do agente                           |
| `timestamp`         | string | Carimbo de data/hora em formato ISO 8601 no momento em que o hook foi acionado |
| `tool_info`         | object | Informações específicas do evento (variam conforme o tipo de hook)             |

Nos exemplos a seguir, os campos comuns são omitidos para brevidade. Existem doze tipos principais de eventos de hook:

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

Acionado **antes** de o Cascade ler um arquivo de código. Isso pode bloquear a ação se o hook terminar com o código 2.

**Casos de uso**: Restringir acesso a arquivos, registrar operações de leitura, verificar permissões

**JSON de entrada**:

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

Este `file_path` pode ser um caminho de diretório quando o Cascade lê uma pasta de forma recursiva.

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

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**:

```json theme={null}
{
  "agent_action_name": "post_read_code",
  "tool_info": {
    "file_path": "/Users/seunome/projeto/arquivo.py"
  }
}
```

Este `file_path` pode ser um caminho de diretório quando o Cascade lê um diretório de forma recursiva.

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

Acionado **antes** de o Cascade escrever ou modificar um arquivo de código. Pode bloquear a ação se o hook encerrar com o código 2.

**Casos de uso**: Impedir modificações em arquivos protegidos, fazer backup dos arquivos antes de alterações

**JSON de entrada**:

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

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

Acionado **depois** que o Cascade escreve ou modifica um arquivo de código.

**Casos de uso**: Executar linters, formatadores ou testes; registrar alterações no código

**JSON de entrada**:

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

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

Acionado **antes** de o Cascade executar um comando no terminal. A ação pode ser bloqueada se o hook terminar 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**:

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

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

Disparado **após** o Cascade executar um comando no terminal.

**Casos de uso**: Registrar resultados do comando, disparar ações subsequentes

**JSON de entrada**:

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

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

Acionado **antes** de o Cascade invocar uma ferramenta MCP (Model Context Protocol). Isso pode bloquear a ação se o hook terminar com o código 2.

**Casos de uso**: Registrar o uso de MCP, restringir quais ferramentas MCP podem ser usadas

**JSON de entrada**:

```json theme={null}
{
  "agent_action_name": "pre_mcp_tool_use",
  "tool_info": {
    "mcp_server_name": "github",
    "mcp_tool_arguments": {
      "owner": "code-owner",
      "repo": "my-cool-repo",
      "title": "Relatório de bug",
      "body": "Descrição do bug"
    },
    "mcp_tool_name": "create_issue"
  }
}
```

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

Acionado **depois** que o Cascade invoca com sucesso uma ferramenta MCP.

**Casos de uso**: Registrar operações do MCP, acompanhar uso de API, visualizar resultados do MCP

**JSON de entrada**:

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

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

Acionado **antes** de o Cascade processar o texto do prompt de um usuário. Isso pode bloquear a ação se o hook for encerrado com o código 2.

**Casos de uso**: Registrar todos os prompts de usuário para auditoria, bloquear prompts potencialmente prejudiciais ou que violem a política

**JSON de entrada**:

```json theme={null}
{
  "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.

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

Acionado de forma assíncrona **depois** que o Cascade conclui uma resposta ao prompt de um usuário. Esse hook recebe a resposta completa do Cascade desde a última interação do usuário.

**Casos de uso**: registrar todas as respostas do Cascade para fins de auditoria, analisar padrões de resposta, enviar respostas a sistemas externos para revisão de conformidade

**JSON de entrada**:

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

O campo `response` contém o conteúdo em formato markdown da resposta do Cascade desde a última entrada do usuário. Isso inclui respostas do planner, ações de ferramentas (leituras de arquivos, gravações, comandos) e quaisquer outras etapas que o Cascade executou. Ele também inclui informações sobre quais [rules](/pt-BR/windsurf/cascade/memories-and-rules) foram acionadas. Veja o exemplo [Tracking Triggered Rules](#tracking-triggered-rules) para saber como analisar o uso de regras.

A opção de configuração `show_output` não se aplica a este hook.

<Warning>
  O conteúdo de `response` é derivado de dados de trajetória e pode conter informações confidenciais da sua base de código ou de conversas. Trate esses dados de acordo com as políticas de segurança e privacidade da sua organização.
</Warning>

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

Acionado de forma assíncrona **após** o Cascade concluir 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 desse arquivo.

**Casos de uso**: registro de auditoria e conformidade em Enterprise, rastreamento de contribuições geradas por IA, envio de transcrições para ferramentas externas de observabilidade ou Analytics

**JSON de entrada**:

```json theme={null}
{
  "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](https://jsonlines.org/) em `~/.windsurf/transcripts/{trajectory_id}.jsonl`. Cada linha é um objeto JSON que representa uma única etapa da conversa, com campos `type` e `status`, além de dados específicos dessa etapa. Por exemplo:

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

A transcrição inclui dados detalhados pertencentes ao cliente, como conteúdo de arquivos, saídas de comandos, argumentos de ferramentas, resultados de busca e [regras](/pt-BR/windsurf/cascade/memories-and-rules) que foram aplicadas. Observe que a estrutura exata de cada etapa pode mudar em versões futuras, portanto, projete quaisquer consumidores de hooks para serem resilientes a essas mudanças.

Arquivos de transcrição são gravados com permissões `0600`. O Windsurf limita automaticamente o diretório de transcrições a, no máximo, 100 arquivos, removendo os mais antigos com base no horário 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`                                                  |
| ---------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Data scope**   | Apenas as etapas desde a última entrada do usuário | A conversa completa desde o início                                                       |
| **Format**       | Resumo em Markdown em `tool_info.response`         | Arquivo JSONL estruturado em `tool_info.transcript_path`                                 |
| **Detail level** | Resumo condensado e legível para humanos           | Dados detalhados e legíveis por máquina (conteúdo de arquivos, saídas de comandos, etc.) |
| **Delivery**     | Inline via JSON em stdin                           | Arquivo em disco (`~/.windsurf/transcripts/`)                                            |

<Warning>
  Os arquivos de transcrição conterão informações sensíveis da sua base de código, incluindo conteúdo de arquivos, saídas de comandos e histórico de conversas. Trate esses arquivos de acordo com as políticas de segurança e privacidade da sua organização.
</Warning>

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

Acionado **depois** que um novo [git worktree](./worktrees) é criado e configurado. O hook é executado dentro do novo diretório do **worktree**.

**Casos de uso**: Copiar arquivos `.env` ou outros arquivos não versionados 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 isto para acessar arquivos ou executar comandos relativos ao repositório original. |

**JSON de entrada**:

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

<div id="exit-codes">
  ## Códigos de saída
</div>

Seus scripts de hook comunicam 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 bloqueador | O agente Cascade verá a mensagem de erro do stderr. Em pré-hooks, isso **bloqueia** a ação. |
| Qualquer outro  | Erro            | A ação prossegue normalmente                                                                |

<Warning>
  Apenas **pré-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. Pós-hooks não podem bloquear, pois a ação já ocorreu.
</Warning>

Lembre-se de que o usuário pode ver qualquer saída padrão e erro padrão gerados pelos hooks na interface do Cascade se `show_output` for true.

<div id="example-use-cases">
  ## Exemplos de casos de uso
</div>

<div id="logging-all-cascade-actions">
  ### Registro de todas as ações do Cascade
</div>

Acompanhe cada ação que o Cascade executa para fins de auditoria.

**Config**:

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

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

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

import sys
import json

def main():
    # Lê os dados JSON da entrada padrão
    input_data = sys.stdin.read()
    
    # Analisa o 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"Erro ao analisar JSON: {e}", file=sys.stderr)
        sys.exit(1)

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

Este script anexa cada execução de hook a um arquivo de log, criando um registro de auditoria de todas as ações do Cascade. Você pode transformar os dados de entrada ou executar lógica personalizada conforme achar necessário.

<div id="restricting-file-access">
  ### Restringir acesso a arquivos
</div>

Impeça o Cascade de ler arquivos fora de um diretório específico.

**Config**:

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

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

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

import sys
import json

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

def main():
    # Read the JSON data from stdin
    input_data = sys.stdin.read()

    # Parse the 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)  # O 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, este hook bloqueia a operação e exibe uma mensagem de erro.

<div id="blocking-dangerous-commands">
  ### Bloqueando comandos perigosos
</div>

Impeça o Cascade de executar comandos potencialmente perigosos.

**Config**:

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

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

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

import sys
import json

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

def main():
    # Read the JSON data from stdin
    input_data = sys.stdin.read()

    # Parse the 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}' não é permitido por motivos de segurança.", file=sys.stderr)
                    sys.exit(2)  # Exit code 2 blocks the command
            
            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 analisa os comandos em busca de padrões perigosos e os bloqueia antes da execução.

<div id="blocking-policy-violating-prompts">
  ### Bloqueando Prompts que Violam Políticas
</div>

Impeça que usuários enviem prompts que violem as políticas da organização.

**Configuração**:

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

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

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

import sys
import json

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

def main():
    # Read the JSON data from stdin
    input_data = sys.stdin.read()

    # Parse the 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 bloqueado: Contém conteúdo proibido. O usuário não pode solicitar ao agente que faça coisas inadequadas.", file=sys.stderr)
                    sys.exit(2)  # Exit code 2 blocks the 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 de serem processados e bloqueia qualquer prompt que contenha padrões proibidos. Quando um prompt é bloqueado, o usuário vê uma mensagem de erro na UI do Cascade.

<div id="logging-cascade-responses">
  ### Registro das respostas do Cascade
</div>

Monitore todas as respostas do Cascade para fins de auditoria de conformidade ou Analytics.

**Configuração**:

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

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

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

import sys
import json
from datetime import datetime

def main():
    # Lê os dados JSON do 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 no 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"Erro ao fazer parse do 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 estendê-lo para enviar dados a sistemas externos de logs, bancos de dados ou plataformas de conformidade.

<div id="tracking-triggered-rules">
  ### Monitorando Regras Acionadas
</div>

Monitore quais [regras](/pt-BR/windsurf/cascade/memories-and-rules) foram aplicadas durante interações com o Cascade para fins de observabilidade e métricas.

**Config**:

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

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

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

import sys
import json
import re
from datetime import datetime

def extract_triggered_rules(response: str) -> dict:
    """
    Analisa regras acionadas da resposta do Cascade.
    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())

            # Log to file
            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 que estão sempre incluídas
* `Model Decision` - Regras cujas descrições foram mostradas ao modelo de IA para aplicação condicional
* `Manual` - Regras explicitamente mencionadas com @ na entrada do usuário
* `Global` - Regras globais de `global_rules.md`
* `Glob` - Regras acionadas por acesso a arquivos que correspondam a padrões glob

<Note>
  Isso registra quais regras foram *apresentadas* ao modelo de IA ou *acionadas* por 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.
</Note>

<div id="running-code-formatters-after-edits">
  ### Executando formatadores de código após edições
</div>

Formate arquivos de código automaticamente depois que o Cascade os modificar.

**Configuração**:

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

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

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

# 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 "Arquivo Python formatado: $file_path"
elif [[ "$file_path" == *.js ]] || [[ "$file_path" == *.ts ]]; then
    prettier --write "$file_path" 2>&1
    echo "Arquivo JS/TS formatado: $file_path"
elif [[ "$file_path" == *.go ]]; then
    gofmt -w "$file_path" 2>&1
    echo "Arquivo Go formatado: $file_path"
fi

exit 0
```

Este hook executa automaticamente o formatador adequado com base no tipo de arquivo após cada edição.

<div id="setting-up-worktrees">
  ### Configurando Worktrees
</div>

Copie arquivos de ambiente e instale dependências quando uma nova worktree for criada.

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

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

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

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

# Copiar arquivos de ambiente do workspace original
if [ -f "$ROOT_WORKSPACE_PATH/.env" ]; then
    cp "$ROOT_WORKSPACE_PATH/.env" .env
    echo "Arquivo .env copiado"
fi

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

# Instalar dependências
if [ -f "package.json" ]; then
    npm install
    echo "Dependências npm instaladas"
fi

exit 0
```

Este hook garante que cada worktree tenha a configuração de ambiente necessária e as dependências necessárias instaladas automaticamente.

<div id="best-practices">
  ## Boas práticas
</div>

<div id="security">
  ### Segurança
</div>

<Warning>
  **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.
</Warning>

* **Valide todas as entradas**: Nunca confie no JSON de entrada sem validação, especialmente para caminhos de arquivo e comandos.
* **Use caminhos absolutos**: Sempre use caminhos absolutos nas configurações de hooks para evitar ambiguidades.
* **Proteja dados sensíveis**: Evite registrar informações sensíveis, como chaves de API ou credenciais.
* **Revise as permissões**: Certifique-se de que seus scripts de hooks tenham permissões adequadas no sistema de arquivos.
* **Audite antes da implantação**: Revise cada comando e script de hooks antes de adicioná-los à sua configuração.
* **Teste em isolamento**: Execute hooks em um ambiente de teste antes de habilitá-los na sua máquina principal de desenvolvimento.

<div id="performance-considerations">
  ### Considerações de desempenho
</div>

* **Mantenha os hooks rápidos**: Hooks lentos afetarão a responsividade do Cascade. Mire em tempos de execução abaixo de 100 ms.
* **Use operações assíncronas**: Para hooks não bloqueantes, considere registrar em uma fila ou em um banco de dados de forma assíncrona.
* **Filtre o quanto antes**: Verifique o tipo de ação no início do script para evitar processamento desnecessário.

<div id="error-handling">
  ### Tratamento de erros
</div>

* **Sempre valide o JSON**: Use blocos try-catch para tratar entradas malformadas de forma adequada.
* **Registre os erros corretamente**: Escreva 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.

<div id="testing-your-hooks">
  ### Testando seus hooks
</div>

1. **Comece registrando logs**: Implemente um hook simples de logging para entender o fluxo de dados.
2. **Use `show_output: true`**: Ative a exibição de saída durante o desenvolvimento para ver o que seus hooks estão fazendo.
3. **Teste o comportamento de bloqueio**: Verifique se o código de saída 2 bloqueia corretamente as ações em pre-hooks.
4. **Verifique todos os caminhos de código**: Teste cenários de sucesso e de falha nos seus scripts.

<div id="enterprise-distribution">
  ## Distribuição Enterprise
</div>

Organizações Enterprise precisam aplicar políticas de segurança, requisitos de conformidade e padrões de desenvolvimento que usuários individuais não podem contornar. O Cascade Hooks oferece suporte a dois métodos de distribuição para Enterprise:

1. **Cloud Dashboard** - Configure hooks via Team Settings no dashboard do Windsurf
2. **System-Level Files** - Implemente hooks via MDM ou ferramentas de gerenciamento de configuração

Ambos os métodos podem ser usados juntos — hooks de todas as fontes são combinados e executados em sequência.

<div id="cloud-dashboard-configuration">
  ### Configuração do painel na nuvem
</div>

Os administradores de equipe podem configurar Cascade Hooks diretamente no painel do Windsurf.

**Requisitos:**

* Plano Enterprise
* Permissão `TEAM_SETTINGS_UPDATE`

**Para configurar:**

1. Acesse **Team Settings** no painel do Windsurf
2. Encontre a seção **Cascade Hooks**
3. Insira a configuração de seus hooks em formato JSON
4. Salve suas alterações

Hooks configurados no painel são distribuídos automaticamente a todos os membros da equipe e carregados quando o Windsurf é iniciado. Hooks configurados na nuvem são carregados primeiro, seguidos pelos hooks em nível de sistema, de usuário e de workspace.

<Note>
  Quando várias configurações de equipe são combinadas, os hooks são agregados por ação em vez de substituídos. Isso significa que os hooks de todas as configurações de equipe aplicáveis serão executados em conjunto.
</Note>

<div id="system-level-file-deployment">
  ### Implantação de arquivos em nível de sistema
</div>

Para organizações que preferem configurações baseadas em arquivos ou precisam que os hooks operem offline, implante sua configuração obrigatória `hooks.json` nestes locais específicos do sistema operacional:

**macOS:**

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

**Linux/WSL:**

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

**Windows:**

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

Coloque seus scripts de hook em um 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.

<div id="mdm-and-configuration-management">
  #### MDM e Gerenciamento de Configuração
</div>

As equipes de TI do Enterprise podem implantar hooks em nível de 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 implantação por políticas
* **Workspace ONE**, **Google Endpoint Management** e outras soluções de MDM

**Gerenciamento de Configuração**

* **Ansible**, **Puppet**, **Chef**, **SaltStack** - Use sua automação de infraestrutura existente
* **Scripts de implantação personalizados** - Scripts de shell, PowerShell ou suas ferramentas preferidas

<div id="verification-and-auditing">
  #### Verificação e auditoria
</div>

Após a implantação, verifique se os hooks estão instalados corretamente:

```bash theme={null}
# 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)
# Solicite que um desenvolvedor acione a ação relevante do 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
```

<Note>
  **Importante**: Hooks em nível de sistema são totalmente gerenciados pela sua equipe de TI ou segurança. O Windsurf não implanta nem gerencia arquivos em caminhos de sistema. Certifique-se de que suas equipes internas cuidem da implantação, das atualizações e da conformidade de acordo com as políticas da sua organização.
</Note>

<div id="workspace-hooks-for-team-projects">
  ### Hooks de workspace para projetos em equipe
</div>

Para convenções específicas de projeto, as equipes podem usar hooks no nível do workspace no controle de versão:

```bash theme={null}
# Adicione ao seu repositório
.windsurf/
├── hooks.json
└── scripts/
    └── format-check.py

# Faça commit no git
git add .windsurf/
git commit -m "Adiciona hooks de workspace para formatação de código"
```

Isso permite que as equipes padronizem as práticas de desenvolvimento. Mantenha as políticas críticas de segurança no nível da nuvem ou do sistema e evite registrar informações sensíveis no controle de versão.

<div id="additional-resources">
  ## Recursos adicionais
</div>

* **Integração MCP**: Saiba mais sobre o [Model Context Protocol no Windsurf](/pt-BR/windsurf/cascade/mcp)
* **Workflows**: Descubra como combinar hooks com os [Workflows do Cascade](/pt-BR/windsurf/cascade/workflows)
* **Analytics**: Acompanhe o uso do Cascade com [Team Analytics](/pt-BR/windsurf/accounts/analytics)
