Public wiki

Architecture

Canonical source: docs/wiki in the repository (mirrored to GitHub Wiki).

Architecture

Monorepo layout

cursor-usage-monitor/
├── src/                 # VS Code / Cursor extension (TypeScript)
├── packages/shared/     # Shared API types + budget math
├── browser-extension/   # Firefox AMO + Chrome zip WebExtension
├── website/             # Marketing static site (GitHub Pages)
│   └── admin/           # Mission Control SPA + Cloudflare Pages Functions
├── media/               # Extension & repo assets
└── docs/wiki/           # GitHub Wiki source (sync to wiki repo)

Data flow

flowchart LR
  IDE[Cursor / VS Code] -->|auth token + local metadata| EXT[IDE Extension]
  EXT -->|usage-summary + profile| API[api2.cursor.sh]
  EXT -->|scan files / clipboard| SCAN[packages/shared scanSecrets]
  Browser[Firefox / Chrome] -->|token from cursor.com or manual| BEXT[Browser Extension]
  BEXT -->|usage-summary + profile| API
  BEXT -->|paste validation| SCAN
  SCAN -->|redacted findings| ALERT[Security Alert UI]
  GitHook[pre-commit secretlint] --> SCAN
  Visitor[Website visitor] --> SITE[GitHub Pages]
  Admin[Admin operator] --> MC[Mission Control]
  MC -->|Pages Functions| KV[(ADMIN_KV)]
  MC -->|dispatch| GHA[GitHub Actions]
  MC -->|send| MAIL[Cloudflare Email]
  GHA --> OVSX[Open VSX]
  GHA --> VSM[VS Code Marketplace]
  GHA --> AMO[Firefox AMO]
  GHA --> CHROME[Chrome zip]

Schedules & Discord

Weekly GitHub Actions jobs regenerate marketing data; Cloudflare ccm-stats-cron calls Mission Control every minute and respects the Settings → Live stats refresh interval in ADMIN_KV. Discord cards fire on deploy events, CI website/admin deploy, and feedback tests.

flowchart TB
  subgraph settings["Mission Control Settings"]
    CronCfg["Cron schedules · stats refresh + Discord digest"]
    DiscordCfg["Discord webhooks · deployment + feedback"]
  end

  subgraph gh["GitHub Actions — fixed schedule"]
    SEO["seo-pipeline · Mon 06:00 UTC"]
    DepSec["dependency-security · Mon 07:30 UTC"]
    SEO --> Artifacts["site-data.json · SEO · badges · sitemap"]
  end

  subgraph cf["Cloudflare"]
    Worker["ccm-stats-cron worker · every minute"]
    CronStats["POST /api/cron/stats-refresh"]
    CronDigest["POST /api/cron/discord-digest"]
    KV[("ADMIN_KV")]
    Pages["Pages Functions /api/*"]
  end

  subgraph stats["Live download stats"]
    Refresh["runStatsRefresh"]
    Cache["stats:live-cache"]
    Public["GET /api/site-data · badge.json"]
  end

  subgraph discord["Discord notifications"]
    Digest["runDiscordDigest · download breakdown"]
    DeployEvt["Deploy started / completed watch"]
    CINotify["CI discord-deployment-notify.mjs"]
    Feedback["Feedback webhook test"]
    Webhook[("deploymentWebhookUrl")]
    FeedbackHook[("feedbackWebhookUrl")]
  end

  CronCfg -.->|interval gate| CronStats
  CronCfg -.->|interval gate| CronDigest
  DiscordCfg --> Webhook
  DiscordCfg --> FeedbackHook
  Worker -->|X-Cron-Secret| CronStats
  Worker -->|X-Cron-Secret| CronDigest
  CronStats -->|when due| Refresh
  CronDigest -->|when due| Digest
  Refresh --> KV
  Refresh --> Cache
  Cache --> Public
  Digest --> Webhook
  Pages --> KV

  DeployEvt --> Webhook
  CINotify --> Webhook
  Feedback --> FeedbackHook

  MC["Operator"] --> settings
  MC -->|manual refresh| Refresh
  MC -->|send digest now| Digest

Stats storage (KV, R2, D1)

Live download stats and Mission Control config today live in Cloudflare KV (ADMIN_KV). There is no in-app KV usage percentage — Cloudflare enforces daily read/write quotas on the Workers plan (Free tier: ~100k reads / ~1k writes per day). When writes are exhausted, runStatsRefresh fails or auto-pauses until UTC reset (writesPausedUntil in integrations:stats-refresh).

Current KV keys (stats path)

KeyContentWrites per refresh
stats:live-cacheJSON totals + channel breakdown1 when data changes
stats:badges-bundleShields.io JSON payloads1 when displayTotal changes
stats:readme-svgREADME chart SVG string1 when displayTotal changes
integrations:stats-refreshCron metadata (lastRunAt, lastError, pause guard)1 always
system:log:*Scatter event logskipped when stats unchanged

Optimizations shipped (Phase B1): badge/readme writes only when verified totals change; scatter log skipped on unchanged refresh; KV quota errors set writesPausedUntil and skip automatic cron until UTC reset. Settings → General → Infrastructure shows estimated write budget, last run outcome, and a master-only pause shortcut.

System logs (D1-03): when ADMIN_D1 is bound, new logSystemEvent writes go to system_logs (no KV scatter put). Reads merge D1 + remaining KV scatter/legacy during transition. One-time backfill: node website/admin/scripts/migrate-system-logs-to-d1.mjs.

Storage roadmap

StoreBest forStatus
KVSmall JSON config blobs, hot stats cacheProduction — current path
R2Large blobs (stats:readme-svg, badge assets)Phase 2 — removes 2+ KV puts per refresh when totals change
D1Append-heavy data (system:log:*, subscriber index)Phase 2ADMIN_D1 binding (ccm-admin-d1) provisioned; KV migration pending
GitHub site-data.jsonMarketing fallback when APIs unreachableProduction — weekly GHA + manual regen; not real-time
GCP / AzureOptional off-site backup of stats snapshotsDeferred — export via GHA cron, not runtime dual-write

Recommendation: keep optimizing KV first (done); migrate bulky SVG/JSON to R2 next; move logs/subscribers to D1 when bindings exist. See plan/mission-control-master-tasks.md (KV-08, R2-, D1-).

IDE extension

Browser extension

Versioning

Security scanner (shared)

Marketing site

Admin API

Authenticated /api/* routes on Cloudflare Pages Functions. Secrets in Pages environment / GitHub Actions.

← Home