Spezialisten

Wiederkehrende Arbeit automatisieren

Mach aus einer Prozedur, die du zweimal von Hand erledigt hast, einen Skill und verdrahte einen Hook, damit sie nie übersprungen wird.

Behrad Mirafshar
Behrad Mirafshar
Gründer, Bonanza Design
9 Min. Lesezeit

Wann du dieses Modul brauchst

Den Kurs Context Engineering for Claude Code hast du abgeschlossen, wenn du Core 1–3 und den Übernahme-Test geschafft hast. Dieses Modul ist optional und für eine ganz bestimmte Situation gedacht: eine Prozedur in deinem eigenen Projekt, die du inzwischen mindestens zweimal von Hand erledigt hast.

Am Ende hast du einen Skill, der die Prozedur festhält, und einen Hook, der dafür sorgt, dass sie nie übersprungen wird. Das ist dieselbe Form wie beim updating-claude-md-Skill, den du schon in Core 2 ausgeführt hast. Sein Aufbau ist das Beispiel weiter unten.

Die Lektionen

In dieser Reihenfolge. Erst Skill oder Command, denn eine falsche Wahl macht alles danach unnötig schwer.

  1. Skills, Custom Commands und Projects im Vergleich
    Ein Custom Command fügt Text ein, den du schon geschrieben hast. Er bringt keine neue Fähigkeit, und Claude kann ihn nicht von selbst wählen. Du musst ihn tippen. Ein Skill wird über seine eigene Beschreibung geladen, Claude greift ihn also selbst auf, wenn die Situation passt. Ein Project bündelt Anweisungen und Dateien für einen Workspace, ganz ohne Logik, die es aufgreift. Wenn das, was du automatisierst, einfach passieren soll, sobald die Situation es verlangt, ist es ein Skill.
  2. Wo Skills liegen: User, Projekt, öffentlich
    Ein Skill auf User-Ebene liegt in deinem Home-Ordner und begleitet dich in jedes Projekt. Ein Skill auf Projektebene liegt im Repo, wer es klont, bekommt ihn also mit. Ein öffentlicher Skill oder ein Plugin stammt aus dem Marketplace-Eintrag von jemand anderem: gleiche Form, anderes Vertrauensniveau.
  3. Plugins und Prüfen vor der Installation
    Ein Plugin bündelt Skills, Commands und Hooks, die jemand anderes geschrieben hat. Ein Hook führt Shell-Befehle auf deinem Rechner aus, mit den Berechtigungen deiner Session, sobald er ausgelöst wird. Lies die SKILL.md und jedes Hook-Skript, bevor du installierst, genau wie du ein Package lesen würdest, bevor du es als Dependency einbindest.
  4. Hooks: die neun Events, die du wirklich brauchst
    Claude Code hat mehr als 30 Hook-Events, und die Liste wächst mit jedem Release. Neun davon decken fast jeden sinnvollen Hook ab, vom Start einer Session bis zu ihrem Ende. Führe /hooks in deiner eigenen Session aus, um die vollständige aktuelle Liste zu sehen. Wähle das Event, das zu dem Zeitpunkt passt, an dem etwas passieren soll, nicht das Event, das gerade läuft, während du den Hook schreibst.
  5. Einen Hook in der settings.json verdrahten
    Einen Hook zu registrieren sind ein paar Zeilen in der settings.json: welches Event, welcher Befehl, optional ein Timeout. Ohne diese Verdrahtung läuft nichts: Skill und Hook-Skript sind für sich allein wirkungslos.
  6. Bonus: wie updating-claude-md gebaut wurde
    Der Skill aus Core 2, der deine CLAUDE.md aktuell hält, wurde dir nicht fertig in die Hand gedrückt. Er wurde testgetrieben gebaut, ist einmal dokumentiert gescheitert, und die Korrektur steht unten: ein echter Bauablauf zum Mitmachen, keine Beschreibung davon.

Hooks: die neun Events, die du wirklich brauchst

Jeder Hook, den du je schreibst, wird bei einem dieser Events ausgelöst. Wähle das Event, das zu dem Zeitpunkt passt, an dem etwas passieren soll.

