Skip to main content

Hooks-Konfiguration

Hier finden Sie Informationen zum Konfigurieren von Hooks für die Verwendung mit GitHub Copilot-CLI und Copilot-Programmier-Agent.

In diesem Referenzartikel werden die verfügbaren Hooktypen mit Beispielen beschrieben, einschließlich ihrer Eingabe- und Ausgabeformate, bewährten Skriptmethoden und erweiterten Mustern für Protokollierung, Sicherheitserzwingung und externe Integrationen. Allgemeine Informationen zum Erstellen von Hooks finden Sie unter Verwenden von Hooks mit GitHub Copilot-Agenten.

Hook-Typen

Session Start Hook

Wird ausgeführt, wenn eine neue Agentsitzung beginnt oder wenn eine vorhandene Sitzung fortgesetzt wird.

          **Eingabe-JSON:**
JSON
{
  "timestamp": 1704614400000,
  "cwd": "/path/to/project",
  "source": "new",
  "initialPrompt": "Create a new feature"
}
          **Felder:**

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * source: Entweder "new" (neue Sitzung), "resume" (fortgesetzte Sitzung) oder "startup" * initialPrompt: Die anfängliche Eingabeaufforderung des Benutzers (sofern angegeben)

          **Ausgabe:** Ignoriert (kein Rückgabewert verarbeitet)

          **Beispiel-Hook:**
