from __future__ import annotations import json from copy import deepcopy from datetime import datetime, timezone from pathlib import Path from typing import Any from uuid import uuid4 DEFAULT_STATE = { 'profile': { 'id': 'manndra', 'display_name': 'Manndra', 'role': 'Primary household user', 'persona': 'Minerva', 'house_style': 'Ravenclaw common room', 'tone': 'Elegant, magical, useful', 'primary_color_story': 'Midnight blue, parchment, and warm bronze', 'notes': 'Seeded as the primary user for the Minerva household dashboard scaffold.', }, 'agenda': [ { 'id': 'agenda-1', 'title': 'Morning check-in', 'time_label': '8:30 AM', 'detail': 'Review the day, any errands, and which household lane needs attention first.', }, { 'id': 'agenda-2', 'title': 'After-lunch reset', 'time_label': '1:30 PM', 'detail': 'Tidy loose notes, review reminders, and confirm dinner direction.', }, { 'id': 'agenda-3', 'title': 'Evening wind-down', 'time_label': '8:00 PM', 'detail': 'Wrap tomorrow notes, shortlist meals, and leave one clean next action.', }, ], 'reminders': [ {'id': 'reminder-1', 'title': 'Check school and household messages', 'urgency': 'today'}, {'id': 'reminder-2', 'title': 'Restock one comfort-snack shelf item', 'urgency': 'this week'}, {'id': 'reminder-3', 'title': 'Set aside one graceful task for future Minerva automation', 'urgency': 'someday'}, ], 'lists': [ { 'id': 'list-1', 'title': 'Errands', 'items': [ {'label': 'Pick up household basics', 'done': False}, {'label': 'Confirm any school supply gaps', 'done': False}, {'label': 'Check gift / occasion queue', 'done': False}, ], }, { 'id': 'list-2', 'title': 'House reset', 'items': [ {'label': 'Clear one surface', 'done': True}, {'label': 'Run a fast room sweep', 'done': False}, {'label': 'Stage tomorrow launch pad', 'done': False}, ], }, ], 'notes': [ { 'id': 'note-1', 'title': 'Minerva welcome', 'body': 'This front page should feel calm, capable, and immediately useful from a phone.', 'category': 'welcome', 'source': 'seed', 'pinned': True, 'created_at': '2026-05-23T09:00:00Z', }, { 'id': 'note-2', 'title': 'Household rhythm', 'body': 'Keep the wording practical: what matters now, what can wait, and what would make the day easier.', 'category': 'guidance', 'source': 'seed', 'pinned': False, 'created_at': '2026-05-23T10:15:00Z', }, ], 'links': [ {'id': 'link-1', 'label': 'Calendar', 'url': '#', 'note': 'Placeholder until live integration is chosen.'}, {'id': 'link-2', 'label': 'School hub', 'url': '#', 'note': 'Quick route for classes, due dates, and messages.'}, {'id': 'link-3', 'label': 'Household notes', 'url': '#', 'note': 'Pin common references in one predictable place.'}, ], 'meal_ideas': [ {'id': 'meal-1', 'title': 'Easy comfort dinner', 'detail': 'One low-friction weeknight fallback with leftovers.'}, {'id': 'meal-2', 'title': 'Snack board night', 'detail': 'Small-prep option for a busier day.'}, {'id': 'meal-3', 'title': 'Tomorrow prep idea', 'detail': 'Something that makes the next day easier.'}, ], 'shortcuts': [ {'id': 'shortcut-1', 'label': 'Quick note', 'hint': 'Capture the thing before it evaporates.'}, {'id': 'shortcut-2', 'label': 'Meal spark', 'hint': 'Write one dinner idea without overthinking it.'}, {'id': 'shortcut-3', 'label': 'Errand add', 'hint': 'Drop a list item while already on the move.'}, ], 'quick_actions': [ {'id': 'action-1', 'label': 'Capture note', 'detail': 'Fast jot for reminders, ideas, and school fragments.'}, {'id': 'action-2', 'label': 'Review day', 'detail': 'One-tap habit: scan agenda, reminders, and lists.'}, {'id': 'action-3', 'label': 'Choose dinner lane', 'detail': 'Decide between comfort, fast, or leftovers.'}, ], } class JSONStore: def __init__(self, state_dir: Path) -> None: self.state_dir = Path(state_dir) self.state_path = self.state_dir / 'state.json' self.state_dir.mkdir(parents=True, exist_ok=True) if not self.state_path.exists(): self._write(deepcopy(DEFAULT_STATE)) def _read(self) -> dict[str, Any]: return json.loads(self.state_path.read_text()) def _write(self, payload: dict[str, Any]) -> None: self.state_path.write_text(json.dumps(payload, indent=2, sort_keys=True)) def dashboard_summary(self) -> dict[str, Any]: state = self._read() notes = self._sorted_notes(state['notes']) return { 'profile': state['profile'], 'counts': { 'agenda': len(state['agenda']), 'reminders': len(state['reminders']), 'lists': len(state['lists']), 'notes': len(notes), 'links': len(state['links']), 'meal_ideas': len(state['meal_ideas']), 'shortcuts': len(state['shortcuts']), 'quick_actions': len(state['quick_actions']), }, 'agenda': state['agenda'], 'reminders': state['reminders'], 'lists': state['lists'], 'notes': notes, 'links': state['links'], 'meal_ideas': state['meal_ideas'], 'shortcuts': state['shortcuts'], 'quick_actions': state['quick_actions'], } def add_quick_note(self, payload: dict[str, Any]) -> dict[str, Any]: state = self._read() saved = { 'id': uuid4().hex, 'title': payload['title'].strip(), 'body': payload['body'].strip(), 'category': payload.get('category', 'note').strip() or 'note', 'source': payload.get('source', 'quick-add').strip() or 'quick-add', 'pinned': bool(payload.get('pinned', False)), 'created_at': datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z'), } state['notes'].append(saved) self._write(state) return saved @staticmethod def _sorted_notes(notes: list[dict[str, Any]]) -> list[dict[str, Any]]: return sorted( notes, key=lambda item: ( not item.get('pinned', False), item.get('created_at', ''), ), reverse=False, )[::-1]