Build This Now
Build This Now
TastenkürzelStatus Line Guide
Hooks-LeitfadenPlattformübergreifende Hooks für Claude CodeClaude Code Setup-HooksStop HooksSelbstvalidierende Claude Code AgentenClaude Code Session-HooksKontext-Backup-Hooks für Claude CodeSkill-Aktivierungs-HookClaude Code Permission-HookMCP Tool Hooks in Claude CodeCommands to Skills
Skills, Subagents, HooksSubagent Sweet SpotClaude Code vs CursorCLAUDE.md Best PracticesFix Context LimitSpec-Driven DevRules Into Patterns
speedy_devvkoen_salo
Blog/Toolkit/Hooks/Session Hooks

Claude Code Session-Hooks

Vier Claude Code Session-Lifecycle-Hooks: Init bei Bedarf ausführen, Projektkontext bei SessionStart injizieren, Transkripte sichern und Cleanup beim SessionEnd-Exit protokollieren.

Sie möchten das Framework hinter diesen Projekten?

Holen Sie sich das Claude Code System, mit dem wir produktionsreife Software planen, bauen, testen und ausliefern.

Sehen Sie, was wir für Unternehmen bauen →
speedy_devvkoen_salo
speedy_devvWritten by speedy_devvPublished Feb 12, 2026Toolkit hubHooks index

Problem: Jede neue Session startet blind. Du erklärst erneut den Branch, auf dem du bist, die Task-Queue und die Env-Vars, die deine Skripte brauchen. Wenn die Session endet, passiert das Cleanup, das hätte passieren sollen, nie.

Quick Win: Füge das in settings.json ein. Git-Kontext landet beim Start in jedem Chat:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Git' && git branch --show-current && git status --short | head -10"
          }
        ]
      }
    ]
  }
}

Jede Session öffnet sich jetzt mit Kontext. Null manuelle Einrichtung.

Die vier Session-Lifecycle-Hooks

Session-Verhalten wird von vier Hook-Typen gesteuert:

HookWann er feuertKann blockieren?Anwendungsfall
SetupMit --init oder --maintenanceNEINEinmalige Einrichtung, Migrationen
SessionStartJeder Session-Start/ResumeNEINKontext laden, Env-Vars setzen
PreCompactVor der Kontext-KomprimierungNEINTranskripte sichern
SessionEndSession wird beendetNEINCleanup, Logging

SessionStart: Kontext jedes Mal laden

SessionStart läuft immer, wenn eine Session beginnt oder fortgesetzt wird. Greif darauf zurück, wenn etwas immer in Claudes Kopf sein soll.

Einfache Kontext-Injektion

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Project State' && cat .claude/tasks/session-current.md 2>/dev/null || echo 'No active session'"
          }
        ]
      }
    ]
  }
}

Mit JSON-Ausgabe

Für strukturierte Kontext-Injektion:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
def get_project_context():
    try:
        branch = subprocess.check_output(
            ['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
            text=True, stderr=subprocess.DEVNULL
        ).strip()
        status = subprocess.check_output(
            ['git', 'status', '--porcelain'],
            text=True, stderr=subprocess.DEVNULL
        ).strip()
        changes = len(status.split('\n')) if status else 0
    except:
        branch, changes = "unknown", 0
 
    return f"""=== SESSION CONTEXT ===
Git Branch: {branch}
Uncommitted Changes: {changes}
=== END ===""".strip()
 
output = {
    "hookSpecificOutput": {
        "hookEventName": "SessionStart",
        "additionalContext": get_project_context()
    }
}
print(json.dumps(output))
sys.exit(0)

SessionStart-Matcher

Auf spezifische Session-Events abzielen:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [{ "type": "command", "command": "echo 'Fresh session'" }]
      },
      {
        "matcher": "resume",
        "hooks": [{ "type": "command", "command": "echo 'Resumed session'" }]
      },
      {
        "matcher": "compact",
        "hooks": [{ "type": "command", "command": "echo 'Post-compaction'" }]
      }
    ]
  }
}
  • startup - Neue Session
  • resume - Von --resume, --continue oder /resume
  • clear - Nach /clear
  • compact - Nach Komprimierung

