A remote ePaper dashboard for your vibe-coding + business-ops stack, built for the Seeed Studio reTerminal E1001 (ESP32-S3, 7.5″ 800×480 monochrome ePaper, ~3-month battery) driven by SenseCraft HMI.
It shows, at a glance:
- Claude — current session usage + weekly limit usage
- Lovable — credit balance
- Codex — usage balance
- Cursor — usage balance
- Replit — usage balance
dev machine Vercel (Next.js) Supabase reTerminal E1001
┌────────────────┐ POST /api/ingest ┌──────────────────┐ SQL ┌───────────┐ GET ┌────────────────┐
│ collector │ ─────────────────▶│ ingest route │ ───▶ │ usage_ │ ◀─── │ SenseCraft HMI │
│ (reads CLI │ Bearer token │ │ │ snapshots │ │ binds widgets │
│ session logs) │ │ /api/dashboard │ ◀─── │ (history) │ │ to JSON fields │
└────────────────┘ └──────────────────┘ └───────────┘ └────────────────┘
- A small collector runs on your dev machine. It reads local CLI usage (Claude Code / Codex session JSONL), optional provider APIs (Cursor), and manual values (Lovable / Replit), then pushes a snapshot to the cloud.
- A Next.js app on Vercel stores snapshots in Supabase and exposes a flat JSON endpoint.
- SenseCraft HMI on the reTerminal binds widgets to that JSON and refreshes on a timer.
Why this split? Most of these tools (Lovable, Replit, Codex, and Claude subscription limits) have no clean public usage API — the reliable signal lives in local CLI session files or your account page. So the numbers are gathered on your machine and relayed to a cloud endpoint the battery-powered device can poll.
| Path | What |
|---|---|
app/ |
Next.js App Router — API routes + web preview + /admin |
lib/ |
Supabase client, aggregation, auth, ingest validation |
supabase/migrations/ |
Database schema (usage_snapshots table + latest_usage view) |
collector/ |
Standalone local agent (its own package.json) |
scripts/ |
push-metrics.mjs — push arbitrary metrics to /api/ingest |
docs/ |
Setup guides: SenseCraft, collector, and connectors |
Create a project, then apply supabase/migrations/0001_init.sql (SQL editor or
supabase db push).
npm install
cp .env.example .env.local # fill in the values
npm run dev # http://localhost:3000Set the env vars from .env.example in Vercel and deploy. See .env.example
for the full list (SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, INGEST_TOKEN,
DASHBOARD_READ_TOKEN, ADMIN_TOKEN).
cd collector
npm install
cp .env.example .env # set DASHBOARD_URL + INGEST_TOKEN
npm run once # one push, to verify
npm start # poll foreverBind a SenseCraft HMI dashboard to GET /api/dashboard?key=<DASHBOARD_READ_TOKEN>
and deploy to the device. See docs/sensecraft-setup.md.
| Endpoint | Auth | Purpose |
|---|---|---|
GET /api/dashboard?key=… |
read token | Flat + nested JSON for SenseCraft |
GET /api/metrics/<key>?key=… |
read token | Single value, e.g. claude_session_pct |
POST /api/ingest |
Bearer INGEST_TOKEN |
Collector pushes a snapshot |
GET/POST /api/manual |
X-Admin-Token |
Admin UI reads/writes manual values |
Example GET /api/dashboard response (trimmed):
{
"updated_at": "2026-06-28T12:00:00.000Z",
"claude": { "session_pct": 42, "weekly_pct": 67, "session_pct_label": "Session" },
"lovable": { "credits": 120 },
"flat": {
"claude_session_pct": 42,
"claude_weekly_pct": 67,
"lovable_credits": 120,
"codex_session_pct": 35,
"codex_weekly_pct": 58,
"cursor_balance_usd": 7.5,
"replit_balance_usd": 8.5
}
}Bind SenseCraft widgets to the flat.* keys — they're single-level and easiest
to map.
- Claude session/weekly % — the real utilization. The collector reads the
OAuth token from
~/.claude/.credentials.jsonand makes a minimalPOST /v1/messages; Anthropic returns the live figures in response headers (anthropic-ratelimit-unified-5h/7d-utilization+-reset) — the same numbers/statusshows. If no OAuth token is present (e.g. API-key auth), it falls back to a rolling-cost estimate over local JSONL vs. configurable caps (CLAUDE_SESSION_CAP_USD,CLAUDE_WEEKLY_CAP_USD). (Approach adapted from Claude-Usage-Tracker.) - Codex session/weekly % — the real utilization, read from the
rate_limitssnapshot Codex writes into its session rollout files (~/.codex/sessions/**/rollout-*.jsonl).primary= rolling 5h,secondary= weekly. No auth needed — same data/statusreports. - Cursor spend/remaining — the real numbers from the Cursor Admin API
(
POST /teams/spend, Basic auth withCURSOR_API_KEY). Reports current-cycle spend, and remaining + used % when a limit is known. Individual (non-team) plans have no public API → enter a balance in/admin. - Lovable credits — read from the Lovable MCP connector (
get_workspace) via a connector sync, since Lovable has no public credits API. Seedocs/connectors.md. - Replit — the connector exposes no usage data, so it's manual (
/adminorREPLIT_BALANCE_USD).
Every provider also accepts a manual override, so the display is never blank.