Files
MindSift/AGENTS.md
T
sandrodachandClaude Opus 5.5 fdd6e38065
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m38s
feat(ui): connection status in the header; README screenshots as WebP
- Desktop shows "offline" with a red dot under the user name when the
  server is unreachable; phones show a green/red dot on the avatar.
  Based on the app-wide realtime connection, so a server outage is
  noticed even while the device has network (4 s grace period).
- Screenshots converted to WebP (1280 px desktop, 480 px phone, q90),
  e2e/screenshots.sh converts with cwebp; new journal picture with
  round corners. Rules in AGENTS.md.
- Release v0.26.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 19:17:51 +01:00

6.7 KiB

Hinweise für Coding-Agenten

Regeln für die Arbeit an MindSift, die nicht aus dem Code selbst hervorgehen. Aufbau und Technik stehen in Doku/, vor allem architecture.md.

Sprache und Stil

  • Deutsch: Oberflächentexte, Fehlermeldungen für Nutzer, E-Mails, CHANGELOG.md, README.md, Doku/.
  • Englisch: Code-Kommentare und Commit-Nachrichten.
  • Commit-Nachrichten im Stil feat(bereich): …, fix(bereich): …, docs: …, style(bereich): …. Am Ende die Zeile Co-Authored-By: … des jeweiligen Agenten.
  • Neuer Code richtet sich nach dem umgebenden Code: Benennung, Kommentardichte, vorhandene Helfer statt neuer Varianten.

Umgebung

Auf dem Entwicklungsrechner sind weder Node noch Go installiert. Alles läuft in Containern (podman):

# Frontend: Typen, Lint, Tests
podman run --rm -v "$PWD/frontend":/app:Z -w /app docker.io/library/node:22-alpine \
  sh -c "npx tsc --noEmit && npx eslint src/… && npx vitest run"

# Backend: vet und Tests
podman run --rm -v "$PWD":/src:Z -w /src docker.io/library/golang:1.24-alpine \
  sh -c "go vet ./... && go test ./internal/..."

Die Linter-Warnungen react-hooks/exhaustive-deps gibt es schon länger; neuer Code soll keine zusätzlichen Warnungen bringen.

Prüfen während der Arbeit

  • Gezielt prüfen: tsc, die betroffenen Frontend-Tests, go vet und go test. Den vollen Build macht nur der Server (siehe Release-Ablauf); ein kompletter podman build . vorher ist doppelte Arbeit.

  • Oberfläche im Browser ansehen, besonders Handy-Ansichten: Image bauen, im Demo-Modus starten, mit Playwright aus dem e2e/-Ordner prüfen (Vorbild: e2e/screenshots.sh). Handy-Emulation mit isMobile: true, hasTouch: true; Finger-Gesten lassen sich über das Chrome DevTools Protocol (Input.dispatchTouchEvent) nachstellen.

    podman build -q -t mindsift-check .
    podman run -d --rm --name ms-check --network host -e PORT=18555 -e MINDA_DEMO=true \
      -e DEMO_RESET_MINUTES=0 -e JWT_SECRET=check-only mindsift-check
    # Demo-Anmeldung: admin/admin bzw. user/user
    
  • Zeitabhängiger Code (Alarme, Tageszusammenfassung, Begrüßungen, Termine): nie time.Now() dort, wo eine übergebene Zeit gemeint ist. Die betroffenen Go-Tests zusätzlich mit verschiedenen TZ-Werten laufen lassen (z. B. Europe/Berlin, America/Los_Angeles, Asia/Tokyo). Ein uhrzeitabhängiger Test hat schon einmal einen Release verhindert, weil er nur vormittags grün war.

Screenshots

  • Bilder in screenshots/ (README) sind WebP, keine PNG: Desktop und Theme-Raster 1280 px breit, Handy 480 px, Qualität 90. Das bringt rund ein Fünftel der PNG-Größe bei sauberer Schrift.
  • Erzeugt werden sie mit e2e/screenshots.sh; das Skript nimmt PNGs auf und wandelt sie am Ende mit cwebp (Alpine-Container) um. Einzelne Bilder neu aufnehmen: denselben Ablauf aus screenshots.mjs verwenden und mit dem Umwandlungsschritt aus screenshots.sh konvertieren.
  • Chromiums eigenes WebP (canvas.toDataURL('image/webp')) nicht verwenden: verlustfrei wird es größer als die PNG.

Release-Ablauf