Die neun Hook-Events, die du zuerst kennen solltest, und das eine, das der Bauablauf auf dieser Seite verdrahtet. Führe /hooks aus, um die vollständige Liste deiner Version zu sehen.
EventWird ausgelöst, wenn
SessionStarteine neue Session beginnt.
UserPromptSubmitdu einen Prompt abschickst, bevor Claude ihn liest.
PreToolUsebevor ein Tool-Aufruf läuft. Kann ihn blockieren.
PostToolUsenachdem ein Tool-Aufruf abgeschlossen ist.
PermissionRequestClaude Code deine Erlaubnis für etwas braucht.
NotificationClaude Code eine Benachrichtigung zeigt, z. B. eine Berechtigungsabfrage.
Stopdie Hauptantwort fertig ist.
TaskCompletedein Hintergrund-Task abgeschlossen ist.
SessionEndeine Session endet: das Event, das der Bauablauf auf dieser Seite nutzt.

Was ein Skill eigentlich ist und wo er neben einem Custom Command steht, erklären wir ausführlicher auf der Seite zu Claude Skills.

Die Aufgabe

Diese Aufgabe läuft auf deinem eigenen Projekt. Für Spezialisten gibt es keinen Snapshot eines Referenzprojekts: Deine wiederkehrende Prozedur ersetzt den Schritt „Wettbewerber hinzufügen“, aus dem Von der Idee zum Beleg eine funktionierende Seite geliefert hat.

Ausgangspunkt

Dein eigenes fertiges Core-Projekt, in dem „Wettbewerber hinzufügen“ (oder der entsprechende wiederkehrende Schritt deines Projekts) inzwischen zweimal von Hand erledigt wurde.

Erwartetes Ergebnis

Ein Skill, der diese Prozedur festhält, plus ein Hook.

Bestanden, wenn

Der Skill an einer dritten Instanz läuft und dieselbe Form liefert wie die zwei, die du von Hand gemacht hast. Der Hook feuert in dem Moment, den du angegeben hast, belegt durch sein Log.

Der Claude Code Skill, der Hook, die Verdrahtung

Dieses Beispiel adaptiert den updating-claude-md-Skill aus Core 2, seinen Hook und seine Verdrahtung, in der Reihenfolge, in der du sie baust: erst der Skill, dann der Hook, der ihn ausführt, dann die Verdrahtung, die den Hook auslöst. Wer zuerst den Hook schreibt, hat nichts, worauf er zeigen kann. Die Projektdetails stammen aus einer fiktiven Leselisten-App.

1. Der Skill: wie

SKILL.md (excerpt)
---
name: updating-claude-md
description: Use when a session is about to end, when CLAUDE.md has no
  last_updated marker, or when files, dev-docs or sessions may have changed
  since CLAUDE.md was last updated.
---

# Updating CLAUDE.md

## Overview

CLAUDE.md loads into every session, so it holds the gist of the project and
says where the detail lives. The detail stays in its own folder. A marker in
the frontmatter records when CLAUDE.md was last brought up to date, so each
run only has to look at what changed since then.

Write straight to CLAUDE.md. This runs before a session ends, so there is no
one to approve a draft.

## The shape CLAUDE.md always has

```markdown
---
last_updated: 2026-09-14T16:40
---
# <Project name>

## Overview
What it is and who it is for, in 2 to 3 lines.

## Active work
- `dev-docs/2026_09_12-PROGRESS-pt1-Reading_List_App.md`: Build a
  reading-list app that saves books and tracks reading progress.
```

## Common mistakes

| Mistake | Fix |
|---|---|
| Progress numbers or "status as of" lines in CLAUDE.md | Active work lists the dev-doc file name and its gist |
| Field lists, API tables, long explanations copied in | One line and the path of the file that holds them |
| Marker left unchanged | The marker moves every time, even when nothing else changed |
| Only the latest dev-doc read | Every dev-doc not DONE appears in Active work |
| Hand-written guardrails dropped while restructuring | They stay; only their placement changes |

2. Der Hook: wann

Wird bei SessionEnd ausgelöst. Die vier Schutzmechanismen sind inline kommentiert. Jeder davon ist ein echter Fehler, für den der Hook korrigiert werden musste. Er nutzt deine konfigurierten Berechtigungen. Teste den Skill zuerst interaktiv und erlaube nur die Tools, die er braucht; ein Hintergrundlauf kann dich nicht um Freigabe einer blockierten Aktion bitten. Prüfe das Log auf Fehler.

