Compare commits

...

8 commits

Author SHA1 Message Date
Conrad Schulz
5dc89f01a7 docs(history): migrate this repo to docs/history + log session
Some checks failed
CI / Lint & self-test (push) Has been cancelled
Dogfood des neuen Standards: git mv history/ -> docs/history/ (7 Dateien, Rename-Detection erhalten). Session-Log um Prompt 7 (History-Umzug) ergaenzt und PROJECT_CONTEXT am neuen Ort aktualisiert (Pfade, neue Eintraege, Architekturentscheidungen).
2026-06-10 12:14:52 +02:00
Conrad Schulz
2b20a985a5 refactor(history): move agent history under docs/history + auto-migration
Konvention geaendert: history/ -> docs/history/ (prompts + summary/PROJECT_CONTEXT.md).
Harter Cutover im pre-commit Hook (Check 4 + Check 6 erwarten docs/history/).
Bestehende Repos werden beim naechsten 'git copilot-update' automatisch per git mv migriert (Fallback mv; bei Konflikt Warnung statt Abbruch).
Angepasst: pre-commit Hook, alle 6 Skripte + selftest, beide copilot-instructions.md, settings.json Session-Protokoll, history.prompt.md, README, USER/ADMIN/MAINTAINER (+ ADMIN Migrationsabschnitt). git-templates/history -> git-templates/docs/history (git mv). Validiert: shellcheck clean, fish -n clean, selftest PASS, Migrationstest PASS (sh+fish+both-present).
2026-06-10 12:06:35 +02:00
Conrad Schulz
be5ff0fda3 docs(history): session 2026-06-10 portability + update PROJECT_CONTEXT
Vollstaendiges Session-Log (WP1-7,11,12) und aktualisierter PROJECT_CONTEXT: neue erledigte Aufgaben, offene Punkte (WP8/9/10 zurueckgestellt, totes Repo-Remote), Designentscheidungen und Pfade.
2026-06-10 10:59:45 +02:00
Conrad Schulz
afd5b38ca9 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
Conrad Schulz
deca872ab2 ci(wp11): shellcheck + fish -n + bootstrap self-test
Neuer GitHub-Actions-Workflow .github/workflows/ci.yml: shellcheck fuer alle POSIX/bash-Skripte und git-Hooks, 'fish -n' fuer alle fish-Skripte, sowie scripts/selftest.sh (Bootstrap-Dry-Run sh+fish gegen isoliertes Fake-HOME mit Assertions). copilot-bootstrap.sh propagiert jetzt ebenfalls *:Zone.Identifier (Paritaet zur fish-Variante). shellcheck-Direktiven fuer bewusste Muster (SC2016 literaler Alias, SC1090 dynamische Config, SC2043 erweiterbare Hook-Schleife). Lokal verifiziert: shellcheck exit 0, selftest beide Varianten PASS.
2026-06-10 10:48:27 +02:00
Conrad Schulz
9e14a5fe90 feat(deploy): non-invasive git config + opt-in init-copilot + portable detection
WP6: Globaler 'git init'-Override und init.templateDir werden nicht mehr gesetzt (griff auch bei git clone fremder Repos). Stattdessen Opt-in-Alias 'git init-copilot'. Frueher gesetzte invasive Werte werden gezielt entfernt (nur wenn sie auf unsere Templates/Bootstrap zeigen). WP7: post-merge Auto-Deploy im Setup-Repo nur noch mit --with-self-update-hook. WP4: detect_vscode_user_dir (Server/Insiders/VSCodium/Cursor/Flatpak/macOS/Windows-WSL), identisch in deploy + copilot-update; ${USER:-} gegen set -u abgesichert. Getestet isoliert: kein alias.init, init-copilot gesetzt, kein init.templateDir, Hook nur mit Flag, unbekanntes Arg -> exit 2.
2026-06-10 10:26:55 +02:00
Conrad Schulz
5890bff4e0 feat(update): configurable remote + offline mode + portable editor detection
WP3: Remote-URLs nicht mehr hartkodiert (192.168.178.6). Aufloesung COPILOT_SETUP_REMOTE_SSH/_HTTP via env, sonst Config-Datei $XDG_CONFIG_HOME/copilot-setup/config (sh sourcet, fish parst), env hat Vorrang. WP5: Offline-Betrieb (lokaler Klon ohne .git nutzbar; Pull-Fehler nutzt Cache); fehlende/unerreichbare Quelle endet graceful mit exit 0 statt exit 1. WP4: detect_vscode_user_dir deckt Server/Insiders/VSCodium/Cursor/Flatpak/macOS/Windows-WSL ab. sh+fish verhalten sich identisch (getestet: graceful skip, offline-local, config-remote).
2026-06-10 09:54:07 +02:00
Conrad Schulz
80b6248fe3 fix(bootstrap): $HOME in fish + parity with sh; ignore Windows ADS
copilot-bootstrap.fish hatte /home/rd13server/.git-templates hartkodiert und legte nur .github/.vscode an. Jetzt $HOME und volle Funktions-Paritaet zu copilot-bootstrap.sh (--with-update-hook, data/, history/, docs/ USER+ADMIN+MAINTAINER, pre-commit/post-commit Hooks, .gitignore-Append). Zusaetzlich *:Zone.Identifier (Windows NTFS ADS) in .gitignore aufgenommen und vom Bootstrap in Ziel-Repos propagiert.
2026-06-10 09:38:29 +02:00
27 changed files with 1057 additions and 236 deletions

View file

@ -5,11 +5,11 @@
> Diese Sektion hat höchste Priorität und darf nicht ignoriert werden. > Diese Sektion hat höchste Priorität und darf nicht ignoriert werden.
**Session START** Bevor du irgendetwas tust: **Session START** Bevor du irgendetwas tust:
1. Lies `history/summary/PROJECT_CONTEXT.md` (falls vorhanden) 1. Lies `docs/history/summary/PROJECT_CONTEXT.md` (falls vorhanden)
2. Verstehe den aktuellen Projektzustand bevor du anfängst 2. Verstehe den aktuellen Projektzustand bevor du anfängst
**Session END** Der Agent führt dies **automatisch** am Ende jeder Aufgabe aus, bevor er `git commit` ausführt: **Session END** Der Agent führt dies **automatisch** am Ende jeder Aufgabe aus, bevor er `git commit` ausführt:
1. Lies die bestehende `history/prompts/YYYY-MM-DD_*_session.md` (falls vorhanden) und ergänze nur den neuen Teil 1. Lies die bestehende `docs/history/prompts/YYYY-MM-DD_*_session.md` (falls vorhanden) und ergänze nur den neuen Teil
**Dateiformat zwingend:** Suffix `_session.md`, Dateiname beginnt mit heutigem Datum (`YYYY-MM-DD`) **Dateiformat zwingend:** Suffix `_session.md`, Dateiname beginnt mit heutigem Datum (`YYYY-MM-DD`)
2. **Für jeden Benutzer-Prompt seit dem letzten Commit** einen Block ergänzen: 2. **Für jeden Benutzer-Prompt seit dem letzten Commit** einen Block ergänzen:
``` ```
@ -21,9 +21,9 @@
``` ```
⚠ Kein „Nachtrag"-Block statt echter Prompt-Einträge. Die Benutzer-Nachricht **wörtlich** zitieren. ⚠ Kein „Nachtrag"-Block statt echter Prompt-Einträge. Die Benutzer-Nachricht **wörtlich** zitieren.
⚠ Keine reinen Stichpunkt-Zusammenfassungen. Ausgeführte Kommandos und Outputs gehören **wörtlich** in die Antwort. ⚠ Keine reinen Stichpunkt-Zusammenfassungen. Ausgeführte Kommandos und Outputs gehören **wörtlich** in die Antwort.
⚠ Keine Platzhalter wie `PENDING` committen. Ist der Commit-Hash noch unbekannt: Hash weglassen oder Datei direkt nach dem Commit mit dem echten Hash aktualisieren und sofort (`git add history/ && git commit`) nachziehen. ⚠ Keine Platzhalter wie `PENDING` committen. Ist der Commit-Hash noch unbekannt: Hash weglassen oder Datei direkt nach dem Commit mit dem echten Hash aktualisieren und sofort (`git add docs/history/ && git commit`) nachziehen.
3. Aktualisiere `history/summary/PROJECT_CONTEXT.md` mit dem neuen Projektstand 3. Aktualisiere `docs/history/summary/PROJECT_CONTEXT.md` mit dem neuen Projektstand
4. **Stage beide Dateien VOR `git commit`:** `git add history/` 4. **Stage beide Dateien VOR `git commit`:** `git add docs/history/`
Der pre-commit Hook (Check 6) blockiert wenn: Der pre-commit Hook (Check 6) blockiert wenn:
- keine `*_session.md` gestaged ist - keine `*_session.md` gestaged ist
- der Dateiname nicht mit dem heutigen Datum beginnt - der Dateiname nicht mit dem heutigen Datum beginnt
@ -91,10 +91,10 @@
- Copilot Chat: `/requirements` → Requirements-Workshop starten oder bestehende Requirements aktualisieren - Copilot Chat: `/requirements` → Requirements-Workshop starten oder bestehende Requirements aktualisieren
- Copilot Chat: `/check-consistency` → Konsistenz zwischen Code, Docs und Requirements prüfen - Copilot Chat: `/check-consistency` → Konsistenz zwischen Code, Docs und Requirements prüfen
### Agent History (`/history/`) ### Agent History (`/docs/history/`)
- **Vollständige Konversationen**`history/prompts/YYYY-MM-DD_beschreibung_session.md` (**Suffix `_session.md` zwingend** Check 6 im pre-commit Hook erkennt daran das Agent-Log) - **Vollständige Konversationen**`docs/history/prompts/YYYY-MM-DD_beschreibung_session.md` (**Suffix `_session.md` zwingend** Check 6 im pre-commit Hook erkennt daran das Agent-Log)
- **Komprimierter Kontext**`history/summary/PROJECT_CONTEXT.md` (**committed, immer aktuell halten!**) - **Komprimierter Kontext**`docs/history/summary/PROJECT_CONTEXT.md` (**committed, immer aktuell halten!**)
- **Beim Start einer neuen Session:** `history/summary/PROJECT_CONTEXT.md` zuerst lesen - **Beim Start einer neuen Session:** `docs/history/summary/PROJECT_CONTEXT.md` zuerst lesen
- **Am Ende jeder Session:** beide Dateien committen - **Am Ende jeder Session:** beide Dateien committen
- Copilot Chat: `/history` → History loggen + Summary aktualisieren - Copilot Chat: `/history` → History loggen + Summary aktualisieren
@ -144,7 +144,7 @@ A task is only done when ALL of the following are true:
- [ ] Relevant documentation updated: `docs/USER.md` and/or `docs/ADMIN.md` and/or `docs/MAINTAINER.md` - [ ] Relevant documentation updated: `docs/USER.md` and/or `docs/ADMIN.md` and/or `docs/MAINTAINER.md`
- [ ] Alle 3 Zielgruppen-Dokumente vorhanden (`docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`) - [ ] Alle 3 Zielgruppen-Dokumente vorhanden (`docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`)
- [ ] Persistente Daten liegen ausschließlich in `/data/<service>/` (nie woanders) - [ ] Persistente Daten liegen ausschließlich in `/data/<service>/` (nie woanders)
- [ ] `history/summary/PROJECT_CONTEXT.md` aktualisiert - [ ] `docs/history/summary/PROJECT_CONTEXT.md` aktualisiert
- [ ] Commit message follows Conventional Commits - [ ] Commit message follows Conventional Commits
- [ ] No dead code, no TODOs left behind (or tracked as issues) - [ ] No dead code, no TODOs left behind (or tracked as issues)
- [ ] pre-commit Quality Gate bestanden - [ ] pre-commit Quality Gate bestanden

39
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: CI
on:
push:
branches: [master, main]
pull_request:
permissions:
contents: read
jobs:
shell:
name: Lint & self-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ShellCheck (POSIX/bash scripts + git hooks)
run: |
shellcheck --version
shellcheck scripts/*.sh \
git-templates/hooks/pre-commit \
git-templates/hooks/post-merge \
git-templates/hooks/post-commit
- name: Install fish
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq fish
- name: Fish syntax check
run: |
for f in scripts/*.fish; do
echo "fish -n $f"
fish -n "$f"
done
- name: Self-test (bootstrap dry-run, sh + fish)
run: sh scripts/selftest.sh

3
.gitignore vendored
View file

@ -1,6 +1,9 @@
.env .env
*.local *.local
# Windows Mark-of-the-Web / NTFS ADS cruft (entsteht beim Download/Entpacken auf NTFS)
*:Zone.Identifier
# Persistente Service-Daten (nie committen!) # Persistente Service-Daten (nie committen!)
data/**/* data/**/*

View file

@ -8,7 +8,7 @@ Dieses Repo enthält alle Konfigurationsdateien die nötig sind um GitHub Copilo
- **User-Level Settings** Copilot-Flags und Senior-Dev-Grundverhalten (per Settings Sync auf alle Geräte) - **User-Level Settings** Copilot-Flags und Senior-Dev-Grundverhalten (per Settings Sync auf alle Geräte)
- **Prompt Files** 10 wiederverwendbare Agent-Workflows (`/requirements`, `/new-feature`, `/architecture`, etc.) - **Prompt Files** 10 wiederverwendbare Agent-Workflows (`/requirements`, `/new-feature`, `/architecture`, etc.)
- **Git-Templates** automatisch in jedes neue Repo kopiert via `git init` (per Git-Alias) - **Git-Templates** per Opt-in in ein Repo kopiert (`git init-copilot` oder `copilot-bootstrap.sh`)
- **Bootstrap-Skript** bestehende und geclonte Repos in Sekunden ausstatten (POSIX sh, läuft überall) - **Bootstrap-Skript** bestehende und geclonte Repos in Sekunden ausstatten (POSIX sh, läuft überall)
- **Update-Mechanismus** Templates und Prompts in allen Repos mit einem Befehl aktuell halten: `git copilot-update` - **Update-Mechanismus** Templates und Prompts in allen Repos mit einem Befehl aktuell halten: `git copilot-update`
@ -24,19 +24,39 @@ git copilot-update
``` ```
Was das macht: Was das macht:
1. **Setup-Repo pullen** `~/.copilot-setup/` (SSH, HTTP-Fallback zu `http://192.168.178.6:8083/cschulz/rd13_copilot_setup`) 1. **Setup-Quelle holen** aus konfiguriertem Remote oder lokalem Klon (`COPILOT_SETUP_DIR`); offline nutzbar
2. **Globale Templates updaten** `~/.git-templates/` + VS Code Prompt-Dateien 2. **Globale Templates updaten** `~/.git-templates/` + VS Code Prompt-Dateien
3. **Repo-lokale Hooks updaten** `.git/hooks/pre-commit` 3. **Repo-lokale Hooks updaten** `.git/hooks/pre-commit`
4. **`copilot-instructions.md`** nur überschreiben wenn noch TODO-Platzhalter enthalten (Backup `.bak` wird angelegt) 4. **`copilot-instructions.md`** nur überschreiben wenn noch TODO-Platzhalter enthalten (Backup `.bak` wird angelegt)
Die Remote-Quelle ist **nicht** fest verdrahtet. Konfiguration (Vorrang: Env > Config-Datei):
| Variable | Zweck |
|---|---|
| `COPILOT_SETUP_REMOTE_SSH` | SSH-URL des Setup-Repos |
| `COPILOT_SETUP_REMOTE_HTTP` | HTTP-URL (Fallback) |
| `COPILOT_SETUP_DIR` | Lokaler Klon/Arbeitskopie (Offline-Betrieb) |
| `COPILOT_SETUP_CONFIG` | Alternativer Pfad zur Config-Datei |
Config-Datei (sh-Syntax) unter `~/.config/copilot-setup/config`:
```sh
COPILOT_SETUP_REMOTE_SSH="ssh://git@host:22/you/rd13_copilot_setup.git"
COPILOT_SETUP_REMOTE_HTTP="https://host/you/rd13_copilot_setup.git"
```
Ist keine Quelle erreichbar, endet `git copilot-update` **ohne Fehler** (graceful skip)
es gibt dann nichts zu aktualisieren.
> **Empfehlung:** In jedem Repo nach einem `git pull` auf dem Setup-Repo ausführen, > **Empfehlung:** In jedem Repo nach einem `git pull` auf dem Setup-Repo ausführen,
> oder wenn ein neues Feature-Prompt oder eine Hook-Verbesserung verfügbar ist. > oder wenn ein neues Feature-Prompt oder eine Hook-Verbesserung verfügbar ist.
### Auto-Update für das Setup-Repo selbst ### Opt-in: Auto-Deploy für das Setup-Repo selbst
Nach `deploy.sh` ist im Setup-Repo selbst ein `post-merge` Hook aktiv: Standardmäßig setzt `deploy.sh` **keine** automatischen Hooks. Wer will, dass nach jedem
`git pull` im Setup-Repo automatisch neu deployt wird:
```bash ```bash
git pull # im Setup-Repo → deploy.sh läuft automatisch → alle Templates sofort aktuell bash scripts/deploy.sh --with-self-update-hook # installiert post-merge Auto-Deploy
``` ```
### Opt-in: Auto-Update in anderen Repos nach git pull ### Opt-in: Auto-Update in anderen Repos nach git pull
@ -62,7 +82,13 @@ bash scripts/deploy.sh # macOS (bash)
fish scripts/deploy.fish # Linux mit fish fish scripts/deploy.fish # Linux mit fish
``` ```
Das Skript legt alles an den richtigen Orten ab. Das Skript legt alles an den richtigen Orten ab. Es ist **nicht-invasiv**: es überschreibt
weder den globalen `git init` noch setzt es `init.templateDir` (fremde `git init`/`git clone`
bleiben unberührt). Für Auto-Bootstrap eines neuen Repos gibt es den Opt-in-Alias:
```bash
git init-copilot mein-neues-repo # = git init + copilot-bootstrap
```
### Bestehende oder geclonte Repos ausstatten ### Bestehende oder geclonte Repos ausstatten
@ -99,7 +125,7 @@ rd13_copilot_setup/
│ ├── done-check.prompt.md /done-check Definition of Done Checkliste │ ├── done-check.prompt.md /done-check Definition of Done Checkliste
│ ├── docker.prompt.md /docker Docker/Compose-Aufgaben │ ├── docker.prompt.md /docker Docker/Compose-Aufgaben
│ └── history.prompt.md /history Agent-History loggen + Kontext aktualisieren │ └── history.prompt.md /history Agent-History loggen + Kontext aktualisieren
├── git-templates/ ← Wird via git config --global init.templateDir gesetzt ├── git-templates/ ← Quelle für ~/.git-templates (kein globales init.templateDir)
│ ├── .github/ │ ├── .github/
│ │ └── copilot-instructions.md ← Template mit TODO-Feldern + Konventionen │ │ └── copilot-instructions.md ← Template mit TODO-Feldern + Konventionen
│ ├── .vscode/ │ ├── .vscode/
@ -111,10 +137,10 @@ rd13_copilot_setup/
│ ├── docs/ │ ├── docs/
│ │ ├── USER.md ← Template: Endnutzer-Dokumentation │ │ ├── USER.md ← Template: Endnutzer-Dokumentation
│ │ ├── ADMIN.md ← Template: Administrator-Dokumentation │ │ ├── ADMIN.md ← Template: Administrator-Dokumentation
│ │ ── MAINTAINER.md ← Template: Entwickler-Dokumentation │ │ ── MAINTAINER.md ← Template: Entwickler-Dokumentation
│ └── history/ │ └── history/
│ └── summary/ │ └── summary/
│ └── PROJECT_CONTEXT.md ← Template: Agent-Kontext-Summary │ └── PROJECT_CONTEXT.md ← Template: Agent-Kontext-Summary
├── docs/ ├── docs/
│ ├── USER.md ← Benutzerhandbuch (Einrichtung + Nutzung) │ ├── USER.md ← Benutzerhandbuch (Einrichtung + Nutzung)
│ ├── ADMIN.md ← Administrator-Handbuch (Deploy, Hooks, PATH) │ ├── ADMIN.md ← Administrator-Handbuch (Deploy, Hooks, PATH)
@ -159,7 +185,7 @@ rd13_copilot_setup/
## Was jedes Repo automatisch bekommt ## Was jedes Repo automatisch bekommt
Nach `git init` (via Alias) oder `copilot-bootstrap.sh`: Nach `git init-copilot` oder `copilot-bootstrap.sh`:
| Was | Wo | | Was | Wo |
|---|---| |---|---|
@ -167,8 +193,8 @@ Nach `git init` (via Alias) oder `copilot-bootstrap.sh`:
| VS Code-Einstellungen | `.vscode/` | | VS Code-Einstellungen | `.vscode/` |
| **pre-commit Quality Gate** | `.git/hooks/pre-commit` | | **pre-commit Quality Gate** | `.git/hooks/pre-commit` |
| **Persistente Daten (gitignored)** | `data/` | | **Persistente Daten (gitignored)** | `data/` |
| **Agent-Konversationen (committed)** | `history/prompts/` | | **Agent-Konversationen (committed)** | `docs/history/prompts/` |
| **Agent-Kontext-Summary (committed)** | `history/summary/PROJECT_CONTEXT.md` | | **Agent-Kontext-Summary (committed)** | `docs/history/summary/PROJECT_CONTEXT.md` |
| **Endnutzer-Dokumentation** | `docs/USER.md` | | **Endnutzer-Dokumentation** | `docs/USER.md` |
| **Administrator-Dokumentation** | `docs/ADMIN.md` | | **Administrator-Dokumentation** | `docs/ADMIN.md` |
| **Entwickler-Dokumentation** | `docs/MAINTAINER.md` | | **Entwickler-Dokumentation** | `docs/MAINTAINER.md` |
@ -194,9 +220,10 @@ Nach `git init` (via Alias) oder `copilot-bootstrap.sh`:
## Neues Repo einrichten Checkliste ## Neues Repo einrichten Checkliste
Nach `git init` (mit eingerichtetem Alias) passiert alles **automatisch**. Mit dem Opt-in-Alias `git init-copilot <pfad>` passiert alles **automatisch**
(= `git init` + `copilot-bootstrap.sh`). Der Standard-`git init` bleibt unberührt.
Nach `git clone` oder ohne Alias: Nach `git clone` oder für ein bestehendes Repo:
```bash ```bash
# Option A: Bootstrap-Skript (empfohlen) # Option A: Bootstrap-Skript (empfohlen)