Umgebungsvariablen persistieren

SessionStart hat Zugriff auf CLAUDE_ENV_FILE zum Setzen von session-weiten Umgebungsvariablen:

#!/bin/bash
 
# Persist environment changes from nvm, pyenv, etc.
ENV_BEFORE=$(export -p | sort)
 
# Setup commands that modify environment
source ~/.nvm/nvm.sh
nvm use 20
 
if [ -n "$CLAUDE_ENV_FILE" ]; then
  ENV_AFTER=$(export -p | sort)
  comm -13 <(echo "$ENV_BEFORE") <(echo "$ENV_AFTER") >> "$CLAUDE_ENV_FILE"
fi
 
exit 0

Alles, was in CLAUDE_ENV_FILE geschrieben wird, erscheint in jedem Bash-Befehl, den Claude danach ausführt.

Setup: Einmalige Operationen

Setup-Hooks laufen nur, wenn du explizit --init, --init-only oder --maintenance aufrufst. Gut für Arbeit, die du nicht bei jeder neuen Session ausführen willst.

Wann Setup vs. SessionStart nutzen

OperationSetup nutzenSessionStart nutzen
Abhängigkeiten installierenJaNein
Datenbank-Migrationen ausführenJaNein
Git-Status ladenNeinJa
Umgebungsvariablen setzenJaJa
Projektkontext injizierenNeinJa
Temp-Dateien aufräumenJa (maintenance)Nein

Setup-Konfiguration

{
  "hooks": {
    "Setup": [
      {
        "matcher": "init",
        "hooks": [
          {
            "type": "command",
            "command": "npm install && npm run db:migrate"
          }
        ]
      },
      {
        "matcher": "maintenance",
        "hooks": [
          {
            "type": "command",
            "command": "npm prune && npm dedupe && rm -rf .cache"
          }
        ]
      }
    ]
  }
}

Aufrufen mit:

claude --init          # Runs 'init' matcher
claude --init-only     # Runs 'init' matcher, then exits
claude --maintenance   # Runs 'maintenance' matcher

Setup-Hooks können auch in CLAUDE_ENV_FILE schreiben, um Umgebungsvariablen zu persistieren.

PreCompact: Vor dem Kontextverlust

PreCompact feuert kurz vor der Komprimierung, egal ob der Nutzer sie mit /compact ausgelöst hat oder sie automatisch startete, als das Fenster sich füllte.

Transkripte sichern

#!/usr/bin/env python3
import json
import sys
import shutil
from pathlib import Path
from datetime import datetime
 
input_data = json.load(sys.stdin)
transcript_path = input_data.get('transcript_path', '')
trigger = input_data.get('trigger', 'unknown')
 
if transcript_path and Path(transcript_path).exists():
    backup_dir = Path('.claude/backups')
    backup_dir.mkdir(parents=True, exist_ok=True)
 
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    backup_name = f"transcript_{trigger}_{timestamp}.jsonl"
    shutil.copy2(transcript_path, backup_dir / backup_name)
 
    # Keep only last 10 backups
    backups = sorted(backup_dir.glob('transcript_*.jsonl'))
    for old_backup in backups[:-10]:
        old_backup.unlink()
 
sys.exit(0)

PreCompact-Matcher

{
  "hooks": {
    "PreCompact": [
      {
        "matcher": "auto",
        "hooks": [{ "type": "command", "command": "echo 'Auto-compacting...'" }]
      },
      {
        "matcher": "manual",
        "hooks": [{ "type": "command", "command": "echo 'Manual /compact'" }]
      }
    ]
  }
}
  • auto - Kontextfenster voll, automatische Komprimierung
  • manual - Nutzer hat /compact ausgeführt

Recovery-Marker erstellen

Kombiniere PreCompact mit SessionStart, um Kontext nach einer Komprimierung wieder aufzubauen. Ein funktionierendes Pattern: ein gemeinsames Backup-Core-Modul, ein Statusline-Monitor, der schwellenwertbasierte Trigger feuert, und ein PreCompact-Handler, alle koordiniert durch eine State-Datei, damit nichts zwischen Sessions verloren geht. Schau dir den Context-Recovery-Hook-Leitfaden für den vollständigen Walkthrough an.

