# Cron Job: Abend-Check 20:00

**Job ID:** 0968c1c5dec3
**Run Time:** 2026-06-04 20:01:21
**Schedule:** 0 20 * * *

## Prompt

[IMPORTANT: The user has invoked the "daily-dose" skill, indicating they want you to follow its instructions. The full skill content is loaded below.]

---
name: daily-dose
description: Modify DailyDose (täglicher Aktivitäten-Tracker PWA) — Kategorien, Defaults, Server-Daten. Der Tracker von Zeyd unter /media/HDD_1TB/DailyDose/.
---

# DailyDose — Täglicher Aktivitäten-Tracker

DailyDose ist eine PWA (Progressive Web App), die Zeyds tägliche Aktivitäten trackt. Läuft lokal mit Server-Sync.

## Architektur

- **Pfad:** `/media/HDD_1TB/DailyDose/`
- **Dateien:** `index.html` (komplette App in einer Datei), `manifest.json`, `icon.svg`, `icon.png`, `nginx.conf`
- **Speicher:** localStorage im Browser, synchronisiert über HTTP-API mit Server
- **API:** `http://localhost:8765/api/data` — GET liest alle Daten, POST schreibt Key-Value-Paare
- **Storage-Keys:** `dailydose_YYYY-MM-DD` für Tageseinträge, `dd_custom_cats` für Custom-Kategorien

## Kategorien

### Built-in (in `BUILT_IN_CATS` Array, Zeile ~878)
Schlafen, Lernen, Work, Hausarbeit, Kochen, Islam, Sport, Unterwegs, Körperpflege, Sonstiges

### Custom
In `dd_custom_cats` auf dem Server gespeichert. **Custom-Kategorien überschreiben Built-ins** (Name-Match). Werden in `buildCategoryMaps()` nach den Built-ins geladen und überschreiben deren `COLORS`/`ICONS`.

## Tägliche Defaults (`getDefaults()`)

Definiert, welche Aktivitäten für einen neuen Tag vorausgefüllt werden. Aktuelle Defaults (Zeile ~1031):
- **Islam:** 15 min täglich, 45 min freitags
- **Körperpflege:** 30 min täglich
- **Unterwegs:** 1h Montag + Dienstag

Defaults greifen NUR, wenn für den Tag noch KEINE Daten im localStorage existieren. Sobald ein Tag gespeichert wurde, werden die gespeicherten Daten verwendet.

## Änderungen vornehmen

### Neue Kategorie hinzufügen
1. In `index.html` das `BUILT_IN_CATS` Array patchen — neuen Eintrag mit `value`, `icon`, `color` einfügen
2. Default in `getDefaults()` eintragen, falls gewünscht
3. **Server-Daten prüfen:** Falls bereits eine Custom-Kategorie mit gleichem Namen existiert, diese löschen oder anpassen, da sie sonst das Built-in überschreibt

### Default-Wert ändern
In `getDefaults()` patchen. Greift erst für zukünftige, noch nicht gespeicherte Tage.

### Heutigen Tag direkt korrigieren
Wenn heute schon Daten existieren, müssen sie direkt via API gepatcht werden:
```bash
# Heutige Einträge lesen
curl -s http://localhost:8765/api/data | python3 -c "import json,sys; ..."

# Einträge patchen und zurückschreiben
curl -s -X POST http://localhost:8765/api/data \
  -H 'Content-Type: application/json' \
  -d '{"dailydose_YYYY-MM-DD":"[{\"category\":\"...\",\"hours\":0.5}]"}'
```

## Automatische Erinnerungen per Cron-Job

DailyDose-Einträge werden schnell vergessen. Setze automatische Erinnerungen über den `cronjob`-Agenten, damit Zeyd ("Chef") regelmäßig an das Tracking erinnert wird.

### Morgenbriefing (09:30)

