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
[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:| Code | /Users/friedrichstr/ai-mac-studio/privat/todo_agenda |
| Tests | /Users/friedrichstr/ai-mac-studio/privat/todo_agenda/tests |
| Check | Path | Status | Detail |
|---|---|---|---|
| code | /Users/friedrichstr/ai-mac-studio/privat/todo_agenda | ✓ ok | 15 items, last_modified=2026-08-24 |
| tests | /Users/friedrichstr/ai-mac-studio/privat/todo_agenda/tests | ✓ ok | 5 items, last_modified=2026-08-12 |
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.
gerd.grasshoff@opensciencetechnology.com
und joanna.grasshoff@opensciencetechnology.com. Aufgaben lassen sich als
Termin in den Kalender des jeweiligen Besitzers schreiben.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. |
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
cd ~/ai-mac-studio/privat/todo_agenda # bzw. ai-mac-mini
uv venv --python 3.14
uv pip install --python .venv/bin/python -e .
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).
.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.
Die Einordnung versucht drei Wege in dieser Reihenfolge und meldet im Vorschlag unter „Quelle", welcher gegriffen hat:
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.GEMINI_API_KEY steckt im plist).Die Transkription der Sprachaufnahme läuft immer über Gemini; ffmpeg wandelt
das Browser-Format (webm auf dem Mac, mp4 auf iOS) vorher in WAV.
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"
| 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 |
| 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 |