hugin/TESTEN.md
2026-10-27 08:33:21 +01:00

20 KiB
Raw Blame History

Hugin lokal testen

Schritt für Schritt: Demo-Server starten, Pakete in ein Test-Repo holen, als Autor ein Paket ausprobieren, die automatischen Tests laufen lassen und die Funktionen der Weboberfläche und des CLI durchgehen (Checkliste in Abschnitt 5).

Voraussetzungen: uv, Go ≥ 1.26, zip, curl; für Schritt 2, 3 und 5 außerdem OpenCode (vorrangig) und/oder Claude Code; für die Browser-Prüfungen Google Chrome. Alle Pfade gehen vom Hugin-Repo aus (hier ~/repos/dev/hugin).

1. Demo-Server mit Beispieldaten

cd ~/repos/dev/hugin
scripts/demo.sh            # http://127.0.0.1:8080, Keys stehen in .demo/keys.txt
scripts/demo.sh --neu      # Beispieldaten verwerfen und neu anlegen

Im Browser mit einem Key aus .demo/keys.txt anmelden:

Key Rolle Was ausprobieren
Bert Prüfer Prüfer unter „Prüfungen“ wartet pub-munin-nutzen 1.5.0
Anna Autorin Autorin Pakete anlegen und hochladen
Shop-Admin Tenant-Admin Projekte, Personen und Keys anlegen
demo-admin Plattform-Admin Systemseite, Audit, alle Tenants

Online-Hilfe: http://127.0.0.1:8080/help · API-Doku: http://127.0.0.1:8080/api/docs

2. Pakete in ein Test-Repo holen

In einem zweiten Terminal, während der Server läuft:

cd ~/repos/dev/hugin/cli && go build -o dist/hugin ./cmd/hugin
export PATH=~/repos/dev/hugin/cli/dist:$PATH   # kein alias: OpenCode und Claude Code sehen nur den PATH

mkdir -p /tmp/test-repo && cd /tmp/test-repo && git init -q
export HUGIN_KEY=<Key „Shop CI“ aus .demo/keys.txt>
hugin init --server http://127.0.0.1:8080 --project api

In .hugin.yaml Werkzeuge und Pakete eintragen:

tools: [claude, opencode]     # fest eintragen: „auto“ erkennt im leeren Repo nichts Passendes
packages:
  - pub-munin-nutzen          # Skill
  - pub-hausregeln            # Regeln
  - pub-release-notiz         # Befehl mit Argumenten
  - pub-code-review           # Subagent

pub-munin-anbindung (MCP) kommt als Pflichtpaket von selbst mit.

hugin sync          # schreibt die Dateien, legt hugin.lock an
hugin status        # Abos, Versionen, erkannte Werkzeuge
hugin check         # ändert nichts; Rückgabewert 1, wenn etwas zu tun ist

Dann im Werkzeug ausprobieren, z. B.:

opencode            # oder: claude
> /pub-release-notiz 2.0 Kunden

Was sich zu testen lohnt:

  • Eine verwaltete Datei von Hand ändern, dann hugin sync → Befund „Handänderung“; hugin sync --overwrite setzt sie zurück.
  • Als Bert pub-munin-nutzen 1.5.0 freigeben, dann hugin check (meldet die neue Version) und hugin sync.
  • Ein Paket aus packages entfernen und hugin sync → seine Dateien verschwinden.
  • Claude Code fragt beim ersten Start, ob es den MCP-Server aus .mcp.json nutzen darf.

3. Als Autor ein Paket ausprobieren

cd /tmp
export HUGIN_KEY=<Key von Anna Autorin> HUGIN_SERVER=http://127.0.0.1:8080
hugin new skill pub-mein-test

In pub-mein-test/hugin.yaml mindestens owner: kern und eine echte description eintragen, in SKILL.md den Inhalt. Format und Beispiele: Hilfe → Quellformat.