Das tägliche Morgenbriefing kombiniert Kalender (Google), CallKeep (Telefonhistorie), DailyDose (Tracking) und Wetter zu einem persönlichen Tagesüberblick. Die vollständige Prompt-Vorlage mit Struktur, Stilregeln und Beispielen steht in **`references/morgenbriefing-template.md`** — bei Verbesserungen am Cronjob diese Datei konsultieren und ggf. aktualisieren.

### Prompt-Stil für Erinnerungen

- **Sprache:** Deutsch
- **Ton:** Freundlich, motivierend, nicht nervig
- **Länge:** 1-2 Sätze, kurz
- **Tageszeit-Anpassung:** Morgens energisch/optimistisch, nachmittags sachlich/freundlich, abends entspannt
- **Abwechslung:** Die Formulierung jedes Mal leicht variieren, damit es nicht monoton wirkt
- **Emojis:** Gelegentlich ein passendes Emoji (nicht inflationär)
- **Anrede:** "Chef"

### Beispiele

```
🌅 Guten Morgen Chef! Zeit für deine DailyDose — was hast du heute vor?
☀️ DailyDose-Check! Nicht vergessen, deine Aktivitäten einzutragen.
🌙 Abend-Check! Noch schnell die DailyDose für heute ausfüllen, Chef?
```

### Scheduling

- Tägliche Erinnerungen: `0 9,16,22 * * *` (dreimal am Tag)
- Goal-Tracking: `*/15 * * * *` (alle 15 Minuten) für motivationsgetriebene Lern-/Ziel-Checks
- `repeat: -1` für wiederkehrende Jobs
- `deliver: origin` für Telegram-Zustellung

### Wichtig

- Cron-Job-Prompts müssen **selbsterklärend** sein — der erinnernde Agent läuft unabhängig und hat keinen Gesprächskontext
- Nicht zu oft auf "wir" oder "uns" Bezug nehmen — die Nachricht soll natürlich wirken

### Goal-Based Motivation Cron Jobs (Lernziel-Tracking)

Wenn Chef ein Tagesziel für eine bestimmte Kategorie hat (z.B. "120 Minuten Lernen → Kopfhörer bestellen"), kann ein Cron-Job alle 15 Minuten den Fortschritt checken und motivierend melden.

**Pattern:**
1. Python-Script schreiben, das die DailyDose-API abfragt, die Ziel-Kategorie summiert und Fortschritt/Erfolg ausgibt (siehe `scripts/dailydose_learn_check.py`)
2. Script nach `~/.hermes/scripts/` kopieren (Cron-Job-Tool erwartet Pfad relativ zu `~/.hermes/scripts/`)
3. Cron-Job mit `schedule: "*/15 * * * *"`, `no_agent: true`, `script: dailydose_learn_check.py` anlegen
4. Job pausieren/löschen, sobald Ziel erreicht ist

**Script-Logik:**
- TARGET_MINUTES definieren
- Heutigen Key `dailydose_YYYY-MM-DD` aus der API lesen
- Stunden der Ziel-Kategorie summieren, in Minuten umrechnen
- Drei Ausgaben: Ziel erreicht (🎉), in Progress (📚 mit Prozent), noch nichts (Motivation zum Starten)

## Motivation/Erinnerungen

Wenn der Chef einen Motivations-Workflow will (z.B. "Sag mir alle 15 Minuten wie viel ich gelernt habe, bis Ziel erreicht"), **nicht** direkt einen `no_agent`-Cronjob mit statischem Script bauen. Die Nachrichten wirken mechanisch und frustrieren. Besser:

1. **Cronjob mit Agent:** `no_agent: false` — der Agent kriegt dann Kontext (DailyDose-Check als Prompt) und kann natürlich, variabel und motivierend antworten.
2. **Oder manuell:** Chef fragt selbst nach Stand, Kiwi checkt dann live. Weniger nervig.

Vorher mit Chef klären, ob automatisierte Reminder überhaupt erwünscht sind.

