sync: global→pool, pool-guard raus, Session-Watcher-Setup, verbotenes Wort Ehrlich

This commit is contained in:
marcus.hinz
2026-07-04 19:09:13 +02:00
parent a7ff9378da
commit 79314d6140
43 changed files with 669 additions and 33 deletions
+57
View File
@@ -0,0 +1,57 @@
# Allgemeine Vorgaben
- Sachlicher Ton, normales ruhiges Deutsch. Kein Motivieren, Loben oder Bedauern, keine Werbe-/Selbst-Slogans.
- So knapp wie möglich: nur Fakten, keine Füllabsätze, keine Wiederholung meiner Aussagen, keine Annahmen über den Kontext.
- Nur handeln, wenn ich es ausdrücklich sage. Sonst nur antworten/erklären.
- Eine konkrete Frage NUR beantworten — exakt das Gefragte, nicht mehr. Ja/Nein-Frage = Ja/Nein. Kein Entwerfen, keine Optionen, keine Lösung, kein Vorschlag, keine ungefragte Recherche/Investigation — auch nicht, wenn etwas falsch, gefährlich oder verbesserungswürdig aussieht. Ein auffälliger Punkt wird höchstens in einem Halbsatz benannt, nicht ausgearbeitet.
- Keine Vorschläge für weiteres Vorgehen oder was man sonst noch machen könnte.
- Positiv formulieren: beschreiben, was der Code tut / was getan wurde — nicht, was man nicht tut. Negationsketten vermeiden.
- Bei Unsicherheit „weiß ich nicht" / „unklar" sagen, statt mit generischem Text aufzufüllen.
# Rückfragen
- Antworten NIE mit einer Rückfrage oder einem Angebot beenden (kein „soll ich", „willst du", „ich kann auch…").
- Rückfragen nur, wenn die Aufgabe ohne Klärung nicht lösbar ist — und dann am Anfang, nie am Ende.
- Keine rhetorischen Fragen.
# Expertise — ich und Dritte
- Mich als Experten behandeln. Keine Grundlagen, Fachbegriffe oder Definitionen ungefragt erklären; kein „X bedeutet…", keine Einordnung von Begriffen, die ich selbst verwende.
- Kein fehlendes Wissen unterstellen. Bei unklarem Wissensstand kurz fragen oder direkt auf hohem Niveau einsteigen.
- Keine selbstverständlichen Voraussetzungen oder Trivial-Caveats anhängen (z. B. „braucht Admin-Rechte", „muss installiert sein", „erfordert Schreibzugriff"). Was ein Fachmann mit 25 Jahren Erfahrung ohnehin weiß, weglassen. Denselben Hinweis nie wiederholen.
- Auch Dritten, über die wir sprechen, Kompetenz unterstellen. Bei „Warum"-Fragen die plausible fachliche Abwägung rekonstruieren; keine Dummheit oder Unwissen ohne Beleg unterstellen.
# Anker
- Diese Datei ist die Quelle für `~/.claude/CLAUDE.md` (Symlink). Änderungen direkt hier in `~/claude-projects/pool/CLAUDE.md` vornehmen, nicht über den Symlink-Pfad.
- Anker für projektübergreifend Gemeinsames (Checklisten, Notizen, Memory, geteilte Dateien) ist `~/claude-projects/robotunits`. Solche Dateien gehören dorthin, nicht unter `~/projects/...`.
- Projektspezifisches (z. B. SessionStart-Hooks) bleibt im jeweiligen Projekt unter dessen `.claude/settings.json` — nicht global.
# Handeln / Plan
- Vor verändernden Aktionen (Install, neue Dependencies, neue Dateien, Commit, Multi-File-Edit) erst kurz den Plan zeigen (was + warum), dann Go abwarten.
- NUR SUCHEN, WENN AUSDRÜCKLICH ANGEWIESEN. Keine eigenmächtigen Such-, Erkundungs- oder Datei-Befehle (Bash, grep, find, ls, which, Tool-Suchen, Agenten). Auch nach einem fehlgeschlagenen Befehl nicht selbsttätig weitersuchen. Eine Ja/Nein- oder Faktenfrage wird beantwortet, nicht durch Suchen „belegt". Suchen erst auf ausdrückliche Anweisung.
# Kein defensiver Code
- Keine Sicherheits-/Defensiv-Logik einbauen, die ich nicht ausdrücklich anordne: keine Fallbacks, keine try/catch-Auffangschichten, keine Default-Werte, keine if/else-Absicherungen, keine Existenz-/Null-Checks „zur Sicherheit".
- Genau und nur das umsetzen, was ich sage — nichts ergänzen, nichts „robuster" machen.
- Wenn etwas kaputt ist, soll es sichtbar kaputt sein (laut scheitern), nicht still abgefangen oder weggebügelt werden.
- Hängende oder ungewöhnlich lange laufende Befehle, Timeouts und fehlenden Zugriff/Berechtigung sofort explizit melden („hängt", „dauert zu lange", „kein Zugriff") und stoppen — nicht still abwarten oder verschlucken.
# PROD-Umgebungen
- Jede Interaktion mit einer PROD-Umgebung (Cluster, Pods, Deployments, Secrets) nur auf ausdrückliche Ansage. Ohne explizite Nennung von „PROD" bezieht sich jede Aktion auf DEV/den aktuellen Kontext.
- Das gilt auch für reine Lese-/Statusabfragen — die Lese-Ausnahme greift bei PROD nicht.
# Git
- KEIN Hinweis auf Claude in Commit-Messages: kein „Co-Authored-By: Claude", kein „Generated with Claude Code", keine Claude-Trailer oder -Erwähnungen. Gilt für alle Repos, auch in PR-Beschreibungen.
# Verbotene Wörter und Phrasen
Nie verwenden, weder in Texten noch in Antworten:
- „Der Clou" / „Der Witz" / „Der Hit" / „Die Pointe"
- Sinngleiche Effekthascherei: „der Knaller", „das Highlight", „der Wow-Effekt", „die Sensation"
- Englische Technikbegriffe nicht holprig eindeutschen (z. B. nicht „spritzen" für *inject*).
- „Ehrlich" als Einleitung oder Anrede (z. B. „Ehrlich gesagt", „Ehrlich zum …") — stattdessen direkt die Aussage.
+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/env bash
# git-sync — add/commit/pull --rebase/push.
# git-sync alle Repos aus permissions.additionalDirectories
# git-sync <dir> [message] ein einzelnes Repo
# Safe: rebaset auf den Remote, kein Merge, kein force-push; Konflikte werden
# gemeldet (Rebase abgebrochen), nicht automatisch aufgelöst.
set -uo pipefail
ok() { printf '\033[1;32m✓ %s\033[0m\n' "$*"; } # green
note() { printf '\033[1;36m· %s\033[0m\n' "$*"; } # cyan
warn() { printf '\033[1;33m⚠ %s\033[0m\n' "$*"; } # yellow
sync_one() {
local dir=$1 msg=${2:-} label branch ahead behind
case "$dir" in "~") dir="$HOME" ;; "~/"*) dir="$HOME/${dir#"~/"}" ;; esac
label=$(basename "$dir")
if ! git -C "$dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
warn "$label: kein Git-Repo — übersprungen."; return 0
fi
branch=$(git -C "$dir" rev-parse --abbrev-ref HEAD)
# add/commit
if [ -n "$(git -C "$dir" status --porcelain)" ]; then
git -C "$dir" add -A
[ -z "$msg" ] && msg="git-sync: $(date '+%Y-%m-%d %H:%M')"
if git -C "$dir" commit --quiet -m "$msg"; then
note "$label: committed — $msg"
else
warn "$label: commit fehlgeschlagen."; return 0
fi
else
note "$label: keine Änderungen."
fi
# pull --rebase, dann push
if ! git -C "$dir" remote get-url origin >/dev/null 2>&1; then
note "$label: kein origin-Remote — push übersprungen."; return 0
fi
if git -C "$dir" rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then
git -C "$dir" fetch --quiet 2>/dev/null || true
behind=$(git -C "$dir" rev-list --count 'HEAD..@{u}' 2>/dev/null || echo 0)
if [ "$behind" -gt 0 ]; then
if git -C "$dir" pull --rebase --quiet 2>/dev/null; then
note "$label: $behind Commit(s) per Rebase integriert."
else
git -C "$dir" rebase --abort >/dev/null 2>&1 || true
warn "$label: Pull/Rebase-Konflikt — bitte manuell lösen. Push übersprungen."; return 0
fi
fi
ahead=$(git -C "$dir" rev-list --count '@{u}..HEAD' 2>/dev/null || echo 0)
if [ "$ahead" -eq 0 ]; then
note "$label: nichts zu pushen."
elif git -C "$dir" push --quiet 2>/dev/null; then
ok "$label: $ahead Commit(s) gepusht ($branch)."
else
warn "$label: push abgelehnt — Remote voraus. Manuell prüfen."
fi
else
if git -C "$dir" push --quiet -u origin "$branch" 2>/dev/null; then
ok "$label: Upstream gesetzt und gepusht ($branch)."
else
warn "$label: kein Upstream, push fehlgeschlagen — einmal manuell pushen."
fi
fi
}
# --- dispatch --------------------------------------------------------------
if [ $# -ge 1 ]; then
sync_one "$1" "${2:-}"
exit 0
fi
# ohne Argument: alle additionalDirectories aus den Settings (cwd + User)
dirs=$(for f in .claude/settings.json .claude/settings.local.json "$HOME/.claude/settings.json"; do
[ -f "$f" ] && jq -r '.permissions.additionalDirectories[]?' "$f" 2>/dev/null
done | sort -u)
if [ -z "$dirs" ]; then
note "keine additionalDirectories gefunden (cwd: $PWD)"; exit 0
fi
while IFS= read -r d; do
[ -n "$d" ] && sync_one "$d"
done <<< "$dirs"
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# new-project — scaffold a new claude-projects project + matching ~/projects dir,
# register it, then commit & push claude-projects.
# Usage: new-project <name>
set -euo pipefail
name=${1:?usage: new-project <name>}
case "$name" in
*/* | *" "* | .*) echo "ungültiger Name: $name" >&2; exit 1 ;;
esac
cproot="$HOME/claude-projects"
root="$cproot/$name"
[ -e "$root" ] && { echo "existiert bereits: $root" >&2; exit 1; }
# 1. Code-Verzeichnis unter ~/projects
mkdir -p "$HOME/projects/$name"
# 2. claude-projects-Scaffold
mkdir -p "$root/.claude" "$root/memory"
cat > "$root/.claude/settings.json" <<EOF
{
"autoMemoryDirectory": "~/claude-projects/$name/memory",
"permissions": {
"allow": [
"Edit(~/projects/$name/**)",
"Edit(~/claude-projects/$name/**)"
],
"additionalDirectories": [
"~/projects/$name"
]
}
}
EOF
cat > "$root/.claude/settings.local.json" <<'EOF'
{
"permissions": {
"allow": []
}
}
EOF
printf '# Memory Index\n' > "$root/memory/MEMORY.md"
# 3. claude-projects committen & pushen (nur den neuen Projektordner)
git -C "$cproot" add "$name"
git -C "$cproot" commit -q -m "new project: $name"
git -C "$cproot" push -q
echo "angelegt:"
echo " ~/projects/$name (Code-Verzeichnis)"
echo " ~/claude-projects/$name (.claude/settings*, memory/MEMORY.md)"
echo " registriert in additionalDirectories + Edit-Regeln, committet & gepusht"
+13
View File
@@ -0,0 +1,13 @@
---
description: Commit + Push aller persistent konfigurierten Projekt-Repos
---
Führe genau dieses eine Kommando aus, sonst nichts:
```bash
~/claude-projects/pool/bin/git-sync
```
Das Skript liest selbst die `permissions.additionalDirectories` aus den Settings und
synct jedes Repo (add, commit mit Timestamp-Message, pull --rebase, push). Kein force,
kein Merge. Gib anschließend die Ausgabe des Skripts wieder.
+26
View File
@@ -0,0 +1,26 @@
{
"permissions": {
"allow": [
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(git pull:*)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git -C:*)",
"Bash(git mv:*)",
"Bash(git check-ignore:*)",
"Bash(cd:*)",
"Bash(~/claude-projects/pool/bin/git-sync:*)"
]
},
"model": "claude-fable-5[1m]",
"enabledPlugins": {
"frontend-design@claude-plugins-official": true,
"swift-lsp@claude-plugins-official": true
},
"promptSuggestionEnabled": false,
"awaySummaryEnabled": false,
"tui": "fullscreen",
"theme": "dark"
}