Skip to main content

Configuração de ganchos

Encontre informações sobre como configurar ganchos para utilização com CLI do GitHub Copilot e Agente de codificação do Copilot.

Este artigo de referência descreve os tipos de gancho disponíveis com exemplos, incluindo seus formatos de entrada e saída, práticas recomendadas de script e padrões avançados para registro em log, imposição de segurança e integrações externas. Para obter informações gerais sobre como criar ganchos, consulte Uso de ganchos com agentes do GitHub Copilot.

Tipos de gancho

Gancho de início da sessão

Executado quando uma nova sessão de agente começa ou ao retomar uma sessão existente.

          **JSON de entrada:**
JSON
{
  "timestamp": 1704614400000,
  "cwd": "/path/to/project",
  "source": "new",
  "initialPrompt": "Create a new feature"
}
          **Campos:**

* timestamp: carimbo de data/hora unix em milissegundos * cwd: diretório de trabalho atual * source "new" : (nova sessão), "resume" (sessão retomada) ou"startup" * initialPrompt: o prompt inicial do usuário (se fornecido)

          **Saída:** Ignorado (sem valor de retorno sendo processado)

          **Gancho de exemplo:**
JSON
{
  "type": "command",
  "bash": "./scripts/session-start.sh",
  "powershell": "./scripts/session-start.ps1",
  "cwd": "scripts",
  "timeoutSec": 30
}
          **Script de exemplo (Bash):**
Shell
#!/bin/bash
INPUT=$(cat)
SOURCE=$(echo "$INPUT" | jq -r '.source')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')

echo "Session started from $SOURCE at $TIMESTAMP" >> session.log

Gancho de fim de sessão

Executado quando a sessão do agente é concluída ou encerrada.

          **JSON de entrada:**
JSON
{
  "timestamp": 1704618000000,
  "cwd": "/path/to/project",
  "reason": "complete"
}
          **Campos:**
  •           `timestamp`: Carimbo de data/hora Unix em milissegundos
    
  •         `cwd`: diretório de trabalho atual
    
  •         `reason`: um de `"complete"`, `"error"`, `"abort"`, `"timeout"`ou `"user_exit"`
    
            **Saída:** Ignorado
    
            **Exemplo de script:**
    
Shell
#!/bin/bash
INPUT=$(cat)
REASON=$(echo "$INPUT" | jq -r '.reason')

echo "Session ended: $REASON" >> session.log
# Cleanup temporary files
rm -rf /tmp/session-*

Gancho enviado pelo prompt do usuário

Executado quando o usuário envia um prompt para o agente.

          **JSON de entrada:**
JSON
{
  "timestamp": 1704614500000,
  "cwd": "/path/to/project",
  "prompt": "Fix the authentication bug"
}
          **Campos:**
  •           `timestamp`: Carimbo de data/hora Unix em milissegundos
    
  •         `cwd`: diretório de trabalho atual
    
  •         `prompt`: o texto exato enviado pelo usuário
    
            **Saída:** Ignorado (a modificação de prompts não recebe suporte atualmente em ganchos de cliente)
    
            **Exemplo de script:**
    
Shell
#!/bin/bash
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')

# Log to a structured file
echo "$(date -d @$((TIMESTAMP/1000))): $PROMPT" >> prompts.log

Gancho de uso de pré-ferramenta

Executado antes que o agente use qualquer ferramenta (como bash, , edit). view Esse é o gancho mais poderoso, pois pode aprovar ou negar execuções de ferramentas.

          **JSON de entrada:**
JSON
{
  "timestamp": 1704614600000,
  "cwd": "/path/to/project",
  "toolName": "bash",
  "toolArgs": "{\"command\":\"rm -rf dist\",\"description\":\"Clean build directory\"}"
}
          **Campos:**

* timestamp: marca temporal Unix em milissegundos * cwd: diretório de trabalho atual * toolName: nome da ferramenta que está sendo invocada (como "bash", "edit", "view", "create") * toolArgs: cadeia de caracteres JSON que contém os argumentos da ferramenta

          **JSON de saída (opcional):**
JSON
{
  "permissionDecision": "deny",
  "permissionDecisionReason": "Destructive operations require approval"
}
          **Campos de saída:**

* permissionDecision: ou "allow", "deny" ou "ask" (somente "deny" é processado no momento) * permissionDecisionReason: explicação compreensível por humanos para a decisão

          **Gancho de exemplo para bloquear comandos perigosos:**
Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')
TOOL_ARGS=$(echo "$INPUT" | jq -r '.toolArgs')

# Log the tool use
echo "$(date): Tool=$TOOL_NAME Args=$TOOL_ARGS" >> tool-usage.log

