Package: todo_agenda

All packages Open in Cursor /Users/friedrichstr/ai-mac-studio/privat/todo_agenda
Status
Description: Hierarchische Todo- und Terminverwaltung für Gerd und Joanna. FastAPI-Dienst auf
Port: —
Venv: venv present /Users/friedrichstr/ai-mac-studio/privat/todo_agenda/.venv/bin/python
Git: not a git repo
File tree
todo_agenda/
  scripts/
    caldav_check.py
  src/
    todo_agenda/
  tests/
    test_api.py
    test_calendar.py
    test_dictation.py
    test_frontend_serving.py
    test_store.py
  calendar_cache.json
  events.jsonl
  PROJECT.yaml
  pyproject.toml
  README.md
  todo.json
  todo.json.bak.1
  todo.json.bak.2
  todo.json.bak.3
  todo.json.bak.4
  todo.json.bak.5
Project Goaldraft

[DRAFT — edit this] Hierarchische Todo- und Terminverwaltung fuer Gerd und Joanna mit IONOS-CalDAV und Diktat-Pipeline Inferred stage: development. Define the specific deliverable, success state, and timeline.

Success criteria:
  • [DRAFT] Define 3–5 checkable criteria for project completion
Code/Users/friedrichstr/ai-mac-studio/privat/todo_agenda
Tests/Users/friedrichstr/ai-mac-studio/privat/todo_agenda/tests
Path & Service Checks
CheckPathStatusDetail
code/Users/friedrichstr/ai-mac-studio/privat/todo_agenda✓ ok15 items, last_modified=2026-08-24
tests/Users/friedrichstr/ai-mac-studio/privat/todo_agenda/tests✓ ok5 items, last_modified=2026-08-12
Documentation
README

ai-todo-agenda

Hierarchische Todo- und Terminverwaltung für Gerd und Joanna. FastAPI-Dienst auf Port 5530, erreichbar von allen Rechnern im Tailnet, mit angepasster Oberfläche für macOS, iPad und iPhone.

Was der Dienst kann

  • Organizer-Baum mit bis zu fünf Ebenen. Die oberste Ebene (Gerd, Joanna) dient als Bereichsmenü, darunter liegt der eigentliche Aufgabenbaum. Jede Aufgabe gehört genau einem der beiden; ohne Angabe erbt sie den Besitzer ihres Elternknotens.
  • Zwei IONOS-Kalender über CalDAV: gerd.grasshoff@opensciencetechnology.com und joanna.grasshoff@opensciencetechnology.com. Aufgaben lassen sich als Termin in den Kalender des jeweiligen Besitzers schreiben.
  • Diktierfenster: Aufnahme im Browser, Transkription mit Gemini, Einordnung in den Baum durch eine Agenten-Pipeline. Jeder Vorschlag wird als Diff angezeigt und erst nach Bestätigung geschrieben.

Daten

Alles liegt als Klartext im Projektordner und wird von Syncthing repliziert:

Datei Inhalt
todo.json Der komplette Aufgabenbaum. Einzige Quelle der Wahrheit.
events.jsonl Append-only-Protokoll aller Änderungen, Basis für Undo.
calendar_cache.json Kalender-Cache, wird nicht synchronisiert.
audio/YYYY-MM-DD/ Archivierte Diktate, wird nicht synchronisiert.

Schreibhoheit

Der Ordner liegt in einem Syncthing-Ordner, deshalb darf nur ein Host schreiben. Der schreibende Host trägt sich in todo.json unter updated_by ein; alle anderen starten automatisch im Read-only-Modus. Schreibhoheit übernehmen:

todo-agenda claim

Installation

cd ~/ai-mac-studio/privat/todo_agenda     # bzw. ai-mac-mini
uv venv --python 3.14
uv pip install --python .venv/bin/python -e .

Kalender einrichten

Die Passwörter liegen im macOS-Keychain, niemals im Syncthing-Ordner. Einmalig pro Konto auf dem Host, der den Server betreibt:

security add-generic-password -s todo-agenda-caldav \
  -a gerd.grasshoff@opensciencetechnology.com -w
security add-generic-password -s todo-agenda-caldav \
  -a joanna.grasshoff@opensciencetechnology.com -w

Danach die Verbindung prüfen — das Skript listet alle Kalender und die Termine der nächsten 30 Tage:

.venv/bin/python scripts/caldav_check.py

CalDAV-Endpunkt ist https://caldav.1und1.de/begenda/dav/ mit Basic-Auth (Benutzername = E-Mail-Adresse).

