Eigene Slash-Commands und Hooks für Releases von WebViewGold-Apps mit Claude Code
Zwei kleine Dateien nehmen einem Release das meiste Risiko. Ein /release-check-Command lässt Claude Code jedes Mal dieselbe Checkliste durchgehen, angefangen mit der Frage, ob dieses Release überhaupt einen Store-Build braucht, und ein Hook verweigert jeden Commit, der Config.swift oder Config.java mit einem Verweis auf localhost ausliefern würde. Beide liegen im Repository, dein ganzes Team und jede Cloud-Session bekommen sie also automatisch.
Ab $109 einmalig pro Plattform, oder unser Team erledigt alles ab $698.
Genehmigungsgarantie – oder Geld zurück innerhalb von 14 Tagen
Kein Programmieren nötig
Einmalzahlung, kostenlose Updates
24/7 Support von echten Menschen
Made in Germany seit 2014 · ISO 27001
9:41
Deine App
Deine AppJetzt auf dem Smartphone
App Store · Google Play Freigegeben
Commands leiten an, Hooks setzen durch
Ein eigener Command ist ein gespeicherter Prompt. Eine Datei unter .claude/commands/release-check.md wird in jeder Session in diesem Repository zu /release-check. Claude Code hat Commands mit Skills zusammengeführt: Ein Skill unter .claude/skills/release-check/SKILL.md erzeugt denselben Command und kann zusätzliche Dateien mitbringen, und bestehende Command-Dateien funktionieren weiter. Für eine einzelne Checkliste ist der Ordner commands der einfachste Ort.
Ein Hook ist etwas ganz anderes. Er ist ein Shell-Befehl, den Claude Code selbst zu einem festen Zeitpunkt ausführt, zum Beispiel direkt vor einem Tool-Aufruf. Das Modell hat dabei kein Mitspracherecht: Beendet sich ein PreToolUse-Hook mit Exit-Code 2, wird der Tool-Aufruf blockiert, und Claude bekommt stattdessen deine Fehlermeldung. Genau das willst du für den einen Fehler, der niemals bei Nutzern ankommen darf.
Eine praktische Faustregel: Leitlinien gehören in die CLAUDE.md, wiederholbare Abläufe werden zu Commands, und alles, was nie passieren darf, wird zum Hook.
Der /release-check-Command
Speichere ihn als .claude/commands/release-check.md. Zeilen mit einem führenden ! laufen, bevor Claude den Prompt sieht, und fügen ihre Ausgabe ein, sodass jede Prüfung vom echten Zustand des Repositorys ausgeht. allowed-tools genehmigt genau die Befehle vorab, die der Check braucht, und disable-model-invocation verhindert, dass Claude von sich aus einen Release-Check startet.
markdown
---
description: Pre-release check for the web app and the WebViewGold iOS and Android projects. Starts by deciding whether this release needs a store build.
argument-hint: "[version, for example 1.4.0]"
allowed-tools: Bash(git status *), Bash(git log *), Bash(git describe *), Bash(git diff *), Bash(git ls-files *), Bash(npm run lint), Bash(npm run build), Read, Grep, Glob
disable-model-invocation: true
---
# Release check for version $ARGUMENTS
## Repository state
- Branch and changes: !`git status --short --branch`
- Last release tag (a commit hash if there is no tag yet): !`git describe --tags --abbrev=0 --always`
- Recent commits: !`git log --oneline -20`
## 1. Does this release need a store build?
Run git diff --stat from the last release tag to HEAD. Native changes are files under
native/ios or native/android: Config.swift, Config.java, Info.plist, AndroidManifest.xml,
build.gradle, entitlements, icons and splash images.
- No native changes: report "Web-only release: deploy, no store build needed" and go to step 3.
- Native changes: a new App Store and Google Play build is needed. Continue with step 2.
## 2. Native checks
- Config.swift: host and webviewurl use the production domain over HTTPS.
- Config.java: HOST and HOME_URL match the iOS values.
- Neither file contains localhost, 127.0.0.1, 10.0.2.2, a 192.168.x.x address,
an ngrok or trycloudflare host, or a preview deployment URL.
- iOS: the marketing version is $ARGUMENTS, the build number is higher than the last
uploaded build, and every extension target (for example OneSignalNotificationServiceExtension)
uses the main bundle ID as prefix.
- Android: versionName is $ARGUMENTS and versionCode is higher than the last upload.
Report targetSdk; I will compare it with Google's current requirement.
- Every iOS usage description and every Android permission belongs to a feature we use.
- git ls-files shows no signing material: *.jks, *.keystore, *.p12, *.mobileprovision,
keystore.properties.
## 3. Web app checks
- npm run lint and npm run build pass.
- /privacy, /terms and /delete-account still exist and are linked from settings.
- No new checkout, price or external payment link is visible when isNativeApp() is true.
- No new logging of tokens, email addresses or other personal data.
## Output
One table: check, result (pass, fail, needs me), evidence (file:line or command output).
Then a short list of what I must do by hand: deploy, store uploads, TestFlight,
release notes. Do not fix anything inside this command; I will ask for fixes separately.
Die Hook-Konfiguration
Füge das in .claude/settings.json ein, die Projekt-Einstellungsdatei, die committet und geteilt wird (persönliche Anpassungen gehören in .claude/settings.local.json). Der Matcher Bash startet das Skript vor jedem Shell-Befehl, den Claude ausführen will; das Skript selbst ignoriert alles, was kein Commit ist.
Mit einer gut optimierten Version Ihrer Web-App können Sie innerhalb von wenigen Minuten eine beeindruckende mobile App erstellen. Zusätzlich dazu ist der Kundenservice sehr nett und hilfsbereit! Ich kann WebViewGold nur empfehlen :-)
Julian Koch · Mitbegründer von DuelDonkey · CodeCanyon
Das Hook-Skript
Speichere es als .claude/hooks/guard-native-config.sh und mach es ausführbar. Claude Code schickt den geplanten Tool-Aufruf als JSON über stdin; das Skript liest den Befehl mit jq aus und startet bei Commits den gemeinsamen Checker. Exit-Code 2 blockiert den Commit und gibt den stderr-Text an Claude weiter, das die URL dann meist von selbst korrigiert.
bash
#!/usr/bin/env bash
# .claude/hooks/guard-native-config.sh
# PreToolUse hook (matcher: Bash). Blocks "git commit" while a staged Config.swift
# or Config.java contains a development URL. Exit 0 = allow, exit 2 = block.
input=$(cat)
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
# Not a commit? Allow immediately.
printf '%s' "$cmd" | grep -Eq 'git( -C [^ ]+)? commit' || exit 0
cd "${CLAUDE_PROJECT_DIR:-.}" || exit 0
# "commit -a", "--all" or a "git add" in the same command also commit unstaged
# changes, so check the working tree too.
flag=""
if printf '%s' "$cmd" | grep -Eq 'commit.* (-[a-zA-Z]*a|--all)|git( -C [^ ]+)? add '; then
flag="--include-worktree"
fi
if ! report=$(./scripts/check-native-config.sh $flag 2>&1); then
{
echo "Commit blocked: a native config file points to a development URL."
echo "$report"
echo "Set host and webviewurl (Config.swift) and HOST and HOME_URL (Config.java)"
echo "to the production HTTPS domain, stage the files again and retry the commit."
} >&2
exit 2
fi
exit 0
Der gemeinsame Checker für Claude und Git
Halte die eigentliche Regel in einem einzigen Skript, damit der Claude Code Hook und ein normaler Git-pre-commit-Hook dasselbe durchsetzen. Speichere es als scripts/check-native-config.sh und mach es ausführbar. Über 10.0.2.2 erreicht der Android-Emulator deinen Laptop, ein klassisches Überbleibsel aus dem Testen.
bash
#!/usr/bin/env bash
# scripts/check-native-config.sh [--include-worktree]
# Exit 1 if a staged Config.swift or Config.java contains a development URL.
# Used by the Claude Code hook and by the Git pre-commit hook.
pattern='localhost|127\.0\.0\.1|0\.0\.0\.0|10\.0\.2\.2|192\.168\.[0-9]+\.[0-9]+|\.ngrok(-free)?\.(app|io|dev)|\.trycloudflare\.com'
# Add the preview hosts you use, for example: |-git-[a-z0-9-]+\.vercel\.app
scan() { # $1 = file, $2 = label; file content on stdin
local hits
hits=$(grep -nE "$pattern" | grep -vE '^[0-9]+:[[:space:]]*(//|\*)')
if [ -n "$hits" ]; then
printf '%s (%s):\n%s\n' "$1" "$2" "$hits"
return 1
fi
}
status=0
for f in $(git diff --cached --name-only --diff-filter=ACMR | grep -E '(^|/)Config\.(swift|java)$'); do
git show ":$f" | scan "$f" "staged" || status=1
done
if [ "$1" = "--include-worktree" ]; then
for f in $(git diff --name-only | grep -E '(^|/)Config\.(swift|java)$'); do
scan "$f" "working tree" < "$f" || status=1
done
fi
exit $status
Einrichten und beweisen, dass es funktioniert
Fünfzehn Minuten, inklusive eines absichtlich blockierten Commits.
Die Dateien anlegen
Lege .claude/commands/release-check.md, .claude/hooks/guard-native-config.sh und scripts/check-native-config.sh an und führe dann chmod +x .claude/hooks/guard-native-config.sh scripts/check-native-config.sh aus. Oder füge den Prompt weiter unten ein und lass Claude Code die Dateien anlegen und anpassen.
Sicherstellen, dass jq installiert ist
Der Hook liest JSON mit jq (brew install jq unter macOS, sudo apt install jq unter Debian oder Ubuntu; in Cloud-Sessions ist es schon vorhanden). Ohne jq kann das Skript den Befehl nicht lesen und lässt alles durch, deshalb gehört ein Test zu den nächsten Schritten.
Den Hook registrieren
Füge das JSON in .claude/settings.json ein, behalte die vorhandenen Einstellungen bei und committe die Datei. Führe in Claude Code /hooks aus, um zu prüfen, dass der PreToolUse-Eintrag geladen ist.
Ihn absichtlich auslösen
Setze HOME_URL in Config.java auf http://10.0.2.2:3000, stage die Datei und bitte Claude Code um einen Commit. Der Commit muss mit deiner Meldung abgelehnt werden. Stell danach die Produktions-URL wieder her.
Auch Commits von Hand abdecken
Lege .githooks/pre-commit mit den zwei Zeilen #!/usr/bin/env bash und exec ./scripts/check-native-config.sh an, mach die Datei ausführbar und führe einmal pro Klon git config core.hooksPath .githooks aus. Commits aus Xcode, Android Studio oder dem Terminal laufen jetzt gegen dieselbe Regel, und Claudes eigene Commits ebenfalls, genau in dem Moment, in dem Git sie erstellt.
Den Release-Check ausführen
Tippe vor jedem Release /release-check 1.4.0. Die erste Antwort sagt dir, ob du ein Deploy oder einen Store-Build auslieferst; Web- vs. native Änderungen erklärt, warum diese Unterscheidung für WebViewGold-Apps so wichtig ist.
Lass Claude Code alles installieren
Praktisch, wenn deine Ordner von den Beispielen abweichen. Claude passt die Pfade an und zeigt dir jede Datei, bevor es sie speichert.
In Claude Code im Root des Repositorys einfügen
Richte Release-Tooling für dieses Repository ein. Unsere Web-App wird auch als iOS- und Android-App veröffentlicht, gebaut mit WebViewGold; die nativen Projekte liegen in native/ios und native/android (prüfe zuerst die echte Struktur und passe das an). Finde die tatsächlichen Pfade von Config.swift, Config.java, Info.plist, AndroidManifest.xml und app/build.gradle, bevor du irgendetwas schreibst.
1. Lege .claude/commands/release-check.md an: einen Command mit Release-Checkliste und Frontmatter (description, ein argument-hint für die Version, allowed-tools beschränkt auf lesende Git-Befehle, npm run lint, npm run build, Read, Grep und Glob, sowie disable-model-invocation: true). Er muss zuerst entscheiden, ob das Release native Dateien ändert und damit einen Store-Build braucht, und dann Produktions-URLs, Versions- und Build-Nummern, Berechtigungen, getrackte Signing-Dateien sowie die Routen /privacy, /terms und /delete-account prüfen.
2. Lege scripts/check-native-config.sh an: Exit 1, wenn eine gestagte Config.swift oder Config.java localhost, 127.0.0.1, 0.0.0.0, 10.0.2.2, eine 192.168.x.x-Adresse oder einen ngrok- oder trycloudflare-Host enthält. Ignoriere Kommentarzeilen. Mit --include-worktree prüfe auch nicht gestagte Änderungen.
3. Lege .claude/hooks/guard-native-config.sh an: einen PreToolUse-Hook für das Bash-Tool, der die JSON-Eingabe mit jq liest, alles außer git commit ignoriert, den Checker ausführt (mit --include-worktree bei commit -a, --all oder einem git add im selben Befehl) und mit Exit 2 und einer klaren Meldung auf stderr endet, wenn die Prüfung fehlschlägt.
4. Registriere den Hook in .claude/settings.json, ohne vorhandene Einstellungen zu entfernen.
5. Lege .githooks/pre-commit an, das denselben Checker ausführt.
Mach die Skripte ausführbar, zeig mir jede Datei vor dem Speichern und erklär mir dann, wie ich den Hook mit einer absichtlich gesetzten localhost-URL teste.
Welche Release-Regel wohin gehört
Regel
Bester Ort
Warum
Config-Dateien zeigen auf Produktion, nie auf localhost
Hook plus Git-pre-commit-Hook
Darf nie ausgeliefert werden. Ein blockierter Commit ist billiger als eine kaputte App bei deinen Nutzern oder ein abgelehnter Build.
Versions- und Build-Nummern erhöht
/release-check
Braucht Urteilsvermögen: Nur native Releases brauchen neue Nummern, und die zuletzt hochgeladene Build-Nummer steht nicht im Repository.
Leitlinien beim Coden, ein strenges Review vor dem Release.
Lint und Build laufen durch
/release-check oder CI
Zu langsam für einen Hook bei jedem Commit, ideal als Schritt in der Checkliste oder als verpflichtender Status-Check.
Signing-Dateien werden nie committet
.gitignore plus der Release-Check
Mit .gitignore verhindern, vor jedem Release mit git ls-files prüfen.
Fallstricke
Exit 1 blockiert nicht. Nur Exit-Code 2 (oder eine JSON-Antwort mit permissionDecision auf deny) stoppt den Tool-Aufruf. Exit 1 wird als Hook-Fehler gemeldet, und der Commit läuft trotzdem durch.
Der Hook sieht nur Claude. Er läuft bei Tool-Aufrufen, die Claude Code macht. Commits aus deiner IDE oder dem Terminal umgehen ihn, deshalb läuft derselbe Checker auch als Git-pre-commit-Hook.
Hooks laufen mit deinen Rechten. Prüfe Änderungen an .claude/settings.json und .claude/hooks/ in Pull Requests wie jedes andere Skript; ein Hook läuft auf dem Rechner von allen, die das Projekt öffnen.
Überladene !-Zeilen. Inline-Befehle in einer Command-Datei brauchen passende Einträge in allowed-tools. Beschränke dich auf einfache, lesende Befehle und verlagere Pipes und Logik in die Anweisungen, wo Claude sie als normale Tool-Aufrufe ausführt.
Ein fehlendes Argument.$ARGUMENTS ist alles, was du nach dem Command-Namen tippst. Startest du /release-check ohne Version, hat die Prüfung nichts zum Vergleichen; der argument-hint soll dich daran erinnern.
Secrets in Prompts. Command-Dateien werden committet. Schreib niemals Keystore-Passwörter, API-Keys oder Passwörter von Demo-Accounts hinein.
Häufig gestellte Fragen
Sind eigene Slash-Commands in Claude Code veraltet?
Nein, sie wurden mit Skills zusammengeführt. Dateien in .claude/commands/ funktionieren weiter und erzeugen dieselben /name-Commands. Ein Skill wie .claude/skills/release-check/SKILL.md bringt zusätzlich Begleitdateien und automatisches Laden mit; steig auf dieses Format um, wenn ein Command über eine einzelne Datei hinauswächst.
Wohin gehören persönliche Commands?
Nach ~/.claude/commands/ oder ~/.claude/skills/ in deinem Home-Ordner. Sie stehen in jedem Projekt auf deinem Rechner zur Verfügung, werden aber nicht mit deinem Team geteilt.
Könnte der Hook die URL korrigieren, statt den Commit zu blockieren?
Er könnte die Datei umschreiben, aber stilles Umschreiben versteckt Probleme. Blockieren mit einer klaren Meldung ist sicherer: Claude liest die Meldung, setzt die Produktions-URL und committet erneut, und du siehst, was passiert ist.
Funktionieren Hooks und Commands in Claude Code im Web?
Ja. Cloud-Sessions nutzen die .claude/settings.json, die Commands und die Skills des Repositorys, und jq ist in der Cloud-Umgebung vorinstalliert. Hooks in deiner persönlichen ~/.claude/settings.json bleiben auf deinem eigenen Rechner.
Bremst ein Hook bei jedem Bash-Aufruf Claude aus?
Kaum. Das Skript beendet sich sofort bei allem, was kein Commit ist. Neuere Versionen von Claude Code akzeptieren an einem Hook außerdem ein if-Feld, zum Beispiel "Bash(git commit *)", sodass das Skript nur bei passenden Befehlen startet.
Drei Wege, deine App in die Stores zu bringen
Gleiches Ergebnis, unterschiedlich viel Arbeit auf deiner Seite. Alle drei kommen mit Genehmigungsgarantie und 24/7 Support von echten Menschen.
Selbst machen
$109 pro Plattform, einmalig
Die WebViewGold-Lizenz: ein fertiges Xcode- oder Android-Studio-Projekt. URL einfügen, Name und Icon setzen, Features einschalten, bauen und einreichen. Kostenlose Updates für immer.
Kein Mac, kein Xcode, kein Android Studio: Du konfigurierst im Browser, wir bauen beide Apps in der Cloud und übergeben sie an App Store Connect und die Play Console.
Schick uns deine URL und dein Icon. Unser Team konfiguriert, baut und liefert deine App innerhalb von 72 Stunden, White-Label, inklusive Quellprojekten. Beide Plattformen für $1,158.
Erstattungen erfolgen zu den in unseren FAQ genannten Bedingungen: eine nicht inhaltsbedingte Ablehnung durch Apple und/oder Google, geltend gemacht innerhalb von 14 Tagen nach dem Kauf.