sandrodachandClaude Opus 5.5 b2ecda9896
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m48s
fix(security): safe links and security headers (FLAW-28, FLAW-29)
safeHref lets only http, https and mailto become links (Markdown viewer,
outliner, legal links); javascript: and friends show as text. A
middleware sets a Content-Security-Policy (scripts only from MindSift,
no framing, connections only to this server), X-Frame-Options,
nosniff, Referrer-Policy and a Permissions-Policy. The two inline
scripts of index.html moved to files so script-src stays 'self'.

The second inline script also deleted every cache on each page load,
which undermined the offline start; it is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:02:13 +01:00

🧠 MindSift

Der Kopf frei in drei Sekunden.

Self-Hosted Docker SQLite Version

MindSift ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server.

MindSift Triage Desktop

Philosophie • Funktionen • Schnellstart • Betrieb • Entwicklung • Dokumentation


💡 Die Philosophie

Die meisten Notiz- und Aufgaben-Apps verlangen Struktur im falschen Moment: Wenn dir ein Gedanke kommt, willst du keinen Ordner suchen und keine Felder ausfüllen. MindSift trennt deshalb Erfassen und Organisieren:

  1. Abladen: In die Eingabeleiste tippen, Enter, fertig. Wer will, weist den Gedanken gleich einer Aufgabe, Liste oder Notiz zu.
  2. Sichten (Triage): Später gehst du den Stapel Karte für Karte durch: verwerfen, zur Aufgabe machen, in eine Notiz oder Liste verwandeln.
  3. Vertiefen: Aus losen Ideen werden Aufgaben mit Unteraufgaben, vernetzte Outliner-Notizen oder geteilte Listen für Familie und Team.

✨ Funktionen

⚡ Schnellerfassung & Triage

  • Eingabeleiste im Kopf der App, jederzeit mit C oder / fokussierbar; auch per Spracheingabe (Browser-Funktion).
  • Ziel beim Erfassen wählbar: Posteingang, Aufgabe, Listeneintrag oder Notiz.
  • Triage-Deck: H/← verwerfen, L/→ zur Aufgabe, T Aufgabe mit Termin, D in Notiz verwandeln, Leertaste = später. Auf dem Smartphone per Wischgeste.
  • Papierkorb mit Wiederherstellen.

MindSift Mobile Triage

✅ Aufgaben & Kanban

  • Listen- und Kanban-Ansicht, Spalten pro Aufgabenliste frei konfigurierbar.
  • Prioritäten, Fälligkeitsdatum, Hashtags, Unteraufgaben mit Fortschrittsbalken, Markdown-Notizen.
  • Filter, Gruppierung und Sortierung; Drag & Drop in Liste und Board.
  • Aufgabenlisten teilen mit Benutzern oder Gruppen, wahlweise als Bearbeiter oder nur lesend.
  • Alarme bei Fälligkeit per E-Mail, Discord oder eigenem Webhook.

MindSift Aufgaben und Kanban-Board

📝 Workspace: Outliner-Notizen

  • Jeder Gedanke ein Bullet: Enter, Tab/Shift+Tab, Ein-/Ausklappen, Drag & Drop ganzer Äste.
  • Zoom-Fokus per Klick auf den Bullet, Breadcrumbs zum Zurücknavigieren.
  • Blocktypen und Slash-Befehle: /todo, /link, /h1–/h3, /code (mit Syntax-Hervorhebung), /callout, /divider.
  • Wiki-Links [[Notiz]], Links und #Hashtags; Tag-Seiten bündeln alle Fundstellen.
  • Ordner, Favoriten, To-Do-Rollup über alle Notizen und Export einer Notiz als .md.
  • Einfügen von mehrzeiligem Markdown wird in Blöcke zerlegt; Strg+Z / Strg+Umschalt+Z nimmt eigene Änderungen zurück bzw. stellt sie wieder her.
  • Teilen: Notizen und ganze Ordner lassen sich Benutzern oder Gruppen als Bearbeiter oder Leser freigeben. Empfänger sortieren sie in ihren eigenen Baum ein.

🤝 Gemeinsam bearbeiten

  • Live: Mehrere Personen schreiben gleichzeitig in derselben Notiz; Änderungen erscheinen bei den anderen in Bruchteilen einer Sekunde. Der Kopf der Notiz zeigt, wer gerade mitliest.
  • Kein Überschreiben: Wer in einem Bullet schreibt, hält ihn kurz für sich; andere sehen ein Schloss mit Namen und arbeiten in den übrigen Bullets weiter. Kommt es doch zu einem Konflikt (z. B. nach Offline-Arbeit), bleibt der zweite Text als markierte Kopie mit „Übernehmen“/„Verwerfen“ erhalten.
  • Offline-fest: Jede Eingabe wird zuerst im Browser gesichert und später übertragen, auch nach Neuladen oder Tagen ohne Netz.
  • Hinter strengen Proxys: WebSocket → SSE → Long-Polling → Abfrage alle 3 s; MindSift wählt automatisch, was durchkommt. Der aktive Weg steht im Editor („Live“, „Abgleich alle 3 s“).

