Fortgeschrittene Slash Commands: Befehle mit Kontextbewusstsein

Verwende das !-Präfix, um Shell-Befehle in Slash Commands auszuführen und automatisch Diffs, Dateiinhalte und Testergebnisse einzufügen


Die meisten Slash Commands sehen so aus:

Überprüfe die Codequalität der aktuellen Änderungen und gib konkrete Verbesserungsvorschläge.

Das funktioniert, hat aber eine grundlegende Einschränkung: Claude muss selbst ableiten, was „die aktuellen Änderungen" sind. Wenn dein Command den Kontext aktiv injiziert, sehen die Ergebnisse völlig anders aus.

Dieser Artikel zeigt, wie du Commands in „sehende" Anweisungen verwandelst — sie lesen beim Auslösen automatisch Dateiinhalte, git-Status und Projektinformationen ein und packen alles in den Prompt, sodass Claude nicht raten muss.


Der Kernmechanismus: !`befehl` injiziert Shell-Ausgabe

Benutzerdefinierte Slash Commands erlauben das Einbetten von Shell-Befehlen im Prompt. Die Syntax: den Befehl in Backticks setzen und ein Ausrufezeichen voranstellen — !`befehl`. Beim Auslösen wird der Befehl zuerst ausgeführt, seine Ausgabe ersetzt den Platzhalter, und Claude erhält den fertig zusammengesetzten Prompt.

Hier ist der aktuelle git diff:

!`git diff HEAD`

Überprüfe diese Änderungen mit Fokus auf Logikfehler und Sicherheitsprobleme.

