AI bot that creates PRs when tasked with Issues
  • Python 60.4%
  • Shell 21%
  • HTML 13.5%
  • Dockerfile 5.1%
Find a file
Moritz 312151639a feat(status): mike-Status-Seite v1 (live + Historie + Kosten)
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>
2026-07-22 22:55:25 +02:00
dispatcher feat(status): mike-Status-Seite v1 (live + Historie + Kosten) 2026-07-22 22:55:25 +02:00
job feat(status): mike-Status-Seite v1 (live + Historie + Kosten) 2026-07-22 22:55:25 +02:00
.env.example feat(status): mike-Status-Seite v1 (live + Historie + Kosten) 2026-07-22 22:55:25 +02:00
.gitignore chore: Repo-Skeleton mit Spec, README und Secret-Gitignore 2026-07-22 17:54:23 +02:00
CLAUDE.local.md docs: Standard-Workflow 'Reibungspunkte erforschen' als CLAUDE.local.md 2026-07-22 19:11:36 +02:00
CLAUDE.md feat(job): Flutter 3.44 + clang ins Job-Image für flutter test auf ACT/app 2026-07-22 19:38:31 +02:00
compose.yaml feat(status): mike-Status-Seite v1 (live + Historie + Kosten) 2026-07-22 22:55:25 +02:00
mike-spec.md feat(job): Flutter 3.44 + clang ins Job-Image für flutter test auf ACT/app 2026-07-22 19:38:31 +02:00
observability-spec.md docs: Idee-Spec für mike-Status-Seite (Verlauf + Live-Kosten) 2026-07-22 22:23:47 +02:00
README.md docs: Deployment-Stand M1–M3 verifiziert; Webhook-Einrichtung präzisiert 2026-07-22 18:36:55 +02:00
status-page-spec.md feat(status): mike-Status-Seite v1 (live + Historie + Kosten) 2026-07-22 22:55:25 +02:00

@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/hooks legt 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-DB UPDATE 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-Accounts mike.
  • 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.