~/.claude/hooks/claude-md-update.sh
#!/usr/bin/env bash
# SessionEnd hook: when a session ends on purpose in a project that has a
# CLAUDE.md, spawn a headless Claude that runs the updating-claude-md skill.
# Never blocks the exit.
LOG="$HOME/.claude/claude-md-update.log"
[[ "${CLAUDE_MD_UPDATER:-}" == "1" ]] && exit 0   # guard 1: don't recurse
IN=$(cat 2>/dev/null || true)
command -v jq >/dev/null || exit 0
reason=$(jq -r '.reason // ""' <<<"$IN")
sid=$(jq -r '.session_id // ""' <<<"$IN")
cwd=$(jq -r '.cwd // ""' <<<"$IN")
case "$reason" in prompt_input_exit|logout) ;; *) exit 0 ;; esac   # guard 2: only deliberate exits
[[ -z "$cwd" || "$cwd" == "$HOME" || "$cwd" == *"/.claude/plugins/"* ]] && exit 0   # guard 3a
[[ -f "$cwd/CLAUDE.md" ]] || exit 0   # guard 3b: only projects that already have a CLAUDE.md
lock="$HOME/.claude/claude-md-update.lock.$(printf '%s' "$cwd" | md5 -q)"
mkdir "$lock" 2>/dev/null || exit 0   # guard 4: one updater per project at a time
echo "$(date '+%F %T') start cwd=$cwd sid=$sid" >> "$LOG"
(
  cd "$cwd" && CLAUDE_MD_UPDATER=1 claude -p --model sonnet \
    --permission-mode acceptEdits \
    "Use the updating-claude-md skill now and update CLAUDE.md. Do not ask questions." \
    >> "$LOG" 2>&1
  echo "$(date '+%F %T') done cwd=$cwd rc=$?" >> "$LOG"
  rmdir "$lock" 2>/dev/null
) </dev/null >/dev/null 2>&1 &
disown
exit 0

Die vier Schutzmechanismen

  1. Keine Rekursion.
    Das Claude, das der Hook startet, beendet ebenfalls eine Session, was den Hook endlos wieder auslösen würde. Eine Umgebungsvariable, die nur innerhalb des gestarteten Laufs gesetzt ist, durchbricht die Schleife.
  2. Nur bewusste Beendigungen.
    Greift gezielt bei prompt_input_exit und logout. Ein Absturz soll nicht das Umschreiben einer Datei auslösen, die niemand angefasst haben wollte.
  3. Nur Projekte, die schon eine CLAUDE.md haben.
    Überspringt das Home-Verzeichnis und Plugin-Ordner sowie jedes Projekt, das noch nicht mit dem Skill vertraut gemacht wurde. Der Hook pflegt eine Datei, er legt die erste nicht an.
  4. Einer nach dem anderen.
    Ein Lock, der auf dem Projektpfad basiert, verhindert, dass zwei Sessions, die gleichzeitig schließen, gegenseitig ihr Update überschreiben.

3. Die Verdrahtung: wer es auslöst

Drei Zeilen in der settings.json registrieren das Skript für das Event. Ohne sie läuft nichts: Skill und Hook-Skript sind für sich allein wirkungslos.

settings.json (excerpt)
"SessionEnd": [
  { "hooks": [{ "type": "command", "command": "~/.claude/hooks/claude-md-update.sh" }] }
]
Ein Hook ist das Wann. Ein Skill ist das Wie. claude -p ist das Wer: ein zweites, headless laufendes Claude im Hintergrund, sodass du nie warten musst.

Skills und Hooks sind eine Möglichkeit, ein Tool an Claude anzubinden. Wenn du zwischen dieser und einem direkten API-Call abwägst, lies MCP oder ein einzelner API-Call.

Die Methode korrigiert sich selbst

Das ist der eigene dokumentierte Fehler des Skills aus der Zeit, als er zum ersten Mal gebaut und getestet wurde, keine Hypothese. Der erste Baseline-Lauf schrieb Fortschrittszahlen direkt in die CLAUDE.md, wo sie veraltet waren, sobald sich die Zahlen änderten.

Vorher

CLAUDE.md
## Active work

- pt1-Reading_List_App: Book search working. 3 of 5 tests
  passing as of 2026-09-12. Reading-progress filter still failing
  (investigating filter state, ~60% done overall).

Jede Session, die diese Datei danach öffnete, las eine Zahl, die schon falsch war. Die Lösung war keine längere Datei, sondern eine Regel: Fortschritt zu einem bestimmten Zeitpunkt gehört in das Dev-Doc, das er beschreibt, nie in die CLAUDE.md selbst. Diese Regel ist jetzt die erste Zeile in der Tabelle „Common mistakes“ des Skills, oben.

Nachher

CLAUDE.md
## Active work

- `dev-docs/2026_09_12-PROGRESS-pt1-Reading_List_App.md`: Build a
  reading-list app that saves books and tracks reading progress.
