Skip to content

Repository files navigation

Sidekick Dashboard

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

How it works

 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 │
└────────────────┘                   └──────────────────┘      └───────────┘       └────────────────┘
  1. 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.
  2. A Next.js app on Vercel stores snapshots in Supabase and exposes a flat JSON endpoint.
  3. 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.

Project layout

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

Quick start

1. Database (Supabase)

Create a project, then apply supabase/migrations/0001_init.sql (SQL editor or supabase db push).

2. Web app (Vercel)

npm install
cp .env.example .env.local   # fill in the values
npm run dev                  # http://localhost:3000

Set 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).

3. Collector (your machine)

cd collector
npm install
cp .env.example .env         # set DASHBOARD_URL + INGEST_TOKEN
npm run once                 # one push, to verify
npm start                    # poll forever

See docs/collector-setup.md.

4. Device (reTerminal + SenseCraft)

Bind a SenseCraft HMI dashboard to GET /api/dashboard?key=<DASHBOARD_READ_TOKEN> and deploy to the device. See docs/sensecraft-setup.md.

API

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.

Where the numbers come from

  • Claude session/weekly % — the real utilization. The collector reads the OAuth token from ~/.claude/.credentials.json and makes a minimal POST /v1/messages; Anthropic returns the live figures in response headers (anthropic-ratelimit-unified-5h/7d-utilization + -reset) — the same numbers /status shows. 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_limits snapshot Codex writes into its session rollout files (~/.codex/sessions/**/rollout-*.jsonl). primary = rolling 5h, secondary = weekly. No auth needed — same data /status reports.
  • Cursor spend/remaining — the real numbers from the Cursor Admin API (POST /teams/spend, Basic auth with CURSOR_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. See docs/connectors.md.
  • Replit — the connector exposes no usage data, so it's manual (/admin or REPLIT_BALANCE_USD).

Every provider also accepts a manual override, so the display is never blank.

Sources

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages