Case study · a tool I built to build everything else

Cortex + Den

A native macOS app I built to work with Claude, and now my daily driver. It drives the Claude Agent SDK as its engine on my subscription, not a metered API. One codebase became four apps and a set of always-on server engines. I built this entire site in it.

4
apps, one codebase
Agent SDK
engine
subscription
cost
Tauri 2
shell
Why I built it

I wanted the parts of an AI coding tool I actually use, without the parts I don't, and I wanted it on my own subscription rather than paying per token. So I built a native Mac app that drives the Claude Agent SDK directly. It reads and edits files, runs bash and git, holds several agents as tabs at once, and keeps a live context meter. Then it grew an ops brain, so I split it into two focused apps that share state.

Architecture
One codebase, several faces
shell
Tauri 2 native .app
spawns the engine as a child; macOS vibrancy
Capacitor iPhone app
self-hosted APNs push
ui
React 19 + Vite + Tailwind
chat tabs, file tree, sections
engine
Node + TypeScript
one WebSocket, many agents
@anthropic-ai/claude-agent-sdk
drives the agent, doesn't reimplement it
auth + deploy
subscription credit
setup-token, no metered API
server engines
always-on, den. + cortex., for the phone

The app is self-contained: the Tauri shell spawns the Node engine as a child process, so there is no terminal to babysit. The engine multiplexes several agents over one WebSocket, each its own SDK session with its own working directory, model and context. Crucially it drives the Agent SDK rather than reimplementing the agent, on subscription credit, so a long session costs my plan, not a metered bill. The same hermetic-engine pattern, gated and rate-limited, is what powers the chat on this very site.

Decisions I made, and why
Drive the SDK, don't reimplement the agent
The Agent SDK already is the agent. Wrapping it means every model and tool improvement lands for free, and I own the UX and the ops layer on top.
Subscription credit, not metered API
A daily driver on a per-token bill punishes long sessions. Running on a subscription setup-token makes heavy days free, which changes how I work.
Split into two apps from one codebase
It grew overgrown: a serious dev tool bolted onto an ops dashboard. Den (chat and dev) and Cortex (ops) now share state and a link bus, each doing one job well.
Secure it like production
It runs bash and edits files on my machine, so it's token and Origin gated, after I had it find and close an unauthenticated RCE in itself.
What broke, and what I'd do differently
brokeA new build installed, but kept running stale code.
fixedAn old engine from a previous version squatted the port, so the freshly-launched app reused it and ran old code (features looked 'missing'). I fixed it at the root: the shell now evicts the stale port-holder at startup, so every launch runs its own engine. The lesson: when an engine-side feature looks missing, check the running engine's age before the code.
brokeEvery chat queued forever, waiting for a turn.
fixedA per-turn concurrency limiter leaked a slot on error paths (hung turns, API 500s), so the active count crept to the cap and never recovered. I made the limiter off by default: no cap, nothing to leak. The 529 backoff handles real overload instead.
brokeTauri couldn't do iOS push notifications.
fixedTauri's iOS entry point has no editable AppDelegate to forward the device token, so a hand-rolled plugin compiled and signed but the permission prompt never fired. I stopped fighting it and made the iPhone app a thin Capacitor shell instead, which does push cleanly. Knowing when to stop forcing a path is a skill.
Why it matters here

This is the clearest evidence of how I work: I design, build, secure and operate real software, and I build the tools that build the rest. A native desktop app, a Node engine, a Tauri shell, a Capacitor iPhone app, always-on server engines, all on my own subscription and my own infrastructure. This site, and its chat, were built in it.