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

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

Gesendeter Webhook der Benutzeranfrage

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

Haken zur Verwendung vor Werkzeugen

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

Haken nach der Verwendung des Werkzeugs

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 bei der Hook-Funktion

Wird ausgeführt, wenn während der Agentausführung 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
}

Behandeln von Timeouts

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