diff --git a/AGENTS.md b/AGENTS.md index 1d6d242..0155f73 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ Diese Datei richtet sich an **Coding-Agenten (Claude, Codex u.ä.), die in diese 1. Erst lesen (Zeilen der Zielstelle nennen), dann ändern. 2. Erst ausführen, dann berichten. Prosa ohne Tool-Call ≠ Ausführung. -3. UI-/Server-Änderung → Server starten + `curl` → Ergebnis zitieren. +3. UI-/Server-Änderung → `./scripts/smoke_test.sh` → Ausgabe zitieren. 4. Nach Refactor: `grep -c ` = 1. Sonst nicht fertig. 5. Doku beschreibt Code, nicht die Arbeit am Code. @@ -41,12 +41,16 @@ Für jede angekündigte Änderung muss **mindestens eines** dieser Artefakte vor Fehlen diese Belege, ist die Aufgabe nicht erledigt — die Tool-Aufrufe absetzen und erneut prüfen. ### R4 – UI-/Server-Änderungen gegen das laufende System prüfen -Bei Änderungen an `web/serve.py` oder `web/index.html`: Server starten, betroffene Endpunkte per `curl` testen, und das Ergebnis im Bericht **zitieren**. Beispiel: +Bei Änderungen an `web/serve.py` oder `web/index.html`: führe den Smoke-Test aus und zitiere die Ausgabe im Bericht: ```bash -curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8081/templates.json +./scripts/smoke_test.sh ``` +Das Skript startet den Server temporär auf einem eigenen Port (Default 8082), prüft alle bekannten Endpunkte und räumt sich selbst auf. Du musst nichts über Hintergrund-Jobs, `&`, `nohup` oder Port-Cleanup wissen. Exit-Code 0 = alle 200; sonst 1. + +Für Änderungen, die der Smoke-Test nicht abdeckt (neuer Endpunkt, geänderte Response, JSON-Edit-Flow im Browser), zusätzlich gezielten `curl`-Aufruf oder Browser-Check ergänzen. + „Sieht korrekt aus" ohne ausgeführten Test zählt nicht. ### R5 – Nichts in die Doku schreiben, was nicht existiert @@ -66,6 +70,7 @@ Ein Commit = eine logische Änderung. Commit-Message im Stil der bestehenden His ```bash python3 web/serve.py # startet Server auf http://localhost:8081 +./scripts/smoke_test.sh # temporärer Server + Endpunkt-Check + Cleanup (fuer R4) ./scripts/cleanup_server.sh # beendet hängende Instanzen python3 scripts/validate.py # validiert Template-Struktur ``` diff --git a/scripts/smoke_test.sh b/scripts/smoke_test.sh new file mode 100755 index 0000000..0f28977 --- /dev/null +++ b/scripts/smoke_test.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# Startet web/serve.py temporaer, testet die wichtigsten Endpunkte, +# raeumt den Prozess auch bei Abbruch auf. Ein einziger Aufruf; der +# Agent muss nichts ueber Hintergrund-Jobs wissen. +# +# Nutzung: ./scripts/smoke_test.sh # Port 8082 +# ./scripts/smoke_test.sh 9000 # anderer Port +# Exit-Code: 0 = alle Endpunkte 200, sonst 1. + +set -u +PORT="${1:-8082}" +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +LOG="/tmp/smoke.$PORT.log" +EXIT_CODE=1 +MARKER="SMOKE_TEST_SERVER_$PORT" + +# Vorherige Instanzen dieses Smoke-Tests beenden +pkill -f "$MARKER" 2>/dev/null || true +sleep 0.1 + +# Server im Hintergrund starten (exec → $! ist der Python-Prozess) +cd "$ROOT" +python3 -c " +import sys; sys.argv[0] = '$MARKER' +sys.path.insert(0, 'web') +import http.server, socketserver +from serve import Handler +port = $PORT +print(f'Serving on http://localhost:{port}', flush=True) +with socketserver.TCPServer(('', port), Handler) as httpd: + httpd.serve_forever() +" > "$LOG" 2>&1 & +PID=$! +cleanup() { + kill "$PID" 2>/dev/null || true + wait "$PID" 2>/dev/null || true + # Defensiv: falls der Kill-Signal den Python-Prozess nicht trifft + pkill -f "$MARKER" 2>/dev/null || true + exit "$EXIT_CODE" +} +trap cleanup EXIT INT TERM + +# Auf Port-Binding warten (max. 2s) +for i in $(seq 1 20); do + if curl -sf -o /dev/null "http://localhost:$PORT/"; then break; fi + sleep 0.1 +done + +# Wenn nicht erreichbar: Log ausgeben und fail +if ! curl -sf -o /dev/null "http://localhost:$PORT/"; then + echo "FAIL: Server nicht erreichbar auf Port $PORT" + echo "--- $LOG ---" + cat "$LOG" + EXIT_CODE=1 + exit 1 +fi + +# Endpunkte testen +FAIL=0 +for p in "/" "/index.html" "/templates.json" \ + "/templates/system/commit_analysis.json" \ + "/templates/system/code_reviewer.json" \ + "/templates/system/summarizer.json" \ + "/templates/user/email_draft.md" \ + "/templates/user/brainstorming.md"; do + code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:$PORT$p") + status="ok" + [ "$code" = "200" ] || { status="FAIL"; FAIL=1; } + printf '%-50s %s %s\n' "$p" "$code" "$status" +done + +EXIT_CODE=$FAIL +if [ "$FAIL" -eq 0 ]; then + echo "--- alle $( (echo "/" "/index.html" "/templates.json" "/templates/system/commit_analysis.json" "/templates/system/code_reviewer.json" "/templates/system/summarizer.json" "/templates/user/email_draft.md" "/templates/user/brainstorming.md") | wc -w ) Endpunkte OK ---" +fi +exit $FAIL