**Manueller Check per Script:** `scripts/learn_check.py` — gibt Motivations-Stand für eine Kategorie aus. Aufruf: `python3 scripts/learn_check.py [ziel_minuten] [kategorie]`. Default: 120 Minuten, "Lernen".

## Pitfalls

- **Zeitgeist API: ALLE Werte sind JSON-Strings — doppelt parsen!** `curl http://localhost:8765/api/data` liefert ein JSON-Objekt, bei dem JEDER Wert ein String ist, der selbst wieder JSON enthält. `data['zeitgeist-v2']` ist z.B. der String `"{\"2026-05-22\":[25,25,...]}"`. Direktes Zugreifen mit `.get()` oder Index-Notation auf den Roh-String wirft `AttributeError: 'str' object has no attribute 'get'`. **Immer** so parsen:
  ```python
  for k, v in data.items():
      if isinstance(v, str) and v.strip().startswith(('{', '[')):
          data[k] = json.loads(v)
  ```
  Erst DANACH ist `data['zeitgeist-v2']['2026-05-22']` ein echtes Array.
- **Custom überschreibt Built-in:** Wenn eine Custom-Kategorie denselben Namen hat wie ein Built-in, gewinnt die Custom-Version (Icon + Farbe). Bei Konflikten die Custom-Kategorie auf dem Server anpassen.
- **Defaults gelten nicht für existierende Tage:** `getDefaults()` wird nur als Fallback verwendet, wenn `localStorage.getItem(dateKey)` `null` zurückgibt. Für bereits getrackte Tage muss der Server direkt gepatcht werden.
- **Server-Sync beachten:** Daten liegen auf dem Server (`:8765`). Änderungen nur im HTML reichen nicht, wenn der Tag schon Daten hat.
- **Emoji/Icon-Konsistenz:** Immer sowohl Built-in als auch Custom-Kategorie prüfen, damit das richtige Icon angezeigt wird.

The user has provided the following instruction alongside the skill invocation: [IMPORTANT: You are running as a scheduled cron job. DELIVERY: Your final response will be automatically delivered to the user — do NOT use send_message or try to deliver the output yourself. Just produce your report/output as your final response and the system handles the rest. SILENT: If there is genuinely nothing new to report, respond with exactly "[SILENT]" (nothing else) to suppress delivery. Never combine [SILENT] with content — either report your findings normally, or say [SILENT] and nothing more.]

Abend-Check für den Chef (Zeyd). Führe folgende Schritte aus:

1. **CallKeep Telefonate prüfen:** Rufe curl -s http://localhost:3002/api/calls ab. Prüfe, ob HEUTE Anrufe verbucht wurden (Feld called_at enthält heutiges Datum 2026-05-29). 
   - Falls KEINE Anrufe für heute verbucht sind: Frage den Chef freundlich, ob er heute telefoniert hat und ob er die Anrufe noch in CallKeep eintragen möchte.
   - Falls Anrufe verbucht sind: Sage kurz "Heute wurden X Anrufe verbucht, sehr gut!" und liste sie kurz (mit wem, wie lange).

2. **DailyDose:** Erinnere den Chef nochmal freundlich, seine DailyDose für heute auszufüllen. Kurz, entspannt, auf Deutsch. Variiere die Formulierung jedes Mal.

**Ton:** Entspannt, freundlich, auf Deutsch. Sprich Zeyd mit "Chef" an.

## Response

🌙 **Abend-Check, Chef!**

**📞 CallKeep:** Für heute (29.05.) sind noch keine Anrufe verbucht. Hast du heute telefoniert? Falls ja — schnell noch in CallKeep eintragen, bevor du's vergisst!

**📋 DailyDose:** Deine DailyDose für heute ist auch noch jungfräulich leer. Nur ein kurzer Moment zum Ausfüllen, dann hast du's für heute geschafft. 🧘