hugin validate pub-mein-test        # Linter und Vorschau je Werkzeug, speichert nichts
cd /tmp/test-repo
hugin try ../pub-mein-test          # ins Repo installieren, ohne hugin.lock zu ändern
opencode                            # ausprobieren (oder claude)
hugin try --remove                  # wieder aufräumen
cd /tmp && hugin upload --submit pub-mein-test   # hochladen und zur Prüfung einreichen

Danach als Bert im Browser unter „Prüfungen“ freigeben.

Linter ausprobieren:

Änderung Meldung
description aus der Vorlage stehen lassen H003 (Fehler): noch der Platzhalter
unter extra.opencode z. B. temperature: 0.1 bei einem Skill H020 (Fehler): Feld unbekannt
extra.claude.disable-model-invocation: true H023 (Hinweis): wirkt in OpenCode 1 nicht
„nutze Read“ im Text H021 (Hinweis): neutral formulieren

4. Automatische Tests

Befehl Prüft Kosten
cd server && uv run pytest Server: Linter, Übersetzer, API, Web, MCP, Tenants frei
scripts/postgres-test.sh dieselbe Suite gegen PostgreSQL (Docker) frei
cd cli && go test ./... CLI, gegen die goldenen Bundles des Servers frei
scripts/smoke-test-local.sh ganzer Ablauf Server → CLI, ohne echte Werkzeuge frei
scripts/stage0.sh wie OpenCode die Dateien liest, ohne Modellaufruf frei
uv run --no-project --with websockets --with httpx python scripts/csp/web_browser.py /tmp/shots Weboberfläche in Chrome: CSP-Verstöße je Seite, Bildschirmfotos frei
uv run --no-project --with websockets --with httpx python scripts/csp/web_actions.py Weboberfläche in Chrome bedienen: Topbar, Live-Suche, Kopieren, Rückfragen, Formulare, Editor, Tabs frei
OPENCODE_MODEL=openai/gpt-6-luna scripts/tool-smoke-test.sh echtes Claude Code und OpenCode, schreibt COMPATIBILITY.md ca. 30 Modellaufrufe

Reihenfolge: erst die Server-Tests, dann die CLI-Tests (die CLI testet gegen die Bundles, die der Server erzeugt).

Optionen für tool-smoke-test.sh:

Variable Wirkung
TOOLS=opencode nur ein Werkzeug prüfen
CLAUDE_MODEL=sonnet anderes Modell für Claude Code (Standard haiku)
OPENCODE_MODEL=anbieter/modell Modell für OpenCode; ohne Angabe sein Standard
KEEP=1 Arbeitsordner und Logs bleiben zum Nachsehen
OUT=/pfad/datei.md Ergebnis woandershin statt nach COMPATIBILITY.md

OpenCode braucht dafür einen Anbieter-Zugang (opencode providers login); die kostenlosen Modelle lehnen opencode run ab.

5. Checkliste: Funktionen von Hand durchgehen

Server aus Abschnitt 1 und Test-Repo aus Abschnitt 2. Jede Zeile: was tun, was erwartet wird. Was die Browser-Prüfung (web_actions.py) schon abdeckt, ist mit ⚙ markiert; von Hand lohnt es trotzdem einmal, um das Verhalten zu kennen.

5.1 Weboberfläche: überall

Schritt Erwartung
Fenster schmal ziehen oder Handyansicht (Chrome: F12 → Gerätesymbol) Topbar oben mit ☰, „Hilfe“, Hell/Dunkel, „Abmelden“; nichts abgeschnitten; „Programm hugin“ steht dann im Menü ⚙
Lange Seite (als demo-admin „Tenants, Projekte, Keys“) ganz nach unten scrollen Topbar mit „Abmelden“ bleibt sichtbar, die Sidebar bleibt stehen ⚙
Mond/Sonne in der Topbar Hell/Dunkel wechselt
Hilfe → „Arten von Paketen“ jede Art erklärt (Skill, Regeln, Befehl, Subagent, MCP, Hook) mit „Welche Art passt?“
Auf einer Paketseite das Abzeichen der Art (z. B. „Skill“) anklicken führt zu „Arten von Paketen“

