rd13_copilot_setup/docs/MAINTAINER.md
Conrad Schulz 5d0194a7b8
Some checks are pending
CI / Lint & self-test (push) Waiting to run
feat(bootstrap): auto-detect dev shell into copilot-instructions
Neues Default-Shell-Feld in der Projekt-Sektion (nach ---), damit der Agent die richtige Shell-Syntax waehlt. Bootstrap erkennt $SHELL (Fallback fish, Whitelist gegen sed-Injection) und schreibt es in frisch erzeugte copilot-instructions.md; manuell aenderbar und ueberlebt copilot-update. selftest +3 Faelle (sh & fish), beide MAINTAINER.md dokumentiert.
2026-06-18 10:05:46 +02:00

10 KiB
Raw Blame History

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)            │
└─────────────────────────────────────────────────────────┘

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.

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/
│   │   ├── pre-commit              ← Agent Quality Gate (6 Checks)
│   │   └── post-merge              ← Opt-in: copilot-update.sh nach git pull
│   ├── docs/
│   │   ├── USER.md                 ← Template Endnutzer-Doku
│   │   ├── ADMIN.md                ← Template Admin-Doku
│   │   ├── MAINTAINER.md           ← Template Maintainer-Doku
│   │   ├── requirements/
│   │   │   └── REQUIREMENTS.md     ← Template für persistente Anforderungen
│   │   └── history/
│   │       └── summary/
│   │           └── PROJECT_CONTEXT.md  ← Template Agent-Kontext-Summary
├── prompts/                        ← Wiederverwendbare Copilot-Workflows
│   └── *.prompt.md                 ← /requirements /history /check-consistency ...
├── scripts/
│   ├── deploy.sh                   ← Bash-Deploy (macOS + Linux)
│   ├── deploy.fish                 ← Fish-Deploy (Linux)
│   ├── copilot-bootstrap.sh        ← POSIX-sh Bootstrap für einzelne Repos
│   ├── copilot-bootstrap.fish      ← Fish-Variante (voll funktionsgleich)
│   ├── copilot-update.sh           ← Aktualisiert Templates + Hooks in Repos
│   ├── copilot-update.fish         ← Fish-Variante
│   └── selftest.sh                 ← CI/lokaler Bootstrap-Dry-Run (sh+fish)
└── user-settings/
    └── settings.json               ← VS Code User-Level Settings (Layer 1)

Wie git init-copilot funktioniert (Opt-in)

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.

Git-Alias mit Rekursionsschutz

In ~/.gitconfig (wird von deploy.sh/.fish gesetzt):

[alias]
    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
  • ! → externer Shell-Befehl (via /bin/sh), kein Git-Subcommand
  • $(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)
  • Nach erfolgreichem git init wird copilot-bootstrap.sh ausgeführt
  • Der Standard-git init bleibt unverändert; frühere invasive alias.init/init.templateDir werden von deploy.sh gezielt entfernt

Neuen Prompt hinzufügen

  1. Datei prompts/mein-workflow.prompt.md anlegen
  2. Format:
    ---
    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.

Shell-Skripte ändern

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.


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
docs/history/prompts/ committed Vollständige Agent-History bleibt im Repo erhalten; ermöglicht lückenlose Nachvollziehbarkeit
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
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
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
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

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/
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
$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)
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