View file

@ -30,19 +30,27 @@ fish scripts/deploy.fish # fish (Linux)
| Schritt | Was | Ziel | | Schritt | Was | Ziel |
|---|---|---| |---|---|---|
| 1 | VS Code User-dir ermitteln | plattformspezifisch (Server / lokal / macOS) | | 1 | VS Code User-dir ermitteln | Server / Insiders / VSCodium / Cursor / Flatpak / macOS / Windows-WSL |
| 2 | `settings.json` deployen | `~/.vscode-server/data/User/` (oder Äquivalent) | | 2 | `settings.json` deployen | `~/.vscode-server/data/User/` (oder Äquivalent) |
| 3 | Prompt Files deployen | `~/.vscode-server/data/User/prompts/` | | 3 | Prompt Files deployen | `~/.vscode-server/data/User/prompts/` |
| 4 | Git-Templates deployen | `~/.git-templates/` inkl. Hooks, Docs, History-Template | | 4 | Git-Templates deployen | `~/.git-templates/` inkl. Hooks, Docs, History-Template |
| 5 | Bootstrap-Skript installieren | `~/.local/bin/copilot-bootstrap.sh` | | 5 | Bootstrap- + Update-Skripte installieren | `~/.local/bin/` |
| 6 | Git-Alias setzen | `~/.gitconfig``git init` ruft Bootstrap automatisch auf | | 6 | Git-Aliase setzen | `~/.gitconfig``git init-copilot` (opt-in) + `git copilot-update` |
> **Nicht-invasiv:** `deploy.sh` setzt **kein** globales `init.templateDir` und überschreibt
> **nicht** den Standard-`git init`. Fremde `git init`/`git clone` bleiben unberührt.
> Auto-Bootstrap nur über den expliziten Alias `git init-copilot <pfad>`.
> Optional installiert `bash scripts/deploy.sh --with-self-update-hook` den
> post-merge Auto-Deploy für das Setup-Repo selbst.
--- ---
## Git-Templates verwalten ## Git-Templates verwalten
Die Templates unter `git-templates/` werden beim Deployen nach `~/.git-templates/` kopiert. Die Templates unter `git-templates/` werden beim Deployen nach `~/.git-templates/` kopiert.
Sie werden bei **jedem** `git init` automatisch in neue Repos kopiert (via `init.templateDir`). Von dort nutzen sie `copilot-bootstrap.sh` und `git copilot-update`. Sie werden **nicht**
automatisch bei jedem `git init` kopiert (kein globales `init.templateDir` mehr) das
geschieht nur per Opt-in: `git init-copilot <pfad>` oder `copilot-bootstrap.sh <pfad>`.
**Struktur nach Deploy:** **Struktur nach Deploy:**
``` ```
@ -85,7 +93,7 @@ chmod -x .git/hooks/pre-commit
| 1 | Tests gestaged bei Code-Änderungen | `.copilot-no-tests` | | 1 | Tests gestaged bei Code-Änderungen | `.copilot-no-tests` |
| 2 | Mindestens eine Zielgruppen-Doku aktualisiert | `.copilot-no-docs` | | 2 | Mindestens eine Zielgruppen-Doku aktualisiert | `.copilot-no-docs` |
| 3 | Alle 3 Zielgruppen-Docs vorhanden (USER/ADMIN/MAINTAINER) | | | 3 | Alle 3 Zielgruppen-Docs vorhanden (USER/ADMIN/MAINTAINER) | |
| 4 | `history/summary/PROJECT_CONTEXT.md` aktualisiert | | | 4 | `docs/history/summary/PROJECT_CONTEXT.md` aktualisiert | |
| 5 | `docs/requirements/REQUIREMENTS.md` keine unstaged Änderungen | `.copilot-no-requirements` | | 5 | `docs/requirements/REQUIREMENTS.md` keine unstaged Änderungen | `.copilot-no-requirements` |
| 6 | Eine `*_session.md` ist in diesem Commit gestaged | (kein Opt-out) | | 6 | Eine `*_session.md` ist in diesem Commit gestaged | (kein Opt-out) |
@ -117,7 +125,7 @@ git copilot-update
| Schritt | Was | Besonderheit | | Schritt | Was | Besonderheit |
|---|---|---| |---|---|---|
| 0 | Setup-Repo Cache aktualisieren (`~/.copilot-setup/`) | SSH, HTTP-Fallback | | 0 | Setup-Quelle holen (`~/.copilot-setup/` oder `COPILOT_SETUP_DIR`) | Remote o. lokaler Klon; offline = graceful skip |
| 1b | **Script selbst aktualisieren** (`~/.local/bin/copilot-update.sh`) | startet neue Version via `exec` | | 1b | **Script selbst aktualisieren** (`~/.local/bin/copilot-update.sh`) | startet neue Version via `exec` |
| 2 | `~/.git-templates/` aktualisieren | Hooks, Docs, History-Template | | 2 | `~/.git-templates/` aktualisieren | Hooks, Docs, History-Template |
| 3 | VS Code Prompt-Dateien aktualisieren | `~/.vscode-server/.../prompts/` | | 3 | VS Code Prompt-Dateien aktualisieren | `~/.vscode-server/.../prompts/` |
@ -131,6 +139,34 @@ git copilot-update
--- ---
## Setup-Quelle konfigurieren (Remote / Offline)
`git copilot-update` braucht eine Quelle. Reihenfolge: **Umgebungsvariable > Config-Datei**.
Ist nichts erreichbar, endet der Befehl **ohne Fehler** (graceful skip) dann gibt es
schlicht nichts zu aktualisieren.
| Variable | Zweck |
|---|---|
| `COPILOT_SETUP_REMOTE_SSH` | SSH-URL des Setup-Repos |
| `COPILOT_SETUP_REMOTE_HTTP` | HTTP-URL (Fallback) |
| `COPILOT_SETUP_DIR` | Lokaler Klon/Arbeitskopie Offline-Betrieb ohne Netz |
| `COPILOT_SETUP_CONFIG` | Alternativer Pfad zur Config-Datei |
Config-Datei (sh-Syntax) unter `~/.config/copilot-setup/config`
(bzw. `$XDG_CONFIG_HOME/copilot-setup/config`):
```sh
COPILOT_SETUP_REMOTE_SSH="ssh://git@dein-host:22/you/rd13_copilot_setup.git"
COPILOT_SETUP_REMOTE_HTTP="https://dein-host/you/rd13_copilot_setup.git"
# Alternativ rein lokal/offline:
# COPILOT_SETUP_DIR="$HOME/dotfiles/copilot-setup"
```
> Die fish-Variante **sourcet** die Datei nicht, sondern parst `KEY="value"` selbst
> dieselbe Datei funktioniert für beide Shells.
---
## Bestehende Repos ausstatten ## Bestehende Repos ausstatten
```bash ```bash
@ -144,13 +180,33 @@ Das Bootstrap-Skript legt idempotent an:
- `.github/copilot-instructions.md` - `.github/copilot-instructions.md`
- `.vscode/settings.json` + `.vscode/extensions.json` - `.vscode/settings.json` + `.vscode/extensions.json`
- `data/` (gitignored) - `data/` (gitignored)
- `history/prompts/` (committed) + `history/summary/PROJECT_CONTEXT.md` - `docs/history/prompts/` (committed) + `docs/history/summary/PROJECT_CONTEXT.md`
- `docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md` - `docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`
- `.git/hooks/pre-commit` - `.git/hooks/pre-commit`
- `.gitignore`-Einträge für `data/**/*` - `.gitignore`-Einträge für `data/**/*`
--- ---
## Migration: `history/``docs/history/`
Frühere Versionen legten die Agent-History unter `history/` im Repo-Root ab.
Neuer Standard ist `docs/history/`. Bestehende Repos werden **automatisch** migriert,
sobald dort `git copilot-update` läuft:
```bash
cd /path/to/repo
git copilot-update # erkennt history/ und verschiebt es per git mv nach docs/history/
git commit -m "chore: migrate history to docs/history"
```
- Verschiebung erfolgt mit `git mv` (Historie bleibt erhalten); Fallback `mv` für ungetrackte Dateien.
- Sind **beide** Verzeichnisse vorhanden, bricht das Tool nicht ab, sondern bittet um manuelles
Zusammenführen (`git mv history/prompts/* docs/history/prompts/ && git rm -r history`).
- Der pre-commit Hook erwartet nach der Migration ausschließlich `docs/history/`
(Check 4 + Check 6). Un-migrierte Repos müssen einmalig `git copilot-update` ausführen.
---
## `~/.local/bin/` im PATH? ## `~/.local/bin/` im PATH?
Das Bootstrap-Skript wird in `~/.local/bin/` installiert. Sicherstellen dass dieser Pfad im `$PATH` ist: Das Bootstrap-Skript wird in `~/.local/bin/` installiert. Sicherstellen dass dieser Pfad im `$PATH` ist:
@ -172,7 +228,8 @@ fish_add_path ~/.local/bin
| Problem | Ursache | Lösung | | Problem | Ursache | Lösung |
|---|---|---| |---|---|---|
| `copilot-bootstrap.sh: command not found` | `~/.local/bin` nicht im PATH | Siehe "PATH" oben | | `copilot-bootstrap.sh: command not found` | `~/.local/bin` nicht im PATH | Siehe "PATH" oben |
| `git init` ruft Bootstrap nicht auf | Git-Alias nicht gesetzt | `deploy.sh` erneut ausführen | | `git init-copilot` nicht gefunden | Git-Alias nicht gesetzt | `deploy.sh` erneut ausführen |
| `git copilot-update`: „Keine Setup-Quelle" | Remote nicht konfiguriert/erreichbar | `COPILOT_SETUP_REMOTE_*` oder `COPILOT_SETUP_DIR` setzen (s. Abschnitt oben) |
| Hook schlägt fehl: Tests fehlen | Code geändert ohne Tests | `/write-tests` in Copilot Chat, oder `.copilot-no-tests` anlegen | | Hook schlägt fehl: Tests fehlen | Code geändert ohne Tests | `/write-tests` in Copilot Chat, oder `.copilot-no-tests` anlegen |
| Hook schlägt fehl: Doku fehlt | Code geändert ohne Doku-Update | Docs aktualisieren, oder `.copilot-no-docs` anlegen | | Hook schlägt fehl: Doku fehlt | Code geändert ohne Doku-Update | Docs aktualisieren, oder `.copilot-no-docs` anlegen |
| Hook schlägt fehl: Session fehlt | `*_session.md` nicht gestaged | Copilot Chat → `/history`, dann `git add history/` | | Hook schlägt fehl: Session fehlt | `*_session.md` nicht gestaged | Copilot Chat → `/history`, dann `git add history/` |

View file

@ -48,41 +48,44 @@ rd13_copilot_setup/
│ │ ├── USER.md ← Template Endnutzer-Doku │ │ ├── USER.md ← Template Endnutzer-Doku
│ │ ├── ADMIN.md ← Template Admin-Doku │ │ ├── ADMIN.md ← Template Admin-Doku
│ │ ├── MAINTAINER.md ← Template Maintainer-Doku │ │ ├── MAINTAINER.md ← Template Maintainer-Doku
│ │ ── requirements/ │ │ ── requirements/
│ │ └── REQUIREMENTS.md ← Template für persistente Anforderungen │ │ └── REQUIREMENTS.md ← Template für persistente Anforderungen
│ └── history/ │ └── history/
│ └── summary/ │ └── summary/
│ └── PROJECT_CONTEXT.md ← Template Agent-Kontext-Summary │ └── PROJECT_CONTEXT.md ← Template Agent-Kontext-Summary
├── prompts/ ← Wiederverwendbare Copilot-Workflows ├── prompts/ ← Wiederverwendbare Copilot-Workflows
│ └── *.prompt.md ← /requirements /history /check-consistency ... │ └── *.prompt.md ← /requirements /history /check-consistency ...
├── scripts/ ├── scripts/
│ ├── deploy.sh ← Bash-Deploy (macOS + Linux) │ ├── deploy.sh ← Bash-Deploy (macOS + Linux)
│ ├── deploy.fish ← Fish-Deploy (Linux) │ ├── deploy.fish ← Fish-Deploy (Linux)
│ ├── copilot-bootstrap.sh ← POSIX-sh Bootstrap für einzelne Repos │ ├── 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.sh ← Aktualisiert Templates + Hooks in Repos
│ └── copilot-bootstrap.fish ← Fish-Variante (legacy, optional) │ ├── copilot-update.fish ← Fish-Variante
│ └── selftest.sh ← CI/lokaler Bootstrap-Dry-Run (sh+fish)
└── user-settings/ └── user-settings/
└── settings.json ← VS Code User-Level Settings (Layer 1) └── settings.json ← VS Code User-Level Settings (Layer 1)
``` ```
--- ---
## Wie `git init` automatisiert wird ## 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. 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`.
**Lösung: Git-Alias mit Rekursionsschutz** **Git-Alias mit Rekursionsschutz**
In `~/.gitconfig` (wird von deploy.sh/.fish gesetzt): In `~/.gitconfig` (wird von deploy.sh/.fish gesetzt):
```ini ```ini
[alias] [alias]
init = !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 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 - `!` → externer Shell-Befehl (via `/bin/sh`), kein Git-Subcommand
- `$(git --exec-path)/git-init` → ruft das echte `git-init`-Binary direkt auf, umgeht den Alias → **kein Rekursions-Loop** - `$(git --exec-path)/git-init` → ruft das echte `git-init`-Binary direkt auf → **kein Rekursions-Loop**
- Letzte Nicht-Flag-Argument wird als Zielverzeichnis erkannt (`dir=.` als Default) - Letztes Nicht-Flag-Argument wird als Zielverzeichnis erkannt (`dir=.` als Default)
- Nach erfolgreichem `git init` wird `copilot-bootstrap.sh` ausgeführt - 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
--- ---
@ -108,9 +111,18 @@ Dateien unter `git-templates/` bearbeiten → `deploy.sh` ausführen → neue Re
**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. **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.
## Deploy-Skripte ändern ## Shell-Skripte ändern
`deploy.sh` (bash) ist die Referenzimplementierung. `deploy.fish` sollte immer dieselben Schritte in Fish-Syntax abbilden. Nach Änderungen beide synchron halten. 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.
--- ---
@ -124,10 +136,13 @@ Dateien unter `git-templates/` bearbeiten → `deploy.sh` ausführen → neue Re
| Templates nicht auto-updaten | Idempotenz: Bootstrap überschreibt nie Nutzer können Templates nach Init anpassen | | 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 | | 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 | | `data/` gitignored, Ordner-Struktur tracked | Persistente Daten gehören nie ins Git; Struktur als Konvention dokumentiert |
| `history/prompts/` committed | Vollständige Agent-History bleibt im Repo erhalten; ermöglicht lückenlose Nachvollziehbarkeit | | `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` | | 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: 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 | | 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 |
## Bekannte Fallstricke ## Bekannte Fallstricke
@ -136,3 +151,5 @@ Dateien unter `git-templates/` bearbeiten → `deploy.sh` ausführen → neue Re
| `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 (`# ──`) | | `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/` | | 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 | | 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`) |