5.2 Als Shop CI (Team)

Schritt Erwartung
Katalog: ins Suchfeld „haus“ tippen Liste filtert ohne Enter, Suche steht in der URL ⚙
Katalog: Spalte „Paket“ anklicken sortiert (nur, solange alles auf eine Seite passt)
Paket pub-munin-nutzen → „Im Repo nutzen“ → „Kopieren“ Meldung „Kopiert“; in der Zwischenablage packages: mit dem Paket ⚙
Version 1.4.0 öffnen, Tab „Inhalt“ anklicken, dann ← → Pos1 Ende Tabs wechseln per Tastatur ⚙
„Mein Projekt“ Repos gruppiert; Filter „Alle“ / „Mit neuerer Version“; „Gemeldet“ als relative Zeit („vor 2 Tagen“), genaue Zeit im Tooltip

5.3 Als Bert (Prüfer) und Carla (Prüferin + Tenant-Admin)

Schritt Erwartung
„Prüfungen“ pub-munin-nutzen 1.5.0 mit „eingereicht vor …“
Version öffnen → „Prüfen“ → ohne Kommentar „Zurückgeben“ Browser verlangt einen Kommentar, nichts wird abgeschickt ⚙
Mit Kanal „stabil“ freigeben zurück in „Prüfungen“; danach meldet im Test-Repo hugin check die neue Version
Danach als Shop-Admin „Überblick“ → Karte „Veraltete Installationen“ springt zur Tabelle der Repos mit alter Version
Rechte-Paket: als Anna eine Skill-Version mit extra: {claude: {allowed-tools: [Bash]}} hochladen und einreichen, Bert gibt frei Bert sieht im Dialog kein Kanal-Feld, sondern „Den Kanal wählt die letzte nötige Freigabe“; danach sieht Carla in „Prüfungen“ „Freigaben 1 von 2“ und „Tenant-Admin nötig“
Carla gibt frei Kanal-Feld mit Hinweis zum Risiko; danach freigegeben

5.4 Als Anna (Autorin)

Schritt Erwartung
„Hochladen“ → „direkt im Browser anlegen“ ID ist mit pub- vorausgefüllt
Version pub-munin-nutzen 1.4.0 → „Neue Version auf dieser Basis“ Editor öffnet mit 1.4.1
Im Editor Tab drücken; Esc und dann Tab Tab rückt zwei Leerzeichen ein; Esc+Tab springt zum nächsten Feld ⚙
Etwas ändern und die Seite verlassen Browser warnt vor ungespeicherten Änderungen ⚙
In SKILL.md $1 schreiben und speichern Linter lehnt ab (H010), der Dateiname im Befund springt zur Datei
Alle Dateien unverändert speichern (nur changes ausfüllen) Entwurf 1.4.1 mit denselben Dateien; nichts geht verloren
ZIP mit hugin.yaml (kind: hook) hochladen klare Ablehnung H008 „Hooks kommen mit Stufe 5“, kein Serverfehler
„Zur Prüfung einreichen“ Rückfrage „Danach lässt sich die Version nicht mehr ändern“

5.5 Als Shop-Admin (Verwaltung)

Schritt Erwartung
„Neuer Key“ → Art umschalten Projekt-Key: nur Feld „Projekt“ (Pflicht); Integrations-Key: nur „Nur für diese Projekte“ ⚙
Rollen ansehen lesbare Namen („Autor“, „Prüfer (öffentlich)“, „Tenant-Admin“) mit Tooltip
Key anlegen → „Kopieren“ Key in der Zwischenablage; er wird nur dieses eine Mal angezeigt
„Widerrufen“ bei einem Key Rückfrage; „Abbrechen“ ändert nichts ⚙
Als demo-admin: Tenant „plattform“ → Person „Sperren“; Pflichtpaket „Keine Pflicht mehr“ jeweils Rückfrage (das Pflichtpaket gilt für alle Tenants, nur der Plattform-Admin kann es lösen)
Tabelle „Keys“ „Zuletzt genutzt“ als „vor …“
Als demo-admin „Audit“ → Aktion „Keys“ wählen Liste filtert sofort; ab 50 Einträgen bleibt der Filter beim Blättern („Ältere“) erhalten ⚙

