budi-cloud

May 15, 2026 · View on GitHub

Cloud dashboard and ingest API for budi. AI cost visibility for solo developers and teams across users, repos, models, branches, and tickets.

Overview

  • Dashboard at app.getbudi.dev — Overview, Team, Models, Repos, Sessions, and Settings pages
  • Ingest API — receives pre-aggregated daily rollups and session summaries from the budi daemon
  • Auth — Supabase Auth (GitHub, Google, magic link) with org-based access control

Built with Next.js 16, React 19, Supabase, and Tailwind CSS 4.

New here? Start with CONTRIBUTING.md for the dev workflow, then read SOUL.md for the deeper architecture map.

What data the cloud receives

The budi daemon pushes pre-aggregated daily rollups and session summaries — numeric metrics only. The cloud never receives prompts, code, AI responses, file paths, email addresses, raw payloads, or tag values. There is no "full upload" mode.

What syncs: token counts, costs, model names, hashed repo IDs, branch names, ticket IDs, session durations, and message counts.

See ADR-0083 for the complete privacy contract.

Transport and trust model

  • HTTPS only — the daemon refuses to sync over plain HTTP
  • Push-only — the daemon initiates all connections; the cloud never reaches back to developer machines. There is no webhook, pull, or remote command channel
  • Idempotent — sync uses UPSERT semantics with deterministic keys; retries are safe and produce no duplicates

Team model (cloud alpha)

The cloud alpha works for solo developers and small teams (1–20 developers):

AspectDetail
Rolesmanager (view all org data, manage members) and member (sync data, view own data)
GranularityDaily aggregates; no per-message, per-hour, or real-time views
Retention90 days
Multi-orgNot supported in v1 — one user belongs to one org
SSO / SAMLNot supported in v1 — API key auth for daemon sync, Supabase Auth (GitHub, Google, magic link) for the web dashboard

Auth

  • Web dashboard: Supabase Auth with GitHub, Google, and magic link sign-in
  • Daemon sync: API key (budi_<key>) in Authorization: Bearer header. Users link a local daemon to their cloud account with budi cloud init --api-key <key>; the daemon then owns the on-disk key storage.
  • Ingest API: POST /v1/ingest accepts the sync envelope; GET /v1/ingest/status?device_id=… returns watermark and sync health for a linked device.
  • Pricing API: GET /v1/pricing/active returns the org's active price list so the local daemon can mirror cloud math. Pass ?since_version=N (or If-None-Match) to short-circuit to 304 when the daemon is up to date. Returns 404 when no active list is configured (daemon treats this as "no override" and keeps its default LiteLLM-derived pricing). Privacy-safe — only the negotiated sale price is sent; the vendor list price stays cloud-side.

Setup

  1. Copy .env.local.example to .env.local and fill in your Supabase project keys
  2. Install dependencies and run:
npm ci
npm run dev
  1. Open http://localhost:3000

Build

npm run build

Deployment

The app is deployed to Vercel and connects to a Supabase project. Database migrations live in supabase/migrations/ and ship automatically:

  • Pull requests.github/workflows/ci.yml dry-runs every migration against a fresh Postgres so syntax / dependency errors fail at review time.
  • Merges to main.github/workflows/db-push.yml runs supabase db push --include-all against the linked Supabase project whenever a commit on main touches supabase/migrations/**.

Required GitHub Actions secrets: SUPABASE_ACCESS_TOKEN, SUPABASE_DB_PASSWORD, SUPABASE_PROJECT_REF. Do not apply migrations through the Supabase SQL editor — schema applied out-of-band drifts from the migration history and breaks future deploys.

Ecosystem

License

MIT