Starten

.venv/bin/todo-agenda serve            # 0.0.0.0:5530
.venv/bin/todo-agenda status           # Store- und Kalenderzustand
.venv/bin/todo-agenda calendar --refresh

Als Dienst auf mac-studio (dort bereits eingerichtet und geladen):

cp ~/ai-mac-studio/platform/launchd/com.ai-platform.todo-agenda.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.ai-platform.todo-agenda.plist
launchctl kickstart -k gui/$(id -u)/com.ai-platform.todo-agenda   # nach Code-Änderungen

Logs unter ~/Library/Logs/ai-platform/todo-agenda_{stdout,stderr}.log.

Diktat: welches Modell antwortet

Die Einordnung versucht drei Wege in dieser Reihenfolge und meldet im Vorschlag unter „Quelle", welcher gegriffen hat:

  1. Orchestrator auf 127.0.0.1:5401 mit agent-store/todo_agenda_agent/partitur.yaml — die beste Qualität, weil die Partitur den Validity-Evaluator für das JSON-Schema mitbringt. Läuft der Dienst nicht, wird stillschweigend weitergereicht.
  2. Gemini direkt mit demselben Prompt (GEMINI_API_KEY steckt im plist).
  3. Ollama lokal als letzter Ausweg.

Die Transkription der Sprachaufnahme läuft immer über Gemini; ffmpeg wandelt das Browser-Format (webm auf dem Mac, mp4 auf iOS) vorher in WAV.

Zugriff

https://mac-studio.tail147011.ts.net/agenda — von jedem Gerät im Tailnet, also Mac, iPhone und iPad. Auf iOS über „Teilen → Zum Home-Bildschirm" ablegen, dann startet die App im Vollbild ohne Safari-Leisten.

Der Weg läuft über den ai-platform-proxy (Port 5001), den Tailscale unter / veröffentlicht; die Route /agenda steht mit strip_prefix: true in routes.yaml. Deshalb sind alle Pfade im Frontend relativ, und der Server setzt beim Ausliefern ein <base>-Element aus dem Header x-original-path.

Der direkte Weg http://mac-studio:5530 funktioniert nur auf mac-studio selbst: dort ist die macOS-Programmfirewall aktiv und blockt eingehende Verbindungen zu Python-Diensten. Wer den Direktzugriff aus dem Tailnet will, gibt den Interpreter einmalig frei:

FW=/usr/libexec/ApplicationFirewall/socketfilterfw
PY=$(readlink -f ~/ai-mac-studio/privat/todo_agenda/.venv/bin/python)
sudo $FW --add "$PY" && sudo $FW --unblockapp "$PY"

Endpunkte

Methode Pfad Zweck
GET /api/tree Baum, optional gefiltert nach owner, status, q, root
GET /api/areas Oberste Ebene mit Zählern für das Bereichsmenü
POST /api/nodes Knoten anlegen
PATCH /api/nodes/{id} Knoten ändern
DELETE /api/nodes/{id} Knoten löschen
POST /api/nodes/{id}/move Umhängen, prüft Tiefenlimit
POST /api/nodes/{id}/schedule Termin im CalDAV-Kalender anlegen
DELETE /api/nodes/{id}/schedule Termin entfernen
GET /api/calendar Termine beider Konten, Fenster über from/to
POST /api/calendar/refresh Sofortiger CalDAV-Abruf
POST /api/dictate/audio Audio hochladen, Transkript und Vorschlag erhalten
POST /api/dictate/text Wie oben, aber mit fertigem Text
POST /api/dictate/apply Bestätigten Vorschlag schreiben
POST /api/undo Letzte Diktat-Anwendung zurücknehmen
GET /api/status Schreibhoheit, Kalenderzustand, Knotenzahl
GET /health Health-Check

Umgebungsvariablen

Variable Vorgabe Zweck
TODO_AGENDA_ROOT Projektordner Überschreibt den Datenpfad
TODO_AGENDA_PORT 5530 Port
TODO_AGENDA_HOST 0.0.0.0 Bind-Adresse
TODO_AGENDA_FORCE_WRITE — 1 erzwingt Schreibhoheit
TODO_AGENDA_CAL_REFRESH 600 Sekunden zwischen CalDAV-Abrufen
TODO_AGENDA_ORCHESTRATOR http://127.0.0.1:5401 ai-agent-orchestrator
GEMINI_API_KEY aus ~/.zshrc Transkription und Agenten-Fallback
Recent commits
No git history.