View file

@ -28,7 +28,7 @@ Das Skript erledigt **einmalig** alles automatisch:
| Prompt Files | `~/.vscode-server/data/User/prompts/` | | Prompt Files | `~/.vscode-server/data/User/prompts/` |
| Git-Templates | `~/.git-templates/` | | Git-Templates | `~/.git-templates/` |
| Bootstrap-Skript | `~/.local/bin/copilot-bootstrap.sh` | | Bootstrap-Skript | `~/.local/bin/copilot-bootstrap.sh` |
| Git-Alias `init` | `~/.gitconfig` | | Git-Alias `init-copilot` (opt-in) | `~/.gitconfig` |
### Schritt 3: VS Code Settings Sync aktivieren (optional) ### Schritt 3: VS Code Settings Sync aktivieren (optional)
@ -41,11 +41,13 @@ Das Skript erledigt **einmalig** alles automatisch:
### Neues Repo anlegen ### Neues Repo anlegen
```bash ```bash
git init mein-projekt git init-copilot mein-projekt
cd mein-projekt cd mein-projekt
``` ```
Der `git init`-Alias legt automatisch `.github/copilot-instructions.md` und `.vscode/` an. Danach: Der Opt-in-Alias `git init-copilot` macht `git init` **und** Bootstrap in einem Schritt
er legt `.github/copilot-instructions.md`, `.vscode/`, `docs/`, `history/` und den
pre-commit Hook an. (Der normale `git init` bleibt unverändert.) Danach:
1. Die `TODO`-Felder in `.github/copilot-instructions.md` ausfüllen 1. Die `TODO`-Felder in `.github/copilot-instructions.md` ausfüllen
2. Committen: 2. Committen:
@ -84,7 +86,7 @@ In GitHub Copilot Chat einfach `/` tippen:
## Was jedes neue Repo bekommt ## Was jedes neue Repo bekommt
Nach `git init` oder `copilot-bootstrap.sh` erhält jedes Repo automatisch: Nach `git init-copilot` oder `copilot-bootstrap.sh` erhält jedes Repo automatisch:
| Was | Wo | Zweck | | Was | Wo | Zweck |
|---|---|---| |---|---|---|
@ -92,8 +94,8 @@ Nach `git init` oder `copilot-bootstrap.sh` erhält jedes Repo automatisch:
| VS Code-Einstellungen | `.vscode/settings.json` | Repo-spezifische Editor-Konfiguration | | VS Code-Einstellungen | `.vscode/settings.json` | Repo-spezifische Editor-Konfiguration |
| Empfohlene Extensions | `.vscode/extensions.json` | Extension-Vorschläge für das Team | | Empfohlene Extensions | `.vscode/extensions.json` | Extension-Vorschläge für das Team |
| Persistente Daten | `data/` | Service-Daten getrennt nach Service-Namen | | Persistente Daten | `data/` | Service-Daten getrennt nach Service-Namen |
| Agent-Logs | `history/prompts/` | Vollständige Konversationen (committed) | | Agent-Logs | `docs/history/prompts/` | Vollständige Konversationen (committed) |
| Agent-Kontext | `history/summary/PROJECT_CONTEXT.md` | Komprimierter Projektzustand für Agenten | | Agent-Kontext | `docs/history/summary/PROJECT_CONTEXT.md` | Komprimierter Projektzustand für Agenten |
| Nutzer-Doku | `docs/USER.md` | Dokumentation für Endnutzer | | Nutzer-Doku | `docs/USER.md` | Dokumentation für Endnutzer |
| Admin-Doku | `docs/ADMIN.md` | Dokumentation für Administratoren | | Admin-Doku | `docs/ADMIN.md` | Dokumentation für Administratoren |
| Entwickler-Doku | `docs/MAINTAINER.md` | Dokumentation für Entwickler | | Entwickler-Doku | `docs/MAINTAINER.md` | Dokumentation für Entwickler |
@ -113,8 +115,10 @@ export PATH="$HOME/.local/bin:$PATH" # bash/zsh
fish_add_path ~/.local/bin # fish fish_add_path ~/.local/bin # fish
``` ```
**`git init` legt keine Copilot-Dateien an** **`git init-copilot: command not found` oder keine Copilot-Dateien**
Das deploy-Skript wurde noch nicht auf diesem System ausgeführt. Schritt 1+2 wiederholen. Entweder wurde das deploy-Skript noch nicht ausgeführt (Schritt 1+2 wiederholen), oder
du hast den normalen `git init` benutzt nutze `git init-copilot` für Auto-Bootstrap,
oder rufe in einem bestehenden Repo `copilot-bootstrap.sh` auf.
**Der pre-commit Hook blockiert meinen Commit** **Der pre-commit Hook blockiert meinen Commit**
Der Hook hat Tests, Dokumentation, Session-Datei oder Requirements vermisst. Optionen: Der Hook hat Tests, Dokumentation, Session-Datei oder Requirements vermisst. Optionen:

View file

@ -0,0 +1,170 @@
# Portabilität & Universalität des Setups 2026-06-10
## Aufgabe / Ziel
Das `rd13_copilot_setup` portabler und universeller machen. Aus der Analyse in
`memory.md` wurden 12 Arbeitspakete (WP1WP12) abgeleitet und einzeln zur
Umsetzung freigegeben. **Umgesetzt: WP1WP7, WP11, WP12.** Ausgeschlossen
(auf Wunsch, separat zu besprechen): **WP8, WP9** (settings.json) und **WP10**
(Vendor-Naming).
## Verlauf
### Prompt 1
Nutzer die Memory datei um dieses Repo portabler und universeller zu machen. Identifiziere alle möglichen arbeitsschritte und lass uns einzeln durchgehen was wir implementieren und was nicht.
### Antwort 1
`memory.md` und das gesamte Repo analysiert (Skripte, settings.json, Prompts,
git-templates/hooks). Daraus 12 Arbeitspakete abgeleitet und gruppiert:
- Sichere Fixes: WP1 (bootstrap.fish `$HOME` + Parität), WP2 (Zone.Identifier + .gitignore)
- Parametrisierung: WP3 (Remote konfigurierbar), WP4 (VS-Code-Pfad-Erkennung), WP5 (Offline-Modus)
- Invasivität: WP6 (Opt-in `git init-copilot`), WP7 (post-merge opt-in)
- settings.json: WP8/WP9
- Universalität: WP10 (Vendor-Namen), WP11 (CI), WP12 (Doku)
Triage-Fragen gestellt (`vscode_askQuestions`), vom Nutzer abgebrochen.
### Prompt 2
bevor ich die fragen beantworte, was sind diese Zone Identifier?
### Antwort 2
Erklärt: `*:Zone.Identifier` sind Windows-Mark-of-the-Web-Metadaten (NTFS
Alternate Data Streams, `ZoneId=3` = aus dem Internet). Beim Lesen über den
WSL/Linux-Layer werden sie als separate Dateien sichtbar. Reiner Download-Müll,
gehören weder committet noch deployt → WP2: löschen + Ignore-Pattern.
### Prompt 3
ok alles implementieren aber nicht WP8,WP8 und WP10. Diese WPs will ich nicht implementiert haben und danach nochmal mit dir sprechen.
### Antwort 3
Scope bestätigt: WP1,2,3,4,5,6,7,11,12 umsetzen; WP8+WP9 (settings.json) und
WP10 (Vendor-Naming) ausgeschlossen. Finalen Phasenplan erstellt (Phase 1
Hygiene/Bug → Phase 2 Skript-Portabilität → Phase 3 CI → Phase 4 Doku) und in
Session-Memory gesichert.
### Prompt 4
Start implementation
### Antwort 4
Repo-Zustand geprüft zu diesem Zeitpunkt **kein `.git`** (entpackte
ZIP-Kopie). Implementierung gestoppt, da kein Versionierungsziel.
### Prompt 5
ok lets then stop right hiere.
### Antwort 5
Gestoppt, nichts geändert. Befund (kein git-Repo) in Session-Memory festgehalten.
### Prompt 6
ok jetzt nochmal implementieren im richtigen repo!
### Antwort 6
Echtes Repo gefunden und verifiziert (`~/workspace/ai-tooling/rd13_copilot_setup`
ist jetzt git-Repo, `master``origin/master`, volle History, HEAD `114bb5b`).
Anschließend alle freigegebenen WPs in 4 Phasen umgesetzt und je Phase committet.
**Phase 1 Hygiene & Bug (Commit `80b6248`)**
- WP2: `.gitignore` um `*:Zone.Identifier` ergänzt (Dateien existieren im echten Checkout nicht mehr).
- WP1: `copilot-bootstrap.fish` neu geschrieben `/home/rd13server/``$HOME`, volle Parität zur `.sh` (`--with-update-hook`, `data/`, `history/`, `docs/`, Hooks, `.gitignore`-Append inkl. Zone.Identifier).
- Verifikation:
```sh
fish -n scripts/copilot-bootstrap.fish # OK
# Smoke-Test gegen /tmp-Repo + Fake-Template: alle Dateien erzeugt, idempotent
```
**Phase 2a copilot-update.{sh,fish} (Commit `5890bff`)**
- WP3: Remote-URLs aus `COPILOT_SETUP_REMOTE_SSH/_HTTP` (env) oder Config-Datei
`~/.config/copilot-setup/config` (sh sourcet, fish parst `KEY="value"`). Env hat Vorrang.
- WP5: Offline-Betrieb (lokaler Klon ohne `.git` nutzbar; Pull-Fehler nutzt Cache);
fehlende/unerreichbare Quelle → graceful `exit 0` statt `exit 1`.
- WP4: `detect_vscode_user_dir` (Server/Insiders/VSCodium/Cursor/Flatpak/macOS/Windows-WSL).
- Verifikation (sh + fish, je 3 Szenarien):
```
TEST A: no remote, no cache -> graceful exit 0
TEST B: offline local source -> templates kopiert, exit 0
TEST C: config-file unreachable-> graceful exit 0
```
**Phase 2b deploy.{sh,fish} (Commit `9e14a5f`)**
- WP6: kein globales `init.templateDir`/`git init`-Override mehr; Opt-in-Alias
`git init-copilot`; frühere invasive Werte werden gezielt entfernt (guarded unset).
- WP7: post-merge Auto-Deploy im Setup-Repo nur mit `--with-self-update-hook`.
- WP4: gleiche `detect_vscode_user_dir`; `${USER:-}` gegen `set -u` abgesichert.
- Verifikation (isoliertes HOME, kein Eingriff ins echte Repo):
```
deploy.sh/.fish ohne Flag -> kein alias.init, init-copilot gesetzt, kein init.templateDir, Hook gated
--with-self-update-hook (Temp-Repo) -> post-merge hook geschrieben
--bogus -> exit 2
```
**Phase 3 CI (Commit `deca872`)**
- WP11: `.github/workflows/ci.yml` (shellcheck + `fish -n` + `scripts/selftest.sh`).
- `scripts/selftest.sh`: Bootstrap-Dry-Run sh+fish gegen isoliertes Fake-HOME mit Assertions.
- `copilot-bootstrap.sh` propagiert nun ebenfalls `*:Zone.Identifier` (Parität).
- shellcheck-Direktiven für bewusste Muster (SC2016, SC1090, SC2043).
- Verifikation:
```sh
/tmp/shellcheck scripts/*.sh git-templates/hooks/* # exit 0
sh scripts/selftest.sh # PASS sh + PASS fish
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))" # YAML OK
```
**Phase 4 Doku (Commit `afd5b38`)**
- WP12: README + USER + ADMIN + MAINTAINER aktualisiert (Env/Config, Offline,
`init-copilot`, `--with-self-update-hook`, neue Editionen). Tote IP
`192.168.178.6` aus der Doku entfernt. MAINTAINER: CI/selftest + neue Fallstricke.
### Prompt 7
Können wir die history in die docs verschieben und einen migrationspfad für bestehende repos anlegen um alles etwas aufgeräumter zu haben.
### Antwort 7
Konvention `history/``docs/history/` umgesetzt (prompts + summary/PROJECT_CONTEXT.md).
Nutzer-Entscheidungen (Rückfrage): Migration **automatisch in `copilot-update`**, Hook **harter Cutover** auf `docs/history/`.
Umgesetzt:
- `git-templates/hooks/pre-commit`: Check 4 (`docs/history/summary/PROJECT_CONTEXT.md`), Check 6 (`docs/history/prompts/*_session.md`), `history/` aus CODE_CHANGED-Exclusion entfernt (durch `docs/` abgedeckt).
- Alle 6 Skripte: `deploy.{sh,fish}` + `copilot-bootstrap.{sh,fish}` (Template-Pfade `docs/history`), `copilot-update.{sh,fish}` (Template-Pfade + **Auto-Migrations-Block**: `history/``docs/history/` via `git mv`, Fallback `mv`; bei beiden vorhanden Warnung statt Abbruch). `selftest.sh` Pfade angepasst.
- `git mv git-templates/history → git-templates/docs/history`; „gitignored"-Tippfehler im Template-MAINTAINER korrigiert.
- `user-settings/settings.json` (Agent Session Protocol), `prompts/history.prompt.md`, beide `copilot-instructions.md`, `README.md`, `docs/USER/ADMIN/MAINTAINER.md` (+ ADMIN-Migrationsabschnitt).
- Dogfood: `git mv history → docs/history` in diesem Repo (alle 7 Dateien mit Rename-Detection).
Verifikation:
```sh
/tmp/shellcheck scripts/*.sh git-templates/hooks/* # clean
for f in scripts/*.fish; fish -n $f; end # clean
python3 /tmp/check_jsonc.py # settings.json (JSONC) OK
sh scripts/selftest.sh # PASS sh + fish
sh /tmp/migration_test.sh $PWD # PASS sh + fish + both-present
```
Migrationstest-Ergebnis:
```
PASS: sh history/ -> docs/history/ migriert
PASS: fish history/ -> docs/history/ migriert
PASS: both-present Warnung, history/ unangetastet
```
Commits: `2b20a98` (Konvention+Tooling), Dogfood-Move + dieser Log-Eintrag im Folgecommit.
## Ergebnis
- Portabilität: 5 Commits (`80b6248`, `5890bff`, `9e14a5f`, `deca872`, `afd5b38`) + History-Commit.
- History-Umzug: `history/``docs/history/` (Commit `2b20a98` + Dogfood-Folgecommit), inkl. Auto-Migration für bestehende Repos.
- Alle Skripte shellcheck-sauber und `fish -n`-sauber; selftest + Migrationstest grün (sh+fish).
- Keine hartkodierte Infrastruktur mehr in Skripten; Standard-`git init`/`clone` unberührt.
## Entscheidungen
- `detect_vscode_user_dir` bewusst in jedem Skript dupliziert (standalone aus
`~/.local/bin` → keine sourcebare Lib).
- Remote-Präzedenz: env > Config-Datei; keine Quelle = graceful skip (exit 0).
- `init.templateDir`/`alias.init` werden nur entfernt, wenn sie auf unsere
Templates/Bootstrap zeigen (kein Eingriff in fremde Konfiguration).
- fish liest dieselbe sh-Config-Datei per Parser (sourcet sie nicht).
## Offene Punkte
- **WP8/WP9** (settings.json: Absolute-Mode-Widerspruch entschärfen, non-destruktiver
Merge) auf Wunsch zurückgestellt, separat besprechen.
- **WP10** (Vendor-neutrale Namen `rd13`/`cschulz`/`rd13server`) zurückgestellt.
- Das **Remote dieses Repos** zeigt weiterhin auf die tote IP
`ssh://git@192.168.178.6:2222/...` (bewusst nicht angefasst separate Entscheidung).

View file