5.6 CLI im Test-Repo (OpenCode zuerst)

Schritt Erwartung
Frisches Repo, hugin sync opencode.json beginnt mit "$schema": "https://opencode.ai/config.json"; opencode debug config läuft ohne Fehler
In .hugin.yaml tools: [opencode], dann hugin sync Skills unter .opencode/skills/; kein .claude/, keine .mcp.json, kein Block in CLAUDE.md; opencode debug skill findet den Skill
Zurück auf tools: [claude, opencode], hugin sync Skills wandern nach .claude/skills/, .opencode/skills/ ist leer
unset MUNIN_KEY; hugin sync Warnung: pub-munin-anbindung braucht die Umgebungsvariable MUNIN_KEY; sie ist nicht gesetzt …
export MUNIN_KEY=x; hugin sync keine Warnung mehr
unset MUNIN_KEY; hugin check; echo $? Warnung, aber Rückgabewert 0 (CI ohne Keys bleibt grün)
In opencode.json unter mcp von Hand "jira": { "url": "https://jira.intern/mcp" } eintragen, dann hugin check; echo $? „OpenCode lehnt die Konfiguration ab“ mit mcp.jira, Rückgabewert 1, Text „das kann hugin sync nicht“
Eintrag reparieren ("type": "remote", "enabled": true), hugin check „Alles aktuell.“
opencode im Repo starten, /pub-release-notiz 2.0 Kunden Befehl läuft; Regeln aus pub-hausregeln werden beachtet
In opencode.json einen Tippfehler wie "modell": "x" wird nicht gemeldet: OpenCode 1.19.3 nimmt unbekannte Felder hin

5.7 Agent installiert über Hugins MCP-Endpunkt (OpenCode)

Frisches Test-Repo, damit nichts vom Abschnitt 2 stört:

mkdir -p /tmp/mcp-repo && cd /tmp/mcp-repo && git init -q
export HUGIN_KEY=<Key „Shop CI“ aus .demo/keys.txt>
export MUNIN_KEY=x               # nur gegen die Warnung; Munin selbst gibt es in der Demo nicht
hugin init --server http://127.0.0.1:8080 --project api
sed -i '' 's/^tools: auto/tools: [opencode]/' .hugin.yaml
hugin sync                       # nur das Pflichtpaket pub-munin-anbindung

In opencode.json unter "mcp" Hugin selbst als MCP-Server eintragen (von Hand; Hugin lässt diesen Eintrag in Ruhe):

"hugin": {
  "type": "remote",
  "url": "http://127.0.0.1:8080/mcp",
  "enabled": true,
  "headers": { "Authorization": "Bearer {env:HUGIN_KEY}" }
}
Schritt Erwartung
opencode mcp list hugin steht auf „connected“ (munin verbindet in der Demo nicht, das ist erwartet)
hugin check „Alles aktuell.“ (OpenCode akzeptiert den Eintrag)
which hugin in derselben Shell, aus der du opencode startest zeigt …/cli/dist/hugin; sonst findet der Agent hugin sync nicht (Abschnitt 2: PATH, kein alias)
opencode starten: „Gibt es in Hugin einen Befehl für Release-Notizen?“ ruft search_packages auf, nennt pub-release-notiz
„Zeig mir, was pub-release-notiz macht, ohne es zu installieren.“ ruft get_package auf, erklärt den Inhalt; im Repo ändert sich nichts (git status)
„Richte pub-release-notiz dauerhaft in diesem Repo ein.“ trägt pub-release-notiz in .hugin.yaml ein und führt hugin sync aus (OpenCode fragt vorher nach Erlaubnis für den Befehl); schreibt nicht selbst nach .opencode/commands/
Danach hugin status und cat hugin.lock pub-release-notiz steht in beiden; die Datei .opencode/commands/pub-release-notiz.md hat Hugin geschrieben
OpenCode neu starten, /pub-release-notiz 2.0 Kunden der Befehl läuft
Als Anna eine neue Version von pub-release-notiz hochladen, Bert gibt frei; dann hugin check meldet die neue Version (das geht nur, weil hugin sync installiert hat)

