Skip to content

Product · Full-stack · September 2026

ClueCode

A Windows desktop AI assistant with subscriptions. Press a shortcut, it captures the screen, sends it to Gemini with the user's own key, and streams the answer into a small overlay. I designed, built, secured and deployed all of it.

Role
Solo: product, architecture, engineering, deployment
Desktop
Electron, TypeScript, React (control window), vanilla TS overlay
Backend
Next.js on Vercel, PostgreSQL on Neon, Drizzle, Better Auth, Razorpay
Links
cluecode.in ↗Source is private; happy to walk through it.
270+SourceClueCode's recorded green run, Sep 2026: web 138, shared 13, desktop unit 67, Electron security and a11y 11, website E2E 43, installer and auto-update 7.
automated tests: unit, Postgres integration, Electron security, WCAG 2.1 AA E2E
1SourceActive desktop session per account, enforced by a partial unique index on (user_id) WHERE status = 'active' in Postgres, not just application code.
active device per account, enforced by the database
₹0SourceAI inference cost to operate: users bring their own Gemini key, and requests go from the desktop straight to Google, never through ClueCode's servers.
inference cost to operate, by design (bring your own key)
15SourceRows in the written threat model (docs/security.md): each with the attack, the mitigation and the residual risk.
threats modelled, each with mitigation and residual risk

ARCHITECTURE

Three concepts, three mechanisms

The design separates three questions that are easy to tangle: has this account paid? (subscriptions, driven only by verified payment webhooks), may this device run the assistant right now? (a server-side session lease), and who pays for inference? (the user's own Gemini key, encrypted on their machine). The server is authoritative for the first two; the key never reaches it.

Desktop (Electron)
  • Main process: auth, session lease, key store, screen capture, AI provider, hotkeys
  • Preload: fixed typed API; ipcRenderer never exposed
  • Renderers: sandboxed, strict CSP, no network
HTTPS · bearer tokens
Web & API (Next.js on Vercel)
  • Better Auth: email + password, verification, resets
  • Desktop sessions: start, heartbeat, end, revoke
  • Billing: checkout, signed webhooks, entitlement
  • Admin console, audit log, daily retention cron
SQL · webhooks
Data & services
  • PostgreSQL on Neon: the only stateful component
  • Razorpay subscriptions
  • Google Gemini, called from the desktop with the user's key

No Redis or queues: rate limiting and idempotency are atomic Postgres statements. Runtime settings (maintenance mode, minimum client version, model list) live in a config table cached for 30 seconds, so they change without a deploy.

DECISIONS

The parts worth explaining

Session leases the database enforces

Starting a session locks the user row, checks entitlement, expires lapsed sessions, and inserts a lease: 10 minutes, renewed by a heartbeat every 2 minutes, capped at 3 hours. A partial unique index on active sessions makes “one device at a time” a database invariant. All times come from Postgres now() and are sent as relative seconds; the desktop tracks them on a monotonic clock, so changing the PC clock does nothing. Crash, sleep, network loss, a second device, a payment lapsing mid-session: each has a defined outcome, and the server fails closed.

Payments as a state machine driven only by signed webhooks

Access is granted only when a Razorpay webhook with a valid HMAC-SHA256 signature arrives; the browser's checkout callback changes no state. Each event is processed once (a unique (provider, event_id) row inside the same transaction), with an out-of-order guard, and maps onto one internal subscription state machine. A single entitlement function answers “is this account entitled?” everywhere, including grace periods for late renewals.

The user's key never leaves their machine

The Gemini key is stored with Electron safeStorage (Windows DPAPI, bound to the OS user), decrypted per request, never returned to a renderer, never logged, never sent to the server. If the OS cannot encrypt, the app refuses to store it. That choice is also the business model: inference costs the operator ₹0SourceAI inference cost to operate: users bring their own Gemini key, and requests go from the desktop straight to Google, never through ClueCode's servers..

Treat model output as hostile

A screenshot can contain text written to manipulate the model. The system prompt treats on-screen text as material, not instructions; the answer is rendered through a strict sanitizer (no links, images, forms or styles) into a sandboxed renderer whose CSP allows no network. An end-to-end test feeds malicious model output and checks nothing executes.

An AI layer that degrades gracefully

One provider interface with a single streaming method covers every mode. The model menu is the server's supported list intersected with what the user's key can reach; a 404 falls back to the default model; a request with no first token in time is treated as stalled and moves to another model. Prompts are versioned and the version is logged with each request.

QUALITY

Tests that would catch the expensive mistakes

  • Web unit and integration tests against a real Postgres (started automatically), covering billing, entitlement, sessions and admin permissions.
  • Electron security E2E: no Node in renderers, CSP enforced, IPC surface fixed, malicious AI output inert.
  • Website E2E with axe checks for WCAG 2.1 AA on every public, customer and admin page, in dark and light themes.
  • A full-system journey against production with a real key, and installer plus auto-update tests.

Together that is 270+SourceClueCode's recorded green run, Sep 2026: web 138, shared 13, desktop unit 67, Electron security and a11y 11, website E2E 43, installer and auto-update 7. tests in the latest recorded green run.

PRODUCT BOUNDARY

What it deliberately does not do

ClueCode is an ordinary visible window. It does not hide from screen sharing, recording or proctoring software, and its prompts do not try to disguise AI output. It is built for coding practice, learning (its Hint mode gives nudges rather than answers), and work where AI assistance is permitted. That boundary is written into the product's documentation and its behaviour.

↑↓ to move · ↵ to select⌘K / Ctrl K