SessionEnd: Cleanup

SessionEnd läuft, wenn eine Session auf dem Weg raus ist. Es kann das Herunterfahren nicht blockieren, aber es kann Cleanup erledigen.

Session-Stats protokollieren

#!/usr/bin/env python3
import json
import sys
from pathlib import Path
from datetime import datetime
 
input_data = json.load(sys.stdin)
session_id = input_data.get('session_id', 'unknown')
reason = input_data.get('reason', 'unknown')
 
log_dir = Path('.claude/logs')
log_dir.mkdir(parents=True, exist_ok=True)
 
log_entry = {
    "session_id": session_id,
    "ended_at": datetime.now().isoformat(),
    "reason": reason
}
 
with open(log_dir / 'session-history.jsonl', 'a') as f:
    f.write(json.dumps(log_entry) + '\n')
 
sys.exit(0)

SessionEnd-Gründe

Das reason-Feld sagt dir, warum die Session beendet wurde:

  • clear - Nutzer hat /clear ausgeführt
  • logout - Nutzer hat sich ausgeloggt
  • prompt_input_exit - Nutzer hat beendet, während der Prompt sichtbar war
  • other - Andere Exit-Gründe

Vollständiges Lifecycle-Beispiel

Eine vollständige Lifecycle-Konfiguration von Ende zu Ende verdrahtet:

{
  "hooks": {
    "Setup": [
      {
        "matcher": "init",
        "hooks": [
          {
            "type": "command",
            "command": "npm install && echo 'Dependencies installed'"
          }
        ]
      }
    ],
 
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Context' && git status --short && echo '## Tasks' && cat .claude/tasks/session-current.md 2>/dev/null | head -20"
          }
        ]
      }
    ],
 
    "PreCompact": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cp \"$CLAUDE_TRANSCRIPT_PATH\" .claude/backups/last-transcript.jsonl 2>/dev/null || true"
          }
        ]
      }
    ],
 
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"Session ended: $(date)\" >> .claude/logs/sessions.log"
          }
        ]
      }
    ]
  }
}

Input-Payloads

SessionStart-Input

{
  "session_id": "abc123",
  "hook_event_name": "SessionStart",
  "source": "startup",
  "model": "claude-sonnet-4-20250514",
  "cwd": "/path/to/project"
}

Setup-Input

{
  "session_id": "abc123",
  "hook_event_name": "Setup",
  "trigger": "init",
  "cwd": "/path/to/project"
}

PreCompact-Input

{
  "session_id": "abc123",
  "hook_event_name": "PreCompact",
  "transcript_path": "~/.claude/projects/.../transcript.jsonl",
  "trigger": "auto",
  "custom_instructions": ""
}

SessionEnd-Input

{
  "session_id": "abc123",
  "hook_event_name": "SessionEnd",
  "reason": "clear",
  "cwd": "/path/to/project"
}

Best Practices

  1. SessionStart schnell halten - Er läuft bei jeder Session. Schwere Arbeit in Setup verschieben.

  2. Setup für einmalige Arbeit nutzen - Abhängigkeits-Installationen, Migrationen, erstmaliges Projekt-Bootstrap.

  3. Vor der Komprimierung sichern - PreCompact ist deine letzte Chance, das Transkript zu greifen.

  4. Session-Enden protokollieren - SessionEnd ist praktisch für Analytics und Debugging.

  5. Sorgfältig matchen - Unterschiedliches Verhalten für startup vs. resume vs. compact vermeidet Überraschungen.

Nächste Schritte

  • Richte den Haupt-Hooks-Leitfaden für alle 12 Hooks ein
  • Konfiguriere Context Recovery für das Überleben von Komprimierungen
  • Nutze Stop-Hooks für Task-Durchsetzung
  • Erkunde Skill-Aktivierung für automatisches Skill-Loading