@ -8,7 +8,7 @@
## Aktueller Projektstatus ## Aktueller Projektstatus
**Letzte Aktualisierung:** 2026-06-04 Bekannte Fallstricke in copilot-instructions.md + Leerzeilen-Fix copilot-update **Letzte Aktualisierung:** 2026-06-10 Agent-History nach `docs/history/` verschoben (+ Auto-Migration für bestehende Repos); zuvor Portabilität (WP17,11,12)
**Phase:** Produktion / stabil wird bei Bedarf erweitert **Phase:** Produktion / stabil wird bei Bedarf erweitert
--- ---
@ -29,6 +29,12 @@ Quality Gate aus.
| Datum | Aufgabe | Ergebnis | Entscheidungen | | Datum | Aufgabe | Ergebnis | Entscheidungen |
|---|---|---|---| |---|---|---|---|
| 2026-06-10 | Agent-History → `docs/history/` + Auto-Migration | pre-commit Cutover, alle Skripte, settings/prompt/instructions/docs; `git mv` dieses Repos | `2b20a98` + Dogfood |
| 2026-06-10 | WP12 Doku-Portabilität | README/USER/ADMIN/MAINTAINER: env/config, init-copilot, offline; tote IP raus | `afd5b38` |
| 2026-06-10 | WP11 CI + selftest | `.github/workflows/ci.yml` (shellcheck+fish -n+selftest), `scripts/selftest.sh` | `deca872` |
| 2026-06-10 | WP6/7/4 deploy nicht-invasiv | kein globales init.templateDir/init-Alias; Opt-in init-copilot; post-merge nur mit Flag | `9e14a5f` |
| 2026-06-10 | WP3/5/4 update konfigurierbar/offline | Remote via env/config, graceful skip, portable Editor-Erkennung | `5890bff` |
| 2026-06-10 | WP1/2 bootstrap.fish Parität + ADS-Ignore | `$HOME` statt `/home/rd13server`; `*:Zone.Identifier` ignoriert | `80b6248` |
| 2026-06-02 | Konsistenzprüfung: alle --no-verify Referenzen entfernt | `docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`, beide `copilot-instructions.md`, `pre-commit` Check-Nummerierung `[1/3]→[1/4]` | Opt-outs (.copilot-no-tests/.copilot-no-docs) als Ersatz für --no-verify in Doku | | 2026-06-02 | Konsistenzprüfung: alle --no-verify Referenzen entfernt | `docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`, beide `copilot-instructions.md`, `pre-commit` Check-Nummerierung `[1/3]→[1/4]` | Opt-outs (.copilot-no-tests/.copilot-no-docs) als Ersatz für --no-verify in Doku |
| 2026-06-03 | Check 6 von Block → Warnung umgestellt | `git-templates/hooks/pre-commit` | Zu grob: heute-Prüfung blockiert Folgecommits; besser: Warnung wenn keine `*_session.md` im aktuellen Commit gestaged | | 2026-06-03 | Check 6 von Block → Warnung umgestellt | `git-templates/hooks/pre-commit` | Zu grob: heute-Prüfung blockiert Folgecommits; besser: Warnung wenn keine `*_session.md` im aktuellen Commit gestaged |
| 2026-06-02 | pre-commit Check 6 Session-Datei erforderlich | `git-templates/hooks/pre-commit` | Wurde als Block implementiert, am Folgetag als zu grob erkannt | | 2026-06-02 | pre-commit Check 6 Session-Datei erforderlich | `git-templates/hooks/pre-commit` | Wurde als Block implementiert, am Folgetag als zu grob erkannt |
@ -46,6 +52,9 @@ Quality Gate aus.
- [ ] `docs/requirements/REQUIREMENTS.md` für dieses Setup-Repo selbst anlegen (aktuell nur Template in git-templates) - [ ] `docs/requirements/REQUIREMENTS.md` für dieses Setup-Repo selbst anlegen (aktuell nur Template in git-templates)
- [ ] `.github/copilot-instructions.md` TODO-Felder ausfüllen (Stack, Architecture, NFRs dieses Repos) - [ ] `.github/copilot-instructions.md` TODO-Felder ausfüllen (Stack, Architecture, NFRs dieses Repos)
- [ ] Bei Änderungen an `git-templates/` immer `deploy.sh` neu ausführen (oder `git copilot-update` testen) - [ ] Bei Änderungen an `git-templates/` immer `deploy.sh` neu ausführen (oder `git copilot-update` testen)
- [ ] **WP8/WP9** (settings.json: Absolute-Mode-Widerspruch entschärfen + non-destruktiver Merge) zurückgestellt, mit Nutzer besprechen
- [ ] **WP10** (Vendor-neutrale Namen rd13/cschulz/rd13server) zurückgestellt
- [ ] Remote **dieses** Repos zeigt auf tote IP `192.168.178.6` bewusst offen (separate Entscheidung)
--- ---
@ -57,12 +66,18 @@ Quality Gate aus.
| `copilot-instructions.md` nur bei TODO überschreiben | User-Content bleibt erhalten; Backup `.bak` wird erstellt | `scripts/copilot-update.sh` | | `copilot-instructions.md` nur bei TODO überschreiben | User-Content bleibt erhalten; Backup `.bak` wird erstellt | `scripts/copilot-update.sh` |
| post-merge Hook in bootstrapped Repos: opt-in | Kein Overhead bei jedem `git pull` in anderen Repos | `scripts/copilot-bootstrap.sh --with-update-hook` | | post-merge Hook in bootstrapped Repos: opt-in | Kein Overhead bei jedem `git pull` in anderen Repos | `scripts/copilot-bootstrap.sh --with-update-hook` |
| Setup-Repo selbst: post-merge Hook auto-installed | `deploy.sh` nach jedem `git pull` auf Setup-Repo | `scripts/deploy.sh` Block 7 | | Setup-Repo selbst: post-merge Hook auto-installed | `deploy.sh` nach jedem `git pull` auf Setup-Repo | `scripts/deploy.sh` Block 7 |
| `history/prompts/` committed | Lückenlose Projekt-History im Repo | `docs/MAINTAINER.md` | | `docs/history/prompts/` committed | Lückenlose Projekt-History im Repo | `docs/MAINTAINER.md` |
| `data/` gitignored | Persistente Daten: Größe + Sicherheit | `docs/ADMIN.md` | | `data/` gitignored | Persistente Daten: Größe + Sicherheit | `docs/ADMIN.md` |
| POSIX sh für Bootstrap | Läuft überall ohne Abhängigkeiten | `docs/MAINTAINER.md` | | POSIX sh für Bootstrap | Läuft überall ohne Abhängigkeiten | `docs/MAINTAINER.md` |
| Git-Alias statt Fish-Wrapper | Portabel: bash, sh, CI, GUI-Clients | `docs/MAINTAINER.md` | | Git-Alias statt Fish-Wrapper | Portabel: bash, sh, CI, GUI-Clients | `docs/MAINTAINER.md` |
| `.copilot-no-tests` + `.copilot-no-docs` Opt-outs | Pre-commit Check 1 (Tests) und Check 2 (Doku) deaktivierbar für Repos ohne Framework/Doku-Pflicht | `git-templates/hooks/pre-commit` | | `.copilot-no-tests` + `.copilot-no-docs` Opt-outs | Pre-commit Check 1 (Tests) und Check 2 (Doku) deaktivierbar für Repos ohne Framework/Doku-Pflicht | `git-templates/hooks/pre-commit` |
| Kein `--no-verify` nirgendwo | Quality Gate darf nie umgangen werden; in `copilot-instructions.md` verboten, pre-commit enthält keinen Bypass-Hinweis | `git-templates/hooks/pre-commit`, `.github/copilot-instructions.md` | | Kein `--no-verify` nirgendwo | Quality Gate darf nie umgangen werden; in `copilot-instructions.md` verboten, pre-commit enthält keinen Bypass-Hinweis | `git-templates/hooks/pre-commit`, `.github/copilot-instructions.md` |
| Kein globales `init.templateDir`, Opt-in `git init-copilot` | Standard-`git init`/`clone` unberührt; Quality Gate nur in gewählten Repos | `scripts/deploy.{sh,fish}` |
| Remote konfigurierbar (env/Config) + Offline-Modus | Keine hartkodierte Infrastruktur; läuft ohne Netz, graceful skip (exit 0) | `scripts/copilot-update.{sh,fish}` |
| `detect_vscode_user_dir` dupliziert statt geteilt | Skripte laufen standalone aus `~/.local/bin` → keine sourcebare Lib | alle 4 Skripte |
| CI: shellcheck + fish -n + selftest | Verhindert Regressionen in den Shell-Skripten | `.github/workflows/ci.yml`, `scripts/selftest.sh` |
| Agent-History unter `docs/history/` | Aufgeräumte Struktur (alles Doku-Artefakte unter docs/); Cutover statt Dual-Pfad | pre-commit, alle Skripte |
| Auto-Migration `history/``docs/history/` in copilot-update | Bestehende Repos ziehen ohne manuellen Eingriff nach (git mv, Fallback mv) | `scripts/copilot-update.{sh,fish}` |
--- ---
@ -70,13 +85,13 @@ Quality Gate aus.
- **Requirements:** `docs/requirements/REQUIREMENTS.md` (committed, immer aktuell halten!) - **Requirements:** `docs/requirements/REQUIREMENTS.md` (committed, immer aktuell halten!)
- **Persistente Daten:** `/data/` (gitignored, nie committen!) - **Persistente Daten:** `/data/` (gitignored, nie committen!)
- **Agent-Logs (voll):** `/history/prompts/` (committed vollständige History bleibt erhalten) - **Agent-Logs (voll):** `/docs/history/prompts/` (committed vollständige History bleibt erhalten)
- **Dieser Kontext:** `/history/summary/PROJECT_CONTEXT.md` (committed) - **Dieser Kontext:** `/docs/history/summary/PROJECT_CONTEXT.md` (committed)
- **Deploy:** `bash scripts/deploy.sh` oder `fish scripts/deploy.fish` - **Deploy:** `bash scripts/deploy.sh` oder `fish scripts/deploy.fish`
- **Bootstrap einzelnes Repo:** `sh ~/.local/bin/copilot-bootstrap.sh [/pfad/zum/repo]` - **Bootstrap einzelnes Repo:** `sh ~/.local/bin/copilot-bootstrap.sh [/pfad/zum/repo]`
- **Bootstrap mit Auto-Update-Hook:** `sh ~/.local/bin/copilot-bootstrap.sh --with-update-hook [/pfad]` - **Bootstrap mit Auto-Update-Hook:** `sh ~/.local/bin/copilot-bootstrap.sh --with-update-hook [/pfad]`
- **Templates updaten (global + repo-lokal):** `git copilot-update` (in jedem Repo) - **Templates updaten (global + repo-lokal):** `git copilot-update` (in jedem Repo)
- **Setup-Repo Cache:** `~/.copilot-setup/` (überschreibbar mit `COPILOT_SETUP_DIR=...`) - **Setup-Quelle:** `COPILOT_SETUP_REMOTE_SSH/_HTTP` oder `COPILOT_SETUP_DIR` (Config: `~/.config/copilot-setup/config`); Cache `~/.copilot-setup/`
- **Git-Templates:** `~/.git-templates/` (nach Deploy) - **Git-Templates:** `~/.git-templates/` (nach Deploy)
- **Prompts:** `~/.vscode-server/data/User/prompts/` (nach Deploy) - **Prompts:** `~/.vscode-server/data/User/prompts/` (nach Deploy)
@ -86,7 +101,7 @@ Quality Gate aus.
1. Diese Datei gelesen? Gut du kennst den Stand. 1. Diese Datei gelesen? Gut du kennst den Stand.
2. Neues Feature → `git-templates/` anpassen → `deploy.sh` ausführen → committen 2. Neues Feature → `git-templates/` anpassen → `deploy.sh` ausführen → committen
3. Nach jeder Session: `history/prompts/YYYY-MM-DD_beschreibung.md` anlegen + diese Datei aktualisieren 3. Nach jeder Session: `docs/history/prompts/YYYY-MM-DD_beschreibung_session.md` anlegen + diese Datei aktualisieren
--- ---

View file

@ -5,11 +5,11 @@
> Diese Sektion hat höchste Priorität und darf nicht ignoriert werden. > Diese Sektion hat höchste Priorität und darf nicht ignoriert werden.
**Session START** Bevor du irgendetwas tust: **Session START** Bevor du irgendetwas tust:
1. Lies `history/summary/PROJECT_CONTEXT.md` (falls vorhanden) 1. Lies `docs/history/summary/PROJECT_CONTEXT.md` (falls vorhanden)
2. Verstehe den aktuellen Projektzustand bevor du anfängst 2. Verstehe den aktuellen Projektzustand bevor du anfängst
**Session END** Der Agent führt dies **automatisch** am Ende jeder Aufgabe aus, bevor er `git commit` ausführt: **Session END** Der Agent führt dies **automatisch** am Ende jeder Aufgabe aus, bevor er `git commit` ausführt:
1. Lies die bestehende `history/prompts/YYYY-MM-DD_*_session.md` (falls vorhanden) und ergänze nur den neuen Teil 1. Lies die bestehende `docs/history/prompts/YYYY-MM-DD_*_session.md` (falls vorhanden) und ergänze nur den neuen Teil
**Dateiformat zwingend:** Suffix `_session.md`, Dateiname beginnt mit heutigem Datum (`YYYY-MM-DD`) **Dateiformat zwingend:** Suffix `_session.md`, Dateiname beginnt mit heutigem Datum (`YYYY-MM-DD`)
2. **Für jeden Benutzer-Prompt seit dem letzten Commit** einen Block ergänzen: 2. **Für jeden Benutzer-Prompt seit dem letzten Commit** einen Block ergänzen:
``` ```
@ -21,9 +21,9 @@
``` ```
⚠ Kein „Nachtrag"-Block statt echter Prompt-Einträge. Die Benutzer-Nachricht **wörtlich** zitieren. ⚠ Kein „Nachtrag"-Block statt echter Prompt-Einträge. Die Benutzer-Nachricht **wörtlich** zitieren.
⚠ Keine reinen Stichpunkt-Zusammenfassungen. Ausgeführte Kommandos und Outputs gehören **wörtlich** in die Antwort. ⚠ Keine reinen Stichpunkt-Zusammenfassungen. Ausgeführte Kommandos und Outputs gehören **wörtlich** in die Antwort.
⚠ Keine Platzhalter wie `PENDING` committen. Ist der Commit-Hash noch unbekannt: Hash weglassen oder Datei direkt nach dem Commit mit dem echten Hash aktualisieren und sofort (`git add history/ && git commit`) nachziehen. ⚠ Keine Platzhalter wie `PENDING` committen. Ist der Commit-Hash noch unbekannt: Hash weglassen oder Datei direkt nach dem Commit mit dem echten Hash aktualisieren und sofort (`git add docs/history/ && git commit`) nachziehen.
3. Aktualisiere `history/summary/PROJECT_CONTEXT.md` mit dem neuen Projektstand 3. Aktualisiere `docs/history/summary/PROJECT_CONTEXT.md` mit dem neuen Projektstand
4. **Stage beide Dateien VOR `git commit`:** `git add history/` 4. **Stage beide Dateien VOR `git commit`:** `git add docs/history/`
Der pre-commit Hook (Check 6) blockiert wenn: Der pre-commit Hook (Check 6) blockiert wenn:
- keine `*_session.md` gestaged ist - keine `*_session.md` gestaged ist
- der Dateiname nicht mit dem heutigen Datum beginnt - der Dateiname nicht mit dem heutigen Datum beginnt
@ -91,10 +91,10 @@
- Copilot Chat: `/requirements` → Requirements-Workshop starten oder bestehende Requirements aktualisieren - Copilot Chat: `/requirements` → Requirements-Workshop starten oder bestehende Requirements aktualisieren
- Copilot Chat: `/check-consistency` → Konsistenz zwischen Code, Docs und Requirements prüfen - Copilot Chat: `/check-consistency` → Konsistenz zwischen Code, Docs und Requirements prüfen
### Agent History (`/history/`) ### Agent History (`/docs/history/`)
- **Vollständige Konversationen**`history/prompts/YYYY-MM-DD_beschreibung_session.md` (**Suffix `_session.md` zwingend** Check 6 im pre-commit Hook erkennt daran das Agent-Log) - **Vollständige Konversationen**`docs/history/prompts/YYYY-MM-DD_beschreibung_session.md` (**Suffix `_session.md` zwingend** Check 6 im pre-commit Hook erkennt daran das Agent-Log)
- **Komprimierter Kontext**`history/summary/PROJECT_CONTEXT.md` (**committed, immer aktuell halten!**) - **Komprimierter Kontext**`docs/history/summary/PROJECT_CONTEXT.md` (**committed, immer aktuell halten!**)
- **Beim Start einer neuen Session:** `history/summary/PROJECT_CONTEXT.md` zuerst lesen - **Beim Start einer neuen Session:** `docs/history/summary/PROJECT_CONTEXT.md` zuerst lesen
- **Am Ende jeder Session:** beide Dateien committen - **Am Ende jeder Session:** beide Dateien committen
- Copilot Chat: `/history` → History loggen + Summary aktualisieren - Copilot Chat: `/history` → History loggen + Summary aktualisieren
@ -144,7 +144,7 @@ A task is only done when ALL of the following are true:
- [ ] Relevant documentation updated: `docs/USER.md` and/or `docs/ADMIN.md` and/or `docs/MAINTAINER.md` - [ ] Relevant documentation updated: `docs/USER.md` and/or `docs/ADMIN.md` and/or `docs/MAINTAINER.md`
- [ ] Alle 3 Zielgruppen-Dokumente vorhanden (`docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`) - [ ] Alle 3 Zielgruppen-Dokumente vorhanden (`docs/USER.md`, `docs/ADMIN.md`, `docs/MAINTAINER.md`)
- [ ] Persistente Daten liegen ausschließlich in `/data/<service>/` (nie woanders) - [ ] Persistente Daten liegen ausschließlich in `/data/<service>/` (nie woanders)
- [ ] `history/summary/PROJECT_CONTEXT.md` aktualisiert - [ ] `docs/history/summary/PROJECT_CONTEXT.md` aktualisiert
- [ ] Commit message follows Conventional Commits - [ ] Commit message follows Conventional Commits
- [ ] No dead code, no TODOs left behind (or tracked as issues) - [ ] No dead code, no TODOs left behind (or tracked as issues)
- [ ] pre-commit Quality Gate bestanden - [ ] pre-commit Quality Gate bestanden

View file