Mehrzeilige Befehle gehören in einen Fenced-Code-Block, der mit ```! beginnt:

```!
node --version
git status --short
```

Wird /review ausgelöst, sieht das, was Claude tatsächlich erhält, so aus:

Hier ist der aktuelle git diff:

diff --git a/app/models/user.rb b/app/models/user.rb
index 3a2f1c8..9b4e2d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,9 @@ class User < ApplicationRecord
...

Überprüfe diese Änderungen mit Fokus auf Logikfehler und Sicherheitsprobleme.

Kein manuelles Kopieren — in dem Moment, in dem der Command ausgelöst wird, ist der Diff bereits drin.


Praktische Muster

Aktuellen Dateiinhalt injizieren

---
allowed-tools: Bash(cat:*)
---

Hier ist der vollständige Inhalt der aktuellen Datei:

!`cat $ARGUMENTS`

Finde alle potenziellen Performance-Probleme in dieser Datei. Gib konkrete Zeilennummern und Lösungsvorschläge an.

Verwendung: /perf app/models/order.rb

$ARGUMENTS nimmt den Dateipfad entgegen, cat liest den Inhalt ein und injiziert ihn. Claude bekommt echten Code, nicht eine vage Umschreibung wie „schau dir die aktuelle Datei an".

allowed-tools im Frontmatter autorisiert den cat-Befehl vorab, sodass beim Auslösen kein Berechtigungsdialog erscheint. Ohne diese Zeile müsstest du jedes Mal manuell auf „Erlauben" klicken. Alle folgenden Beispiele brauchen dieselbe Deklaration.

Git-Status injizieren

Aktueller Branch und Änderungsstand:

!`git status --short`
!`git log --oneline -10`

Generiere auf dieser Basis eine knappe PR-Beschreibung, die abdeckt, was sich geändert hat und warum.

Bei diesem /pr-Command musst du nicht beschreiben, „was ich geändert habe" — er liest es selbst aus.

Projektspezifische Informationen injizieren

Projekt-Tech-Stack:

!`cat .claude/context/stack.md`

Aktuelle Datenbankstruktur (Schlüsseltabellen):

!`head -100 db/schema.rb`

Schreibe mit diesem Hintergrund ein Migrationsskript für $ARGUMENTS gemäß den Projektkonventionen.

Lege Projektkontext-Dateien vorab in .claude/context/ ab; der Command liest sie beim Auslösen bei Bedarf, ohne dass du das Projekt jedes Mal neu beschreiben musst.

Testergebnisse dynamisch einlesen

Letzter Testlauf:

!`bundle exec rspec --format progress 2>&1 | tail -30`

Das sind die fehlgeschlagenen Tests. Analysiere die Ursache und schlage Korrekturen vor. Die Tests selbst nicht ändern.

Wenn /fix-tests ausgelöst wird, läuft der Test direkt und liefert das Ergebnis — Claude sieht echte Fehlermeldungen.


Vollständiges Beispiel: kontextbewusstes Code-Review

Kombiniert man all das, kann /review ziemlich präzise werden:

---
description: Reviewt aktuelle Änderungen, injiziert Diff und Kontext automatisch
allowed-tools: Bash(git diff:*), Bash(cat:*)
---

## Aktuelle Änderungen

!`git diff HEAD`

## Geänderte Dateien

!`git diff HEAD --name-only`

## Coding-Standards des Projekts

!`cat .claude/context/coding-standards.md 2>/dev/null || echo "(keine Standards-Datei)"`

---

Überprüfe die obigen Änderungen:

1. Logische Korrektheit: nicht behandelte Edge Cases, Logikfehler
2. Sicherheit: SQL-Injection, Autorisierungsprüfungen, Exposition sensibler Daten
3. Standard-Konformität: hält es die Coding-Standards des Projekts ein?
4. Lesbarkeit: Benennung, Kommentare, Struktur

Gib für jedes Problem Dateiname, Zeilennummer und einen konkreten Vorschlag an. Wenn es keine Probleme gibt, sag das — füll nicht künstlich auf.

Dieser Command verlangt keinerlei Vorbereitung — beim Auslösen werden Diff, Dateiliste und Coding-Standards alle automatisch injiziert.


Umgang mit Befehlsfehlern

Shell-Befehle können fehlschlagen (Datei existiert nicht, Befehl liegt nicht im PATH usw.). Nutze ||, um einen Standardwert zu liefern und den Command nicht abbrechen zu lassen:

!`git diff HEAD 2>/dev/null || echo "(keine git-Änderungen oder kein git-Repository)"`
!`cat .env.example 2>/dev/null || echo "(keine .env.example-Datei)"`
!`which rspec > /dev/null 2>&1 && bundle exec rspec --dry-run 2>&1 | head -20 || echo "(RSpec nicht gefunden)"`

Wenn ein Befehl fehlschlägt, bekommt Claude einen erklärenden Text statt eines leeren Felds und kann seine Antwortstrategie entsprechend anpassen.


Performance-Überlegungen: nicht zu viel injizieren

Die gesamte Ausgabe von !-Befehlen landet im Context Window. Ein paar typische Fallen:

Keine großen Dateien komplett caten

# Gefährlich: kann zehntausende Zeilen injizieren
!`cat db/schema.rb`

# Besser: nur das herausziehen, was du brauchst
!`grep -A 5 "create_table \"orders\"" db/schema.rb`

Log-Dateien mit Zeilenlimit

!`tail -50 log/development.log`

Test-Output abschneiden

!`bundle exec rspec 2>&1 | tail -40`

Je präziser der Kontext, desto besser Claudes Antworten. Die ganze Codebase reinzukippen macht ihn nicht klüger — es lässt ihn im Rauschen verlorengehen.


Aufgabenteilung mit CLAUDE.md

Häufige Frage: gehören Projekt-Hintergrundinfos in CLAUDE.md oder sollen sie dynamisch via ! injiziert werden?

Entscheidungskriterium:

Informationstyp Wo es hingehört
Immer benötigter Projekthintergrund (Tech-Stack, Verzeichnisstruktur, Konventionen) CLAUDE.md
Sich über die Zeit ändernder Zustand (aktueller Diff, Testergebnisse, Dateiinhalte) Dynamisch via !
Aufgabenspezifischer Kontext (Designdokument eines bestimmten Moduls) !cat bei Bedarf

CLAUDE.md ist persistentes Hintergrundwissen, ! ist ein Snapshot zum Aufgabenzeitpunkt. Beide ergänzen sich — nicht doppelt führen.


Ein vollständiges .claude/commands/-Verzeichnis

.claude/
├── commands/
│   ├── review.md        # Review: injiziert Diff + Standards
│   ├── test.md          # Tests schreiben: injiziert die Zieldatei
│   ├── fix-tests.md     # Tests reparieren: injiziert Fehlschläge
│   ├── pr.md            # PR-Beschreibung: injiziert git log + status
│   ├── explain.md       # Code erklären: injiziert Dateiinhalt
│   └── migrate.md       # Migration schreiben: injiziert Schema-Ausschnitt
├── context/
│   ├── stack.md         # Tech-Stack-Beschreibung
│   └── coding-standards.md  # Coding-Standards
└── settings.json

Im context/-Verzeichnis liegen statische Hintergrunddateien, die die einzelnen Commands bei Bedarf einlesen. Diese Struktur kannst du direkt in git committen und im Team teilen.


Der Unterschied in der Praxis

Statischer Command:

Überprüfe die aktuellen Code-Änderungen.

Claude muss erst fragen „wo sind die Änderungen?" oder selbst danach suchen — inkonsistente Ergebnisse.

Kontextbewusster Command:

Hier ist der Diff (mit echtem Inhalt), hier sind die relevanten Standards (mit echtem Inhalt), bitte überprüfen.

Claude geht direkt in die Analyse. Präzise Antworten, kein Geschwafel, kein Hin und Her.

Der Unterschied liegt nicht in Claudes Fähigkeiten, sondern darin, wie viele echte Informationen du ihm gibst.