KyryloКирило · ProjectsПроєкти

Dispatch

Dispatch is a planner I'm building for myself — a native macOS and iPhone app that keeps my tasks on my own devices first and syncs them second. It's early: it runs, it's not finished, and it's already the most complicated thing I've written.

The rule I set at the start is that it never has to ask the network for permission. Every write lands in SwiftData locally and works offline; Supabase carries it to the other device afterwards, and realtime updates are a nudge to refresh rather than the thing recovery depends on.

The half I actually find interesting is letting an AI agent use it. Dispatch speaks MCP, but an agent never gets my account — it gets a scope that's explicit, short-lived, revocable, and narrower than my workspace, and every write it makes is checked against that scope and recorded.

A few decisions so far:

  • One write path. Every model mutation goes through WorkspaceStore, so revision history, undo, widget snapshots and cloud sync can't drift apart.
  • Personal use only. No paid Apple Developer membership, so it installs on my machines and nowhere else — no App Store review, no settings for other people's preferences.
  • Keys aren't permissions. The publishable Supabase key is client-side and proves nothing; row-level security and the signed-in user's token are what actually protect the data.
  • Conflicts are loud. Revision-sensitive writes carry the revision they expect, retries carry an idempotency key, and a conflict stops rather than overwrites.

Stack: Swift + SwiftUI, SwiftData, Supabase (Postgres, RLS, Realtime), an OAuth portal on Vercel, MCP for agent access. Xcode 27 beta. watchOS later, maybe.

I wrote up the thinking behind it in Building my own planner.

Dispatch — це планер, який я роблю для себе: нативний застосунок для macOS та iPhone, що тримає мої задачі спершу на моїх власних пристроях, а вже потім синхронізує їх. Він на ранній стадії: запускається, але не готовий, і це вже найскладніше, що я писав.

Правило, яке я поставив на початку, — застосунок ніколи не має питати дозволу в мережі. Кожен запис одразу лягає локально у SwiftData й працює офлайн; Supabase доносить його до іншого пристрою вже потім, а realtime-оновлення — це поштовх оновитися, а не те, на чому тримається відновлення даних.

Половина, яка мені справді цікава, — дати застосунку користуватися AI-агенту. Dispatch говорить через MCP, але агент ніколи не отримує мій акаунт — він отримує дозвіл, який є явним, короткочасним, відкличним і вужчим за мій робочий простір, і кожен його запис перевіряється на відповідність цьому дозволу та записується в журнал.

Кілька рішень, які вже прийняті:

  • Єдиний шлях запису. Будь-яка зміна моделі йде через WorkspaceStore, щоб історія ревізій, скасування дій, знімки для віджетів і хмарна синхронізація не розійшлися між собою.
  • Тільки для особистого користування. Платного членства Apple Developer немає, тож застосунок ставиться на мої машини й більше нікуди — жодного рев'ю в App Store, жодних налаштувань під чужі вподобання.
  • Ключі — це не дозволи. Публічний ключ Supabase живе на клієнті й нічого не доводить; дані захищають row-level security та токен авторизованого користувача.
  • Конфлікти мають бути гучними. Записи, чутливі до ревізії, несуть із собою очікувану ревізію, повторні спроби — ключ ідемпотентності, а конфлікт зупиняє запис, а не перезаписує його.

Стек: Swift + SwiftUI, SwiftData, Supabase (Postgres, RLS, Realtime), OAuth-портал на Vercel, MCP для доступу агентів. Xcode 27 beta. watchOS — колись пізніше, можливо.

Я описав міркування, що стоять за цим, у Building my own planner.