Desklight
Allie — an AI ops agent that runs a brand’s content calendar end to end. Brief her in an email or a chat; she learns the brand’s taste, generates the on-brand graphic, writes the copy, and publishes. I designed her and I wrote her — every layer.
- Role
- Solo — product, design & code
- When
- 2026
- Built with
- ReactNode / ExpressSupabase · pgvectorClaude tool-usePuppeteer / SatoriStripeOKLCH
A boutique brand can’t afford an agency and doesn’t have the time to be one. On-brand posts, on a schedule, everywhere — real, repetitive, and entirely taste-dependent. Generic AI gets you generic; the whole game is taste.
Solo. Product, brand, the whole front-end and back-end, the render pipeline, the prompt engine, the agent, the billing — designed and coded.
A working AI ops agent (“Allie”) that takes a brief over email or chat, reasons through Claude’s native tool-use loop, generates a brand-consistent graphic, and publishes to eight platforms — with a three-tier memory that learns what works. Deployed and running end to end; pre-external-beta.
Drive the real thing.
Desklight is live at desklight.ai. Recruiter or hiring manager? Ask for an access code and I’ll set you up with a login — brief the agent, generate something, break whatever you like.
The bet
AI gave me back the parts of product design I love — and got me writing the code myself. Desklight is where that clicked: a product I could design to my own standard and actually ship, instead of writing a spec and handing it off. The bet underneath it: accumulated, per-brand visual memory — not a system prompt — is what closes the gap between “a model made you something” and “this is on-brand and done.”
Allie, end to end
Allie takes a brief over email or chat. She classifies the intent, pulls thirteen context sources in parallel — the brand’s voice, its past posts, a semantic memory of what’s worked, the calendar — and reasons through Claude’s native tool-use loop with 27 real tools. A reflex layer answers trivial turns instantly, without invoking the model; she drops to a faster model for follow-ups after an image, saving 30–60 seconds a reply. Email and chat ride the same transport-agnostic pipeline.
Taste, encoded
The hard part was never raw generation — a model will make you something. The hard part is on-brand, every time. So Desklight accumulates a brand’s visual DNA: its photo register, named references, banned visuals, type rules. A colour engine turns two hex values into a full, WCAG-safe OKLCH palette. The renderer composes each graphic in headless Chrome, fits the headline by measuring the actual DOM (not estimating), and samples the photo’s own luminance with APCA scoring to pick legible text. I built the guardrails so the easy path is the on-brand path.
Engram — a memory that prunes itself
Most “agent memory” is flat RAG that accumulates noise. Engram is a three-tier lifecycle: raw facts (L0) get extracted after every reply; when a cluster is dense enough, Claude compresses it into a decision-grade heuristic (L1); weekly, it synthesises cross-heuristic strategy and detects drift (L2), deactivating heuristics the evidence has outgrown. It runs autonomously on cron, with dedup guards and contradiction detection. Extract → reinforce → compress → synthesise → prune.
The systems under it
Under the surface it’s a real platform — roughly 150 service files and 135 React components, all solo: a multi-model engine that compiles a structured intent into each model’s native prompt idiom; native publishing to eight social platforms in pure Node; multi-tenant isolation down to the row; and a billing layer built on one abstraction — chargeGuard — that makes an uncharged generation structurally impossible. The hard part isn’t any one system; it’s their behaviour when they touch. Every integration point is a trust boundary, and most of the code is the boring, correct handling that no demo ever shows.
Where it stands
Desklight is deployed and running end to end — the pipeline on Railway, the React backoffice on Netlify. It’s pre-external-beta: feature-complete for the core loop, not yet opened to users, so there are no usage or revenue numbers to quote. The figures here are counts from the codebase. This is a working product, built to my own standard — not a demo.
Under the hood.
export const handleMessage = async (message, transport) => { if (!(await claimMessage(message.id))) return // atomic dedup const tenant = await resolveTenant(message) // workspace + brand + team const intent = await classify(message) // what are they asking for? const context = await gatherContext(tenant, intent) // 13 sources, in parallel const reply = await runAgent({ intent, context }, transport) // Claude tool-use loop return transport.send(reply) // email · chat — one path} The core loop — classify the intent, pull the brand’s context and memory in parallel, reason through Claude’s tool-use, act. Email and chat are just two transports into the same agent.
const gate = await chargeGuard({ tenantId, modelId, costOpts, resource: 'graphic' })if (!gate.ok) return { error: gate.error } // wallet gated up frontconst artifact = await render(spec, brand) // do the paid workif (!artifact) return { error: 'no_artifact' }await gate.settle({ chargeModelId: artifact.modelUsed, costOpts })// settle() charges the model that actually succeeded (waterfall-aware),// waives cheap-rail fallbacks, and always verifies the charge landed. Charge on success, not before — and structurally. One gate replaced eleven hand-rolled preflight→charge pairs; you can’t call the paid work without opening it first, and it settles for what actually ran.
// If the scraped accent is muddy (chroma < 0.04, or < 0.085 in the// yellow-brown band), derive a fresh accent from the primary hue instead.const isMuddy = accentC < 0.04 || (accentC < 0.085 && accentH >= 50 && accentH <= 100)if (isMuddy) { accentC = 0.14 // give it real chroma accentH = primary.h // borrow the primary's hue if (accentC < 0.06) accentH = (primary.h + 38) % 360 // fallback rotation}return ensureContrast(buildRamp(accentH, accentC), { min: 4.5 }) // WCAG AA, always Two brand colours in, a full accessible palette out — in OKLCH. Real brand sites often yield a “pop” colour that’s actually mud; the engine detects it and derives a true accent instead.
Lumen — one source of truth.
Desklight's public design system, embedded live from lumen.desklight.ai — 12 foundations, 30+ components, every value a real token, dark and light. Scroll and click through it.
Open Lumen at lumen.desklight.ai