Das Wesentliche in der CLAUDE.md, die Details in der Datei, auf die sie zeigt: Das ist der Unterschied zwischen Anweisungen, die nützlich bleiben, und Anweisungen, die niemand liest.

Mach aus einer wiederkehrenden Aufgabe einen Skill

Eine leere Skill-Datei zum Ausfüllen, plus eine einseitige Karte mit den neun Hook-Events, die du wirklich brauchst, damit der Skill läuft, ohne dass du ihn startest.

Eine Prozedur in einem Dokument

„Aktualisiere am Ende einer Session die Projektnotizen: Lies die Arbeitsprotokolle, behalte das Wesentliche, lass die Details in ihrer eigenen Datei.“

Das funktioniert nur, wenn jemand daran denkt, das Dokument zu öffnen, und Claude kann es nicht von selbst aufgreifen.

Dieselbe Prozedur als Skill

Ein Skill ist das Wie · ein Hook ist das Wann
SKILL.md plus die Zeile, die sie auslöst
Die Beschreibungszeile„Use when a session is about to end, or when files may have changed since the notes were last updated.“ Claude liest diese Zeile und greift den Skill auf, ohne dass man es ihm sagt.
Die SchritteMarker lesen, sammeln, was sich seitdem geändert hat, das Wesentliche in die Notizen schreiben, Marker weiterschieben.
Der HookDrei Zeilen in der settings.json lösen ihn in dem Moment aus, in dem eine Session endet, im Hintergrund, sodass niemand wartet.
Die SchutzmechanismenNicht bei einem Absturz auslösen, nicht zweimal gleichzeitig laufen, Ordner ohne Notizen überspringen und nie zulassen, dass die gestartete Session sich selbst auslöst.

Unlock all course materials

One email unlocks every material in the course. Verify, and they open in that browser.

FAQ

Er schreibt eine Datei, deshalb läuft er mit --permission-mode acceptEdits. Das ist die gesamte Freigabe: Er darf nichts anderes tun und stellt dir nie eine Frage, weil nach dem Ende einer Session niemand mehr an der Tastatur sitzt. Wenn dein eigenes Setup Schreibzugriffe weiter einschränkt, erlaube CLAUDE.md für dieses Projekt, sonst endet der Lauf, ohne etwas geändert zu haben, und sagt das in seinem Log.

Nein. Beginne mit dem Frontmatter (ein Name und eine Beschreibung, wann er zu nutzen ist) und einem klaren Schritt. Führe ihn einmal aus, behebe, was nicht stimmt, und füge den nächsten Schritt hinzu. Der updating-claude-md-Skill auf dieser Seite ist genauso entstanden.

Ein Custom Command läuft nur, wenn du ihn tippst, und fügt lediglich Text ein, den du schon geschrieben hast. Keine neue Fähigkeit. Ein Skill wird über seine eigene Beschreibung geladen, Claude kann ihn also selbst aufgreifen, wenn die Situation passt, ohne dass du ihn nennst.

Lies zuerst die SKILL.md und jedes Hook-Skript. Ein Hook führt Shell-Befehle auf deinem Rechner aus, mit den Berechtigungen deiner Session, sobald sein Event ausgelöst wird. Behandle ihn wie eine neue Dependency, nicht wie einen Textschnipsel.

SessionEnd: dasselbe Event, das der Bauablauf auf dieser Seite verdrahtet. Sichere es ab, sodass es nur bei einer bewussten Beendigung auslöst, nicht bei einem Absturz.

Nicht, wenn er im Hintergrund läuft. Der updating-claude-md-Hook startet mit claude -p ein zweites, headless laufendes Claude und löst es vom Terminal. Die Session, in der du bist, ist bereits beendet, wenn es läuft.

Zweimal bedeutet meist, dass zwei Sessions gleichzeitig schließen: Füge einen Lock hinzu, der auf dem Projektpfad basiert, siehe Schutzmechanismus 4 oben. Gar nicht bedeutet meist, dass der Event-Name in der settings.json zu keinem Event passt, das deine Version unterstützt (führe /hooks aus, um die Liste zu sehen), oder dass der Befehlspfad falsch ist. Prüfe zuerst die Log-Datei des Hooks.

Du willst deine wiederkehrende Arbeit automatisieren, nicht nur darüber lesen?

Eine Arbeitssession, in der die wiederkehrenden Prozeduren deines Teams zu Skills und Hooks werden.

Workshop buchenMehr erfahren