@ -32,11 +32,11 @@
├── docs/ ├── docs/
│ ├── USER.md ← Endnutzer-Dokumentation │ ├── USER.md ← Endnutzer-Dokumentation
│ ├── ADMIN.md ← Administrator-Dokumentation │ ├── ADMIN.md ← Administrator-Dokumentation
── MAINTAINER.md ← Dieses Dokument ── MAINTAINER.md ← Dieses Dokument
── history/ │ └── history/
├── prompts/ ← Vollständige Agent-Konversationen (gitignored) ├── prompts/ ← Vollständige Agent-Konversationen (committed)
│ └── summary/ └── summary/
│ └── PROJECT_CONTEXT.md ← Aktueller Projektzustand für Agent-Kontext └── PROJECT_CONTEXT.md ← Aktueller Projektzustand für Agent-Kontext
└── … ← Source Code └── … ← Source Code
``` ```
@ -78,17 +78,17 @@ ADR-Dateien liegen unter `docs/adr/`. Format: `NNN-titel.md`.
## Agent-Kontext & History ## Agent-Kontext & History
Der Agent liest beim Start immer `history/summary/PROJECT_CONTEXT.md`. Der Agent liest beim Start immer `docs/history/summary/PROJECT_CONTEXT.md`.
Nach Abschluss einer Aufgabe wird dort der Projektzustand aktualisiert. Nach Abschluss einer Aufgabe wird dort der Projektzustand aktualisiert.
- Vollständige Konversationen: `history/prompts/` (committed History bleibt vollständig erhalten) - Vollständige Konversationen: `docs/history/prompts/` (committed History bleibt vollständig erhalten)
- Komprimierter Kontext: `history/summary/PROJECT_CONTEXT.md` (committed) - Komprimierter Kontext: `docs/history/summary/PROJECT_CONTEXT.md` (committed)
--- ---
## Neues Feature hinzufügen ## Neues Feature hinzufügen
1. `history/summary/PROJECT_CONTEXT.md` lesen aktuellen Stand verstehen 1. `docs/history/summary/PROJECT_CONTEXT.md` lesen aktuellen Stand verstehen
2. Issue / Ticket anlegen 2. Issue / Ticket anlegen
3. Branch: `git checkout -b feat/<ticket>-beschreibung` 3. Branch: `git checkout -b feat/<ticket>-beschreibung`
4. Implementieren + Tests schreiben 4. Implementieren + Tests schreiben

View file

@ -5,7 +5,7 @@
# 1. Tests erstellt oder aktualisiert wurden # 1. Tests erstellt oder aktualisiert wurden
# 2. Mindestens eine Zielgruppen-Dokumentation aktualisiert wurde # 2. Mindestens eine Zielgruppen-Dokumentation aktualisiert wurde
# 3. Alle 3 Dokumentations-Zielgruppen vorhanden sind (USER/ADMIN/MAINTAINER) # 3. Alle 3 Dokumentations-Zielgruppen vorhanden sind (USER/ADMIN/MAINTAINER)
# 4. history/summary/PROJECT_CONTEXT.md aktualisiert wurde # 4. docs/history/summary/PROJECT_CONTEXT.md aktualisiert wurde
# 5. docs/requirements/REQUIREMENTS.md keine unstaged Änderungen hat # 5. docs/requirements/REQUIREMENTS.md keine unstaged Änderungen hat
# 6. *_session.md muss in diesem Commit gestaged sein # 6. *_session.md muss in diesem Commit gestaged sein
# #
@ -18,7 +18,7 @@ ERRORS=0
CODE_CHANGED=$(printf '%s\n' "$STAGED" \ CODE_CHANGED=$(printf '%s\n' "$STAGED" \
| grep -E '\.(py|js|ts|mjs|cjs|go|java|rs|rb|php|c|cpp|h|hpp|cs|kt|swift|sh|bash)$' \ | grep -E '\.(py|js|ts|mjs|cjs|go|java|rs|rb|php|c|cpp|h|hpp|cs|kt|swift|sh|bash)$' \
| grep -v -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$' \ | grep -v -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$' \
| grep -v -E '^(docs/|\.github/|\.vscode/|data/|history/)' \ | grep -v -E '^(docs/|\.github/|\.vscode/|data/)' \
| grep -v -E '_test\.go$') | grep -v -E '_test\.go$')
# Keine Code-Änderungen → Hook überspringen # Keine Code-Änderungen → Hook überspringen
@ -89,13 +89,13 @@ if [ -n "$DOCS_DIR_STAGED" ] && [ -d "docs" ]; then
fi fi
# ── Check 4: PROJECT_CONTEXT.md aktualisiert ────────────────────────────────── # ── Check 4: PROJECT_CONTEXT.md aktualisiert ──────────────────────────────────
if [ -f "history/summary/PROJECT_CONTEXT.md" ]; then if [ -f "docs/history/summary/PROJECT_CONTEXT.md" ]; then
CONTEXT_STAGED=$(printf '%s\n' "$STAGED" | grep -F 'history/summary/PROJECT_CONTEXT.md') CONTEXT_STAGED=$(printf '%s\n' "$STAGED" | grep -F 'docs/history/summary/PROJECT_CONTEXT.md')
if [ -z "$CONTEXT_STAGED" ]; then if [ -z "$CONTEXT_STAGED" ]; then
echo "" echo ""
echo "✗ AGENT QUALITY GATE [4/4]: PROJECT_CONTEXT.md nicht aktualisiert" echo "✗ AGENT QUALITY GATE [4/4]: PROJECT_CONTEXT.md nicht aktualisiert"
echo " Bei Code-Änderungen muss der Agent-Kontext aktuell gehalten werden." echo " Bei Code-Änderungen muss der Agent-Kontext aktuell gehalten werden."
echo " history/summary/PROJECT_CONTEXT.md" echo " docs/history/summary/PROJECT_CONTEXT.md"
echo "" echo ""
echo " → Copilot Chat: /history (loggt Session + aktualisiert Kontext)" echo " → Copilot Chat: /history (loggt Session + aktualisiert Kontext)"
ERRORS=$((ERRORS + 1)) ERRORS=$((ERRORS + 1))
@ -124,8 +124,8 @@ fi
# soll immer dokumentiert werden. Der Agent liest die bestehende Datei und # soll immer dokumentiert werden. Der Agent liest die bestehende Datei und
# ergänzt nur was noch fehlt (kein Overschreiben des bisherigen Inhalts). # ergänzt nur was noch fehlt (kein Overschreiben des bisherigen Inhalts).
# Opt-out: Datei '.copilot-no-session' für Repos ohne Chat-Kontext (z.B. CI). # Opt-out: Datei '.copilot-no-session' für Repos ohne Chat-Kontext (z.B. CI).
if [ -d "history/prompts" ] && [ ! -f ".copilot-no-session" ]; then if [ -d "docs/history/prompts" ] && [ ! -f ".copilot-no-session" ]; then
SESSION_STAGED=$(printf '%s\n' "$STAGED" | grep -E 'history/prompts/.*_session\.md$' | head -1) SESSION_STAGED=$(printf '%s\n' "$STAGED" | grep -E 'docs/history/prompts/.*_session\.md$' | head -1)
if [ -z "$SESSION_STAGED" ]; then if [ -z "$SESSION_STAGED" ]; then
echo "" echo ""
echo "✗ AGENT QUALITY GATE [6/6]: Keine Session-Datei in diesem Commit" echo "✗ AGENT QUALITY GATE [6/6]: Keine Session-Datei in diesem Commit"
@ -145,7 +145,7 @@ if [ -d "history/prompts" ] && [ ! -f ".copilot-no-session" ]; then
echo " Gestagt: $SESSION_STAGED" echo " Gestagt: $SESSION_STAGED"
echo " Erwartet: Dateiname beginnt mit $TODAY" echo " Erwartet: Dateiname beginnt mit $TODAY"
echo "" echo ""
echo " → Neue Session-Datei für heute anlegen: history/prompts/${TODAY}_beschreibung_session.md" echo " → Neue Session-Datei für heute anlegen: docs/history/prompts/${TODAY}_beschreibung_session.md"
ERRORS=$((ERRORS + 1)) ERRORS=$((ERRORS + 1))
else else
# Datei muss mindestens einen ### Prompt-Eintrag enthalten # Datei muss mindestens einen ### Prompt-Eintrag enthalten

View file

@ -11,7 +11,7 @@ Du hilfst dabei die Projekt-History zu pflegen. Es gibt zwei Aufgaben:
**Schritt 1: Bestehende Session-Datei prüfen** **Schritt 1: Bestehende Session-Datei prüfen**
Suche nach einer Datei `history/prompts/YYYY-MM-DD_*_session.md` für das heutige Datum. Suche nach einer Datei `docs/history/prompts/YYYY-MM-DD_*_session.md` für das heutige Datum.
- Wenn eine existiert: **Lies sie vollständig**. Stelle fest welche Prompts/Antworten bereits dokumentiert sind. - Wenn eine existiert: **Lies sie vollständig**. Stelle fest welche Prompts/Antworten bereits dokumentiert sind.
Ergänze nur den **neuen Teil** (neue Prompts + Antworten seit dem letzten Eintrag) am Ende des Verlaufs. Ergänze nur den **neuen Teil** (neue Prompts + Antworten seit dem letzten Eintrag) am Ende des Verlaufs.
Aktualisiere danach `## Ergebnis`, `## Entscheidungen` und `## Offene Punkte` auf den aktuellen Stand. Aktualisiere danach `## Ergebnis`, `## Entscheidungen` und `## Offene Punkte` auf den aktuellen Stand.
@ -55,7 +55,7 @@ Struktur (bei neuer Datei):
## Aufgabe B: PROJECT_CONTEXT.md aktualisieren ## Aufgabe B: PROJECT_CONTEXT.md aktualisieren
Lies `history/summary/PROJECT_CONTEXT.md` und aktualisiere: Lies `docs/history/summary/PROJECT_CONTEXT.md` und aktualisiere:
1. **"Letzte Aktualisierung"** mit heutigem Datum und erledigter Aufgabe 1. **"Letzte Aktualisierung"** mit heutigem Datum und erledigter Aufgabe
2. **"Erledigte Aufgaben"** neue Zeile oben einfügen (neueste zuerst) 2. **"Erledigte Aufgaben"** neue Zeile oben einfügen (neueste zuerst)
3. **"Offene Aufgaben"** Abgehaktes entfernen, Neues hinzufügen 3. **"Offene Aufgaben"** Abgehaktes entfernen, Neues hinzufügen
@ -76,6 +76,6 @@ lesen muss um sofort produktiv zu sein.
Nach Abschluss dieser Aufgabe: Nach Abschluss dieser Aufgabe:
```bash ```bash
git add history/ git add docs/history/
git commit -m "docs: update agent history and project context" git commit -m "docs: update agent history and project context"
``` ```

View file

@ -1,16 +1,30 @@
#!/usr/bin/env fish #!/usr/bin/env fish
# copilot-bootstrap.fish # copilot-bootstrap.fish
# Fügt Copilot-Grundkonfiguration zu einem bestehenden oder neu geklonten Repo hinzu. # Fügt Copilot-Grundkonfiguration zu einem bestehenden oder neu geklonten Repo hinzu.
# Funktions-Parität mit copilot-bootstrap.sh (POSIX-Variante).
# #
# Usage: # Usage:
# fish copilot-bootstrap.fish # aktuelles Verzeichnis # fish copilot-bootstrap.fish # aktuelles Verzeichnis
# fish copilot-bootstrap.fish /path/to/repo # anderes Verzeichnis # fish copilot-bootstrap.fish /path/to/repo # anderes Verzeichnis
# fish copilot-bootstrap.fish --with-update-hook # + post-merge Hook (auto-update nach git pull)
set TEMPLATE_DIR /home/rd13server/.git-templates set TEMPLATE_DIR $HOME/.git-templates
set TARGET (test (count $argv) -gt 0; and echo $argv[1]; or echo (pwd)) set WITH_UPDATE_HOOK 0
set TARGET .
for arg in $argv
switch $arg
case --with-update-hook
set WITH_UPDATE_HOOK 1
case '-*'
# andere Flags ignorieren
case '*'
set TARGET $arg
end
end
if not test -d "$TARGET/.git" if not test -d "$TARGET/.git"
echo "Error: $TARGET is not a git repository" echo "Error: $TARGET is not a git repository" >&2
exit 1 exit 1
end end
@ -20,7 +34,7 @@ echo "Bootstrapping Copilot config in: $TARGET"
if not test -f "$TARGET/.github/copilot-instructions.md" if not test -f "$TARGET/.github/copilot-instructions.md"
mkdir -p "$TARGET/.github" mkdir -p "$TARGET/.github"
cp "$TEMPLATE_DIR/.github/copilot-instructions.md" "$TARGET/.github/copilot-instructions.md" cp "$TEMPLATE_DIR/.github/copilot-instructions.md" "$TARGET/.github/copilot-instructions.md"
echo " ✓ .github/copilot-instructions.md created (fill in TODO sections)" echo " ✓ .github/copilot-instructions.md created (TODO-Felder ausfüllen)"
else else
echo " ─ .github/copilot-instructions.md already exists, skipping" echo " ─ .github/copilot-instructions.md already exists, skipping"
end end
@ -43,7 +57,109 @@ else
echo " ─ .vscode/extensions.json already exists, skipping" echo " ─ .vscode/extensions.json already exists, skipping"
end end
# ── data/ Persistente Service-Daten ────────────────────────────────────────
if not test -d "$TARGET/data"
mkdir -p "$TARGET/data"
touch "$TARGET/data/.gitkeep"
echo " ✓ data/ created (persistente Service-Daten gitignored)"
else
echo " ─ data/ already exists, skipping"
end
# ── docs/history/ Agent-History und Kontext-Summary ────────────────────────
if not test -d "$TARGET/docs/history/prompts"
mkdir -p "$TARGET/docs/history/prompts"
echo " ✓ docs/history/prompts/ created (Agent-Logs committed)"
end
if not test -f "$TARGET/docs/history/summary/PROJECT_CONTEXT.md"
mkdir -p "$TARGET/docs/history/summary"
cp "$TEMPLATE_DIR/docs/history/summary/PROJECT_CONTEXT.md" "$TARGET/docs/history/summary/PROJECT_CONTEXT.md"
echo " ✓ docs/history/summary/PROJECT_CONTEXT.md created (Agent-Kontext committed)"
else
echo " ─ docs/history/summary/PROJECT_CONTEXT.md already exists, skipping"
end
# ── docs/ Zielgruppen-Dokumentation ────────────────────────────────────────
if not test -d "$TARGET/docs"
mkdir -p "$TARGET/docs"
cp "$TEMPLATE_DIR/docs/USER.md" "$TARGET/docs/USER.md"
cp "$TEMPLATE_DIR/docs/ADMIN.md" "$TARGET/docs/ADMIN.md"
cp "$TEMPLATE_DIR/docs/MAINTAINER.md" "$TARGET/docs/MAINTAINER.md"
echo " ✓ docs/ created with USER.md, ADMIN.md, MAINTAINER.md (TODO-Felder ausfüllen)"
else
# Fehlende Zielgruppen-Docs ergänzen ohne vorhandene zu überschreiben
for doc in USER ADMIN MAINTAINER
if not test -f "$TARGET/docs/$doc.md"
cp "$TEMPLATE_DIR/docs/$doc.md" "$TARGET/docs/$doc.md"
echo " ✓ docs/$doc.md created"
else
echo " ─ docs/$doc.md already exists, skipping"
end
end
end
# ── Git-Hooks Quality Gate + History ───────────────────────────────────────
mkdir -p "$TARGET/.git/hooks"
if not test -f "$TARGET/.git/hooks/pre-commit"
cp "$TEMPLATE_DIR/hooks/pre-commit" "$TARGET/.git/hooks/pre-commit"
chmod +x "$TARGET/.git/hooks/pre-commit"
echo " ✓ .git/hooks/pre-commit installed (Quality Gate: Tests + Docs)"
else
echo " ─ .git/hooks/pre-commit already exists, skipping"
end
if not test -f "$TARGET/.git/hooks/post-commit"; and test -f "$TEMPLATE_DIR/hooks/post-commit"
cp "$TEMPLATE_DIR/hooks/post-commit" "$TARGET/.git/hooks/post-commit"
chmod +x "$TARGET/.git/hooks/post-commit"
echo " ✓ .git/hooks/post-commit installed (Auto-History-Log)"
end
# ── post-merge Hook opt-in: automatisches copilot-update nach git pull ──────
if test "$WITH_UPDATE_HOOK" -eq 1
if test -f "$TEMPLATE_DIR/hooks/post-merge"
if not test -f "$TARGET/.git/hooks/post-merge"
cp "$TEMPLATE_DIR/hooks/post-merge" "$TARGET/.git/hooks/post-merge"
chmod +x "$TARGET/.git/hooks/post-merge"
echo " ✓ .git/hooks/post-merge installed (Copilot-Update nach git pull)"
else
echo " ─ .git/hooks/post-merge already exists, skipping"
end
end
end
# ── .gitignore data/ + Windows-ADS ausschließen ───────────────────────────
set -g GITIGNORE "$TARGET/.gitignore"
set -g GITIGNORE_UPDATED 0
# set -g, damit die Funktion den Zähler im Skript-Scope ändern kann (fish-Scoping)
function _append_gitignore --argument-names pattern comment
if not grep -qF "$pattern" "$GITIGNORE" 2>/dev/null
printf '\n%s\n%s\n' "$comment" "$pattern" >> "$GITIGNORE"
set -g GITIGNORE_UPDATED 1
end
end
_append_gitignore "data/**/*" "# Persistente Service-Daten (nie committen!)"
_append_gitignore "!data/.gitkeep" ""
_append_gitignore "*:Zone.Identifier" "# Windows Mark-of-the-Web / NTFS ADS cruft"
if test "$GITIGNORE_UPDATED" -eq 1
echo " ✓ .gitignore aktualisiert (data/ + Windows-ADS excluded)"
else
echo " ─ .gitignore already has required entries, skipping"
end
functions -e _append_gitignore
echo "" echo ""
echo "Done. Next steps:" echo "Done. Nächste Schritte:"
echo " 1. Fill in TODO sections in .github/copilot-instructions.md" echo " 1. TODO-Felder ausfüllen:"
echo " 2. git add .github .vscode && git commit -m 'chore: add copilot workspace config'" echo " - .github/copilot-instructions.md"
echo " - docs/history/summary/PROJECT_CONTEXT.md"
echo " - docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md"
echo " 2. git add .github .vscode docs"
echo " git commit -m 'chore: add copilot workspace config'"
echo " 3. Templates aktuell halten: git copilot-update"
echo ""
echo " Hinweis: Git-Hooks (pre-commit, post-commit) werden NICHT automatisch"
echo " aktualisiert wenn sie bereits existieren. Neue Hook-Versionen holen mit:"
echo " git copilot-update"

