2026-05-30 17:19:52 +00:00
# Maintainer-Handbuch – rd13_copilot_setup
Dieses Dokument beschreibt Architektur, Designentscheidungen und wie das Projekt erweitert wird.
---
## Architektur: 3-Schichten-Modell
```
┌─────────────────────────────────────────────────────────┐
│ Layer 1: Immer aktiv (User settings.json) │
│ • Senior-Dev-Grundregeln in codeGeneration.instructions │
│ • Commit-Format, Review-Standard, Test-Standard │
│ • Copilot Feature-Flags │
├─────────────────────────────────────────────────────────┤
│ Layer 2: Auf Abruf (Prompt Files ~/.vscode-server/…) │
│ • /requirements /architecture /new-feature │
│ • /code-review /debug /refactor │
│ • /write-tests /done-check /docker │
├─────────────────────────────────────────────────────────┤
│ Layer 3: Repo-spezifisch (.github/copilot-instructions) │
│ • Stack, Konventionen, ADR-Entscheidungen │
│ • Definition of Done für dieses Projekt │
│ • NFRs (Performance, Availability, Security) │
└─────────────────────────────────────────────────────────┘
```
2026-06-13 05:49:02 +00:00
Für Repos mit einem Namen beginnend mit `rd13_` gilt als Grundannahme:
- Der Runner läuft in Docker.
- Alle Services werden über Caddy als Proxy bereitgestellt.
- Die zentrale Proxy-Infrastruktur liegt im Repo `rd13_system_proxy` .
2026-05-30 17:19:52 +00:00
---
## Dateistruktur
```
rd13_copilot_setup/
├── docs/
│ ├── USER.md ← Endnutzer-Dokumentation
│ ├── ADMIN.md ← Administrator-Dokumentation (Deploy, Hooks, PATH)
│ └── MAINTAINER.md ← Dieses Dokument
├── git-templates/ ← Template-Quellen für neue Repos
│ ├── .github/
│ │ └── copilot-instructions.md ← Wird pro Repo individualisiert (TODO-Felder)
│ ├── .vscode/
│ │ ├── settings.json ← Repo-spezifische VS Code Einstellungen
│ │ └── extensions.json ← Empfohlene Extensions für neue Repos
│ ├── hooks/
2026-06-03 06:07:57 +00:00
│ │ ├── pre-commit ← Agent Quality Gate (6 Checks)
│ │ └── post-merge ← Opt-in: copilot-update.sh nach git pull
2026-05-30 17:19:52 +00:00
│ ├── docs/
│ │ ├── USER.md ← Template Endnutzer-Doku
│ │ ├── ADMIN.md ← Template Admin-Doku
2026-06-03 06:07:57 +00:00
│ │ ├── MAINTAINER.md ← Template Maintainer-Doku
2026-06-10 12:06:35 +02:00
│ │ ├── requirements/
│ │ │ └── REQUIREMENTS.md ← Template für persistente Anforderungen
│ │ └── history/
│ │ └── summary/
│ │ └── PROJECT_CONTEXT.md ← Template Agent-Kontext-Summary
2026-05-30 17:19:52 +00:00
├── prompts/ ← Wiederverwendbare Copilot-Workflows
2026-06-03 06:07:57 +00:00
│ └── *.prompt.md ← /requirements /history /check-consistency ...
2026-05-30 17:19:52 +00:00
├── scripts/
│ ├── deploy.sh ← Bash-Deploy (macOS + Linux)
│ ├── deploy.fish ← Fish-Deploy (Linux)
2026-06-03 06:07:57 +00:00
│ ├── copilot-bootstrap.sh ← POSIX-sh Bootstrap für einzelne Repos
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
│ ├── copilot-bootstrap.fish ← Fish-Variante (voll funktionsgleich)
2026-06-03 06:07:57 +00:00
│ ├── copilot-update.sh ← Aktualisiert Templates + Hooks in Repos
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
│ ├── copilot-update.fish ← Fish-Variante
│ └── selftest.sh ← CI/lokaler Bootstrap-Dry-Run (sh+fish)
2026-05-30 17:19:52 +00:00
└── user-settings/
└── settings.json ← VS Code User-Level Settings (Layer 1)
```
---
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
## Wie `git init-copilot` funktioniert (Opt-in)
2026-05-30 17:19:52 +00:00
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
Git hat keinen `post-init` Hook – `.github/` und `.vscode/` befinden sich im Working Tree, nicht in `.git/` , weshalb `init.templateDir` allein nicht ausreicht. Statt den globalen `git init` zu überschreiben (invasiv – würde auch bei `git clone` fremder Repos greifen), gibt es einen **separaten Opt-in-Alias** `init-copilot` .
2026-05-30 17:19:52 +00:00
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
**Git-Alias mit Rekursionsschutz**
2026-05-30 17:19:52 +00:00
In `~/.gitconfig` (wird von deploy.sh/.fish gesetzt):
```ini
[alias]
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
init-copilot = !f() { dir=.; for a in "$@"; do case "$a" in -*) ;; *) dir="$a" ;; esac; done; "$(git --exec-path)/git-init" "$@" & & "$HOME/.local/bin/copilot-bootstrap.sh" "$dir"; }; f
2026-05-30 17:19:52 +00:00
```
- `!` → externer Shell-Befehl (via `/bin/sh` ), kein Git-Subcommand
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
- `$(git --exec-path)/git-init` → ruft das echte `git-init` -Binary direkt auf → **kein Rekursions-Loop**
- Letztes Nicht-Flag-Argument wird als Zielverzeichnis erkannt (`dir=.` als Default)
2026-05-30 17:19:52 +00:00
- Nach erfolgreichem `git init` wird `copilot-bootstrap.sh` ausgeführt
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
- Der Standard-`git init` bleibt unverändert; frühere invasive `alias.init` /`init.templateDir` werden von deploy.sh gezielt entfernt
2026-05-30 17:19:52 +00:00
---
## Neuen Prompt hinzufügen
1. Datei `prompts/mein-workflow.prompt.md` anlegen
2. Format:
```markdown
---
mode: agent
description: Kurzbeschreibung für den Chat-Slash-Command
---
# Mein Workflow
…
```
3. `deploy.sh` erneut ausführen → deployed die neue Datei in `~/.vscode-server/…/prompts/`
4. In `README.md` und `docs/USER.md` in der Prompt-Tabelle eintragen
5. Committen
## Template-Dateien ändern
Dateien unter `git-templates/` bearbeiten → `deploy.sh` ausführen → neue Repos bekommen die neue Version. Bestehende Repos werden **nicht** automatisch aktualisiert (Bootstrap überschreibt nicht).
**Wichtig beim Ändern von `git-templates/hooks/pre-commit` :** Die Datei muss nach dem Deployen ausführbar sein (`chmod +x` ). `deploy.sh` erledigt das automatisch.
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
## Shell-Skripte ändern
2026-05-30 17:19:52 +00:00
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
Alle Skripte gibt es paarweise (POSIX/bash + fish) und müssen synchron bleiben:
`deploy` , `copilot-bootstrap` , `copilot-update` . Die `.sh` -Variante ist jeweils die
Referenz, die `.fish` -Variante bildet dieselben Schritte in Fish-Syntax ab.
CI (`.github/workflows/ci.yml` ) prüft bei jedem Push/PR:
- `shellcheck` für alle `*.sh` + git-Hooks
- `fish -n` für alle `*.fish`
- `scripts/selftest.sh` (Bootstrap-Dry-Run sh+fish gegen isoliertes Fake-HOME)
Lokal vor dem Commit: `sh scripts/selftest.sh` ausführen.
2026-05-30 17:19:52 +00:00
---
## Designentscheidungen
| Entscheidung | Begründung |
|---|---|
| POSIX sh für Bootstrap-Script | Läuft auf jedem System ohne extra Dependencies (kein fish nötig) |
| Git-Alias statt Fish-Wrapper | Portabel: funktioniert in bash, sh, CI, GUI-Clients – nicht nur in fish |
| `git --exec-path` statt `command git` | `command` umgeht Aliases in fish/zsh, aber nicht in POSIX sh; `--exec-path` ist universell |
| Templates nicht auto-updaten | Idempotenz: Bootstrap überschreibt nie – Nutzer können Templates nach Init anpassen |
| 3 Zielgruppen-Docs (USER/ADMIN/MAINTAINER) | Klare Trennung: Nutzer ≠ Ops ≠ Dev; jede Gruppe findet ihren Kontext direkt |
| `data/` gitignored, Ordner-Struktur tracked | Persistente Daten gehören nie ins Git; Struktur als Konvention dokumentiert |
2026-06-10 12:06:35 +02:00
| `docs/history/prompts/` committed | Vollständige Agent-History bleibt im Repo erhalten; ermöglicht lückenlose Nachvollziehbarkeit |
2026-06-03 06:07:57 +00:00
| pre-commit Hook als Quality Gate (6 Checks) | Automatisches Netz: Tests, Doku, 3-Zielgruppen, PROJECT_CONTEXT, Requirements, Session-Datei; Opt-outs via `.copilot-no-tests` / `.copilot-no-docs` / `.copilot-no-requirements` |
| Check 6: Session-Datei muss in jedem Commit gestaged sein | Jeder Commit ist mit Agent-Session verknüpft; kein Opt-out; erzwingt `/history` vor `git commit` |
2026-06-03 09:59:18 +00:00
| Check 6 prüft Datum + `### Prompt` -Inhalt | Verhindert reine Nachtrag-Blöcke ohne echte Prompt-Einträge; Session-Datei muss heutiges Datum im Namen tragen |
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
| Kein globales `init.templateDir` , Opt-in `git init-copilot` | Standard-`git init` /`git clone` bleiben unberührt; Quality Gate landet nur in bewusst gewählten Repos |
| Remote-Quelle konfigurierbar (env/Config) + Offline-Modus | Keine hartkodierte Infrastruktur; `git copilot-update` läuft auch ohne Netz und endet graceful (exit 0) |
| `detect_vscode_user_dir` in jedem Skript dupliziert | Skripte laufen standalone aus `~/.local/bin` → keine gemeinsame Lib sourcebar; bewusst kopiert statt geteilt |
2026-06-18 10:05:46 +02:00
| Default-Shell-Feld in der Projekt-Sektion (nach `---` ) | Bootstrap erkennt `$SHELL` und schreibt es nach `.github/copilot-instructions.md` ; liegt bewusst **nach** dem `---` , damit `copilot-update` die Framework-Sektion neu schreiben kann, ohne den repo-/maschinenspezifischen Shell-Wert zu überschreiben |
2026-06-03 09:59:18 +00:00
## Bekannte Fallstricke
| Problem | Ursache | Fix |
|---|---|---|
| `Syntax error: word unexpected` in `copilot-update.sh` Zeile ~60 | Box-Drawing-Zeichen (`────` ) direkt ans `fi` angehängt statt auf eigener Zeile | `fi` allein auf Zeile, Kommentar-Linie separat (`# ──` ) |
| Self-Update überschreibt manuell deployten Fix | Self-Update holt Version aus Remote-Cache, der noch kaputten Stand hat | Erst committen + pushen, dann manuell deployen: `cp scripts/copilot-update.sh ~/.local/bin/` |
2026-06-04 09:20:05 +00:00
| Leerzeile vor `---` in `copilot-instructions.md` wird entfernt | `$(awk ...)` strippt trailing newlines; `printf '%s\n%s\n'` setzt Blöcke direkt zusammen | `printf '%s\n\n%s\n'` verwenden |
docs(wp12): document portability model (env/config, init-copilot, offline)
README + USER + ADMIN + MAINTAINER aktualisiert: nicht-invasives Deploy (kein globales init.templateDir / git-init-Override), Opt-in-Alias 'git init-copilot', konfigurierbare Remote-Quelle (COPILOT_SETUP_REMOTE_SSH/_HTTP, Config-Datei ~/.config/copilot-setup/config) inkl. Offline-Modus und graceful skip, deploy --with-self-update-hook, neue VS-Code-Editionen in der Pfad-Erkennung. Tote IP 192.168.178.6 aus der Doku entfernt. MAINTAINER: CI/selftest dokumentiert, Skript-Paare synchron halten, neue Fallstricke ($USER/set -u, fish-Funktions-Scoping).
2026-06-10 10:54:25 +02:00
| `$USER` unbound unter `set -u` | `deploy.sh` nutzt `set -euo pipefail` ; `$USER` fehlt in minimalen Envs (`env -i` , CI) | In `detect_vscode_user_dir` `${USER:-}` statt `$USER` |
| fish: Funktion ändert Skript-Variable nicht | fish-Funktionen sehen Caller-Locals nicht | `set -g` für Zähler/Flags die eine Funktion schreibt (z. B. `_append_gitignore` ) |
2026-06-18 10:05:46 +02:00
| Anpassbares Feld wird von `copilot-update` überschrieben | Inhalt stand **vor** dem ersten `---` (Framework-Sektion wird immer aus Template neu geschrieben) | Repo-/maschinenspezifische, anpassbare Felder immer **nach** `---` platzieren (Projekt-Sektion bleibt erhalten) – siehe Default-Shell-Feld |