Track
First-real-user E2E: web sign-in → CLI login → host agent registers → Cronlet visible/approvable in UI.
Purpose
Today the web app is a static SPA with no auth and no backend (app/src/main.tsx picks SeededDemoApi or EmptyApi; vercel.json is static). The CLI is 100% local (~/.mycron/store.json, zero network calls). Nothing an agent registers can ever appear in the hosted UI. This PR creates the spine everything else attaches to: Supabase Auth (Google) + an account-scoped READ path.
Scope
app/src/backend/supabase.ts client from VITE_SUPABASE_URL/ANON_KEY (env-driven; absent env → app behaves exactly as today)
- Google OAuth sign-in/out; AccountSurface shows identity + sign-out
supabase/migrations/0001_init.sql: accounts, cronlets (unique (account_id, client_ref)), RLS owner-only SELECT, no insert/update policies (mutations come via server API later)
SupabaseApi implements MyCronApi reads only; all writes throw NotImplementedError
resolveApi: demo flag → SeededDemoApi; session+env → SupabaseApi; else EmptyApi
Non-scope
Mutation endpoints, CLI changes, approval/audit endpoints, device auth, seeding.
Acceptance
- Sign in with Google → empty dashboard scoped to my account; sign out → today's behavior
npm run typecheck && npm test && npm run build pass with and without Supabase env
- No mock data added to
src/; src/ contract unchanged
Track
First-real-user E2E: web sign-in → CLI login → host agent registers → Cronlet visible/approvable in UI.
Purpose
Today the web app is a static SPA with no auth and no backend (
app/src/main.tsxpicks SeededDemoApi or EmptyApi;vercel.jsonis static). The CLI is 100% local (~/.mycron/store.json, zero network calls). Nothing an agent registers can ever appear in the hosted UI. This PR creates the spine everything else attaches to: Supabase Auth (Google) + an account-scoped READ path.Scope
app/src/backend/supabase.tsclient fromVITE_SUPABASE_URL/ANON_KEY(env-driven; absent env → app behaves exactly as today)supabase/migrations/0001_init.sql: accounts, cronlets (unique(account_id, client_ref)), RLS owner-only SELECT, no insert/update policies (mutations come via server API later)SupabaseApiimplements MyCronApi reads only; all writes throwNotImplementedErrorresolveApi: demo flag → SeededDemoApi; session+env → SupabaseApi; else EmptyApiNon-scope
Mutation endpoints, CLI changes, approval/audit endpoints, device auth, seeding.
Acceptance
npm run typecheck && npm test && npm run buildpass with and without Supabase envsrc/;src/contract unchanged