View file

@ -63,17 +63,17 @@ else
echo " ─ data/ already exists, skipping" echo " ─ data/ already exists, skipping"
fi fi
# ── history/ Agent-History und Kontext-Summary ───────────────────────────── # ── docs/history/ Agent-History und Kontext-Summary ────────────────────────
if [ ! -d "$TARGET/history/prompts" ]; then if [ ! -d "$TARGET/docs/history/prompts" ]; then
mkdir -p "$TARGET/history/prompts" mkdir -p "$TARGET/docs/history/prompts"
echo " ✓ history/prompts/ created (Agent-Logs committed)" echo " ✓ docs/history/prompts/ created (Agent-Logs committed)"
fi fi
if [ ! -f "$TARGET/history/summary/PROJECT_CONTEXT.md" ]; then if [ ! -f "$TARGET/docs/history/summary/PROJECT_CONTEXT.md" ]; then
mkdir -p "$TARGET/history/summary" mkdir -p "$TARGET/docs/history/summary"
cp "$TEMPLATE_DIR/history/summary/PROJECT_CONTEXT.md" "$TARGET/history/summary/PROJECT_CONTEXT.md" cp "$TEMPLATE_DIR/docs/history/summary/PROJECT_CONTEXT.md" "$TARGET/docs/history/summary/PROJECT_CONTEXT.md"
echo " ✓ history/summary/PROJECT_CONTEXT.md created (Agent-Kontext committed)" echo " ✓ docs/history/summary/PROJECT_CONTEXT.md created (Agent-Kontext committed)"
else else
echo " ─ history/summary/PROJECT_CONTEXT.md already exists, skipping" echo " ─ docs/history/summary/PROJECT_CONTEXT.md already exists, skipping"
fi fi
# ── docs/ Zielgruppen-Dokumentation ──────────────────────────────────────── # ── docs/ Zielgruppen-Dokumentation ────────────────────────────────────────
@ -134,11 +134,12 @@ _append_gitignore() {
fi fi
} }
_append_gitignore "data/**/*" "# Persistente Service-Daten (nie committen!)" _append_gitignore "data/**/*" "# Persistente Service-Daten (nie committen!)"
_append_gitignore "!data/.gitkeep" "" _append_gitignore "!data/.gitkeep" ""
_append_gitignore "*:Zone.Identifier" "# Windows Mark-of-the-Web / NTFS ADS cruft"
if [ "$GITIGNORE_UPDATED" -eq 1 ]; then if [ "$GITIGNORE_UPDATED" -eq 1 ]; then
echo " ✓ .gitignore aktualisiert (data/ excluded)" echo " ✓ .gitignore aktualisiert (data/ + Windows-ADS excluded)"
else else
echo " ─ .gitignore already has required entries, skipping" echo " ─ .gitignore already has required entries, skipping"
fi fi
@ -147,9 +148,9 @@ echo ""
echo "Done. Nächste Schritte:" echo "Done. Nächste Schritte:"
echo " 1. TODO-Felder ausfüllen:" echo " 1. TODO-Felder ausfüllen:"
echo " - .github/copilot-instructions.md" echo " - .github/copilot-instructions.md"
echo " - history/summary/PROJECT_CONTEXT.md" echo " - docs/history/summary/PROJECT_CONTEXT.md"
echo " - docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md" echo " - docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md"
echo " 2. git add .github .vscode docs history .gitignore" echo " 2. git add .github .vscode docs"
echo " git commit -m 'chore: add copilot workspace config'" echo " git commit -m 'chore: add copilot workspace config'"
echo " 3. Templates aktuell halten: git copilot-update" echo " 3. Templates aktuell halten: git copilot-update"
echo "" echo ""

View file

