docs: pi-Doku zusammengeführt, FUNKTIONSWEISE/CHANGELOG/LICENSE; mcp.json versioniert und verlinkt

Hinweise zu pi und der Coder/Judge-Erweiterung (MCP-Server, Web-Tests, schneller
entwickeln, Fehlerbilder) aus strata-betrieb übernommen. Kapitel 2/3 und README
auf Strata als Standard gebracht. deploy-pi-config.sh verlinkt jetzt auch mcp.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-16 04:56:38 +02:00
commit e1796c0ccc
9 changed files with 411 additions and 131 deletions

View file

@ -9,17 +9,19 @@ einsetzt, um Software automatisch zu schreiben, zu prüfen und zu verbessern —
## Inhaltsverzeichnis ## Inhaltsverzeichnis
1. [Konzept: Coder und Judge](#1-konzept-coder-und-judge) 1. [Konzept: Coder und Judge](#1-konzept-coder-und-judge)
2. [Vorbereitung](#2-vorbereitung) 2. [Vorbereitung](#2-vorbereitung) (Modell wählen, Einrichten, pi aktualisieren)
3. [Server starten und stoppen](#3-server-starten-und-stoppen) 3. [Alternative: llama.cpp-Server (:8001)](#3-alternative-llamacpp-server-8001)
4. [Neues Projekt anlegen](#4-neues-projekt-anlegen) 4. [Neues Projekt anlegen](#4-neues-projekt-anlegen)
5. [Manueller Workflow: /coder → /judge → /fix → /shipit](#5-manueller-workflow) 5. [Manueller Workflow: /coder → /judge → /fix → /shipit](#5-manueller-workflow)
6. [Automatischer Workflow: /optimize](#6-automatischer-workflow-optimize) (inkl. [Interactive-Modus](#interactive-modus)) 6. [Automatischer Workflow: /optimize](#6-automatischer-workflow-optimize) (inkl. [Schneller entwickeln](#schneller-entwickeln), [Interactive-Modus](#interactive-modus))
7. [Kleine Änderungen: /patch und /quick_check](#7-kleine-änderungen-patch-und-quick_check) 7. [Kleine Änderungen: /patch und /quick_check](#7-kleine-änderungen-patch-und-quick_check)
8. [Dokumentation generieren: /update_doku](#8-dokumentation-generieren-update_doku) 8. [Dokumentation generieren: /update_doku](#8-dokumentation-generieren-update_doku)
9. [Versionsverwaltung: /version](#9-versionsverwaltung-version) 9. [Versionsverwaltung: /version](#9-versionsverwaltung-version)
10. [TASK.md verstehen und nutzen](#10-taskmd-verstehen-und-nutzen) 10. [TASK.md verstehen und nutzen](#10-taskmd-verstehen-und-nutzen)
11. [Typische Anwendungsfälle](#11-typische-anwendungsfälle) 11. [Werkzeuge für pi: MCP-Server](#11-werkzeuge-für-pi-mcp-server)
12. [Fehlermeldungen und Lösungen](#12-fehlermeldungen-und-lösungen) 12. [Web-Anwendungen testen](#12-web-anwendungen-testen)
13. [Typische Anwendungsfälle](#13-typische-anwendungsfälle)
14. [Fehlermeldungen und Lösungen](#14-fehlermeldungen-und-lösungen)
--- ---
@ -57,47 +59,67 @@ der Judge kritisiert direkt und konkret, der Coder repariert ohne Widerspruch.
## 2. Vorbereitung ## 2. Vorbereitung
### Server starten ### Modell wählen
Coder und Judge sind **ein** Modell. Standard ist `strata/qwen3.8-flash-next-iq3_s`, der lokale Strata-Server auf
`127.0.0.1:9090`. Seinen Betrieb (Start, GPU-Freigabe, Entladen nach 10 Minuten, Bilder) beschreibt
`~/nvme2n1p7_home/strata-betrieb/BEDIENUNGSANLEITUNG.md`. Ist das Modell entladen, lädt Strata es bei der ersten
Anfrage; die Bereitschaftsprüfung der Extension wartet darauf bis zu 3 Minuten.
Ein anderes Modell aus `models.json` setzt die Umgebungsvariable `PI_CODER_MODEL=<provider>/<id>` beim Start von pi,
z. B. der llama.cpp-Server aus [Kapitel 3](#3-alternative-llamacpp-server-8001):
```bash ```bash
cd ~/pi_coder PI_CODER_MODEL=llama-cpp-single/coding_model pi
./start-coding-server.sh
``` ```
Ausgabe bei Erfolg: Freie Eingaben (ohne Slash-Befehl) nutzen pis eigenes Standardmodell aus `~/.pi/agent/settings.json`.
``` `--provider`/`--model` ändern es für einen Lauf, ohne die globalen Einstellungen anzufassen:
[*] Verwende HF_HOME = /home/.../huggingface
[*] GPU device = 1
[✓] Single-Server (:8001) bereit
```
Dauer: bis zu 5 Minuten (Modell wird in GPU-VRAM geladen; neuere llama.cpp-Versionen
prüfen beim Start die VRAM-Verfügbarkeit, was zusätzliche Zeit kostet).
### Status prüfen
```bash ```bash
./status-coding-server.sh pi --provider strata --model qwen3.8-flash-next-iq3_s
``` ```
``` **Bilder** (Screenshots, `read` auf PNG/JPG, Browser-Screenshots) erreichen nur Modelle, die in `models.json`
=== LLaMA-Server Status === `"input": ["text", "image"]` haben. Strata ist so eingetragen. Bei anderen Modellen meldet pi „Current model does not
coding_model (Port 8001): Container=RUNNING HTTP=OK support images“ und lässt das Bild weg.
### Einrichten
Einmalig und nach Änderungen an `models.json` oder `settings.json`:
```bash
cd ~/pi_coder_v2
./deploy-pi-config.sh
``` ```
### pi agent öffnen Das Skript **verlinkt** `pi-coding-extension.ts` und `mcp.json` nach `~/.pi/agent/`. Änderungen im Repo gelten
damit ab dem nächsten pi-Start (oder `/reload`), auch noch nicht committete, und `pi mcp add` schreibt direkt ins
Repo. `models.json` wird kopiert, aus `settings.json` nur die Liste `packages` übernommen. Eine abweichende alte
Datei sichert das Skript vorher als `.bak`.
pi agent im Projektverzeichnis starten — das ist das Verzeichnis, in dem dein Code liegt, ### pi öffnen
**nicht** `~/pi_coder`:
pi im Projektordner starten, also dort, wo der Code liegt, nicht in `~/pi_coder_v2`:
```bash ```bash
cd ~/MeinProjekt cd ~/MeinProjekt
pi pi
``` ```
### pi aktualisieren
`pi update` ersetzt pis Programmdateien. Ein pi, das dabei läuft, findet danach Teile seines eigenen Codes nicht mehr,
und jede Modellanfrage scheitert (siehe [Fehlermeldungen](#cannot-find-module--chunks-nach-pi-update)). Deshalb
nur aktualisieren, wenn kein pi läuft, oder alle laufenden pi danach neu starten.
--- ---
## 3. Server starten und stoppen ## 3. Alternative: llama.cpp-Server (:8001)
Nur nötig, wenn Coder und Judge statt Strata das Modell `llama-cpp-single/coding_model` nutzen sollen: Qwen3.6-27B
IQ4_XS im Docker-Container `coding_model` auf einer GPU. Danach pi mit `PI_CODER_MODEL=llama-cpp-single/coding_model`
starten (siehe [Modell wählen](#modell-wählen)).
### GPU-Zuordnung ### GPU-Zuordnung
@ -120,7 +142,7 @@ nvidia-smi --query-gpu=index,name,memory.used,memory.free --format=csv
### Server starten ### Server starten
```bash ```bash
cd ~/pi_coder cd ~/pi_coder_v2
./start-coding-server.sh ./start-coding-server.sh
``` ```
@ -153,29 +175,6 @@ Falls die GGUF-Datei an einem anderen Ort liegt:
HF_HOME=/mnt/daten/huggingface ./start-coding-server.sh HF_HOME=/mnt/daten/huggingface ./start-coding-server.sh
``` ```
### Anderes Modell für die Schleife
Ohne weitere Angabe arbeiten Coder und Judge mit `strata/qwen3.8-flash-next-iq3_s` (Strata, Port 9090). Das Modell
liest auch Bilder (`"input": ["text", "image"]` in `models.json`): Screenshots, die pi mit dem `read`-Werkzeug
öffnet, erreichen das Modell.
Web-Apps testet pi über den global eingetragenen MCP-Server `playwright` (headless Chrome, Werkzeuge
`browser_*`), auch in der Coder/Judge-Schleife. Einrichtung und Grenzen: `~/nvme2n1p7_home/strata-betrieb`,
BEDIENUNGSANLEITUNG, „Web-Anwendungen testen“. Ist das
Modell entladen, lädt Strata es bei der ersten Anfrage und gibt vorher GPU 1 und 2 frei; die Bereitschaftsprüfung
wartet darauf bis zu 3 Minuten. Eingerichtet ist das in `~/nvme2n1p7_home/strata-betrieb` (dort
BEDIENUNGSANLEITUNG, „GPUs teilen“). Ein anderes Modell aus `models.json` setzt die Umgebungsvariable
`PI_CODER_MODEL` beim Start von pi, als `<provider>/<id>`, z. B. der llama.cpp-Server auf Port 8001:
```bash
PI_CODER_MODEL=llama-cpp-single/coding_model pi
```
`--provider`/`--model` machen das Modell auch für freie Eingaben zum Standard dieses Laufs; die globalen
Einstellungen bleiben unverändert. Die Bereitschaftsprüfung fragt den Endpunkt aus `baseUrl` des Modells ab. Der
Provider `strata` (lokaler Strata-Server auf `127.0.0.1:9090`) steht in `models.json`; den Server startet man außerhalb
dieses Repos.
--- ---
## 4. Neues Projekt anlegen ## 4. Neues Projekt anlegen
@ -446,6 +445,23 @@ den Rest automatisch ablaufen lassen:
Die Implementierungsphase wird übersprungen — der Judge prüft sofort den aktuellen Die Implementierungsphase wird übersprungen — der Judge prüft sofort den aktuellen
Stand und der Fix-Zyklus läuft automatisch bis PASS oder max. N Runden. Stand und der Fix-Zyklus läuft automatisch bis PASS oder max. N Runden.
### Schneller entwickeln
Eine lange Sitzung an einem Tauri-Projekt mit Strata dauerte 12 Stunden, davon rund 9 Stunden Warten auf den
nächsten Befehl (Messung: `~/nvme2n1p7_home/strata-betrieb/FUNKTIONSWEISE.md`, „Messwerte“). Was schneller macht, nach
Wirkung:
1. **Eine Schleife statt einzelner Befehle.** Für einen weiteren Auftrag am selben Projekt
`/optimize --continue "Zusatzauftrag …" --rounds 5 --test-cmd "…"` statt `/judge`, `/fix` und `/shipit` von Hand.
Die Schleife geht ohne Pause von Prüfung zu Reparatur.
2. **Neue pi-Sitzung je Auftrag** (pi neu starten). Der Kontext beginnt klein; in der gemessenen Sitzung lag der
Prompt im Median bei 126 000 Tokens. Was pi wissen muss, steht in `TASK.md` und in Git.
3. **Teure Builds erst zur Freigabe.** Im Auftrag z. B.: „In den Fix-Runden nur `cargo test` und `npm run build`;
`npx tauri build` erst bei der Freigabe.“
4. **Kurze Berichte** sind Standard (siehe [Konzept](#1-konzept-coder-und-judge)).
5. Ein schnelleres Cloud-Modell (`PI_CODER_MODEL=openrouter/…`) ist die letzte Stufe: kostet Geld, und der Code geht
nach außen.
### Loop-Erkennung ### Loop-Erkennung
Wenn zweimal hintereinander dieselbe Beanstandung auftritt, bricht `/optimize` ab: Wenn zweimal hintereinander dieselbe Beanstandung auftritt, bricht `/optimize` ab:
@ -765,7 +781,67 @@ Die Checkboxen werden automatisch abgehakt:
--- ---
## 11. Typische Anwendungsfälle ## 11. Werkzeuge für pi: MCP-Server
Eingetragen in `mcp.json` dieses Repos, nach `~/.pi/agent/mcp.json` verlinkt (`pi mcp list` zeigt den Zustand). Sie
gelten in jeder pi-Sitzung, auch in der Coder/Judge-Schleife:
| Server | Version | Zweck |
|---|---|---|
| `playwright` | `@playwright/mcp@0.0.83` | Web-Apps in einem headless Chrome bedienen (siehe [Kapitel 12](#12-web-anwendungen-testen)) |
| `context7` | `@upstash/context7-mcp@4.1.1` | aktuelle Doku von Bibliotheken nachschlagen (`resolve-library-id`, `query-docs`), damit das Modell keine veralteten APIs erfindet; Anfragen gehen an `context7.com` |
**codemode:** pi beschreibt MCP-Werkzeuge dem Modell nicht einzeln. Das Modell schreibt ein kurzes JavaScript, das sie
aufruft (`tools.mcp__context7__query_docs(...)`). Beide Server zusammen kosten so nur rund 870 Prompt-Tokens.
**Context7 benutzen:** im Auftrag den Server und die Bibliothek mit Version nennen, ein Thema je Frage, z. B.:
```
Schlage mit context7 in der aktuellen Doku von Tauri 2 nach: Wie sende ich aus einem Rust-Command
Fortschritts-Events an das Frontend? Kurzes Beispiel für beide Seiten, nenne die Bibliotheks-ID.
```
In `/optimize`-Aufträgen hilft der Satz „Schlage unklare APIs mit context7 nach, bevor du sie benutzt.“
**API-Key:** `mcp.json` enthält nur den Verweis `"CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"`. Der Key selbst gehört in
die Umgebung, z. B. `export CONTEXT7_API_KEY=…` in `~/.bashrc`. Fehlt die Variable, startet pi den Server **nicht**
(`pi mcp list`: `context7: failed`, „Failed to resolve … env "CONTEXT7_API_KEY"“). Steht der `export` in `~/.bashrc`
nach der Abfrage auf interaktive Shells, gilt das für Skripte, Cron und Dienste. Prüfen, ob der Key beim Server
ankommt (zeigt nur die Länge):
`tr '\0' '\n' < /proc/$(pgrep -f context7-mcp | head -1)/environ | grep '^CONTEXT7_API_KEY=' | cut -d= -f2- | wc -c`.
Den Einrichtungsassistenten `npx ctx7 setup` nicht benutzen: Er schreibt den Key im Klartext in die Konfiguration.
**Weitere Server** nur bei Bedarf, z. B. Serena (Code-Navigation über Language Server, lohnt bei großen Projekten)
oder ein Forgejo-Server (Issues, Pull Requests). Unnötig sind Dateisystem-, Git- oder Fetch-Server: Das können
`bash`, `read` und `research_web` schon. Versionen fest wählen, nur eine Version, die mindestens zwei Wochen alt ist.
---
## 12. Web-Anwendungen testen
pi testet Web-Apps über den MCP-Server `playwright` in einem **headless** Chrome (der installierte, `--browser chrome`),
nie über Klicks auf dem Desktop. Die Seite kommt als Text (Accessibility-Baum) beim Modell an; dafür reicht jedes
Textmodell. Für die Optik kann pi Screenshots machen; die sieht nur ein bildfähiges Modell (siehe
[Modell wählen](#modell-wählen)).
```bash
pi --provider strata --model qwen3.8-flash-next-iq3_s
# dann z. B.: Teste http://127.0.0.1:5173/ mit den Browser-Werkzeugen: fülle das Formular aus, sende es ab
# und nenne das Ergebnis wörtlich. Mach danach einen Screenshot und prüfe das Layout.
```
**Für Projekte** ist eine Playwright-Testsuite verlässlicher: reproduzierbar, auch in CI. Im Auftrag an `/optimize`:
„Schreibe Playwright-E2E-Tests (`@playwright/test`, headless, `channel: 'chrome'`, `webServer` startet die App).“ und
`--test-cmd "npm test && npx playwright test" --test-timeout 900`. `channel: 'chrome'` nutzt den installierten Chrome,
`npx playwright install` ist dann nicht nötig.
Inhalte prüft man über Snapshot oder Testsuite; Screenshots kosten Zeit und sind ungenauer. Messwerte mit Strata und
die Einrichtung anderer Agenten (Hermes, OpenCode): `~/nvme2n1p7_home/strata-betrieb/BEDIENUNGSANLEITUNG.md`,
„Web-Anwendungen testen“.
---
## 13. Typische Anwendungsfälle
### Neues Rust-Programm von Null ### Neues Rust-Programm von Null
@ -876,7 +952,7 @@ Die Checkboxen werden automatisch abgehakt:
--- ---
## 12. Fehlermeldungen und Lösungen ## 14. Fehlermeldungen und Lösungen
### "Urteil unklar: … Judge-Urteil nicht erkennbar" ### "Urteil unklar: … Judge-Urteil nicht erkennbar"
@ -934,6 +1010,29 @@ HF_HOME=/korrekter/pfad ./start-coding-server.sh
./start-coding-server.sh ./start-coding-server.sh
``` ```
### "Cannot find module … chunks" nach pi update
```
Cannot find module '…/pi-coding-agent/dist/bundle/chunks/openai-completions-….js'
```
**Ursache:** pi wurde aktualisiert (`pi update`), während diese pi-Sitzung lief. Jede Modellanfrage scheitert sofort;
`/optimize` läuft dann mit leeren Antworten durch, ohne zu arbeiten.
**Lösung:** pi beenden und neu starten, dann den Befehl wiederholen (bei `/optimize` mit `--continue`).
### pi -p hängt in Skripten
**Ursache:** `pi -p "…"` liest zusätzlich stdin, wenn das kein Terminal ist, und wartet auf dessen Ende.
**Lösung:** `pi … -p "…" </dev/null`.
### "Current model does not support images"
**Ursache:** Das gewählte Modell ist in `models.json` nicht als bildfähig eingetragen; pi lässt das Bild weg.
**Lösung:** Ein bildfähiges Modell wählen, z. B. Strata (siehe [Modell wählen](#modell-wählen)).
### "Agent is already processing a prompt" ### "Agent is already processing a prompt"
**Ursache:** Ein Kommando wurde aufgerufen während pi agent noch auf eine Antwort wartet. **Ursache:** Ein Kommando wurde aufgerufen während pi agent noch auf eine Antwort wartet.
@ -986,7 +1085,7 @@ Falls der Judge wiederholt Concerns findet, die du akzeptierst:
**Lösung:** **Lösung:**
```bash ```bash
cd ~/pi_coder cd ~/pi_coder_v2
./deploy-pi-config.sh ./deploy-pi-config.sh
# Dann /reload in pi agent # Dann /reload in pi agent
``` ```

53
CHANGELOG.md Normal file
View file

@ -0,0 +1,53 @@
# Changelog
Alle wichtigen Änderungen an pi_coder. Format: [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).
Ältere Änderungen vor Oktober 2026 stehen nur in `git log`.
## [Unreleased]
### Hinzugefügt
- `mcp.json` im Repo (MCP-Server `playwright@0.0.83` und `context7-mcp@4.1.1`, Key nur als
`${CONTEXT7_API_KEY}`); `deploy-pi-config.sh` verlinkt sie nach `~/.pi/agent/mcp.json`. Tests prüfen feste Versionen
und dass kein Key im Klartext steht.
- `FUNKTIONSWEISE.md` (Aufbau, Ablauf von `/optimize` als Diagramm, Einrichtung, Designentscheidungen, Grenzen),
`CHANGELOG.md`, `LICENSE` (MIT).
- BEDIENUNGSANLEITUNG: Kapitel „Werkzeuge für pi: MCP-Server“ und „Web-Anwendungen testen“, Abschnitt „Schneller
entwickeln“, Fehlerbilder „Cannot find module … chunks“ (nach `pi update`), „`pi -p` hängt in Skripten“,
„Current model does not support images“. Übernommen aus `strata-betrieb`, wo diese Hinweise bisher standen.
### Geändert
- BEDIENUNGSANLEITUNG Kapitel 2 neu (Modell wählen, Einrichten, pi aktualisieren); Kapitel 3 ist jetzt die Alternative
llama.cpp-Server. README auf Strata als Standard gebracht, Abschnitt „Documentation“.
### Behoben
- README: falscher Klon-Pfad (`~/pi_coder`), nicht mehr zutreffende Aussage zum Standard-Provider in `settings.json`,
nicht vorhandener Ordner `examples/` in der Dateitabelle.
### Beim Update zu tun
- `./deploy-pi-config.sh` ausführen (legt den Symlink `~/.pi/agent/mcp.json` an; eine abweichende alte Datei wird als
`mcp.json.bak` gesichert). Danach laufende pi neu starten.
- Für Context7 `CONTEXT7_API_KEY` in der Umgebung setzen, sonst startet der Server nicht.
## [2026-10-16]
### Geändert
- Judge und Freigabeprüfung berichten kurz (`reportBrevityRules`): keine Tabelle bestandener Prüfungen, Blocker und
Major vollständig, übrige Abschnitte höchstens 5 Punkte.
## [2026-10-15]
### Hinzugefügt
- Modell der Schleife per `PI_CODER_MODEL` wählbar, Bereitschaft aus `baseUrl` des Modells.
- Urteilsregeln für den Judge (`judgeVerdictSection`): PASS gegen TASK/SPEC, Abschnitt „Hinweise“.
- Strata (`strata/qwen3.8-flash-next-iq3_s`) liest Bilder (`"input": ["text", "image"]`).
### Geändert
- Standardmodell für Coder und Judge ist Strata statt `llama-cpp-single/coding_model`.
- `deploy-pi-config.sh` verlinkt die Extension statt sie zu kopieren.
### Behoben
- Judge-Urteil auch mit Markdown erkennen (`## Urteil: **PASS**`).
- Schleifenerkennung meldet bei „Blocker: Keine“ keinen falschen Abbruch mehr (`loopKey`).
### Beim Update zu tun
- `./deploy-pi-config.sh` ausführen (Symlink der Extension, `models.json` mit Provider `strata`).

95
FUNKTIONSWEISE.md Normal file
View file

@ -0,0 +1,95 @@
# Funktionsweise
Wie die Coder/Judge-Erweiterung für pi aufgebaut ist, wie `/optimize` abläuft und warum sie so gebaut ist. Bedienung:
[BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md). Messwerte mit dem lokalen Strata-Server stehen im Repo
`strata-betrieb` (`~/nvme2n1p7_home/strata-betrieb/FUNKTIONSWEISE.md`, „Messwerte“ und „Testreihe pi mit Strata“).
## Inhalt
- [Aufbau](#aufbau)
- [Ablauf von /optimize](#ablauf-von-optimize)
- [Einrichtung auf dem Rechner](#einrichtung-auf-dem-rechner)
- [Designentscheidungen](#designentscheidungen)
- [Bekannte Grenzen](#bekannte-grenzen)
## Aufbau
| Teil | Aufgabe |
|---|---|
| `pi-coding-extension.ts` | die Erweiterung: registriert `/coder`, `/judge`, `/fix`, `/shipit`, `/optimize`, `/patch`, `/quick_check`, `/version`, `/update_doku`, `/plan`, `/continue`, `/cancel`, `/new_project` und das Werkzeug `apply_patch` |
| Rollen | **ein** Modell für Coder und Judge; die Rolle setzt ein System-Prompt, den der Hook `before_agent_start` je nach `currentRole` einfügt. `selectRole()` stellt das Modell ein (`PI_CODER_MODEL`, Standard `strata/qwen3.8-flash-next-iq3_s`), `deselectRole()` stellt danach das vorige Modell für freie Eingaben wieder her |
| Aufträge an das Modell | Funktionen `judgePrompt`, `judgeWithTestsPrompt`, `fixPrompt`, `shipitPrompt` …; gemeinsame Teile in `judgeVerdictSection()` (Urteilsregeln, Ausgabeformat) und `reportBrevityRules()` (kurze Berichte) |
| Auswertung | `parseVerdict()` liest „Urteil: PASS / PASS WITH CONCERNS / FAIL“ (auch mit Markdown), `parseShipVerdict()` „SHIP / NO-SHIP“, `loopKey()` den Vergleichsschlüssel für die Schleifenerkennung |
| `TASK.md` | Auftrag im Projekt; `/coder` und `/optimize` legen sie an oder hängen einen „Zusatzauftrag“ an; die Extension setzt die Status-Häkchen |
| Bereitschaft | `waitUntilModelReady()` schickt bis zu 3 Minuten lang alle 3 s eine Anfrage mit `max_tokens: 1` an den `baseUrl` des Modells und wartet auf HTTP 200 |
## Ablauf von /optimize
```mermaid
flowchart TB
S["/optimize Auftrag<br/>z. B. --rounds 5<br/>--continue<br/>--test-cmd"]
B["Bereitschaft prüfen<br/>bis 3 min auf HTTP 200"]
C["Coder implementiert,<br/>TASK.md, Commit<br/>(entfällt mit --continue)"]
T["Tests extern ausführen<br/>--test-cmd oder erkannt"]
J["Judge prüft<br/>TASK.md, letzter Commit,<br/>Test-Ergebnis"]
V{"Urteil"}
L{"Gleicher Schlüssel<br/>wie Vorrunde<br/>oder letzte Runde?"}
F["Coder repariert<br/>Blocker, Major, Minor;<br/>Commit"]
X["Abbruch:<br/>manuell weiter mit<br/>/judge und /fix"]
P["SHIP: Status in TASK.md,<br/>Abschluss-Commit,<br/>optional Version, Doku"]
S --> B --> C --> T --> J --> V
V -->|"PASS oder PASS WITH CONCERNS<br/>mit --approve-concerns"| P
V -->|"sonst"| L
L -->|ja| X
L -->|nein| F --> T
```
- Die Tests führt die Extension selbst aus (`runTestsParallel`, Zeitlimit `--test-timeout`, Standard 120 s) und gibt
die Ausgabe dem Judge mit; der Judge führt dann keine Tests aus.
- Der Schleifenschlüssel ist der Blocker-Abschnitt, bei „Blocker: Keine“ der Major-Abschnitt, sonst der ganze Text.
- Mit `--interactive` pausiert die Schleife nach PASS und wartet bis 30 Minuten auf `/continue`.
- Jeder Schritt ist eine normale Nachricht in derselben pi-Sitzung; der Kontext wächst mit jeder Runde.
## Einrichtung auf dem Rechner
`deploy-pi-config.sh` legt die Dateien nach `~/.pi/agent/`:
| Datei im Repo | Ziel | Art |
|---|---|---|
| `pi-coding-extension.ts` | `~/.pi/agent/extensions/pi-coding-extension.ts` | Symlink |
| `mcp.json` | `~/.pi/agent/mcp.json` | Symlink |
| `models.json` | `~/.pi/agent/models.json` | Kopie |
| `settings.json` | `~/.pi/agent/settings.json` | nur die Liste `packages` wird übernommen |
pi lädt Extensions über Symlinks und bindet MCP-Server standardmäßig im **codemode** ein: Die Werkzeuge stehen nicht
einzeln im Prompt, das Modell ruft sie aus einem kurzen JavaScript auf.
## Designentscheidungen
| Entscheidung | Verworfene Alternativen | Grund |
|---|---|---|
| Ein Modell für beide Rollen, Rolle per System-Prompt | zwei Server bzw. Modelle für Coder und Judge | ein Modell spart GPU-Speicher; der Rollenwechsel kostet keinen Modellwechsel |
| Modell über `PI_CODER_MODEL`, Bereitschaft aus `baseUrl` des Modells | fester Port 8001; Extension-Kopie je Modell | eine Quelle für alle Modelle; Strata (Port 9090) und llama.cpp (8001) gehen ohne Codeänderung |
| Standard Strata statt llama.cpp (15.10.2026) | llama.cpp-Container auf `:8001` | Strata gibt die GPUs selbst frei und lädt bei Bedarf; der llama.cpp-Container blockierte GPU 1 dauerhaft |
| Extension und `mcp.json` als Symlink | Kopie bei jedem Deploy | Änderungen gelten sofort; `pi mcp add` landet im Repo und ist in `git diff` sichtbar; ein `cp` auf den Symlink bräche mit „same file“ ab |
| Urteilsregeln im Judge-Prompt (`judgeVerdictSection`) | freie Bewertung „Produktionsreife“ | ohne Regeln urteilte der Judge mit Strata am 15.10. in keiner Aufgabe PASS; Härtung über die Anforderungen hinaus steht jetzt unter „Hinweise“ |
| Kurze Berichte (`reportBrevityRules`, 16.10.) | ausführliche Prüfprotokolle | eine 12-Stunden-Sitzung erzeugte 777 000 Tokens; lange Berichte kosten Rechenzeit und bleiben im Kontext jeder Runde. Blocker und Major bleiben vollständig |
| Urteil auch mit Markdown erkennen (`## Urteil: **PASS**`) | nur exaktes `Urteil: PASS` | Strata schreibt Markdown; vorher lief die Schleife bei erfülltem Auftrag weiter |
| Schleifenschlüssel mit Major-Rückfall (`loopKey`) | nur Blocker vergleichen | zwei Runden mit „Blocker: Keine“ und verschiedenen Majors galten sonst als Schleife |
| MCP-Server Playwright (headless, System-Chrome) und Context7 im codemode | Klicks per `xdotool` auf dem Desktop; Dateisystem-, Git-, Fetch-Server; `npx ctx7 setup` | headless stört den Nutzer nicht, der Accessibility-Baum reicht jedem Textmodell; Context7 behebt veraltete APIs; die übrigen Server doppeln `bash`/`read`/`research_web`; `ctx7 setup` schreibt den Key im Klartext. codemode kostet für beide Server rund 870 Prompt-Tokens |
| `mcp.json` im Repo mit Verweis `${CONTEXT7_API_KEY}` | Key in der Datei; `mcp.json` nur lokal | reproduzierbare Einrichtung ohne Geheimnis im Repo |
| Feste Paketversionen (`@playwright/mcp@0.0.83`, `@upstash/context7-mcp@4.1.1`), mindestens zwei Wochen alt | `@latest` | ein kompromittiertes neues Paket würde sonst bei jedem Start geladen |
## Bekannte Grenzen
- **Coder und Judge sind dasselbe Modell:** Der Judge übersieht eher, was der Coder auch übersieht. Verdeckte
Abnahmetests (wie in `strata-betrieb/pi-test/`) prüfen unabhängig.
- **Langer Kontext:** Eine Sitzung sammelt alle Runden; in einer gemessenen Sitzung lag der Prompt im Median bei
126 000 Tokens. Für jeden neuen Auftrag eine neue Sitzung beginnen.
- **pi-Updates:** Ein laufendes pi verträgt kein `pi update`; danach scheitert jede Modellanfrage, bis pi neu startet.
- **`pi -p` in Skripten** wartet auf stdin; dort immer `</dev/null`.
- **Context7 ohne Key startet nicht:** Fehlt `CONTEXT7_API_KEY` in der Umgebung (Skripte, Cron, Dienste), meldet
`pi mcp list` `context7: failed`.
- **Bilder** nur mit einem Modell, das in `models.json` `"input": ["text", "image"]` hat.
- **Tests der Extension** (`run-tests.sh`) prüfen die reinen Funktionen und Konfigurationen, nicht das Zusammenspiel mit
einem echten Modell.

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 dschlueter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -52,89 +52,46 @@ dasselbe Modell, unterschiedliche Persona. Freie Eingaben in pi nutzen weiter pi
Strata lädt sein Modell bei der ersten Anfrage selbst, gibt vorher die GPUs frei und entlädt es nach 10 Minuten ohne Strata lädt sein Modell bei der ersten Anfrage selbst, gibt vorher die GPUs frei und entlädt es nach 10 Minuten ohne
Anfrage (eingerichtet in `strata-betrieb`). Ein anderes Modell für beide Rollen setzt Anfrage (eingerichtet in `strata-betrieb`). Ein anderes Modell für beide Rollen setzt
`PI_CODER_MODEL=<provider>/<id>`, siehe `PI_CODER_MODEL=<provider>/<id>`, siehe
[BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md#anderes-modell-für-die-schleife). [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md#modell-wählen).
--- ---
## Voraussetzungen ## Voraussetzungen
- Docker mit NVIDIA-GPU-Support: - [pi](https://pi.dev) installiert (`~/.pi/`).
```bash - Ein Modell für Coder und Judge:
# NVIDIA Container Toolkit installieren (falls nicht vorhanden) - **Standard:** der lokale Strata-Server auf `127.0.0.1:9090` (Betrieb: `~/nvme2n1p7_home/strata-betrieb`).
distribution=$(. /etc/os-release; echo $ID$VERSION_ID) - **Alternative:** der llama.cpp-Server in Docker auf Port 8001 (unten). Dafür Docker mit NVIDIA Container Toolkit,
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - eine GPU mit 24 GB (Standard GPU 1, `GPU_DEVICE=…`) und das GGUF-Modell unter
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list \
| sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
```
- NVIDIA-GPU: empfohlen RTX 3090 (24 GB VRAM). Standard: GPU 1. Überschreibbar mit
`GPU_DEVICE=0 ./start-coding-server.sh`. Bei 3 GPUs: GPU 0 für Display reservieren.
- GGUF-Modell vorhanden unter:
`$HF_HOME/models/qwen3/Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS.gguf` `$HF_HOME/models/qwen3/Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS.gguf`
- Standard-Pfad: `HF_HOME=/home/dschlueter/nvme2n1p7_home/huggingface` (Standard `HF_HOME=/home/dschlueter/nvme2n1p7_home/huggingface`).
- Überschreibbar: `HF_HOME=/anderer/pfad ./start-coding-server.sh`
- [pi agent](https://github.com/earendil-works/pi) installiert (`~/.pi/`)
--- ---
## Installation ## Installation
```bash ```bash
# 1. Repository klonen git clone https://kitux.de/forgejo/dschlueter/pi_coder_2.git ~/pi_coder_v2
git clone https://kitux.de/forgejo/dschlueter/pi_coder.git ~/pi_coder cd ~/pi_coder_v2
cd ~/pi_coder ./deploy-pi-config.sh # verlinkt Extension und mcp.json, kopiert models.json, übernimmt settings.json (nur packages)
# 2. Extension, Modell-Config und settings.json nach ~/.pi/agent/ deployen
./deploy-pi-config.sh
# 3. pi agent neu laden (in der pi-Oberfläche)
# /reload
# 4. Server starten
./start-coding-server.sh
``` ```
Das Install-Skript sichert eine vorhandene `~/.pi/agent/settings.json` als `.bak` und Danach pi im Projektordner starten. Was das Skript genau tut und wie man das Modell wählt:
kopiert dann `settings.json` aus dem Repo. Damit ist der korrekte Default-Provider [BEDIENUNGSANLEITUNG.md, Kapitel 2](BEDIENUNGSANLEITUNG.md#2-vorbereitung).
(`llama-cpp-single/coding_model`) automatisch konfiguriert.
Die Extension wird nicht kopiert, sondern verlinkt
(`~/.pi/agent/extensions/pi-coding-extension.ts` → Repo). Änderungen an `pi-coding-extension.ts` gelten
damit für jeden pi-Aufruf ab dem nächsten Start bzw. `/reload`, ohne erneutes Deploy. Das gilt auch für noch
nicht committete Änderungen.
Nach späteren Änderungen an `models.json` oder `settings.json`:
```bash
./deploy-pi-config.sh # verlinkt die Extension, kopiert models.json, settings.json (nur packages)
# dann /reload in pi agent
```
--- ---
## Server starten / stoppen / status ## llama.cpp-Server (Alternative)
```bash ```bash
# Server starten (empfohlen — dauert 1–3 Minuten) ./start-coding-server.sh # startet den Container coding_model, wartet bis HTTP bereit (bis 5 min)
./start-coding-server.sh
# Server auf anderer GPU starten
GPU_DEVICE=0 ./start-coding-server.sh GPU_DEVICE=0 ./start-coding-server.sh
# Stoppen
./stop-coding-server.sh ./stop-coding-server.sh
# Status prüfen
./status-coding-server.sh ./status-coding-server.sh
``` ```
`start-coding-server.sh` startet den Container und wartet bis HTTP-ready (max. 5 Minuten — die Ein erneuter Start entfernt einen laufenden Container zuerst (`docker rm -f`); eine laufende Anfrage bricht dabei ab.
neue llama.cpp-Version prüft beim Start, ob Modell + KV-Cache in den VRAM passen, was Coder und Judge nutzen ihn mit `PI_CODER_MODEL=llama-cpp-single/coding_model pi`.
zusätzliche Zeit kostet).
Wenn der Server bereits läuft und du `start-coding-server.sh` aufrufst, wird der laufende
Container zuerst per `docker rm -f` gestoppt und dann neu gestartet — ein laufender
Inference-Request wird dabei abgebrochen.
--- ---
@ -261,15 +218,14 @@ und Extension-Guards gegen Regressionen.
|---|---| |---|---|
| `pi-coding-extension.ts` | pi agent Extension (Kommandos, Tools, Hooks, Rollen-Logik) | | `pi-coding-extension.ts` | pi agent Extension (Kommandos, Tools, Hooks, Rollen-Logik) |
| `models.json` | Provider- und Modell-Konfiguration für pi agent | | `models.json` | Provider- und Modell-Konfiguration für pi agent |
| `settings.json` | pi-agent-Settings (Default-Modell, aktivierte Modelle) — wird von Install-Skript deployt | | `settings.json` | pi-Settings; `deploy-pi-config.sh` übernimmt daraus nur die Liste `packages` |
| `mcp.json` | MCP-Server für pi (Playwright, Context7), nach `~/.pi/agent/mcp.json` verlinkt |
| `run-tests.sh` | Tests ausführen | | `run-tests.sh` | Tests ausführen |
| `tests/` | Testdateien (pure-logic, config, extension-guards, scripts) | | `tests/` | Testdateien (pure-logic, config, extension-guards, scripts) |
| `start-coding-server.sh` | Single-Server starten (Port 8001, Coder + Judge) | | `start-coding-server.sh` | Single-Server starten (Port 8001, Coder + Judge) |
| `stop-coding-server.sh` | Container stoppen | | `stop-coding-server.sh` | Container stoppen |
| `status-coding-server.sh` | Laufstatus anzeigen | | `status-coding-server.sh` | Laufstatus anzeigen |
| `deploy-pi-config.sh` | Extension nach `~/.pi/agent/extensions/` verlinken, models.json + settings.json kopieren | | `deploy-pi-config.sh` | Extension und `mcp.json` nach `~/.pi/agent/` verlinken, `models.json` kopieren, `packages` aus `settings.json` übernehmen |
| `examples/` | Demo-Projekte (Python, Rust, Go, C, Bash, HTML/JS) für Live-Demos |
| `examples/restore-all.sh` | Examples nach Demo-Lauf in Ausgangszustand zurücksetzen |
--- ---
@ -292,7 +248,7 @@ und Extension-Guards gegen Regressionen.
| `/cancel` | — | Laufenden Loop nach aktuellem Schritt abbrechen | | `/cancel` | — | Laufenden Loop nach aktuellem Schritt abbrechen |
| `/new_project <pfad>` | — | Neues Projektverzeichnis + git init | | `/new_project <pfad>` | — | Neues Projektverzeichnis + git init |
Ausführliche Beschreibung aller Kommandos mit Beispielen: siehe **BEDIENUNGSANLEITUNG.md**. Ausführliche Beschreibung aller Kommandos mit Beispielen: [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md).
--- ---
@ -326,3 +282,14 @@ inklusive eines laufenden `[MM:SS]`-Timers während jeder LLM-Inference-Phase:
| Interactive-Pause | `⏸ PASS – warte auf /continue…` | | Interactive-Pause | `⏸ PASS – warte auf /continue…` |
Der Timer beweist, dass die LLM tatsächlich arbeitet. Steht er still, hängt der Prozess. Der Timer beweist, dass die LLM tatsächlich arbeitet. Steht er still, hängt der Prozess.
---
## Documentation
- [BEDIENUNGSANLEITUNG.md](BEDIENUNGSANLEITUNG.md) – Einrichtung, Modellwahl, alle Befehle, MCP-Server, Web-Tests,
schneller entwickeln, Fehlermeldungen
- [FUNKTIONSWEISE.md](FUNKTIONSWEISE.md) – Aufbau der Extension, Ablauf von `/optimize`, Designentscheidungen, Grenzen
- [CHANGELOG.md](CHANGELOG.md) – Änderungen und was beim Update zu tun ist
- [LICENSE](LICENSE) – MIT
- Strata-Server und Messwerte auf diesem PC: `~/nvme2n1p7_home/strata-betrieb`

View file

@ -1,20 +1,25 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Verlinkt die Extension und kopiert models.json/settings.json aus dem Repo nach ~/.pi/agent/. # Verlinkt Extension und mcp.json und kopiert models.json/settings.json aus dem Repo nach ~/.pi/agent/.
# Die Extension ist ein Symlink: Änderungen im Repo gelten ab dem nächsten pi-Start bzw. /reload. # Extension und mcp.json sind Symlinks: Änderungen im Repo gelten ab dem nächsten pi-Start bzw. /reload, und
# Erneut ausführen nur nach Änderungen an models.json oder settings.json. # `pi mcp add` schreibt direkt ins Repo. Erneut ausführen nur nach Änderungen an models.json oder settings.json.
set -euo pipefail set -euo pipefail
REPO="$(cd "$(dirname "$0")" && pwd)" REPO="$(cd "$(dirname "$0")" && pwd)"
mkdir -p ~/.pi/agent/extensions mkdir -p ~/.pi/agent/extensions
# A previous, differing copy is kept as .bak before it is replaced by the symlink. # Links $1 (repo file) to $2; a previous, differing regular file is kept as .bak first.
EXT=~/.pi/agent/extensions/pi-coding-extension.ts link_file() {
if [ -f "$EXT" ] && [ ! -L "$EXT" ] && ! cmp -s "$EXT" "$REPO/pi-coding-extension.ts"; then local src="$1" dest="$2"
cp "$EXT" "$EXT.bak" if [ -f "$dest" ] && [ ! -L "$dest" ] && ! cmp -s "$dest" "$src"; then
echo "Backup: pi-coding-extension.ts → pi-coding-extension.ts.bak" cp "$dest" "$dest.bak"
fi echo "Backup: $(basename "$dest") → $(basename "$dest").bak"
ln -sfn "$REPO/pi-coding-extension.ts" "$EXT" fi
echo "Verlinkt: ~/.pi/agent/extensions/pi-coding-extension.ts → $REPO/pi-coding-extension.ts" ln -sfn "$src" "$dest"
echo "Verlinkt: $dest → $src"
}
link_file "$REPO/pi-coding-extension.ts" ~/.pi/agent/extensions/pi-coding-extension.ts
link_file "$REPO/mcp.json" ~/.pi/agent/mcp.json
cp "$REPO/models.json" ~/.pi/agent/models.json cp "$REPO/models.json" ~/.pi/agent/models.json
echo "Kopiert: models.json → ~/.pi/agent/" echo "Kopiert: models.json → ~/.pi/agent/"

27
mcp.json Normal file
View file

@ -0,0 +1,27 @@
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"-y",
"@playwright/mcp@0.0.83",
"--browser",
"chrome",
"--headless",
"--isolated",
"--output-dir",
"/tmp/playwright-mcp"
]
},
"context7": {
"command": "npx",
"args": [
"-y",
"@upstash/context7-mcp@4.1.1"
],
"env": {
"CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
}
}
}
}

View file

@ -7,6 +7,7 @@ import { readJson, readRepoFile } from "./helpers.mjs";
const models = readJson("models.json"); const models = readJson("models.json");
const settings = readJson("settings.json"); const settings = readJson("settings.json");
const mcp = readJson("mcp.json");
test("models.json: Provider llama-cpp-single hat genau ein Modell coding_model auf Port 8001", () => { test("models.json: Provider llama-cpp-single hat genau ein Modell coding_model auf Port 8001", () => {
const p = models.providers["llama-cpp-single"]; const p = models.providers["llama-cpp-single"];
@ -54,3 +55,13 @@ test("settings.json enthält keine Modell-Auswahl (Nutzer-Präferenz bleibt erha
assert.ok(!("defaultModel" in settings), "defaultModel soll nicht im Repo-settings sein"); assert.ok(!("defaultModel" in settings), "defaultModel soll nicht im Repo-settings sein");
assert.ok(!("enabledModels" in settings), "enabledModels soll nicht im Repo-settings sein"); assert.ok(!("enabledModels" in settings), "enabledModels soll nicht im Repo-settings sein");
}); });
test("mcp.json: Playwright und Context7 mit fester Version, Key nur als Umgebungsverweis", () => {
const servers = mcp.mcpServers;
assert.deepEqual(Object.keys(servers).sort(), ["context7", "playwright"]);
assert.ok(servers.playwright.args.includes("@playwright/mcp@0.0.83"));
assert.ok(servers.playwright.args.includes("--headless"), "Browser-Tests nie auf dem Desktop");
assert.ok(servers.context7.args.includes("@upstash/context7-mcp@4.1.1"));
assert.deepEqual(servers.context7.env, { CONTEXT7_API_KEY: "${CONTEXT7_API_KEY}" });
assert.doesNotMatch(JSON.stringify(mcp), /ctx7sk|--api-key/, "kein API-Key im Klartext");
});

View file

@ -45,8 +45,10 @@ test("install-Skript deployt settings.json mit vorherigem Backup", () => {
assert.match(s, /pi-coding-extension\.ts/); assert.match(s, /pi-coding-extension\.ts/);
}); });
test("install-Skript verlinkt die Extension statt sie zu kopieren", () => { test("install-Skript verlinkt Extension und mcp.json statt sie zu kopieren", () => {
const s = readRepoFile("deploy-pi-config.sh"); const s = readRepoFile("deploy-pi-config.sh");
assert.match(s, /ln -sfn "\$REPO\/pi-coding-extension\.ts" "\$EXT"/); assert.match(s, /ln -sfn "\$src" "\$dest"/);
assert.doesNotMatch(s, /cp "\$REPO\/pi-coding-extension\.ts"/, "cp auf den Symlink bricht mit 'same file' ab"); assert.match(s, /link_file "\$REPO\/pi-coding-extension\.ts" ~\/\.pi\/agent\/extensions\/pi-coding-extension\.ts/);
assert.match(s, /link_file "\$REPO\/mcp\.json" ~\/\.pi\/agent\/mcp\.json/);
assert.doesNotMatch(s, /cp "\$REPO\/(pi-coding-extension\.ts|mcp\.json)"/, "cp auf den Symlink bricht mit 'same file' ab");
}); });