Skip to content
Work

Product · AI assistant

AI Todo

A todo list and reminder app you can run by chatting with an AI or by hand — one Go binary with SQLite, an installable PWA and a macOS menu bar app, where the AI only proposes actions and the server validates them.

Role
Full-stack Developer
Timeline
Oct 2026 — Nov 2026
Context
Personal project
Stack
  • Go
  • SQLite
  • Vue 3
  • PWA
  • Web Push
  • Swift
  • AppKit
  • Docker

Problem

Todo apps make you fill in forms; chat assistants forget what you told them yesterday and can't be trusted to touch your data. I wanted to type "tomorrow at 9 remind me to call the workshop, and mark buy water done" and have it happen — on my phone and on my Mac — without giving an AI free rein over a database.

Context

A personal tool, built to run cheaply on my own VPS: free AI models only, one small server, and notifications on every device I use. Everything the chat can do must also be possible by hand, so the app stays useful when the AI is down or wrong.

Solution

  • Chat as a shortcut: add, edit, complete, delete, search and summarise todos and reminders from one chat box. Actions show up as cards with an Undo button; deletes and bulk changes ask for confirmation first. Slash commands (/todo, /hari-ini, /undo) work without any AI at all.
  • Manual is complete: todo lists with Today / Upcoming / No date / Done tabs, search, lists, priority, notes, and reminders that can be one-off or recurring with an end date, a count, snooze and pause.
  • An assistant that remembers: a profile and notes (inspired by Hermes Agent) are sent with every message and can be reviewed, edited and exported. Memory is scanned before saving and rejects passwords, PINs, tokens, card numbers and prompt-injection patterns.
  • Notifications everywhere: Web Push for the PWA, native notifications with Done / Snooze 10 min on the Mac, plus a morning summary and overdue nudges.
  • Separate admin mode: AI model catalog (test, enable, fallback order), assistant persona and limits, AI call log and system log — with no endpoint that can read another user's todos, chats or memory.

Architecture

Layer detail

PWA & Mac menu bar app

Vue 3 PWA for phone, tablet and PC (Web Push), plus a native AppKit menu bar app with a badge, quick check-off, a chat panel (⌥⌘T) and local notifications.

Simplified architecture — select a layer to inspect it.

Technical challenges

  • Keeping the AI out of the database. The model can only propose a JSON plan. The server checks each operation against a whitelist, validates its shape, runs it through the same core functions as the forms inside a transaction, and records an undo entry.
  • Free models are unreliable. The client tolerates odd replies, falls back across providers in order, and logs every outgoing call so the admin can see which model failed and why.
  • Recurring schedules are easy to get wrong. The scheduler — not the AI — computes every next occurrence in the user's time zone and stores times as UTC, with tests for windows, month ends, end dates and counts.
  • A Mac app without a Mac in CI. The HTTP client is Foundation-only, so it is tested on Linux against the real Go server; the AppKit part is compiled and released by a macOS GitHub Actions workflow.
  • Deploys that can't brick the server. Each merge to main backs up the database, rebuilds the container, runs a health check and rolls back automatically if it fails.

Impact

free AI providers with fallback
3free AI providers with fallback
reminder schedule types
6reminder schedule types
binary + one SQLite file
1binary + one SQLite file

Lessons learned

Treat the language model as a user with a very fast keyboard, not as part of the backend: give it the same forms everyone else gets, make dangerous actions need a human click, and make everything undoable. That one rule kept the rest of the design simple.

Snapshots

Mac menu bar app, Todo tab: quick add, Today / All / Done, check off with one click. Illustration based on the app's AppKit layout.
Chat tab (⌥⌘T) in dark mode: actions appear as a card with Undo. Illustration based on the app's AppKit layout.
Chat with me