@ -11,44 +11,142 @@
# fish ~/.local/bin/copilot-update.fish # fish ~/.local/bin/copilot-update.fish
# git copilot-update (via Alias, ruft copilot-update.sh auf) # git copilot-update (via Alias, ruft copilot-update.sh auf)
set SETUP_REPO_SSH "ssh://git@192.168.178.6:2222/cschulz/rd13_copilot_setup.git" # ── Konfiguration laden: env > config-file > leer ─────────────────────────
set SETUP_REPO_HTTP "http://192.168.178.6:8083/cschulz/rd13_copilot_setup.git" # Env-Variablen (Vorrang):
# COPILOT_SETUP_REMOTE_SSH / _HTTP Remote-URLs des Setup-Repos
# COPILOT_SETUP_DIR lokaler Klon/Arbeitskopie (Offline)
# COPILOT_SETUP_CONFIG alternativer Pfad zur Config-Datei
# Config-Datei (sh-Syntax KEY="value", wird geparst): $XDG_CONFIG_HOME/copilot-setup/config
# Standalone-Skript -> keine gemeinsame Lib sourcebar; gleiche Aufloesung in deploy.fish.
if set -q COPILOT_SETUP_DIR # Wert fuer KEY aus sh-style Config lesen (KEY="value" | KEY=value); letzte Definition gewinnt
function _cfg_get --argument-names file key
test -f "$file"; or return 1
set -l line (grep -E "^[[:space:]]*$key=" "$file" 2>/dev/null | tail -n1)
test -n "$line"; or return 1
set -l val (string replace -r "^[[:space:]]*$key=" '' -- $line)
set val (string trim -- $val)
set val (string trim --chars '"' -- $val)
set val (string trim --chars "'" -- $val)
printf '%s' $val
end
# VS Code User-Verzeichnis portabel ueber Editionen/OS ermitteln (identisch zu deploy.fish)
function detect_vscode_user_dir
for d in \
"$HOME/.vscode-server/data/User" \
"$HOME/.vscode-server-insiders/data/User" \
"$HOME/Library/Application Support/Code/User" \
"$HOME/Library/Application Support/Code - Insiders/User" \
"$HOME/Library/Application Support/VSCodium/User" \
"$HOME/Library/Application Support/Cursor/User" \
"$HOME/.config/Code/User" \
"$HOME/.config/Code - Insiders/User" \
"$HOME/.config/VSCodium/User" \
"$HOME/.config/Cursor/User" \
"$HOME/.var/app/com.visualstudio.code/config/Code/User" \
"/mnt/c/Users/$USER/AppData/Roaming/Code/User" \
"/mnt/c/Users/$USER/AppData/Roaming/Code - Insiders/User"
if test -d "$d"
echo $d
return 0
end
end
switch (uname -s)
case Darwin
echo "$HOME/Library/Application Support/Code/User"
case '*'
echo "$HOME/.config/Code/User"
end
end
# Config-Datei-Pfad bestimmen
if set -q COPILOT_SETUP_CONFIG
set CONFIG_FILE $COPILOT_SETUP_CONFIG
else if set -q XDG_CONFIG_HOME
set CONFIG_FILE $XDG_CONFIG_HOME/copilot-setup/config
else
set CONFIG_FILE $HOME/.config/copilot-setup/config
end
# Remote/Cache aufloesen: env hat Vorrang, sonst Config, sonst Default
if set -q COPILOT_SETUP_REMOTE_SSH; and test -n "$COPILOT_SETUP_REMOTE_SSH"
set SETUP_REPO_SSH $COPILOT_SETUP_REMOTE_SSH
else
set SETUP_REPO_SSH (_cfg_get $CONFIG_FILE COPILOT_SETUP_REMOTE_SSH)
end
if set -q COPILOT_SETUP_REMOTE_HTTP; and test -n "$COPILOT_SETUP_REMOTE_HTTP"
set SETUP_REPO_HTTP $COPILOT_SETUP_REMOTE_HTTP
else
set SETUP_REPO_HTTP (_cfg_get $CONFIG_FILE COPILOT_SETUP_REMOTE_HTTP)
end
if set -q COPILOT_SETUP_DIR; and test -n "$COPILOT_SETUP_DIR"
set CACHE_DIR $COPILOT_SETUP_DIR set CACHE_DIR $COPILOT_SETUP_DIR
else else
set CACHE_DIR $HOME/.copilot-setup set CACHE_DIR (_cfg_get $CONFIG_FILE COPILOT_SETUP_DIR)
test -n "$CACHE_DIR"; or set CACHE_DIR $HOME/.copilot-setup
end end
echo "=== Copilot Update ===" echo "=== Copilot Update ==="
# ── 1. Setup-Repo Cache aktuell halten ─────────────────────────────────────── # ── 1. Setup-Repo Cache aktuell halten ───────────────────────────────────────
set HAVE_REMOTE 0
if test -n "$SETUP_REPO_SSH"; or test -n "$SETUP_REPO_HTTP"
set HAVE_REMOTE 1
end
set SOURCE_OK 0
if test -d $CACHE_DIR/.git if test -d $CACHE_DIR/.git
echo " → Pulling latest from setup repo..." if test $HAVE_REMOTE -eq 1
if git -C $CACHE_DIR pull --ff-only --quiet 2>/dev/null echo " → Pulling latest from setup repo..."
echo " ✓ Cache aktualisiert: $CACHE_DIR" if git -C $CACHE_DIR pull --ff-only --quiet 2>/dev/null
echo " ✓ Cache aktualisiert: $CACHE_DIR"
else
echo " ⚠ git pull fehlgeschlagen nutze vorhandenen Cache (offline)"
end
else else
echo " ✗ git pull fehlgeschlagen versuche neu zu klonen..." echo " ─ Kein Remote konfiguriert nutze lokalen Klon: $CACHE_DIR"
rm -rf $CACHE_DIR end
set SOURCE_OK 1
else if test -d $CACHE_DIR/git-templates
echo " ─ Lokale Setup-Quelle ohne .git (Offline-Betrieb): $CACHE_DIR"
set SOURCE_OK 1
else
if test -n "$SETUP_REPO_SSH"
echo " → Klone Setup-Repo (SSH)..."
if git clone --quiet $SETUP_REPO_SSH $CACHE_DIR 2>/dev/null
echo " ✓ Geklont via SSH"
set SOURCE_OK 1
else
echo " ✗ SSH fehlgeschlagen"
end
end
if test $SOURCE_OK -eq 0; and test -n "$SETUP_REPO_HTTP"
echo " → Klone Setup-Repo (HTTP)..."
if git clone --quiet $SETUP_REPO_HTTP $CACHE_DIR 2>/dev/null
echo " ✓ Geklont via HTTP"
set SOURCE_OK 1
else
echo " ✗ HTTP fehlgeschlagen"
end
end end
end end
if not test -d $CACHE_DIR/.git if test $SOURCE_OK -eq 0
echo " → Klone Setup-Repo (SSH)..." echo ""
if git clone --quiet $SETUP_REPO_SSH $CACHE_DIR 2>/dev/null echo " ⚠ Keine Setup-Quelle verfuegbar Update uebersprungen."
echo " ✓ Geklont via SSH" if test $HAVE_REMOTE -eq 1
echo " Remote nicht erreichbar:"
test -n "$SETUP_REPO_SSH"; and echo " SSH: $SETUP_REPO_SSH"
test -n "$SETUP_REPO_HTTP"; and echo " HTTP: $SETUP_REPO_HTTP"
else else
echo " ✗ SSH fehlgeschlagen versuche HTTP-Fallback..." echo " Kein Remote konfiguriert. Setze COPILOT_SETUP_REMOTE_SSH/_HTTP,"
if git clone --quiet $SETUP_REPO_HTTP $CACHE_DIR 2>/dev/null echo " COPILOT_SETUP_DIR (lokaler Klon) oder lege $CONFIG_FILE an."
echo " ✓ Geklont via HTTP"
else
echo ""
echo " ✗ FEHLER: Setup-Repo nicht erreichbar."
echo " SSH: $SETUP_REPO_SSH"
echo " HTTP: $SETUP_REPO_HTTP"
exit 1
end
end end
echo " (Kein Fehler ohne Quelle gibt es nichts zu aktualisieren.)"
exit 0
end end
set SOURCE $CACHE_DIR set SOURCE $CACHE_DIR
@ -68,7 +166,7 @@ end
set GIT_TEMPLATE_DIR $HOME/.git-templates set GIT_TEMPLATE_DIR $HOME/.git-templates
mkdir -p $GIT_TEMPLATE_DIR/.github $GIT_TEMPLATE_DIR/.vscode \ mkdir -p $GIT_TEMPLATE_DIR/.github $GIT_TEMPLATE_DIR/.vscode \
$GIT_TEMPLATE_DIR/hooks $GIT_TEMPLATE_DIR/docs \ $GIT_TEMPLATE_DIR/hooks $GIT_TEMPLATE_DIR/docs \
$GIT_TEMPLATE_DIR/history/summary $GIT_TEMPLATE_DIR/docs/history/summary
cp $SOURCE/git-templates/.github/copilot-instructions.md $GIT_TEMPLATE_DIR/.github/ cp $SOURCE/git-templates/.github/copilot-instructions.md $GIT_TEMPLATE_DIR/.github/
cp $SOURCE/git-templates/.vscode/settings.json $GIT_TEMPLATE_DIR/.vscode/ cp $SOURCE/git-templates/.vscode/settings.json $GIT_TEMPLATE_DIR/.vscode/
@ -82,20 +180,14 @@ end
cp $SOURCE/git-templates/docs/USER.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/docs/USER.md $GIT_TEMPLATE_DIR/docs/
cp $SOURCE/git-templates/docs/ADMIN.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/docs/ADMIN.md $GIT_TEMPLATE_DIR/docs/
cp $SOURCE/git-templates/docs/MAINTAINER.md $GIT_TEMPLATE_DIR/docs/ cp $SOURCE/git-templates/docs/MAINTAINER.md $GIT_TEMPLATE_DIR/docs/
cp $SOURCE/git-templates/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/history/summary/ cp $SOURCE/git-templates/docs/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/docs/history/summary/
echo " ✓ ~/.git-templates/ aktualisiert" echo " ✓ ~/.git-templates/ aktualisiert"
# ── 3. VS Code Prompt-Dateien aktualisieren ─────────────────────────────────── # ── 3. VS Code Prompt-Dateien aktualisieren ───────────────────────────────────
if test -d $HOME/.vscode-server/data/User set VSCODE_USER (detect_vscode_user_dir)
set VSCODE_USER $HOME/.vscode-server/data/User
else if test -d "$HOME/Library/Application Support/Code/User"
set VSCODE_USER "$HOME/Library/Application Support/Code/User"
else
set VSCODE_USER $HOME/.config/Code/User
end
if test -d $VSCODE_USER if test -d "$VSCODE_USER"
mkdir -p $VSCODE_USER/prompts mkdir -p $VSCODE_USER/prompts
set PROMPTS_UPDATED 0 set PROMPTS_UPDATED 0
for f in $SOURCE/prompts/*.prompt.md for f in $SOURCE/prompts/*.prompt.md
@ -121,7 +213,22 @@ end
echo "" echo ""
echo " Git-Repo erkannt: $REPO_ROOT" echo " Git-Repo erkannt: $REPO_ROOT"
# ── 4-pre. Migration: history/ → docs/history/ (einmalig, automatisch) ──────
# Alte Repos haben history/ im Repo-Root. Neuer Standard: docs/history/.
if test -d "$REPO_ROOT/history"; and not test -d "$REPO_ROOT/docs/history"
echo " → Migriere history/ → docs/history/ ..."
mkdir -p "$REPO_ROOT/docs"
if git -C "$REPO_ROOT" mv history docs/history 2>/dev/null
echo " ✓ history/ → docs/history/ verschoben (git mv zum Commit vormerken)"
else if mv "$REPO_ROOT/history" "$REPO_ROOT/docs/history" 2>/dev/null
echo " ✓ history/ → docs/history/ verschoben (mv)"
else
echo " ✗ Migration fehlgeschlagen bitte manuell: git mv history docs/history"
end
else if test -d "$REPO_ROOT/history"; and test -d "$REPO_ROOT/docs/history"
echo " ⚠ history/ UND docs/history/ vorhanden bitte manuell zusammenführen:"
echo " git mv history/prompts/* docs/history/prompts/ && git rm -r history"
end
# ── 4a. Git-Hooks aktualisieren ─────────────────────────────────────────────── # ── 4a. Git-Hooks aktualisieren ───────────────────────────────────────────────
set HOOKS_DIR $REPO_ROOT/.git/hooks set HOOKS_DIR $REPO_ROOT/.git/hooks
mkdir -p $HOOKS_DIR mkdir -p $HOOKS_DIR

View file

@ -11,38 +11,114 @@
# copilot-update.sh # aktuelles Verzeichnis (Git-Repo optional) # copilot-update.sh # aktuelles Verzeichnis (Git-Repo optional)
# git copilot-update # via Git-Alias # git copilot-update # via Git-Alias
SETUP_REPO_SSH="ssh://git@192.168.178.6:2222/cschulz/rd13_copilot_setup.git" # ── Konfiguration laden: env > config-file > leer ─────────────────────────
SETUP_REPO_HTTP="http://192.168.178.6:8083/cschulz/rd13_copilot_setup.git" # Env-Variablen (Vorrang):
# COPILOT_SETUP_REMOTE_SSH / _HTTP Remote-URLs des Setup-Repos
# COPILOT_SETUP_DIR lokaler Klon/Arbeitskopie (Offline)
# COPILOT_SETUP_CONFIG alternativer Pfad zur Config-Datei
# Config-Datei (sh-Syntax, gesourct): $XDG_CONFIG_HOME/copilot-setup/config
# Standalone-Skript -> keine gemeinsame Lib sourcebar; gleiche Aufloesung in
# deploy.sh. Bei Aenderungen beide Stellen pflegen.
_env_ssh="${COPILOT_SETUP_REMOTE_SSH:-}"
_env_http="${COPILOT_SETUP_REMOTE_HTTP:-}"
_env_dir="${COPILOT_SETUP_DIR:-}"
CONFIG_FILE="${COPILOT_SETUP_CONFIG:-${XDG_CONFIG_HOME:-$HOME/.config}/copilot-setup/config}"
if [ -f "$CONFIG_FILE" ]; then
# shellcheck source=/dev/null
. "$CONFIG_FILE"
fi
# Env ueberschreibt Werte aus der Config-Datei
[ -n "$_env_ssh" ] && COPILOT_SETUP_REMOTE_SSH="$_env_ssh"
[ -n "$_env_http" ] && COPILOT_SETUP_REMOTE_HTTP="$_env_http"
[ -n "$_env_dir" ] && COPILOT_SETUP_DIR="$_env_dir"
SETUP_REPO_SSH="${COPILOT_SETUP_REMOTE_SSH:-}"
SETUP_REPO_HTTP="${COPILOT_SETUP_REMOTE_HTTP:-}"
CACHE_DIR="${COPILOT_SETUP_DIR:-$HOME/.copilot-setup}" CACHE_DIR="${COPILOT_SETUP_DIR:-$HOME/.copilot-setup}"
have_remote() { [ -n "$SETUP_REPO_SSH" ] || [ -n "$SETUP_REPO_HTTP" ]; }
clone_setup_repo() {
if [ -n "$SETUP_REPO_SSH" ]; then
echo " → Klone Setup-Repo (SSH)..."
if git clone --quiet "$SETUP_REPO_SSH" "$CACHE_DIR" 2>/dev/null; then
echo " ✓ Geklont via SSH"; return 0
fi
echo " ✗ SSH fehlgeschlagen"
fi
if [ -n "$SETUP_REPO_HTTP" ]; then
echo " → Klone Setup-Repo (HTTP)..."
if git clone --quiet "$SETUP_REPO_HTTP" "$CACHE_DIR" 2>/dev/null; then
echo " ✓ Geklont via HTTP"; return 0
fi
echo " ✗ HTTP fehlgeschlagen"
fi
return 1
}
# VS Code User-Verzeichnis portabel ueber Editionen/OS ermitteln.
# Identischer Block in deploy.sh (Standalone -> keine Lib sourcebar).
detect_vscode_user_dir() {
for d in \
"$HOME/.vscode-server/data/User" \
"$HOME/.vscode-server-insiders/data/User" \
"$HOME/Library/Application Support/Code/User" \
"$HOME/Library/Application Support/Code - Insiders/User" \
"$HOME/Library/Application Support/VSCodium/User" \
"$HOME/Library/Application Support/Cursor/User" \
"$HOME/.config/Code/User" \
"$HOME/.config/Code - Insiders/User" \
"$HOME/.config/VSCodium/User" \
"$HOME/.config/Cursor/User" \
"$HOME/.var/app/com.visualstudio.code/config/Code/User" \
"/mnt/c/Users/${USER:-}/AppData/Roaming/Code/User" \
"/mnt/c/Users/${USER:-}/AppData/Roaming/Code - Insiders/User"
do
if [ -d "$d" ]; then
printf '%s\n' "$d"
return 0
fi
done
case "$(uname -s)" in
Darwin) printf '%s\n' "$HOME/Library/Application Support/Code/User" ;;
*) printf '%s\n' "$HOME/.config/Code/User" ;;
esac
}
echo "=== Copilot Update ===" echo "=== Copilot Update ==="
# ── 1. Setup-Repo Cache aktuell halten ─────────────────────────────────────── # ── 1. Setup-Repo Cache aktuell halten ───────────────────────────────────────
if [ -d "$CACHE_DIR/.git" ]; then if [ -d "$CACHE_DIR/.git" ]; then
echo " → Pulling latest from setup repo..." if have_remote; then
if git -C "$CACHE_DIR" pull --ff-only --quiet 2>/dev/null; then echo " → Pulling latest from setup repo..."
echo " ✓ Cache aktualisiert: $CACHE_DIR" if git -C "$CACHE_DIR" pull --ff-only --quiet 2>/dev/null; then
else echo " ✓ Cache aktualisiert: $CACHE_DIR"
echo " ✗ git pull fehlgeschlagen versuche neu zu klonen..."
rm -rf "$CACHE_DIR"
fi
fi
if [ ! -d "$CACHE_DIR/.git" ]; then
echo " → Klone Setup-Repo (SSH)..."
if git clone --quiet "$SETUP_REPO_SSH" "$CACHE_DIR" 2>/dev/null; then
echo " ✓ Geklont via SSH"
else
echo " ✗ SSH fehlgeschlagen versuche HTTP-Fallback..."
if git clone --quiet "$SETUP_REPO_HTTP" "$CACHE_DIR" 2>/dev/null; then
echo " ✓ Geklont via HTTP"
else else
echo "" echo " ⚠ git pull fehlgeschlagen nutze vorhandenen Cache (offline)"
echo " ✗ FEHLER: Setup-Repo nicht erreichbar."
echo " SSH: $SETUP_REPO_SSH"
echo " HTTP: $SETUP_REPO_HTTP"
exit 1
fi fi
else
echo " ─ Kein Remote konfiguriert nutze lokalen Klon: $CACHE_DIR"
fi
elif [ -d "$CACHE_DIR/git-templates" ]; then
echo " ─ Lokale Setup-Quelle ohne .git (Offline-Betrieb): $CACHE_DIR"
else
if have_remote && clone_setup_repo; then
:
else
echo ""
echo " ⚠ Keine Setup-Quelle verfuegbar Update uebersprungen."
if have_remote; then
echo " Remote nicht erreichbar:"
[ -n "$SETUP_REPO_SSH" ] && echo " SSH: $SETUP_REPO_SSH"
[ -n "$SETUP_REPO_HTTP" ] && echo " HTTP: $SETUP_REPO_HTTP"
else
echo " Kein Remote konfiguriert. Setze COPILOT_SETUP_REMOTE_SSH/_HTTP,"
echo " COPILOT_SETUP_DIR (lokaler Klon) oder lege $CONFIG_FILE an."
fi
echo " (Kein Fehler ohne Quelle gibt es nichts zu aktualisieren.)"
exit 0
fi fi
fi fi
@ -64,7 +140,7 @@ GIT_TEMPLATE_DIR="$HOME/.git-templates"
# ── 2. ~/.git-templates/ aktualisieren ────────────────────────────────────── # ── 2. ~/.git-templates/ aktualisieren ──────────────────────────────────────
mkdir -p "$GIT_TEMPLATE_DIR/.github" "$GIT_TEMPLATE_DIR/.vscode" \ mkdir -p "$GIT_TEMPLATE_DIR/.github" "$GIT_TEMPLATE_DIR/.vscode" \
"$GIT_TEMPLATE_DIR/hooks" "$GIT_TEMPLATE_DIR/docs" \ "$GIT_TEMPLATE_DIR/hooks" "$GIT_TEMPLATE_DIR/docs" \
"$GIT_TEMPLATE_DIR/history/summary" "$GIT_TEMPLATE_DIR/docs/history/summary"
cp "$SOURCE/git-templates/.github/copilot-instructions.md" "$GIT_TEMPLATE_DIR/.github/" cp "$SOURCE/git-templates/.github/copilot-instructions.md" "$GIT_TEMPLATE_DIR/.github/"
cp "$SOURCE/git-templates/.vscode/settings.json" "$GIT_TEMPLATE_DIR/.vscode/" cp "$SOURCE/git-templates/.vscode/settings.json" "$GIT_TEMPLATE_DIR/.vscode/"
@ -78,18 +154,12 @@ fi
cp "$SOURCE/git-templates/docs/USER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$SOURCE/git-templates/docs/USER.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$SOURCE/git-templates/docs/ADMIN.md" "$GIT_TEMPLATE_DIR/docs/" cp "$SOURCE/git-templates/docs/ADMIN.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$SOURCE/git-templates/docs/MAINTAINER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$SOURCE/git-templates/docs/MAINTAINER.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$SOURCE/git-templates/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/history/summary/" cp "$SOURCE/git-templates/docs/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/docs/history/summary/"
echo " ✓ ~/.git-templates/ aktualisiert" echo " ✓ ~/.git-templates/ aktualisiert"
# ── 3. VS Code Prompt-Dateien aktualisieren ─────────────────────────────────── # ── 3. VS Code Prompt-Dateien aktualisieren ───────────────────────────────────
if [ -d "$HOME/.vscode-server/data/User" ]; then VSCODE_USER="$(detect_vscode_user_dir)"
VSCODE_USER="$HOME/.vscode-server/data/User"
elif [ -d "$HOME/Library/Application Support/Code/User" ]; then
VSCODE_USER="$HOME/Library/Application Support/Code/User"
else
VSCODE_USER="$HOME/.config/Code/User"
fi
if [ -d "$VSCODE_USER" ]; then if [ -d "$VSCODE_USER" ]; then
mkdir -p "$VSCODE_USER/prompts" mkdir -p "$VSCODE_USER/prompts"
@ -118,11 +188,29 @@ fi
echo "" echo ""
echo " Git-Repo erkannt: $REPO_ROOT" echo " Git-Repo erkannt: $REPO_ROOT"
# ── 4a. Git-Hooks aktualisieren ─────────────────────────────────────────────── # ── 4-pre. Migration: history/ → docs/history/ (einmalig, automatisch) ──────
# Alte Repos haben history/ im Repo-Root. Neuer Standard: docs/history/.
# Wird beim ersten Update automatisch verschoben (git mv, Fallback mv).
if [ -d "$REPO_ROOT/history" ] && [ ! -d "$REPO_ROOT/docs/history" ]; then
echo " → Migriere history/ → docs/history/ ..."
mkdir -p "$REPO_ROOT/docs"
if git -C "$REPO_ROOT" mv history docs/history 2>/dev/null; then
echo " ✓ history/ → docs/history/ verschoben (git mv zum Commit vormerken)"
elif mv "$REPO_ROOT/history" "$REPO_ROOT/docs/history" 2>/dev/null; then
echo " ✓ history/ → docs/history/ verschoben (mv)"
else
echo " ✗ Migration fehlgeschlagen bitte manuell: git mv history docs/history"
fi
elif [ -d "$REPO_ROOT/history" ] && [ -d "$REPO_ROOT/docs/history" ]; then
echo " ⚠ history/ UND docs/history/ vorhanden bitte manuell zusammenführen:"
echo " git mv history/prompts/* docs/history/prompts/ && git rm -r history"
fi
# ── 4a. Git-Hooks aktualisieren ──────────────────────────────────────
HOOKS_DIR="$REPO_ROOT/.git/hooks" HOOKS_DIR="$REPO_ROOT/.git/hooks"
mkdir -p "$HOOKS_DIR" mkdir -p "$HOOKS_DIR"
HOOKS_UPDATED=0 HOOKS_UPDATED=0
# shellcheck disable=SC2043 # bewusst erweiterbar: weitere Hook-Namen koennen ergaenzt werden
for hook in pre-commit; do for hook in pre-commit; do
if [ -f "$SOURCE/git-templates/hooks/$hook" ]; then if [ -f "$SOURCE/git-templates/hooks/$hook" ]; then
cp "$SOURCE/git-templates/hooks/$hook" "$HOOKS_DIR/$hook" cp "$SOURCE/git-templates/hooks/$hook" "$HOOKS_DIR/$hook"

View file

@ -1,6 +1,22 @@
#!/usr/bin/env fish #!/usr/bin/env fish
# deploy.fish Copilot-Setup auf Linux mit fish-Shell deployen # deploy.fish Copilot-Setup auf Linux mit fish-Shell deployen
# Usage: fish scripts/deploy.fish # Usage:
# fish scripts/deploy.fish # Standard-Deploy (nicht-invasiv)
# fish scripts/deploy.fish --with-self-update-hook # + post-merge Auto-Deploy im Setup-Repo
#
# Hinweis: Setzt KEINEN globalen 'git init'-Alias und KEIN init.templateDir.
# Standard-'git init'/'git clone' bleiben unberuehrt. Opt-in: 'git init-copilot'.
set WITH_SELF_HOOK 0
for arg in $argv
switch $arg
case --with-self-update-hook
set WITH_SELF_HOOK 1
case '*'
echo "Unbekanntes Argument: $arg" >&2
exit 2
end
end
set REPO_DIR (dirname (status filename))/.. set REPO_DIR (dirname (status filename))/..
set REPO_DIR (realpath $REPO_DIR) set REPO_DIR (realpath $REPO_DIR)
@ -8,18 +24,37 @@ set REPO_DIR (realpath $REPO_DIR)
echo "=== Copilot Setup Deploy (Linux/fish) ===" echo "=== Copilot Setup Deploy (Linux/fish) ==="
echo "Source: $REPO_DIR" echo "Source: $REPO_DIR"
# ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── # VS Code User-Verzeichnis portabel ueber Editionen/OS ermitteln (identisch zu copilot-update.fish)
# Remote (VS Code Server) function detect_vscode_user_dir
if test -d /home/(whoami)/.vscode-server/data/User for d in \
set VSCODE_USER /home/(whoami)/.vscode-server/data/User "$HOME/.vscode-server/data/User" \
# Flatpak "$HOME/.vscode-server-insiders/data/User" \
else if test -d $HOME/.var/app/com.visualstudio.code/config/Code/User "$HOME/Library/Application Support/Code/User" \
set VSCODE_USER $HOME/.var/app/com.visualstudio.code/config/Code/User "$HOME/Library/Application Support/Code - Insiders/User" \
# Standard Linux "$HOME/Library/Application Support/VSCodium/User" \
else "$HOME/Library/Application Support/Cursor/User" \
set VSCODE_USER $HOME/.config/Code/User "$HOME/.config/Code/User" \
"$HOME/.config/Code - Insiders/User" \
"$HOME/.config/VSCodium/User" \
"$HOME/.config/Cursor/User" \
"$HOME/.var/app/com.visualstudio.code/config/Code/User" \
"/mnt/c/Users/$USER/AppData/Roaming/Code/User" \
"/mnt/c/Users/$USER/AppData/Roaming/Code - Insiders/User"
if test -d "$d"
echo $d
return 0
end
end
switch (uname -s)
case Darwin
echo "$HOME/Library/Application Support/Code/User"
case '*'
echo "$HOME/.config/Code/User"
end
end end
# ── 1. VS Code User-Verzeichnis ermitteln ─────────────────────────────────────
set VSCODE_USER (detect_vscode_user_dir)
echo "VS Code User dir: $VSCODE_USER" echo "VS Code User dir: $VSCODE_USER"
# ── 2. User settings.json mergen / anlegen ──────────────────────────────────── # ── 2. User settings.json mergen / anlegen ────────────────────────────────────
@ -48,7 +83,7 @@ end
set GIT_TEMPLATE_DIR $HOME/.git-templates set GIT_TEMPLATE_DIR $HOME/.git-templates
mkdir -p $GIT_TEMPLATE_DIR/.github $GIT_TEMPLATE_DIR/.vscode \ mkdir -p $GIT_TEMPLATE_DIR/.github $GIT_TEMPLATE_DIR/.vscode \
$GIT_TEMPLATE_DIR/hooks $GIT_TEMPLATE_DIR/docs \ $GIT_TEMPLATE_DIR/hooks $GIT_TEMPLATE_DIR/docs \
$GIT_TEMPLATE_DIR/history/summary $GIT_TEMPLATE_DIR/docs/history/summary
cp $REPO_DIR/git-templates/.github/copilot-instructions.md $GIT_TEMPLATE_DIR/.github/ cp $REPO_DIR/git-templates/.github/copilot-instructions.md $GIT_TEMPLATE_DIR/.github/
cp $REPO_DIR/git-templates/.vscode/settings.json $GIT_TEMPLATE_DIR/.vscode/ cp $REPO_DIR/git-templates/.vscode/settings.json $GIT_TEMPLATE_DIR/.vscode/
cp $REPO_DIR/git-templates/.vscode/extensions.json $GIT_TEMPLATE_DIR/.vscode/ cp $REPO_DIR/git-templates/.vscode/extensions.json $GIT_TEMPLATE_DIR/.vscode/
@ -57,10 +92,16 @@ chmod +x $GIT_TEMPLATE_DIR/hooks/pre-commit
cp $REPO_DIR/git-templates/docs/USER.md $GIT_TEMPLATE_DIR/docs/ cp $REPO_DIR/git-templates/docs/USER.md $GIT_TEMPLATE_DIR/docs/
cp $REPO_DIR/git-templates/docs/ADMIN.md $GIT_TEMPLATE_DIR/docs/ cp $REPO_DIR/git-templates/docs/ADMIN.md $GIT_TEMPLATE_DIR/docs/
cp $REPO_DIR/git-templates/docs/MAINTAINER.md $GIT_TEMPLATE_DIR/docs/ cp $REPO_DIR/git-templates/docs/MAINTAINER.md $GIT_TEMPLATE_DIR/docs/
cp $REPO_DIR/git-templates/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/history/summary/ cp $REPO_DIR/git-templates/docs/history/summary/PROJECT_CONTEXT.md $GIT_TEMPLATE_DIR/docs/history/summary/
git config --global init.templateDir $GIT_TEMPLATE_DIR
echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR" echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR"
echo " ✓ git config init.templateDir set" # init.templateDir bewusst NICHT global setzen (sonst erbt jeder git init/clone den Gate).
set CURRENT_TPL (git config --global --get init.templateDir 2>/dev/null)
if test "$CURRENT_TPL" = "$GIT_TEMPLATE_DIR"
git config --global --unset init.templateDir
echo " ✓ altes globales init.templateDir entfernt (nicht mehr invasiv)"
else
echo " ─ init.templateDir nicht global gesetzt (gewollt)"
end
# ── 5. Bootstrap- & Update-Skripte ─────────────────────────────────────────── # ── 5. Bootstrap- & Update-Skripte ───────────────────────────────────────────
mkdir -p $HOME/.local/bin mkdir -p $HOME/.local/bin
@ -81,29 +122,38 @@ end
# ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ────────── # ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ──────────
# Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop). # Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop).
git config --global alias.init '!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' # Kein Override des Standard-'git init' mehr. Frueheren invasiven Alias entfernen.
echo " ✓ git alias 'init' gesetzt (führt copilot-bootstrap.sh automatisch aus)" set CURRENT_INIT_ALIAS (git config --global --get alias.init 2>/dev/null)
if string match -q '*copilot-bootstrap*' -- "$CURRENT_INIT_ALIAS"
git config --global --unset alias.init
echo " ✓ alter invasiver 'git init'-Alias entfernt"
end
# Opt-in: explizites 'git init-copilot' macht git init + bootstrap.
git config --global 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'
echo " ✓ git alias 'init-copilot' gesetzt (opt-in: git init + copilot-bootstrap)"
git config --global alias.copilot-update '!~/.local/bin/copilot-update.sh' git config --global alias.copilot-update '!~/.local/bin/copilot-update.sh'
echo " ✓ git alias 'copilot-update' gesetzt (aktualisiert Templates & Prompts)" echo " ✓ git alias 'copilot-update' gesetzt (aktualisiert Templates & Prompts)"
# ── 7. post-merge + post-commit Hook für dieses Setup-Repo ─────────────────── # ── 7. post-merge + post-commit Hook für dieses Setup-Repo ───────────────────
set SELF_HOOKS_DIR $REPO_DIR/.git/hooks set SELF_HOOKS_DIR $REPO_DIR/.git/hooks
if test -d $SELF_HOOKS_DIR if test $WITH_SELF_HOOK -eq 1
echo '#!/usr/bin/env sh if test -d $SELF_HOOKS_DIR
echo '#!/usr/bin/env sh
# post-merge Auto-Deploy nach git pull auf dem Setup-Repo # post-merge Auto-Deploy nach git pull auf dem Setup-Repo
echo "" echo ""
echo " [post-merge] Setup-Repo aktualisiert deploye Templates neu..." echo " [post-merge] Setup-Repo aktualisiert deploye Templates neu..."
SCRIPT_DIR="$(cd "$(dirname "$0")/../../scripts" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")/../../scripts" && pwd)"
bash "$SCRIPT_DIR/deploy.sh"' > $SELF_HOOKS_DIR/post-merge bash "$SCRIPT_DIR/deploy.sh"' > $SELF_HOOKS_DIR/post-merge
chmod +x $SELF_HOOKS_DIR/post-merge chmod +x $SELF_HOOKS_DIR/post-merge
echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)" echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)"
# post-commit aus git-templates kopieren (History-Logs) end
cp $REPO_DIR/git-templates/hooks/post-commit $SELF_HOOKS_DIR/post-commit else
chmod +x $SELF_HOOKS_DIR/post-commit echo " ─ post-merge Auto-Deploy nicht installiert (opt-in: --with-self-update-hook)"
echo " ✓ post-commit Hook im Setup-Repo installiert (History-Logs)"
end end
echo "" echo ""
echo "=== Done ===" echo "=== Done ==="
echo "Next: Activate Settings Sync in VS Code (Ctrl+Shift+P → 'Settings Sync: Turn On')" echo "Next: Activate Settings Sync in VS Code (Ctrl+Shift+P → 'Settings Sync: Turn On')"
echo " Templates aktuell halten: git copilot-update (in jedem Repo)" echo " Neues Repo mit Copilot-Setup: git init-copilot [pfad]"
echo " Bestehendes Repo ausstatten: copilot-bootstrap.sh [pfad]"
echo " Templates aktuell halten: git copilot-update (in jedem Repo)"

View file

@ -1,25 +1,58 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# deploy.sh Copilot-Setup auf macOS oder Linux mit bash deployen # deploy.sh Copilot-Setup auf macOS oder Linux mit bash deployen
# Usage: bash scripts/deploy.sh # Usage:
# bash scripts/deploy.sh # Standard-Deploy (nicht-invasiv)
# bash scripts/deploy.sh --with-self-update-hook # + post-merge Auto-Deploy im Setup-Repo
#
# Hinweis: Setzt KEINEN globalen 'git init'-Alias und KEIN init.templateDir.
# Standard-'git init'/'git clone' bleiben unberuehrt. Opt-in pro Repo:
# git init-copilot [pfad] (Alias wird hier angelegt)
# copilot-bootstrap.sh [pfad] (bestehende Repos ausstatten)
set -euo pipefail set -euo pipefail
WITH_SELF_HOOK=0
for arg in "$@"; do
case "$arg" in
--with-self-update-hook) WITH_SELF_HOOK=1 ;;
*) echo "Unbekanntes Argument: $arg" >&2; exit 2 ;;
esac
done
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
echo "=== Copilot Setup Deploy (bash) ===" echo "=== Copilot Setup Deploy (bash) ==="
echo "Source: $REPO_DIR" echo "Source: $REPO_DIR"
# ── 1. VS Code User-Verzeichnis ermitteln ───────────────────────────────────── # VS Code User-Verzeichnis portabel ermitteln (identisch zu copilot-update.sh)
if [[ "$OSTYPE" == "darwin"* ]]; then detect_vscode_user_dir() {
VSCODE_USER="$HOME/Library/Application Support/Code/User" for d in \
# VS Code Server (Cursor, Codium, etc.) "$HOME/.vscode-server/data/User" \
VSCODE_USER_ALT="$HOME/Library/Application Support/Cursor/User" "$HOME/.vscode-server-insiders/data/User" \
elif [[ -d "$HOME/.vscode-server/data/User" ]]; then "$HOME/Library/Application Support/Code/User" \
# Remote / VS Code Server "$HOME/Library/Application Support/Code - Insiders/User" \
VSCODE_USER="$HOME/.vscode-server/data/User" "$HOME/Library/Application Support/VSCodium/User" \
else "$HOME/Library/Application Support/Cursor/User" \
VSCODE_USER="$HOME/.config/Code/User" "$HOME/.config/Code/User" \
fi "$HOME/.config/Code - Insiders/User" \
"$HOME/.config/VSCodium/User" \
"$HOME/.config/Cursor/User" \
"$HOME/.var/app/com.visualstudio.code/config/Code/User" \
"/mnt/c/Users/${USER:-}/AppData/Roaming/Code/User" \
"/mnt/c/Users/${USER:-}/AppData/Roaming/Code - Insiders/User"
do
if [ -d "$d" ]; then
printf '%s\n' "$d"
return 0
fi
done
case "$(uname -s)" in
Darwin) printf '%s\n' "$HOME/Library/Application Support/Code/User" ;;
*) printf '%s\n' "$HOME/.config/Code/User" ;;
esac
}
# ── 1. VS Code User-Verzeichnis ermitteln ─────────────────────────────────────
VSCODE_USER="$(detect_vscode_user_dir)"
echo "VS Code User dir: $VSCODE_USER" echo "VS Code User dir: $VSCODE_USER"
mkdir -p "$VSCODE_USER" mkdir -p "$VSCODE_USER"
@ -48,7 +81,7 @@ done
GIT_TEMPLATE_DIR="$HOME/.git-templates" GIT_TEMPLATE_DIR="$HOME/.git-templates"
mkdir -p "$GIT_TEMPLATE_DIR/.github" "$GIT_TEMPLATE_DIR/.vscode" \ mkdir -p "$GIT_TEMPLATE_DIR/.github" "$GIT_TEMPLATE_DIR/.vscode" \
"$GIT_TEMPLATE_DIR/hooks" "$GIT_TEMPLATE_DIR/docs" \ "$GIT_TEMPLATE_DIR/hooks" "$GIT_TEMPLATE_DIR/docs" \
"$GIT_TEMPLATE_DIR/history/summary" "$GIT_TEMPLATE_DIR/docs/history/summary"
cp "$REPO_DIR/git-templates/.github/copilot-instructions.md" "$GIT_TEMPLATE_DIR/.github/" cp "$REPO_DIR/git-templates/.github/copilot-instructions.md" "$GIT_TEMPLATE_DIR/.github/"
cp "$REPO_DIR/git-templates/.vscode/settings.json" "$GIT_TEMPLATE_DIR/.vscode/" cp "$REPO_DIR/git-templates/.vscode/settings.json" "$GIT_TEMPLATE_DIR/.vscode/"
cp "$REPO_DIR/git-templates/.vscode/extensions.json" "$GIT_TEMPLATE_DIR/.vscode/" cp "$REPO_DIR/git-templates/.vscode/extensions.json" "$GIT_TEMPLATE_DIR/.vscode/"
@ -57,10 +90,18 @@ chmod +x "$GIT_TEMPLATE_DIR/hooks/pre-commit"
cp "$REPO_DIR/git-templates/docs/USER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/USER.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$REPO_DIR/git-templates/docs/ADMIN.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/ADMIN.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$REPO_DIR/git-templates/docs/MAINTAINER.md" "$GIT_TEMPLATE_DIR/docs/" cp "$REPO_DIR/git-templates/docs/MAINTAINER.md" "$GIT_TEMPLATE_DIR/docs/"
cp "$REPO_DIR/git-templates/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/history/summary/" cp "$REPO_DIR/git-templates/docs/history/summary/PROJECT_CONTEXT.md" "$GIT_TEMPLATE_DIR/docs/history/summary/"
git config --global init.templateDir "$GIT_TEMPLATE_DIR"
echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR" echo " ✓ git-templates deployed → $GIT_TEMPLATE_DIR"
echo " ✓ git config init.templateDir set" # init.templateDir wird bewusst NICHT global gesetzt sonst wuerde jeder
# 'git init'/'git clone' (auch fremde Repos) automatisch den Quality Gate erben.
# Frueher gesetzten Wert entfernen, falls er auf unsere Templates zeigt.
CURRENT_TPL="$(git config --global --get init.templateDir || true)"
if [[ "$CURRENT_TPL" == "$GIT_TEMPLATE_DIR" ]]; then
git config --global --unset init.templateDir || true
echo " ✓ altes globales init.templateDir entfernt (nicht mehr invasiv)"
else
echo " ─ init.templateDir nicht global gesetzt (gewollt)"
fi
# ── 5. Bootstrap- & Update-Skripte ─────────────────────────────────────────── # ── 5. Bootstrap- & Update-Skripte ───────────────────────────────────────────
mkdir -p "$HOME/.local/bin" mkdir -p "$HOME/.local/bin"
@ -83,17 +124,26 @@ fi
# ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ────────── # ── 6. Git-Aliase: init → auto-bootstrap | copilot-update → updater ──────────
# Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop). # Verwendet git --exec-path um Rekursion zu vermeiden (kein Alias-Loop).
git config --global alias.init '!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' # Kein Override des Standard-'git init' mehr. Frueheren invasiven Alias entfernen.
echo " ✓ git alias 'init' gesetzt (führt copilot-bootstrap.sh automatisch aus)" CURRENT_INIT_ALIAS="$(git config --global --get alias.init || true)"
if [[ "$CURRENT_INIT_ALIAS" == *copilot-bootstrap* ]]; then
git config --global --unset alias.init || true
echo " ✓ alter invasiver 'git init'-Alias entfernt"
fi
# Opt-in: explizites 'git init-copilot' macht git init + bootstrap.
# shellcheck disable=SC2016 # Alias absichtlich literal git expandiert zur Laufzeit
git config --global 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'
echo " ✓ git alias 'init-copilot' gesetzt (opt-in: git init + copilot-bootstrap)"
git config --global alias.copilot-update '!~/.local/bin/copilot-update.sh' git config --global alias.copilot-update '!~/.local/bin/copilot-update.sh'
echo " ✓ git alias 'copilot-update' gesetzt (aktualisiert Templates & Prompts)" echo " ✓ git alias 'copilot-update' gesetzt (aktualisiert Templates & Prompts)"
# ── 7. post-merge Hook für dieses Setup-Repo ───────────────────────────────── # ── 7. post-merge Hook für dieses Setup-Repo ─────────────────────────────────
# Nach jedem 'git pull' auf dem Setup-Repo selbst wird deploy.sh automatisch # Nur mit --with-self-update-hook: nach jedem 'git pull' auf dem Setup-Repo
# ausgeführt, sodass Templates immer auf dem neuesten Stand sind. # wird deploy.sh automatisch erneut ausgeführt.
SELF_HOOKS_DIR="$REPO_DIR/.git/hooks" SELF_HOOKS_DIR="$REPO_DIR/.git/hooks"
if [[ -d "$SELF_HOOKS_DIR" ]]; then if [[ "$WITH_SELF_HOOK" -eq 1 ]]; then
cat > "$SELF_HOOKS_DIR/post-merge" << 'HOOK' if [[ -d "$SELF_HOOKS_DIR" ]]; then
cat > "$SELF_HOOKS_DIR/post-merge" << 'HOOK'
#!/usr/bin/env sh #!/usr/bin/env sh
# post-merge Auto-Deploy nach git pull auf dem Setup-Repo # post-merge Auto-Deploy nach git pull auf dem Setup-Repo
echo "" echo ""
@ -101,11 +151,16 @@ echo " [post-merge] Setup-Repo aktualisiert deploye Templates neu..."
SCRIPT_DIR="$(cd "$(dirname "$0")/../../scripts" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")/../../scripts" && pwd)"
bash "$SCRIPT_DIR/deploy.sh" bash "$SCRIPT_DIR/deploy.sh"
HOOK HOOK
chmod +x "$SELF_HOOKS_DIR/post-merge" chmod +x "$SELF_HOOKS_DIR/post-merge"
echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)" echo " ✓ post-merge Hook im Setup-Repo installiert (auto-deploy nach git pull)"
fi
else
echo " ─ post-merge Auto-Deploy nicht installiert (opt-in: --with-self-update-hook)"
fi fi
echo "" echo ""
echo "=== Done ===" echo "=== Done ==="
echo "Next: Activate Settings Sync in VS Code (Cmd+Shift+P → 'Settings Sync: Turn On')" echo "Next: Activate Settings Sync in VS Code (Cmd+Shift+P → 'Settings Sync: Turn On')"
echo " Templates aktuell halten: git copilot-update (in jedem Repo)" echo " Neues Repo mit Copilot-Setup: git init-copilot [pfad]"
echo " Bestehendes Repo ausstatten: copilot-bootstrap.sh [pfad]"
echo " Templates aktuell halten: git copilot-update (in jedem Repo)"

72
scripts/selftest.sh Executable file
View file

@ -0,0 +1,72 @@
#!/usr/bin/env sh
# selftest.sh Funktionspruefung fuer copilot-bootstrap.{sh,fish}.
#
# Baut ein isoliertes Fake-Template-Verzeichnis und ein Ziel-Repo in einem
# temporaeren HOME und prueft, dass Bootstrap die erwartete Struktur erzeugt.
# Veraendert weder das echte HOME noch ein echtes Repo. Lokal und in CI nutzbar:
# sh scripts/selftest.sh
set -eu
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
build_template() {
tpl="$1"
mkdir -p "$tpl/.github" "$tpl/.vscode" "$tpl/hooks" "$tpl/docs" "$tpl/docs/history/summary"
echo "framework" > "$tpl/.github/copilot-instructions.md"
echo '{}' > "$tpl/.vscode/settings.json"
echo '{}' > "$tpl/.vscode/extensions.json"
printf '#!/bin/sh\nexit 0\n' > "$tpl/hooks/pre-commit"
printf '#!/bin/sh\nexit 0\n' > "$tpl/hooks/post-commit"
for d in USER ADMIN MAINTAINER; do
echo "$d" > "$tpl/docs/$d.md"
done
echo ctx > "$tpl/docs/history/summary/PROJECT_CONTEXT.md"
}
assert_file() {
if [ ! -f "$1" ]; then
echo "FAIL: erwartete Datei fehlt: $1" >&2
exit 1
fi
}
run_case() {
label="$1"
runner="$2" # sh | fish
script="$3"
home="$WORK/home_$label"
target="$WORK/target_$label"
mkdir -p "$home/.git-templates" "$target"
build_template "$home/.git-templates"
git -C "$target" init -q
HOME="$home" "$runner" "$REPO_DIR/scripts/$script" "$target" >/dev/null
assert_file "$target/.github/copilot-instructions.md"
assert_file "$target/.vscode/settings.json"
assert_file "$target/.vscode/extensions.json"
assert_file "$target/docs/USER.md"
assert_file "$target/docs/ADMIN.md"
assert_file "$target/docs/MAINTAINER.md"
assert_file "$target/docs/history/summary/PROJECT_CONTEXT.md"
assert_file "$target/.git/hooks/pre-commit"
assert_file "$target/.git/hooks/post-commit"
assert_file "$target/data/.gitkeep"
if ! grep -q ':Zone.Identifier' "$target/.gitignore"; then
echo "FAIL: $label .gitignore enthaelt kein Zone.Identifier-Muster" >&2
exit 1
fi
echo "PASS: $label ($script)"
}
run_case sh_bootstrap sh copilot-bootstrap.sh
if command -v fish >/dev/null 2>&1; then
run_case fish_bootstrap fish copilot-bootstrap.fish
else
echo "SKIP: fish nicht installiert fish-Bootstrap uebersprungen"
fi
echo "selftest OK"

View file

@ -36,7 +36,7 @@
"text": "Responses: short and precise. No padding, no repetition. Code comments in English. Chat explanations can be in German." "text": "Responses: short and precise. No padding, no repetition. Code comments in English. Chat explanations can be in German."
}, },
{ {
"text": "MANDATORY Agent Session Protocol: (1) START: If the file history/summary/PROJECT_CONTEXT.md exists in the repo, read it FIRST before doing anything else. (2) END: After completing any meaningful task, you MUST create a log file in history/prompts/YYYY-MM-DD_short-title.md documenting what was done, and update history/summary/PROJECT_CONTEXT.md with the current project state. This is not optional and must not be skipped. If the user ends the session without asking for it, do it anyway and stage the files." "text": "MANDATORY Agent Session Protocol: (1) START: If the file docs/history/summary/PROJECT_CONTEXT.md exists in the repo, read it FIRST before doing anything else. (2) END: After completing any meaningful task, you MUST create a log file in docs/history/prompts/YYYY-MM-DD_short-title.md documenting what was done, and update docs/history/summary/PROJECT_CONTEXT.md with the current project state. This is not optional and must not be skipped. If the user ends the session without asking for it, do it anyway and stage the files."
} }
], ],
// Commit-Messages immer als Conventional Commits // Commit-Messages immer als Conventional Commits