Committen ist jederzeit erlaubt. Jeder Push ist ein Release, also mit Version und CHANGELOG-Eintrag.

  1. Version erhöhen (SemVer: Fehlerbehebung → Patch, neue Funktion → Minor):
    • frontend/package.json (Feld version)
    • frontend/package-lock.json: nur die beiden Versionszeilen von MindSift selbst (Zeile 3 und 9), nicht die gleichlautenden Versionen von Abhängigkeiten
    • Versions-Badge oben in README.md
  2. CHANGELOG: neuer Abschnitt ## [x.y.z] - JJJJ-MM-TT unter ## [Unreleased] (Format Keep a Changelog, Abschnitte Added/Changed/Fixed), unten die Vergleichslinks [Unreleased] und [x.y.z] anpassen. Einträge auf Deutsch und aus Sicht der Nutzer.
  3. Doku nachziehen, wenn sich Verhalten oder API ändern (README.md, Doku/api/rest.md, Doku/architecture.md).
  4. Committen, dann nur nach dev pushen.
  5. Warten, bis der dev-Build auf dem Server grün ist. Schlägt er fehl: auf dev beheben, nicht nach main mergen.
  6. Nach main mergen (git merge --no-ff dev -m "Merge dev into main (vx.y.z)") und pushen.
  7. Warten, bis der main-Build grün ist. Erst dann gilt das Release als draußen.

Ist ein Release nie gebaut worden (CI fehlgeschlagen), bleibt die Versionsnummer, und die Korrektur kommt in denselben CHANGELOG-Abschnitt.

Git-Tags nur auf ausdrücklichen Wunsch. Tags lassen zusätzliche Images bauen; genutzt werden nur :dev und :latest. Wenn gewünscht: git tag -a vx.y.z -m "MindSift vx.y.z" auf den Merge-Commit in main und den Tag pushen.

Fremde Branches (z. B. von anderen Agenten) werden vor dem Mergen geprüft.

CI auf dem Git-Server

  • Workflow: .gitea/workflows/build-and-publish.yaml, Entscheidung in .gitea/scripts/build-plan.sh.

  • dev → Image :dev, mit allen Tests (Dockerfile: tsc, Lint, Frontend-Tests, go vet, Go-Tests).

  • main → Image :latest mit APP_VERSION=v<package.json-Version>; überspringt die Tests, wenn :dev aus demselben Code gebaut wurde. Deshalb erst nach grünem dev-Build mergen.

  • Tag v* → :vx.y.z und :stable.

  • Status der letzten Läufe:

    curl -s "https://git.dsit.me/api/v1/repos/sandrodach/MindSift/actions/tasks?limit=4"
    # workflow_runs[].head_branch / .status (success|failure|…) / .display_title
    

Oberfläche

  • Einheitliche Bedienelemente: Personen-Suche, Profilbild-Stapel, Zähler und weitere Muster stehen in Doku/ui-patterns.md. Vorhandene Komponenten verwenden statt neuer Varianten; neue gemeinsame Muster dort ergänzen.
  • Handy und Desktop: Unter sm ist Handy-Layout, ab lg die volle Desktop-Ansicht (z. B. Seitenleiste neben der Notiz). Wird nur das Handy geändert, bleiben die Werte ab sm/lg exakt wie vorher.
  • Antippen am Handy: Ziele mindestens 44 px hoch (h-11 sm:h-…). Auf reinen Touch-Geräten gibt es kein HTML5-Drag-&-Drop; Kanban nutzt dafür useKanbanTouchDrag, die Notizen die Leiste über der Tastatur (MobileOutlineBar).
  • Themes: Farben nur über die Theme-Variablen bzw. Klassen (bg-panel, bg-canvas, text-main, text-muted, border-border, bg-accent …), keine festen Farben. Rahmen mit bg-panel/bg-canvas bekommen die Ecken des Themes automatisch; liegt darin ein Kopfbereich mit eigenem Hintergrund, braucht der Rahmen overflow-hidden, sonst ragen bei runden Ecken die Kanten heraus.
  • Installierte App (PWA): Manifest-Änderungen (Farben, Verknüpfungen) übernimmt Android erst, wenn es die App aktualisiert (bis etwa einen Tag) oder nach Neuinstallation; normaler App-Code kommt beim nächsten Start. Ändert sich der Cache-Inhalt des Service Workers, VERSION in frontend/public/sw.js erhöhen.