- Python 60.4%
- Shell 21%
- HTML 13.5%
- Dockerfile 5.1%
Read-only Terminal-Ansicht am bestehenden Dispatcher (status-page-spec.md): - status.py: reine Aggregation aus RUNS_DIR (Transcript-Parsing robust gegen Rich-UI-Müll, Ausgang aus <ts>.result.json, Kosten aus <ts>.cost.json-Cache) - app.py: GET / + GET /api/runs, OpenRouter-Kostenabruf (async, 404-robust, cacht fertige Läufe als <ts>.cost.json) - status.html: dunkel/Monospace, Layout A, Polling 4 s, pulsierender Punkt - entrypoint.sh: Ausgangs-Marker <ts>.result.json (pr|blocked|failed) - dev_preview.py: lokaler Vorschau-Server mit Demo-Fixtures (ohne Docker/ OpenRouter/.env) — uv run --with fastapi --with uvicorn dispatcher/dev_preview.py - test_status.py: Tests der Aggregation (23 passed gesamt) - compose/Dockerfile/requirements: RUNS_DIR-Mount, neue Dateien, httpx Deploy (Caddy-basic_auth-Split, RUNS_DIR auf lab, lab.md) steht noch aus, dokumentiert in status-page-spec.md §8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| dispatcher | ||
| job | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.local.md | ||
| CLAUDE.md | ||
| compose.yaml | ||
| mike-spec.md | ||
| observability-spec.md | ||
| README.md | ||
| status-page-spec.md | ||
@mike
AI-Coder-Bot für die Forgejo-Instanz git.moritz.run. Issue an den Account
mike zuweisen → der Dispatcher startet einen OpenHands-headless-Job →
Branch mike/issue-<n> → PR. Kommentare und Reviews auf mikes PRs triggern
eine Nachbesserungs-Runde. Details: mike-spec.md.
Aufbau
dispatcher/— FastAPI-Webhook-Empfänger (System-Webhook der Instanz), filtert Events (filter.py), startet Job-Container über den Docker-Socket.job/— Dockerfile + Entrypoint für den OpenHands-Job (clone → fix → push → PR via Forgejo-API).mike-spec.md— Grob-Spec und Entscheidungen.observability-spec.md— Überwachung: Transcripts, Run-Stats, Tool-Lücken-Auswertung.compose.yaml— startet den Dispatcher und baut das Job-Image.
Entwickeln
uv run --with pytest pytest dispatcher/ # Tests der Trigger-Regeln
Betrieb
cp .env.example .env # und befüllen
docker compose --profile build-only build
docker compose up -d # Dispatcher lauscht auf 127.0.0.1:8330
Danach den System-Webhook der Forgejo-Instanz (Admin → Webhooks →
System-Webhook; Events: issues, issue_assign, issue_comment,
pull_request_comment, pull_request_review) auf
http://<dispatcher-host>:8330/webhook zeigen lassen — bzw. auf den
Reverse-Proxy-Vhost davor —, Secret = WEBHOOK_SECRET.
Stolperfalle:
POST /api/v1/admin/hookslegt einen Default-Webhook an (gilt nur für künftig neu erstellte Repos), keinen System-Webhook. Also entweder die Admin-UI nutzen oder nachträglich in der Forgejo-DBUPDATE webhook SET is_system_webhook=1 WHERE id=<id>;setzen.
Secrets (nicht im Repo)
.env auf dem Deployment-Host, gitignored (Vorlage: .env.example):
OPENROUTER_API_KEY— LLM-Zugang (Modell:openrouter/z-ai/glm-5.2).MIKE_FORGEJO_TOKEN— Token des Bot-Accountsmike.WEBHOOK_SECRET— validiert den System-Webhook.
Disaster Recovery
Wenn der Host abraucht: Repo clonen, .env mit den drei Secrets neu befüllen
(OpenRouter-Key ggf. neu erzeugen, mike-Token in Forgejo neu ausstellen,
Webhook-Secret neu setzen — steht im System-Webhook der Instanz), bauen und
docker compose up -d. Kein weiterer Zustand — der Dispatcher ist stateless,
Jobs sind Wegwerf-Container, Transcripts unter RUNS_DIR sind verzichtbar.