Gegenprobe ohne hugin im PATH (z. B. env PATH=/usr/bin:/bin opencode): Der Agent soll melden, dass hugin fehlt, und nichts selbst schreiben. Schreibt er die Datei doch selbst, fehlt pub-release-notiz in hugin.lock, und das nächste hugin sync meldet „Datei gibt es schon, sie stammt nicht von Hugin (Konflikt)“. Dann bitte Modell und Wortlaut notieren, das wäre ein Befund. Aufräumen: hugin sync --overwrite.

Der automatische Test dazu: scripts/tool-smoke-test.sh, Prüfungen „Installieren auf Bitte“ und „Ohne hugin nichts schreiben“.

5.8 Demo und Betrieb

Schritt Erwartung
scripts/demo.sh mit einer Datenbank aus einem alten Stand statt Traceback: „Migration gescheitert …“ mit dem Hinweis auf --neu
cd server && uv run pytest tests/test_migration.py nach einer Änderung an 0001_initial_tables.py Fehler „ausgelieferte Migrationen nie ändern, sondern eine neue anlegen“

5.9 Lokaler MCP-Server (Python)

Das Beispiel pub-zeit-lokal braucht nur die Standardbibliothek. Als Anna im Test-Repo aus Abschnitt 3 (mit tools: [opencode] oder [claude, opencode]):

export HUGIN_MCP_HOME=/tmp/hugin-mcp ZEIT_ZONE_HINWEIS=test   # Ablage zum Wegwerfen
hugin try ~/repos/dev/hugin/contract/examples/packages/pub-zeit-lokal/1.0.0
Schritt Erwartung
Ausgabe von hugin try „installiere pub-zeit-lokal 1.0.0 (lokaler Server) nach /tmp/hugin-mcp/…“
ls -a /tmp/hugin-mcp/pub-zeit-lokal/1.0.0 zeit_server.py, .venv, .hugin-install.json
grep -A6 zeit opencode.json "command": ["hugin", "mcp", "run", "pub-zeit-lokal"], kein Pfad
opencode mcp list zeit connected
in OpenCode: „Rufe das Werkzeug zeit auf“ Uhrzeit mit UHR-4711 (test)
rm -rf /tmp/hugin-mcp, dann opencode mcp list zeit failed; hugin mcp run pub-zeit-lokal sagt „nicht installiert; im Repo hugin sync ausführen“
hugin try erneut installiert wieder
hugin try --remove, dann hugin mcp prune --dry-run „würde löschen pub-zeit-lokal 1.0.0“
mkdir -p /tmp/hugin-mcp/eigener && hugin mcp prune löscht nur das Hugin-Paket; eigener bleibt

Freigabe und Verteilung: als Anna hugin upload --submit (persönlicher Key nötig, H043 beim Projekt-Key), Risiko „Skripte“, also zwei Freigaben (Bert und Carla). Die Versionsseite zeigt „Lokaler Server“ mit Ablage. Danach im Repo pub-zeit-lokal unter packages eintragen und hugin sync; hugin check meldet, wenn der Server auf dem Rechner fehlt.

Mit Abhängigkeiten: requirements.txt mit Hashes erzeugen (Hilfe → Quellformat, uv pip compile --universal --generate-hashes). pip nimmt den Index aus der pip.conf; zum Test einen anderen Index: PIP_CONFIG_FILE=/tmp/pip.conf. Ohne Hash lehnt der Linter mit H037 ab.

5.10 OpenCode-Plugin

Das Beispiel pub-specht-plugin gibt OpenCode das Werkzeug specht_marke. Als Anna im Test-Repo (tools: [opencode] oder [claude, opencode]):

