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. Para obter um tutorial sobre como criar ganchos para a CLI, consulte Usando ganchos com a CLI do Copilot para execução previsível e compatível com políticas.

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: carimbo de data/hora 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: carimbo de data/hora 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