Merge pull request 'chore: Workflow-Aktualisierungen — Bootstrap, Skill-Defs, Gitea-Wrapper' (#14) from chore/workflow-updates into main
This commit was merged in pull request #14.
This commit is contained in:
@@ -15,7 +15,7 @@ git clone https://gitea.troeger-net.org/martin/claude-workflow.git /mnt/projekte
|
||||
/mnt/projekte/claude-workflow/bootstrap.sh
|
||||
```
|
||||
|
||||
Das Bootstrap-Skript installiert alle Tools, erstellt alle Symlinks und richtet den Gitea-Token ein.
|
||||
Das Bootstrap-Skript erstellt alle Symlinks, prueft Voraussetzungen und zeigt fehlende Installationsbefehle an.
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
@@ -25,14 +25,15 @@ Das Bootstrap-Skript installiert alle Tools, erstellt alle Symlinks und richtet
|
||||
| `ruff` | Python-Formatter (Hook) | `pipx install ruff` |
|
||||
| `eslint` | JS/TS/Vue-Formatter (Hook) | Projektabhängig |
|
||||
| `shellcheck` | Bash-Linter (Hook + /script) | `apt install shellcheck` |
|
||||
| `secret-tool` | Gitea-Token abrufen | `apt install libsecret-tools` |
|
||||
| `markdownlint-cli2` | Markdown-Lint (Hook) | `npm install -g markdownlint-cli2` |
|
||||
| `gh` | GitHub CLI | `apt install gh` |
|
||||
| `go` + `gitea-mcp` | Gitea-MCP-Binary | `go install gitea.com/gitea/gitea-mcp@latest` |
|
||||
|
||||
### Gitea-Token einrichten
|
||||
|
||||
```bash
|
||||
secret-tool store --label="Gitea claude-code Token" user claude-code token gitea
|
||||
mkdir -p ~/.config/gitea && chmod 700 ~/.config/gitea
|
||||
echo 'DEIN_TOKEN' > ~/.config/gitea/token && chmod 600 ~/.config/gitea/token
|
||||
```
|
||||
|
||||
### Sync zwischen Rechnern
|
||||
|
||||
+106
-87
@@ -5,139 +5,158 @@ REPO="/mnt/projekte/claude-workflow"
|
||||
|
||||
echo "=== Claude-Workflow Bootstrap ==="
|
||||
|
||||
# Skills (als Verzeichnis-Symlinks: ~/.claude/skills/<name> → repo/skills/<name>/)
|
||||
# --- Symlinks und Berechtigungen ---
|
||||
|
||||
mkdir -p ~/.claude/skills
|
||||
for d in "$REPO/skills/"/*/; do
|
||||
name=$(basename "$d")
|
||||
ln -sfn "$d" ~/.claude/skills/"$name"
|
||||
done
|
||||
echo "✓ Skills verlinkt"
|
||||
echo " Skills verlinkt"
|
||||
|
||||
# Agents
|
||||
mkdir -p ~/.claude/agents
|
||||
for f in "$REPO/agents/"*.md; do
|
||||
ln -sf "$f" ~/.claude/agents/
|
||||
done
|
||||
echo "✓ Agents verlinkt"
|
||||
echo " Agents verlinkt"
|
||||
|
||||
# Dotfiles
|
||||
ln -sf "$REPO/dotfiles/CLAUDE.md" ~/.claude/CLAUDE.md
|
||||
ln -sf "$REPO/dotfiles/settings.json" ~/.claude/settings.json
|
||||
ln -sf "$REPO/dotfiles/statusline-command.sh" ~/.claude/statusline-command.sh
|
||||
ln -sf "$REPO/dotfiles/gitea-mcp-wrapper.sh" ~/.claude/gitea-mcp-wrapper.sh
|
||||
chmod +x "$REPO/dotfiles/gitea-mcp-wrapper.sh"
|
||||
echo "✓ Dotfiles verlinkt"
|
||||
echo " Dotfiles verlinkt"
|
||||
|
||||
# Hooks ausführbar machen
|
||||
chmod +x "$REPO/hooks/"*.sh
|
||||
echo "✓ Hooks ausführbar"
|
||||
echo " Hooks ausfuehrbar"
|
||||
|
||||
# --- Voraussetzungen pruefen ---
|
||||
|
||||
echo ""
|
||||
echo "=== Voraussetzungen prüfen ==="
|
||||
echo "=== Voraussetzungen ==="
|
||||
|
||||
# --- gh (GitHub CLI, wird auch für Gitea-PRs genutzt) ---
|
||||
if command -v gh &>/dev/null; then
|
||||
echo "✓ gh $(gh --version | head -1)"
|
||||
missing_apt=()
|
||||
missing_other=()
|
||||
|
||||
check_cmd() {
|
||||
local cmd="$1"
|
||||
local version_info="$2"
|
||||
if command -v "$cmd" &>/dev/null; then
|
||||
echo " OK $cmd ($version_info)"
|
||||
return 0
|
||||
else
|
||||
echo " gh fehlt – installiere via apt..."
|
||||
sudo apt-get install -y gh
|
||||
echo "✓ gh installiert"
|
||||
echo " FEHLT $cmd"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- jq ---
|
||||
if command -v jq &>/dev/null; then
|
||||
echo "✓ jq $(jq --version)"
|
||||
check_cmd "gh" "$(gh --version 2>/dev/null | head -1 || true)" \
|
||||
|| missing_apt+=("gh")
|
||||
|
||||
check_cmd "jq" "$(jq --version 2>/dev/null || true)" \
|
||||
|| missing_apt+=("jq")
|
||||
|
||||
check_cmd "shellcheck" "$(shellcheck --version 2>/dev/null | awk '/^version:/ {print $2}' || true)" \
|
||||
|| missing_apt+=("shellcheck")
|
||||
|
||||
if command -v pipx &>/dev/null; then
|
||||
check_cmd "ruff" "$(ruff --version 2>/dev/null || true)" \
|
||||
|| missing_other+=("pipx install ruff")
|
||||
else
|
||||
echo " jq fehlt – installiere via apt..."
|
||||
sudo apt-get install -y jq
|
||||
echo "✓ jq installiert"
|
||||
fi
|
||||
|
||||
# --- ruff ---
|
||||
if command -v ruff &>/dev/null; then
|
||||
echo "✓ ruff $(ruff --version)"
|
||||
if ! command -v ruff &>/dev/null; then
|
||||
echo " FEHLT ruff (pipx ebenfalls nicht vorhanden)"
|
||||
missing_apt+=("pipx")
|
||||
missing_other+=("pipx ensurepath" "pipx install ruff")
|
||||
else
|
||||
echo " ruff fehlt – installiere via pipx..."
|
||||
if ! command -v pipx &>/dev/null; then
|
||||
sudo apt-get install -y pipx
|
||||
pipx ensurepath
|
||||
echo " OK ruff ($(ruff --version 2>/dev/null || true))"
|
||||
fi
|
||||
pipx install ruff
|
||||
echo "✓ ruff installiert"
|
||||
fi
|
||||
|
||||
# --- shellcheck (Bash-Lint-Hook + /script) ---
|
||||
if command -v shellcheck &>/dev/null; then
|
||||
echo "✓ shellcheck $(shellcheck --version | awk '/^version:/ {print $2}')"
|
||||
if command -v npm &>/dev/null; then
|
||||
check_cmd "markdownlint-cli2" "$(markdownlint-cli2 --version 2>/dev/null | head -1 || true)" \
|
||||
|| missing_other+=("npm install -g markdownlint-cli2")
|
||||
else
|
||||
echo " shellcheck fehlt – installiere via apt..."
|
||||
sudo apt-get install -y shellcheck
|
||||
echo "✓ shellcheck installiert"
|
||||
fi
|
||||
|
||||
# --- markdownlint-cli2 (Markdown-Lint-Hook, custom rule no-hr) ---
|
||||
if command -v markdownlint-cli2 &>/dev/null; then
|
||||
echo "✓ markdownlint-cli2 $(markdownlint-cli2 --version 2>/dev/null | head -1)"
|
||||
if ! command -v markdownlint-cli2 &>/dev/null; then
|
||||
echo " FEHLT markdownlint-cli2 (npm nicht vorhanden)"
|
||||
echo " Node.js zuerst installieren, z.B. via nvm"
|
||||
missing_other+=("# Node.js installieren: https://github.com/nvm-sh/nvm" "npm install -g markdownlint-cli2")
|
||||
else
|
||||
echo " markdownlint-cli2 fehlt – installiere via npm..."
|
||||
if ! command -v npm &>/dev/null; then
|
||||
sudo apt-get install -y npm
|
||||
echo " OK markdownlint-cli2 ($(markdownlint-cli2 --version 2>/dev/null | head -1 || true))"
|
||||
fi
|
||||
sudo npm install -g markdownlint-cli2
|
||||
echo "✓ markdownlint-cli2 installiert"
|
||||
fi
|
||||
|
||||
# --- gitea-mcp Binary ---
|
||||
if command -v go &>/dev/null; then
|
||||
if [[ -x ~/go/bin/gitea-mcp ]]; then
|
||||
echo "✓ gitea-mcp vorhanden"
|
||||
echo " OK gitea-mcp"
|
||||
else
|
||||
echo " gitea-mcp fehlt – installiere via go install..."
|
||||
go install gitea.com/gitea/gitea-mcp@latest
|
||||
echo "✓ gitea-mcp installiert"
|
||||
echo " FEHLT gitea-mcp"
|
||||
missing_other+=("go install gitea.com/gitea/gitea-mcp@latest")
|
||||
fi
|
||||
else
|
||||
if [[ ! -x ~/go/bin/gitea-mcp ]]; then
|
||||
echo " FEHLT gitea-mcp (go nicht vorhanden)"
|
||||
missing_apt+=("golang-go")
|
||||
missing_other+=("go install gitea.com/gitea/gitea-mcp@latest")
|
||||
else
|
||||
echo " OK gitea-mcp"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- context7 Plugin-Check ---
|
||||
# --- Claude-Code-Integrationen ---
|
||||
|
||||
echo ""
|
||||
echo "=== Claude-Code-Integrationen ==="
|
||||
|
||||
if command -v claude &>/dev/null; then
|
||||
if claude mcp list 2>/dev/null | grep -q "context7"; then
|
||||
echo "✓ context7 Plugin aktiv"
|
||||
echo " OK context7 Plugin"
|
||||
else
|
||||
echo "⚠ context7 Plugin nicht aktiv – prüfe enabledPlugins in settings.json"
|
||||
echo " Ggf. Claude Code neu starten oder Plugin manuell aktivieren."
|
||||
echo " FEHLT context7 Plugin -- in Claude Code aktivieren"
|
||||
fi
|
||||
|
||||
# --- gitea-mcp in Claude Code registrieren ---
|
||||
if claude mcp list 2>/dev/null | grep -q "^gitea:"; then
|
||||
echo "✓ gitea MCP bereits registriert"
|
||||
echo " OK gitea MCP"
|
||||
else
|
||||
echo " Registriere gitea MCP..."
|
||||
claude mcp add --scope user gitea -- bash ~/.claude/gitea-mcp-wrapper.sh
|
||||
echo "✓ gitea MCP registriert"
|
||||
echo " FEHLT gitea MCP"
|
||||
missing_other+=("claude mcp add --scope user gitea -- bash ~/.claude/gitea-mcp-wrapper.sh")
|
||||
fi
|
||||
else
|
||||
echo " claude CLI nicht gefunden -- MCP-Checks uebersprungen"
|
||||
fi
|
||||
|
||||
# --- secret-tool + Gitea-Token ---
|
||||
if ! command -v secret-tool &>/dev/null; then
|
||||
echo " secret-tool fehlt – installiere libsecret-tools..."
|
||||
sudo apt-get install -y libsecret-tools
|
||||
echo "✓ secret-tool installiert"
|
||||
else
|
||||
echo "✓ secret-tool vorhanden"
|
||||
fi
|
||||
# --- Gitea-Token ---
|
||||
|
||||
echo " Gitea-Token prüfen..."
|
||||
if secret-tool lookup user claude-code token gitea &>/dev/null; then
|
||||
echo "✓ Gitea-Token vorhanden"
|
||||
else
|
||||
echo ""
|
||||
echo " Gitea-Token für claude-code nicht gefunden."
|
||||
read -r -p " Gitea-Token eingeben (https://gitea.troeger-net.org): " GITEA_TOKEN
|
||||
if [[ -n "${GITEA_TOKEN// /}" ]]; then
|
||||
echo -n "$GITEA_TOKEN" | secret-tool store \
|
||||
--label="Gitea claude-code token" \
|
||||
user claude-code token gitea
|
||||
echo "✓ Gitea-Token gespeichert"
|
||||
else
|
||||
echo "⚠ Kein Token eingegeben – übersprungen"
|
||||
fi
|
||||
fi
|
||||
GITEA_TOKEN_FILE="$HOME/.config/gitea/token"
|
||||
|
||||
echo ""
|
||||
echo "✓ Bootstrap abgeschlossen"
|
||||
echo "=== Gitea-Token ==="
|
||||
|
||||
if [[ -f "$GITEA_TOKEN_FILE" ]]; then
|
||||
echo " OK $GITEA_TOKEN_FILE"
|
||||
else
|
||||
echo " FEHLT $GITEA_TOKEN_FILE"
|
||||
missing_other+=("mkdir -p ~/.config/gitea && chmod 700 ~/.config/gitea"
|
||||
"echo 'DEIN_TOKEN' > ~/.config/gitea/token && chmod 600 ~/.config/gitea/token")
|
||||
fi
|
||||
|
||||
# --- Zusammenfassung ---
|
||||
|
||||
echo ""
|
||||
if [[ ${#missing_apt[@]} -eq 0 && ${#missing_other[@]} -eq 0 ]]; then
|
||||
echo "Alles vorhanden. Keine weiteren Schritte noetig."
|
||||
else
|
||||
echo "=== Fehlende Pakete installieren ==="
|
||||
echo "Folgende Befehle ausfuehren:"
|
||||
echo ""
|
||||
|
||||
if [[ ${#missing_apt[@]} -gt 0 ]]; then
|
||||
echo " sudo apt-get install -y ${missing_apt[*]}"
|
||||
fi
|
||||
|
||||
for cmd in "${missing_other[@]}"; do
|
||||
echo " $cmd"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Danach bootstrap.sh erneut ausfuehren zur Kontrolle."
|
||||
fi
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ Wenn ein benötigtes CLI-Tool fehlt: **nicht** mit Workarounds (curl, rohe API-C
|
||||
|
||||
## Gitea-Integration
|
||||
|
||||
Instanz: `https://gitea.troeger-net.org`. Bot-User `claude-code`, Token: `GITEA_TOKEN=$(secret-tool lookup user claude-code token gitea)`. Bot hat nur Collaborator-Rechte.
|
||||
Instanz: `https://gitea.troeger-net.org`. Bot-User `claude-code`, Token: `~/.config/gitea/token` (Datei mit `chmod 600`). Bot hat nur Collaborator-Rechte.
|
||||
|
||||
## MCP
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#!/bin/bash
|
||||
exec env GITEA_ACCESS_TOKEN="$(secret-tool lookup user claude-code token gitea)" \
|
||||
TOKEN_FILE="$HOME/.config/gitea/token"
|
||||
if [[ ! -f "$TOKEN_FILE" ]]; then
|
||||
echo "Gitea-Token nicht gefunden: $TOKEN_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
exec env GITEA_ACCESS_TOKEN="$(cat "$TOKEN_FILE")" \
|
||||
~/go/bin/gitea-mcp -host https://gitea.troeger-net.org
|
||||
|
||||
+32
-5
@@ -76,11 +76,20 @@ shellcheck <script>
|
||||
|
||||
Alle Befunde beheben. Falls nicht installiert: User informieren (`sudo apt install shellcheck`) und in `bootstrap.sh` aufnehmen.
|
||||
|
||||
### S3: Test-Empfehlungen
|
||||
### S3: Review-Checkliste
|
||||
|
||||
Auch bei kleinen Änderungen prüfen:
|
||||
|
||||
- Vertauschte oder irreführende Variablennamen
|
||||
- Unmögliche Shell-Operationen (z.B. `tar -rf` auf `.gz`)
|
||||
- Gleiche Daten mehrfach abfragen statt Variable wiederverwenden
|
||||
- Ausgaben die Erfolg suggerieren obwohl nichts passiert ist
|
||||
|
||||
### S4: Test-Empfehlungen
|
||||
|
||||
Gib dem User konkrete Kommandos zum Verifizieren der Änderung. Warte auf Rückmeldung.
|
||||
|
||||
### S4: Abschluss via /ship
|
||||
### S5: Abschluss via /ship
|
||||
|
||||
Rufe `/ship` auf (Commit → Push → PR → Merge → Cleanup).
|
||||
|
||||
@@ -105,9 +114,13 @@ Plan-Inhalt:
|
||||
- **CLI-Interface:** Positionsargumente und Flags (`--help`, `--dry-run` Pflicht bei destruktiven Aktionen, `--verbose`, ggf. `--yes`)
|
||||
- **Abhängigkeiten:** Externe CLI-Tools, werden am Script-Start per `command -v` geprüft
|
||||
- **Error-Handling:** Cleanup-Strategie (`trap`), definierte Exit-Codes (0 Erfolg, 1 Fehler, 2 Usage, weitere dokumentiert)
|
||||
- **Log-/Konsolenausgabe:** `log_info`/`log_warn`/`log_error`, Fehler nach `stderr`, TTY-Farben (`[[ -t 1 ]]`)
|
||||
- **Konsolenausgabe:** Eine Zeile pro Hauptschritt (` Schritt ... ok (Details)`). Keine Farben außer Gelb (Warnungen) und Rot (Fehler). Keine Querlinien, Tabellen oder Raw-Ausgabe. Ergebnis in die Hauptzeile, nicht als separater Block. "Erfolgreich" nur wenn tatsächlich etwas passiert ist — keine irreführenden Meldungen
|
||||
- **Output-Beispiel:** Exakte Zeile-für-Zeile-Ausgabe für den typischen Ablauf, so wie der User sie sehen soll
|
||||
- **Code-Skelett:** Hauptfunktion als Ablauf von Funktionsaufrufen, Hilfsfunktionen als Signatur mit Kommentar. Sonnet füllt die Funktionskörper
|
||||
- **Dry-Run:** Welche Aktionen werden durch Log-Ausgabe ersetzt
|
||||
- **User-Einbindung:** Rückfragen bei irreversiblen Operationen (`read -p`), `--yes` für nicht-interaktive Ausführung
|
||||
- **Explizite Verbote:** Bekannte Pitfalls, Redundanzen und Stilfehler benennen, die Sonnet vermeiden muss
|
||||
- **Randfälle:** Für jeden Hauptschritt: "Was kann hier schiefgehen oder sinnlos sein?"
|
||||
- **Test-Szenarien:** Konkrete Aufrufe für die spätere Verifikation
|
||||
|
||||
Speichere den Plan unter `<repo-root>/plans/script-<name>.md` (Verzeichnis bei Bedarf anlegen).
|
||||
@@ -139,7 +152,21 @@ shellcheck <script>
|
||||
|
||||
Alle Befunde beheben. Falls nicht installiert: User informieren (`sudo apt install shellcheck`) und in `bootstrap.sh` aufnehmen.
|
||||
|
||||
### V4: Test-Empfehlungen
|
||||
### V4: Review-Checkliste
|
||||
|
||||
Prüfe Sonnets Implementierung auf typische Fehler:
|
||||
|
||||
- Vertauschte oder irreführende Variablennamen
|
||||
- Unmögliche Shell-Operationen (z.B. `tar -rf` auf `.gz`)
|
||||
- Syntax die `bash -n` nicht findet aber zur Laufzeit crasht
|
||||
- Gleiche Daten mehrfach abfragen statt Variable wiederverwenden
|
||||
- Variablen die geschrieben aber nie gelesen werden
|
||||
- Funktionen die nur einmal aufgerufen werden und keinen Mehrwert bieten
|
||||
- Ausgaben die Erfolg suggerieren obwohl nichts passiert ist
|
||||
|
||||
Alle Befunde beheben, dann erneut `shellcheck` laufen lassen.
|
||||
|
||||
### V5: Test-Empfehlungen
|
||||
|
||||
```
|
||||
# Hilfe
|
||||
@@ -157,7 +184,7 @@ Alle Befunde beheben. Falls nicht installiert: User informieren (`sudo apt insta
|
||||
|
||||
Warte auf Rückmeldung des Users. Bei Problemen: Fehler beheben, Tests erneut empfehlen.
|
||||
|
||||
### V5: Abschluss via /ship
|
||||
### V6: Abschluss via /ship
|
||||
|
||||
Rufe `/ship` auf (Commit → Push → PR → Merge → Cleanup).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user