hugin validate ~/repos/dev/hugin/contract/examples/packages/pub-specht-plugin/1.0.0
hugin try ~/repos/dev/hugin/contract/examples/packages/pub-specht-plugin/1.0.0
Schritt Erwartung
Ausgabe von hugin validate Risiko: permissions, Kompatibilität: opencode-only, keine Fehler
find .opencode/plugins pub-specht-plugin.ts und pub-specht-plugin/index.ts, …/lib/marke.ts; nichts unter .claude/
opencode debug config | grep -A2 '"plugin"' …/.opencode/plugins/pub-specht-plugin.ts
in OpenCode: „Rufe das Werkzeug specht_marke auf“ SPECHT-5127
dasselbe mit opencode --pure Werkzeug unbekannt (so gewollt)
git status .opencode/plugins/… neu; node_modules, package.json unter .opencode/ nicht (eigene .gitignore von OpenCode)
in index.ts import _ from "lodash" ergänzen, hugin validate H039
targets auf [claude, opencode], hugin validate H038
hugin try --remove Ordner und Startdatei weg

Freigabe: hugin upload --submit, dann Bert und Carla (Tenant-Admin); mit Bert und Dora allein bleibt es bei „Tenant-Admin nötig“. Danach abonnieren und hugin sync.

5.11 Windows (von Hand)

Auf einem Windows-Rechner mit Python (Starter py), OpenCode und Zugang zu Hugin. Programm bauen auf dem Mac: cd cli && GOOS=windows GOARCH=amd64 go build -o dist/hugin.exe ./cmd/hugin, hugin.exe in einen Ordner im PATH legen. In PowerShell:

Schritt Erwartung
hugin init …, .hugin.yaml wie in Abschnitt 2 mit tools: [opencode], hugin sync Dateien unter .opencode\…, keine unter .claude
opencode debug skill > s.txt; opencode agent list; opencode mcp list Skill, Subagent, MCP wie unter macOS
hugin try …\pub-zeit-lokal\1.0.0 (mit $env:ZEIT_ZONE_HINWEIS="test") installiert nach %USERPROFILE%\.local\share\mcp\pub-zeit-lokal\1.0.0, venv unter .venv\Scripts
opencode mcp list zeit connected
in OpenCode das Werkzeug zeit aufrufen Antwort mit UHR-4711, Umlaute korrekt
aus einem Unterordner des Repos starten lokaler Server verbindet trotzdem
ohne py, nur python aus python.org im PATH wird gefunden; nur der Store-Platzhalter python.exe: Meldung „kein Python gefunden“
$env:HUGIN_PYTHON="C:\Pfad\python.exe" wird genommen
Paket mit requirements.txt, pip.ini unter %APPDATA%\pip\ mit Artifactory pip installiert aus dem Artifactory
hugin mcp prune wie unter macOS
Repo unter einem langen Pfad (> 200 Zeichen), dann hugin sync Befund notieren, falls Windows-Pfadgrenze greift
hugin try …\pub-specht-plugin\1.0.0, OpenCode neu starten, Werkzeug specht_marke aufrufen SPECHT-5127
hugin-install.ps1 mit einem Paket mit lokalem Server Warnung „ist ein lokaler MCP-Server; installieren mit dem Programm hugin“, sonst läuft alles durch

Befunde bitte mit Ausgabe und Windows-Version notieren.

Noch nicht testbar

  • Hooks, Paare, Signaturen, fertige Programme als lokale Server, npm-Abhängigkeiten für Plugins: noch nicht gebaut (Stufe 5c–5e); ein Hook-Paket lehnt der Linter mit H008 ab.
  • OpenCode 2: ungeprüft (STUFE0.md, Frage 10); OPENCODE=<opencode-2> scripts/stage0.sh.
  • hugin-install.ps1 unter Windows PowerShell 5.1: braucht einen Windows-Rechner, siehe README „Integration unter Windows PowerShell 5.1 testen“.