Continue in Hooks

  • Slash Commands Are Now Skills: Migrating Commands to Skills
    Claude Code slash commands and skills now do the same thing. Here is how to migrate .claude/commands to .claude/skills and why it pays off.
  • Claude Code Setup-Hooks
    Verknüpfe Skripte, Agenten und Docs in Claude Code Setup-Hooks. Ein Befehl führt ein deterministisches Skript aus, übergibt die Ausgabe an einen diagnostizierenden Agenten und protokolliert lebendige Dokumentation.
  • Kontext-Backup-Hooks für Claude Code
    Ein StatusLine-gesteuerter Claude Code Kontext-Backup-Hook. Schreibt strukturierte Snapshots alle 10K Tokens, damit die Auto-Komprimierung nie Fehler, Signaturen und Entscheidungen verschluckt.
  • Plattformübergreifende Hooks für Claude Code
    Plattformübergreifende Claude Code Hooks: Vermeide .cmd-, .sh- und .ps1-Wrapper und rufe node direkt auf, damit eine .mjs-Datei auf macOS, Linux und Windows im Team funktioniert.
  • Hooks-Leitfaden
    Claude Code Hooks von Grund auf: Exit-Codes, JSON-Ausgabe, asynchrone Befehle, HTTP-Endpunkte, PreToolUse- und PostToolUse-Matcher, Produktionsmuster.
  • MCP Tool Hooks in Claude Code
    Wie du MCP-Server-Tools direkt aus Claude Code Hooks aufrufst mit type: mcp_tool — Schema, Substitutions-Syntax, Anwendungsfälle und Produktionsmuster.

More from Toolkit

  • CLAUDE.md, Skills, Subagents, Hooks: When to Use Which
    Claude Code skills vs subagents vs hooks vs CLAUDE.md: a plain mental model for picking the right primitive, with token costs and examples.
  • Claude Code Subagents: The 3 to 5 Agent Sweet Spot
    Claude code subagents work best at 3-5 concurrent agents. Here is why that ceiling exists, how to set them up, and what to use past it.
  • Claude Code vs Cursor in 2026: Which Ships Faster?
    Claude Code vs Cursor in 2026: which ships faster? A benchmark-backed breakdown of terminal agent vs IDE, token cost, and how to ship a whole SaaS.
  • CLAUDE.md Best Practices: The File That Makes Claude Code Reliable
    CLAUDE.md best practices: keep it under 200 lines, write it by hand, and use hooks when you need real enforcement, not advice.

Sie möchten das Framework hinter diesen Projekten?

Holen Sie sich das Claude Code System, mit dem wir produktionsreife Software planen, bauen, testen und ausliefern.

Sehen Sie, was wir für Unternehmen bauen →
speedy_devvkoen_salo

Selbstvalidierende Claude Code Agenten

Selbstvalidierende Claude Code Agenten: PostToolUse-Lint-Hooks, Stop-Hooks und schreibgeschützte Reviewer-Subagenten in Agentendefinitionen verdrahten, damit fehlerhafte Ausgaben nie ausgeliefert werden.

Kontext-Backup-Hooks für Claude Code

Ein StatusLine-gesteuerter Claude Code Kontext-Backup-Hook. Schreibt strukturierte Snapshots alle 10K Tokens, damit die Auto-Komprimierung nie Fehler, Signaturen und Entscheidungen verschluckt.

On this page

Die vier Session-Lifecycle-Hooks
SessionStart: Kontext jedes Mal laden
Einfache Kontext-Injektion
Mit JSON-Ausgabe
SessionStart-Matcher
Umgebungsvariablen persistieren
Setup: Einmalige Operationen
Wann Setup vs. SessionStart nutzen
Setup-Konfiguration
PreCompact: Vor dem Kontextverlust
Transkripte sichern
PreCompact-Matcher
Recovery-Marker erstellen
SessionEnd: Cleanup
Session-Stats protokollieren
SessionEnd-Gründe
Vollständiges Lifecycle-Beispiel
Input-Payloads
SessionStart-Input
Setup-Input
PreCompact-Input
SessionEnd-Input
Best Practices
Nächste Schritte

Sie möchten das Framework hinter diesen Projekten?

Holen Sie sich das Claude Code System, mit dem wir produktionsreife Software planen, bauen, testen und ausliefern.

Sehen Sie, was wir für Unternehmen bauen →