JSON
{
  "type": "command",
  "bash": "./scripts/session-start.sh",
  "powershell": "./scripts/session-start.ps1",
  "cwd": "scripts",
  "timeoutSec": 30
}
          **Beispielskript (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

Sitzungsende-Hook

Wird ausgeführt, wenn die Agentsitzung abgeschlossen oder beendet wird.

          **Eingabe-JSON:**
JSON
{
  "timestamp": 1704618000000,
  "cwd": "/path/to/project",
  "reason": "complete"
}
          **Felder:**

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * reason: Eine von "complete", , "error"``"abort", , oder "timeout"``"user_exit"

          **Ausgabe:** Ignoriert

          **Beispielskript:**
Shell
#!/bin/bash
INPUT=$(cat)
REASON=$(echo "$INPUT" | jq -r '.reason')

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

Hook für gesendete Benutzer Prompt

Wird ausgeführt, wenn der Benutzer eine Eingabeaufforderung an den Agent sendet.

          **Eingabe-JSON:**
JSON
{
  "timestamp": 1704614500000,
  "cwd": "/path/to/project",
  "prompt": "Fix the authentication bug"
}
          **Felder:**

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * prompt: Der genaue Text, den der Benutzer übermittelt hat

          **Ausgabe:** Ignoriert (Eingabeaufforderungsänderung wird derzeit in Kunden-Hooks nicht unterstützt)

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

Pre-Tool Verwendungs-Hook

Wird ausgeführt, bevor der Agent ein beliebiges Tool verwendet (z. B. bash, edit, view). Dies ist der leistungsfähigste Hook, da er Toolausführungen genehmigen oder verweigern kann.

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

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * toolName: Name des aufgerufenen Tools (z. B. "bash", "edit", "view", "create") * toolArgs: JSON-Zeichenfolge mit den Argumenten des Tools

          **Ausgabe-JSON (optional):**
JSON
{
  "permissionDecision": "deny",
  "permissionDecisionReason": "Destructive operations require approval"
}
          **Ausgabefelder:**

* permissionDecision: Entweder "allow", "deny" oder "ask" (nur "deny" wird derzeit verarbeitet) * permissionDecisionReason: Menschlich lesbare Erklärung für die Entscheidung

          **Beispielhaken zum Blockieren gefährlicher Befehle:**
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"}'
          **Beispiel-Hook zum Erzwingen von Dateiberechtigungen:**
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

Hook für die Verwendung des Tools nach der Sitzung

Wird ausgeführt, nachdem ein Tool die Ausführung abgeschlossen hat (ob erfolgreich oder fehlgeschlagen).

          **Beispiel für JSON-Eingabe:**
JSON
{
  "timestamp": 1704614700000,
  "cwd": "/path/to/project",
  "toolName": "bash",
  "toolArgs": "{\"command\":\"npm test\"}",
  "toolResult": {
    "resultType": "success",
    "textResultForLlm": "All tests passed (15/15)"
  }
}
          **Felder:**

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * toolName: Name des ausgeführten Tools * toolArgs: JSON-Zeichenfolge mit den Argumenten des Tools * toolResult: Ergebnisobjekt mit: * resultType: Entweder "success", "failure" oder "denied" * textResultForLlm: Der Ergebnistext, der dem Agent angezeigt wird

          **Ausgabe:** Ignoriert (Ergebnisänderung wird zurzeit nicht unterstützt)

          **Beispielskript zum Protokollieren von Toolausführungsstatistiken in einer CSV-Datei:**

Dieses Skript protokolliert Die Toolausführungsstatistiken in einer CSV-Datei und sendet eine E-Mail-Benachrichtigung, wenn ein Tool fehlschlägt.

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" admin@example.com
fi

Fehler ist aufgetreten Hook

Wird ausgeführt, wenn bei der Ausführung des Agents ein Fehler auftritt.

          **Beispiel für JSON-Eingabe:**
JSON
{
  "timestamp": 1704614800000,
  "cwd": "/path/to/project",
  "error": {
    "message": "Network timeout",
    "name": "TimeoutError",
    "stack": "TimeoutError: Network timeout\n    at ..."
  }
}
          **Felder:**

* timestamp: Unix-Zeitstempel in Millisekunden * cwd: Aktuelles Arbeitsverzeichnis * error: Fehlerobjekt mit: * message:Fehlermeldung * name: Fehlertyp/Name * stack: Stapelablaufverfolgung (sofern verfügbar)

          **Ausgabe:** Ignoriert (Fehlerbehandlungsänderung wird derzeit nicht unterstützt)

          **Beispielskript, das Fehlerdetails in eine Protokolldatei extrahiert:**
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

Bewährte Methoden für Skripts

Eingabedaten lesen

In diesem Beispielskript werden JSON-Eingaben von Stdin in eine Variable gelesen und dann jq verwendet, um die Felder timestamp und cwd zu extrahieren.

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

Ausgabe von JSON

Dieses Beispielskript zeigt, wie Sie gültige JSON aus Ihrem Hook-Skript ausgeben. Verwenden Sie jq -c in Bash für kompakte einzeilige Ausgabe oder ConvertTo-Json -Compress in 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

Fehlerbehandlung

In diesem Skriptbeispiel wird veranschaulicht, wie Fehler in Hook-Skripts behandelt werden.

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

Timeouts verarbeiten Handle

Hooks haben ein Standardtimeout von 30 Sekunden. Bei längeren Vorgängen erhöhen Sie timeoutSec:

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

Erweiterte Muster

Mehrere Hooks desselben Typs

Sie können mehrere Hooks für dasselbe Ereignis definieren. Sie werden in der Reihenfolge ausgeführt:

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"
      }
    ]
  }
}

Bedingte Logik in Skripts

          **Beispiel: Nur bestimmte Tools blockieren**
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

Strukturierte Protokollierung

          **Beispiel: JSON-Linienformat**
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

Integration in externe Systeme

          **Beispiel: Senden von Benachrichtigungen an 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\"}"

Beispielhafte Anwendungsfälle

Compliance-Prüfpfad

Protokollieren Sie alle Agentaktionen für Complianceanforderungen, indem Sie Protokollskripts verwenden:

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"}]
  }
}

Kostenverfolgung

Nachverfolgen der Toolnutzung für die Kostenzuteilung:

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

Code-Qualitätserzwingung

Verhindern Sie Commits, die gegen Codestandards verstoßen:

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

Benachrichtigungssystem

Senden von Benachrichtigungen zu wichtigen Ereignissen:

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" team@example.com
fi