cotidie
Personal daily executive-function system for Mason. Slack bot + web dashboard + AI coach tracking medication, cannabis reduction, sleep, meals, fitness, and code activity across the AshlrAI GitHub org.
Private. Not an AshlrAI product. Single-user. Local-first.
Stack
TypeScript · Node · Next.js 15 (App Router) · Prisma + SQLite · Slack Bolt (Socket Mode) · node-cron · Recharts · Ollama (local) with XAI grok-4-1-fast-reasoning fallback.
worker/ long-running process
slack/ Bolt app, slash commands, DM NL parser, reminder actions
schedule/ daily reminder pre-queue via chat.scheduleMessage
ingest/ GitHub / WakaTime / Strava pollers
coach/ nightly summary, weekly digest, pattern watcher
app/ Next.js dashboard (App Router)
api/ POST /api/log/* · GET /api/stats/today · GET /api/insights · /api/chat (stream)
components/ UI primitives + dashboard-specific
lib/ db, logger, time, AI clients (ollama/xai/route), ingest helpers, stats aggregators, shared schemas, logging helpers
prisma/ schema + migrations
scripts/ dev runner · SQLite backup · coach force-run · Slack setup guide
launchd/ macOS LaunchAgents (worker auto-start + daily backup)
Bootstrap
pnpm install
cp .env.example .env # only DATABASE_URL required for Phase 1
pnpm db:push # create cotidie.db from schema
pnpm dev # worker + next dev in parallel
Visit http://localhost:3000. Dashboard works immediately — Slack features come online once you set Slack tokens.
Prerequisites (gather as needed)
| Service | What you need | Where |
|---|---|---|
| Slack | Personal workspace · Slack app with Socket Mode enabled · Bot/App tokens, signing secret, your user ID | api.slack.com/apps — detailed checklist in scripts/init-workspace.md |
| Ollama | Installed + llama3.2:3b pulled |
brew install ollama && ollama pull llama3.2:3b && ollama serve |
| GitHub | PAT with repo scope for AshlrAI org |
github.com/settings/tokens |
| WakaTime | API key + editor plugin actively running | wakatime.com/settings/api-key |
| Strava | App creds → Connect via /settings in the dashboard (OAuth) |
strava.com/settings/api |
| XAI | API key (optional fallback) | console.x.ai |
Slack interaction
Slash commands:
| Command | What it does |
|---|---|
/med · /med at 9:15pm |
Log 100 mg sertraline |
/rip · /rip 3 |
Log bong rip(s) |
/bed · /bed 2:30am |
Log bedtime |
/wake · /wake 11am |
Log wake time |
/ate lunch chipotle |
Log meal |
/workout run 30 |
Log workout |
/day / /week |
Summaries in DM |
Natural-language DM: "took it", "+3 rips", "just woke up", "had lunch" — parsed by local Ollama.
Reminders
Pre-queued with Slack's chat.scheduleMessage daily at 00:01 local, so they deliver even when this Mac is asleep:
- 21:00 — Sertraline reminder with ✓ Taken / Skip tonight buttons
- 02:00 — Gentle "bed soon?" check-in
- 12:30 / 18:30 — Meal window nudges
AI coach
| Cadence | What runs |
|---|---|
| Nightly 23:00 | One-sentence summary of the day, posted to Slack DM |
| Sunday 09:00 | Weekly digest — numbers, trends vs prior week, one correlation callout, one nudge |
| Every 2 hours | Rule-based pattern watcher: rip spike (>2× avg and ≥4), missed meds (past 10 PM unlogged), sleep drift (recent 3-night avg ≥1h later than prior 4) |
Force-run any coach task without starting the full worker:
pnpm tsx scripts/coach-run.ts summary
pnpm tsx scripts/coach-run.ts digest
pnpm tsx scripts/coach-run.ts patterns
Routing: Ollama first (free, local), XAI grok-4-1-fast-reasoning fallback. Each CoachInsight records modelUsed.
Dashboard
- Today — meds hero with countdown + streak flame, quick-action buttons, per-domain tiles with sparklines, insight feed, timeline strip
- Log — day-grouped unified timeline with kind filter chips
- Trends — 6 charts with reference lines (rips, sleep hours, bedtime, last meal, code, commits), 7/30/90-day selector
- Goals — 4 ladders (cannabis reduction, sleep shift, meal shift, meds streak) with 7-day visual ladder + nudge copy
- Settings — connection health dots, reminder schedule, privacy note, Strava OAuth connect
- Chat — streaming AI coach (Ollama → XAI fallback) with today's + weekly context baked in
Mobile: bottom tab bar (Today · Log · Trends · Goals · Chat). Desktop: sidebar + same 5 tabs.
Inline logging (same effect as Slack commands): POST /api/log/{med,rip,bed,wake,meal,workout} with JSON bodies. Used by the dashboard's Quick Actions.
Backup & auto-start
pnpm backup # snapshot cotidie.db into backups/
bash launchd/install.sh # install LaunchAgents (worker auto-start + daily 04:00 backup)
bash launchd/uninstall.sh # reverse
launchctl list | grep cotidie # verify
Backups older than 30 days are auto-pruned.
Privacy
- Sensitive data (meds, cannabis) lives in a personal Slack workspace — not the AshlrAI work Slack.
- SQLite file is local-only; enable macOS FileVault for at-rest encryption.
- No analytics, no telemetry.
.envstays local.
Development
pnpm dev # worker + web (prints LAN URL for phone access)
pnpm dev:worker # just the worker
pnpm dev:web # just Next.js (bound to 0.0.0.0 for LAN access)
pnpm typecheck # tsc --noEmit across the tree
pnpm doctor # health-check every dependency (DB, Ollama, Slack, GitHub, WakaTime, Strava, XAI, TZ)
pnpm seed # seed realistic demo data (14 days); --reset to wipe first
pnpm db:studio # Prisma Studio for inspecting the SQLite file
pnpm db:push # apply schema changes
pnpm build # Next.js production build
First-run checklist
pnpm install && cp .env.example .env && pnpm db:pushpnpm seed --reset— optional, for something to look at on first openpnpm dev— worker + dashboard; banner prints your LAN URL- Open the LAN URL on your iPhone → Share → Add to Home Screen (PWA icon + standalone launch)
- Follow
scripts/init-workspace.mdto wire Slack → refill.env→pnpm devagain pnpm doctorat any time to verify what's live
Phase map
- Phase 1 — Foundation
- Phase 2 — Slack bot core
- Phase 3 — Scheduled reminders
- Phase 4 — Passive ingestion (GitHub + WakaTime + Strava)
- Phase 5 — Dashboard
- Phase 6 — AI coach
- Phase 7 — Hardening (logger, backup, launchd)