# Check for dangerous patterns
if echo "$TOOL_ARGS" | grep -qE "rm -rf /|format|DROP TABLE"; then
  echo '{"permissionDecision":"deny","permissionDecisionReason":"Dangerous command detected"}'
  exit 0
fi

# Allow by default (or omit output to allow)
echo '{"permissionDecision":"allow"}'
          **Gancho de exemplo para impor permissões de arquivo:**
Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')

# Only allow editing specific directories
if [ "$TOOL_NAME" = "edit" ]; then
  PATH_ARG=$(echo "$INPUT" | jq -r '.toolArgs' | jq -r '.path')
  
  if [[ ! "$PATH_ARG" =~ ^(src/|test/) ]]; then
    echo '{"permissionDecision":"deny","permissionDecisionReason":"Can only edit files in src/ or test/ directories"}'
    exit 0
  fi
fi

# Allow all other tools

Gancho de uso pós-ferramenta

Executado depois que uma ferramenta conclui a execução (com êxito ou falha).

          **Exemplo de JSON de entrada:**
JSON
{
  "timestamp": 1704614700000,
  "cwd": "/path/to/project",
  "toolName": "bash",
  "toolArgs": "{\"command\":\"npm test\"}",
  "toolResult": {
    "resultType": "success",
    "textResultForLlm": "All tests passed (15/15)"
  }
}
          **Campos:**
  •           `timestamp`: Carimbo de data/hora Unix em milissegundos
    
  •         `cwd`: diretório de trabalho atual
    
  •         `toolName`: nome da ferramenta que foi executada
    
  •         `toolArgs`: cadeia de caracteres JSON que contém os argumentos da ferramenta
    
  •         `toolResult`: objeto de resultado que contém:
    

    * resultType: "success", "failure" ou "denied" * textResultForLlm: o texto do resultado mostrado ao agente

            **Saída:** Ignorado (a modificação de resultado não tem suporte no momento)
    
            **Script de exemplo que registra estatísticas de execução da ferramenta em um arquivo CSV:**
    

Esse script registra as estatísticas de execução da ferramenta em um arquivo CSV e envia um alerta de email quando uma ferramenta falha.

Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')
RESULT_TYPE=$(echo "$INPUT" | jq -r '.toolResult.resultType')

# Track statistics
echo "$(date),${TOOL_NAME},${RESULT_TYPE}" >> tool-stats.csv

# Alert on failures
if [ "$RESULT_TYPE" = "failure" ]; then
  RESULT_TEXT=$(echo "$INPUT" | jq -r '.toolResult.textResultForLlm')
  echo "FAILURE: $TOOL_NAME - $RESULT_TEXT" | mail -s "Agent Tool Failed" [email protected]
fi

Ocorreu um erro no gancho

Executado quando ocorre um erro durante a execução do agente.

          **Exemplo de JSON de entrada:**
JSON
{
  "timestamp": 1704614800000,
  "cwd": "/path/to/project",
  "error": {
    "message": "Network timeout",
    "name": "TimeoutError",
    "stack": "TimeoutError: Network timeout\n    at ..."
  }
}
          **Campos:**

* timestamp: Timestamp Unix em milissegundos * cwd: diretório de trabalho atual * error: objeto de erro que contém: * message: mensagem de erro * name: tipo/nome de erro * stack: rastreamento de pilha (se disponível)

          **Saída:** Ignorado (não há suporte para modificação de tratamento de erros no momento)

          **Script de exemplo que extrai detalhes de erro para um arquivo de log:**
Shell
#!/bin/bash
INPUT=$(cat)
ERROR_MSG=$(echo "$INPUT" | jq -r '.error.message')
ERROR_NAME=$(echo "$INPUT" | jq -r '.error.name')

echo "$(date): [$ERROR_NAME] $ERROR_MSG" >> errors.log

Práticas recomendadas de script

Leitura de dados de entrada

Este script de exemplo lê a entrada JSON de stdin em uma variável e, em seguida, usa jq para extrair os campos timestamp e cwd.

          **Bash:**
Shell
#!/bin/bash
# Read JSON from stdin
INPUT=$(cat)

# Parse with jq
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')
CWD=$(echo "$INPUT" | jq -r '.cwd')
          **PowerShell:**
PowerShell
# Read JSON from stdin
$input = [Console]::In.ReadToEnd() | ConvertFrom-Json

# Access properties
$timestamp = $input.timestamp
$cwd = $input.cwd

Geração de JSON

Este script de exemplo mostra como produzir JSON válido a partir de seu script de gancho. Use jq -c no Bash para saída de linha única compacta ou ConvertTo-Json -Compress no PowerShell.

          **Bash:**
Shell
#!/bin/bash
# Use jq to compact the JSON output to a single line
echo '{"permissionDecision":"deny","permissionDecisionReason":"Security policy violation"}' | jq -c