Technik dahinter: Doku/modules/collaboration.md.

MindSift Workspace Outliner

🛒 Geteilte Listen

  • Einkaufs-, Pack- und Checklisten mit Kategorien per Hashtag (Hafermilch #Kühlregal), Mengenangaben und Drag & Drop zwischen Kategorien.
  • Freigabe an Benutzer und Gruppen (Bearbeiter oder Leser); abgehakte Einträge erscheinen bei allen in Echtzeit.

MindSift Geteilte Listen

🏢 Benutzer, Gruppen, Administration

  • Geführte Ersteinrichtung, Rollen Admin und Mitglied, Einladungscodes, optional offene Registrierung.
  • Gruppen mit Gruppen-Admins für Freigaben.
  • Admin-Bereich: Benutzer, Einladungen, Instanzname, SMTP, Freigabe-Modus.
  • Vier Themes (Dark, Light, High-Contrast, Soft), installierbar als PWA. Die App startet auch ohne Netz mit dem zuletzt geladenen Stand; offline erfasste Gedanken und abgehakte Aufgaben oder Listeneinträge werden nachgereicht, sobald die Verbindung wieder da ist.

🔌 Integrationen

  • Webhook / API-Key: POST /api/v1/webhooks/ingest legt Aufgaben aus Smarthome, Skripten oder Automationen an.
  • Persönliche API-Keys, Datenexport als JSON.

🚀 Schnellstart

MindSift läuft als einzelner Container mit Webserver, API, Datenbank und Frontend.

Option 1: Installationsskript

curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/install.sh | bash

Das Skript legt ein Verzeichnis an, lädt docker-compose.yml und .env.example, erzeugt ein JWT_SECRET und startet den Container.

Option 2: Docker Compose

mkdir -p mindsift && cd mindsift
curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/docker-compose.yml -o docker-compose.yml
curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/.env.example -o .env
# In .env: JWT_SECRET durch einen langen Zufallswert ersetzen!
docker compose up -d

Minimal:

services:
  mindsift:
    image: git.dsit.me/sandrodach/mindsift:stable   # oder feste Version (:v0.4); :latest = main, :dev = Entwicklungsstand
    restart: unless-stopped
    ports: ["8080:8080"]
    volumes: ["./data:/data"]
    environment:
      - JWT_SECRET=hier-ein-langer-zufaelliger-wert
      - BASE_URL=https://mindsift.example.com

Ersteinrichtung

Rufe http://localhost:8080 auf. Beim ersten Start führt ein Assistent durch das Anlegen des Administrator-Kontos.

⚠️ JWT_SECRET: Ohne Angabe (oder mit einem der Platzhalter aus den Beispielen) erzeugt der Server beim ersten Start einen Zufallswert und speichert ihn als jwt.secret im Datenverzeichnis. Für Produktion lieber selbst einen langen Zufallswert setzen. Rufe die Instanz außerdem direkt nach dem Start auf, damit kein Fremder das erste Konto anlegt.


⚙️ Betrieb & Konfiguration

Variable Standard Zweck
PORT 8080 HTTP-Port
DATA_DIR /data (Container) Ablage der Datenbank mindsift.db
JWT_SECRET zufällig erzeugt (/data/jwt.secret) Signaturschlüssel der Anmelde-Tokens; Platzhalter werden ignoriert
BASE_URL http://localhost:8080 Öffentliche URL. Nur wenn gesetzt (und SMTP eingerichtet ist), gibt es „Passwort vergessen?“ – die Links in den Mails werden ausschließlich daraus gebaut
TRUSTED_PROXIES private Wessen X-Forwarded-For/X-Real-IP geglaubt wird: private (Proxy im Docker-/Heimnetz), all (immer, früheres Verhalten), none oder eigene CIDR-Bereiche (Doku/reverse-proxy.md)
LOGIN_PROTECTION true Sperre nach Fehlversuchen: 3 pro Konto und Adresse, 20 pro Konto, 30 pro Adresse, jeweils 15 Minuten. false schaltet sie ab
TZ Europe/Berlin Zeitzone für Fälligkeiten und Alarme (ganztägige Aufgaben melden sich um 9:00)
ALLOW_REGISTRATION false Offene Registrierung (im Admin-UI änderbar)
LOG_LEVEL / DEBUG info / false Logging
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM, SMTP_TLS leer E-Mail-Alarme (auch im Admin-UI)
SMTP_SKIP_VERIFY false Zertifikatsprüfung für interne Mailserver abschalten
LEGAL_IMPRINT_URL, LEGAL_PRIVACY_URL leer Impressum/Datenschutz als externer Link (nur http(s))
LEGAL_IMPRINT_CONTENT, LEGAL_PRIVACY_CONTENT (oder …_CONTENT_FILE mit Dateipfad) leer Impressum/Datenschutz als Markdown, angezeigt in einem Lesefenster. Ohne URL und Text bleibt der Link unsichtbar.
MINDA_DEMO false Legt Demo-Konten admin/admin (mit Beispieldaten) und user/user an; eine Notiz und zwei Listen sind zwischen beiden geteilt, um das gemeinsame Bearbeiten auszuprobieren. Nie auf öffentlichen Servern!
DEMO_RESET_MINUTES 20 Nur im Demo-Modus: setzt die Datenbank in diesem Abstand auf die Beispieldaten zurück (0 = nie). Angemeldete bleiben angemeldet, die App zeigt einen Countdown und lädt danach neu.
  • Reverse-Proxy: Am besten WebSocket-Upgrade und ungepufferte SSE-Streams durchreichen. Blockiert ein Proxy beides, funktioniert MindSift trotzdem über Long-Polling bzw. regelmäßige Abfragen, nur etwas träger. Beispiele für Nginx, Traefik, Caddy und Cloudflare: Doku/reverse-proxy.md.
  • Datensicherung: In den Admin-Einstellungen lassen sich automatische tägliche Backups einschalten (ganze Datenbank plus ein Backup je Benutzer unter data/backups/, Standard 3 Tage aufbewahrt). Benutzer laden ihre Server-Backups herunter oder spielen sie ganz oder für einzelne Bereiche wieder ein. Der Ordner liegt neben der Datenbank: zusätzlich woanders sichern. Manuell geht weiterhin sqlite3 mindsift.db ".backup 'backup.db'".
  • Updates: Neues Image ziehen und Container neu starten (docker compose pull && docker compose up -d). Das Schema wird beim Start automatisch angepasst. Die laufende Version steht im Kopf der App unter dem Namen.
  • Image-Tags: :dev = Stand des Branches dev, :latest = Stand von main, :stable = zuletzt veröffentlichte Version. Ein Git-Tag wie v1.2.0 erzeugt :v1.2.0 und verschiebt :stable darauf; Vorabversionen wie v1.0.0-rc.1 verschieben :stable nicht.
  • Versionen & Änderungen: Semantic Versioning, was sich geändert hat, steht in der CHANGELOG.md.

🛠 Entwicklung

Voraussetzungen: Go 1.23, Node 22.

# Backend: Vet und Tests
go vet ./... && go test ./...

# Frontend
cd frontend
npm ci
npm run dev                # Vite-Entwicklungsserver
npx tsc --noEmit           # Typprüfung
npm run test:run           # Komponententests (Vitest, jsdom)
npm run build              # Produktions-Build
cd ..
e2e/run.sh                 # Browser-Tests (Playwright, zwei Benutzer) gegen ein frisch gebautes Image
APP_VERSION=v0.4 e2e/screenshots.sh   # Screenshots dieser README neu erzeugen (Demo-Daten)

Für das Binary wird das gebaute Frontend nach cmd/server/dist kopiert (go:embed); das mehrstufige Dockerfile erledigt das und führt Typprüfung, Frontend-Tests, Go-Vet und Go-Tests beim Image-Build aus.

Stack: Go (chi, gorilla/websocket, JWT, modernc SQLite) · React 18, TypeScript, Vite, Tailwind.


📚 Dokumentation

Die technische Doku liegt unter Doku/: Architektur, Datenbank, REST- und Echtzeit-API, Module (inkl. gemeinsamem Bearbeiten), Freigaben und Berechtigungen, Reverse-Proxy, Themes. Bekannte Schwachstellen und offene Punkte stehen in Doku/flaws.md.


🔒 Deine Daten gehören dir

  • Selbst gehostet, keine Telemetrie, keine Fremddienste. Ausgehende Verbindungen gibt es nur zu den Alarm-Zielen, die du selbst einrichtest (SMTP, Discord, Webhook).
  • Alle Inhalte liegen in einer einzigen SQLite-Datei; der ganze Workspace lässt sich als Obsidian-kompatibles Markdown-Archiv (ZIP) exportieren, alle Daten eines Benutzers als JSON.

📄 Lizenz

MindSift ist gemeinfrei unter The Unlicense: Du darfst den Code ohne jede Bedingung nutzen, ändern, weitergeben und verkaufen, auch ohne Namensnennung. Es gibt keine Gewährleistung.

Gebaut für Klarheit, Geschwindigkeit und digitale Souveränität.
S
Description
No description provided
Readme Unlicense
15 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 56.6%
Go 39.4%
JavaScript 1.9%
CSS 1.5%
Shell 0.4%
Other 0.2%