# Morning Report System Design **Date:** 2025-01-02 **Status:** Approved **Author:** PA + User collaboration ## Overview A daily morning dashboard that aggregates useful information into a single Markdown file, generated automatically via systemd timer and refreshable on-demand. ## Output - **Format:** Markdown - **Location:** `~/.claude/reports/morning.md` - **Archive:** `~/.claude/reports/archive/YYYY-MM-DD.md` (30 days retention) ## Schedule - **Automatic:** Systemd timer at 8:00 AM Pacific - **On-demand:** `/morning` command for manual refresh ## Report Sections ### 1. Weather - **Source:** wttr.in (no API key) - **Location:** Seattle, WA, USA - **LLM:** Haiku (parse output, add hints like "bring umbrella") ### 2. Email - **Source:** Gmail skill (existing) - **Display:** Unread count, urgent highlights, top 5 emails - **LLM:** Sonnet (triage urgency, summarize) ### 3. Calendar - **Source:** gcal skill (existing) - **Display:** Today's events + tomorrow preview - **LLM:** None (structured JSON, Python formatting) ### 4. Stocks - **Source:** stock-lookup skill (existing) - **Watchlist:** CRWV, NVDA, MSFT - **Display:** Price, daily change, trend indicator - **LLM:** Haiku (format table, light commentary) ### 5. Tasks - **Source:** Google Tasks API (new integration) - **Display:** Pending items, due dates, top 5 - **LLM:** None (structured JSON, Python formatting) ### 6. Infrastructure - **Source:** k8s-quick-status + sysadmin-health skills (existing) - **Display:** Traffic light status (green/yellow/red) - **LLM:** Haiku (interpret health output) - **Future:** Enhanced detail levels (fc-042) ### 7. News - **Source:** RSS feeds (Hacker News, Lobsters) - **Display:** Top 5 headlines with scores - **LLM:** Sonnet (summarize headlines) ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ morning-report skill │ ├─────────────────────────────────────────────────────────────┤ │ scripts/generate.py # Main orchestrator │ │ scripts/collectors/ # Data fetchers │ │ ├── gmail.py # Reuse existing gmail skill │ │ ├── gcal.py # Reuse existing gcal skill │ │ ├── gtasks.py # New: Google Tasks API │ │ ├── stocks.py # Reuse stock-lookup skill │ │ ├── weather.py # wttr.in integration │ │ ├── infra.py # K8s + workstation health │ │ └── news.py # RSS/Hacker News feeds │ │ scripts/render.py # Markdown templating │ │ config.json # Watchlist, location, feeds │ └─────────────────────────────────────────────────────────────┘ ``` ## Configuration File: `~/.claude/skills/morning-report/config.json` ```json { "version": "1.0", "schedule": { "time": "08:00", "timezone": "America/Los_Angeles" }, "output": { "path": "~/.claude/reports/morning.md", "archive": true, "archive_days": 30 }, "stocks": { "watchlist": ["CRWV", "NVDA", "MSFT"], "show_trend": true }, "weather": { "location": "Seattle,WA,USA", "provider": "wttr.in" }, "email": { "max_display": 5, "triage": true }, "calendar": { "show_tomorrow": true }, "tasks": { "max_display": 5, "show_due_dates": true }, "infra": { "check_k8s": true, "check_workstation": true, "detail_level": "traffic_light" }, "news": { "feeds": [ {"name": "Hacker News", "url": "https://hnrss.org/frontpage", "limit": 3}, {"name": "Lobsters", "url": "https://lobste.rs/rss", "limit": 2} ], "summarize": true } } ``` ## LLM Delegation | Section | LLM Tier | Reason | |---------|----------|--------| | Weather | Haiku | Parse wttr.in, add hints | | Email | Sonnet | Triage urgency, summarize | | Calendar | None | Structured JSON, template | | Stocks | Haiku | Format, light commentary | | Tasks | None | Structured JSON, template | | Infra | Haiku | Interpret health output | | News | Sonnet | Summarize headlines | ## Error Handling Each collector is isolated - failures don't break the whole report. | Collector | Timeout | Retries | Fallback | |-----------|---------|---------|----------| | Weather | 5s | 1 | "Weather unavailable" | | Email | 10s | 2 | Show error + auth hint | | Calendar | 10s | 2 | Show error | | Stocks | 5s | 1 | Partial results per-symbol | | Tasks | 10s | 2 | Show error | | Infra | 15s | 1 | "Status unknown" (yellow) | | News | 10s | 1 | "News unavailable" | ## Logging - Run logs: `~/.claude/logs/morning-report.log` - Systemd logs: `journalctl --user -u morning-report` ## Implementation Order 1. Config + skeleton structure 2. Weather, Stocks, Infra collectors (easy wins) 3. Google Tasks collector (new OAuth scope) 4. News collector 5. Orchestrator + renderer 6. Systemd timer + `/morning` command ## Future Considerations - **fc-041:** Terminal output version (motd-style) - **fc-042:** Enhanced infrastructure detail levels ## Sample Output ```markdown # Morning Report - Thu Jan 2, 2025 ## Weather Seattle: 45°F, Partly Cloudy | High 52° Low 38° | Rain likely 3PM ## Email (3 unread, 1 urgent) [!] From: boss@work.com - "Q4 numbers needed" * From: github.com - "PR #123 merged" * From: newsletter@tech.com - "Weekly digest" ## Today * 9:00 AM - Standup (30m) * 2:00 PM - 1:1 with Sarah (1h) Tomorrow: 3 events, first at 10:00 AM ## Stocks CRWV $79.32 +10.8% NVDA $188.85 +1.3% MSFT $430.50 -0.2% ## Tasks (4 pending) * Finish quarterly report (due today) * Review PR #456 * Book travel for conference * Call dentist ## Infrastructure K8s Cluster: [OK] | Workstation: [OK] ## Tech News * "OpenAI announces GPT-5" (Hacker News, 342 pts) * "Rust 2.0 released" (Lobsters, 89 votes) * "Kubernetes 1.32 features" (Hacker News, 156 pts) --- Generated: 2025-01-02 08:00:00 PT ```