# Or construct with variables
REASON="Too dangerous"
jq -n --arg reason "$REASON" '{permissionDecision: "deny", permissionDecisionReason: $reason}'
          **PowerShell:**
PowerShell
# Use ConvertTo-Json to compact the JSON output to a single line
$output = @{
    permissionDecision = "deny"
    permissionDecisionReason = "Security policy violation"
}
$output | ConvertTo-Json -Compress

Tratamento de erros

Este exemplo de script demonstra como lidar com erros em scripts de gancho.

          **Bash:**
Shell
#!/bin/bash
set -e  # Exit on error

INPUT=$(cat)
# ... process input ...

# Exit with 0 for success
exit 0
          **PowerShell:**
PowerShell
$ErrorActionPreference = "Stop"

try {
    $input = [Console]::In.ReadToEnd() | ConvertFrom-Json
    # ... process input ...
    exit 0
} catch {
    Write-Error $_.Exception.Message
    exit 1
}

Tratamento de tempos limite

Os ganchos têm um tempo limite padrão de 30 segundos. Para operações mais longas, aumente timeoutSec:

JSON
{
  "type": "command",
  "bash": "./scripts/slow-validation.sh",
  "timeoutSec": 120
}

Padrões avançados

Vários ganchos do mesmo tipo

Você pode definir múltiplos hooks para o mesmo evento. Eles executam na ordem:

JSON
{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "./scripts/security-check.sh",
        "comment": "Security validation - runs first"
      },
      {
        "type": "command", 
        "bash": "./scripts/audit-log.sh",
        "comment": "Audit logging - runs second"
      },
      {
        "type": "command",
        "bash": "./scripts/metrics.sh",
        "comment": "Metrics collection - runs third"
      }
    ]
  }
}

Lógica condicional em scripts

          **Exemplo: bloquear somente ferramentas específicas**
Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')

# Only validate bash commands
if [ "$TOOL_NAME" != "bash" ]; then
  exit 0  # Allow all non-bash tools
fi

# Check bash command for dangerous patterns
COMMAND=$(echo "$INPUT" | jq -r '.toolArgs' | jq -r '.command')
if echo "$COMMAND" | grep -qE "rm -rf|sudo|mkfs"; then
  echo '{"permissionDecision":"deny","permissionDecisionReason":"Dangerous system command"}'
fi

Registro em log estruturado

          **Exemplo: formato de linhas JSON**
Shell
#!/bin/bash
INPUT=$(cat)
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')
RESULT_TYPE=$(echo "$INPUT" | jq -r '.toolResult.resultType')

# Output structured log entry
jq -n \
  --arg ts "$TIMESTAMP" \
  --arg tool "$TOOL_NAME" \
  --arg result "$RESULT_TYPE" \
  '{timestamp: $ts, tool: $tool, result: $result}' >> logs/audit.jsonl

Integração com sistemas externos

          **Exemplo: enviar alertas para o Slack**
Shell
#!/bin/bash
INPUT=$(cat)
ERROR_MSG=$(echo "$INPUT" | jq -r '.error.message')

WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

curl -X POST "$WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d "{\"text\":\"Agent Error: $ERROR_MSG\"}"

Exemplos de casos de uso

Trilha de auditoria de conformidade

Registre todas as ações do agente para requisitos de conformidade utilizando scripts de log:

JSON
{
  "version": 1,
  "hooks": {
    "sessionStart": [{"type": "command", "bash": "./audit/log-session-start.sh"}],
    "userPromptSubmitted": [{"type": "command", "bash": "./audit/log-prompt.sh"}],
    "preToolUse": [{"type": "command", "bash": "./audit/log-tool-use.sh"}],
    "postToolUse": [{"type": "command", "bash": "./audit/log-tool-result.sh"}],
    "sessionEnd": [{"type": "command", "bash": "./audit/log-session-end.sh"}]
  }
}

Rastreamento do custo

Acompanhe o uso da ferramenta para alocação de custos:

Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')
USER=${USER:-unknown}

echo "$TIMESTAMP,$USER,$TOOL_NAME" >> /var/log/copilot/usage.csv

Garantia de qualidade do código

Impedir commits que violam os padrões de código:

Shell
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')

if [ "$TOOL_NAME" = "edit" ] || [ "$TOOL_NAME" = "create" ]; then
  # Run linter before allowing edits
  npm run lint-staged
  if [ $? -ne 0 ]; then
    echo '{"permissionDecision":"deny","permissionDecisionReason":"Code does not pass linting"}'
  fi
fi

Sistema de notificação

Enviar notificações sobre eventos importantes:

Shell
#!/bin/bash
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')

# Notify on production-related prompts
if echo "$PROMPT" | grep -iq "production"; then
  echo "ALERT: Production-related prompt: $PROMPT" | mail -s "Agent Alert" [email protected]
fi