Architecture
┌──────────────┐ typed RPC + SSE ┌──────────────┐ Prisma / pg ┌──────────┐
│ packages/cli │ ──────────────────► │ packages/ │ ──────────────► │ Postgres │
│ OpenTUI TUI │ ◄────────────────── │ server │ └──────────┘
│ local tools │ streamText → │ (Hono) │ ──────────────► OpenRouter,
└──────────────┘ tool calls └──────────────┘ Clerk, PolarPackages
packages/cli(@coolcode/cli) — terminal UI via@opentui/react+react-router(memory router). Talks to the server with a typed Hono RPC client (hc<AppType>from@coolcode/server, used only for types) plusDefaultChatTransportfor chat streaming. Auth token injection lives insrc/lib/api-client.ts.packages/server(@coolcode/server) — Hono app exportingAppType. Routes: auth (Clerk), billing (Polar), sessions, chat. All chat/session/billing routes sit behindrequireAuth; chat additionally runsrequireCreditsBalance, and usage is billed to Polar per message in the chatonFinishhandler.packages/database(@coolcode/database) — Prisma 7 +@prisma/adapter-pg. Importdbfrom@coolcode/database/client, not the root export. The generated client lives atpackages/database/generated/prismaand is gitignored.packages/shared(@coolcode/shared) — model registry,modeSchema(BUILD/PLAN), and AI tool contracts (getToolContracts(mode)) shared by the server and the CLI.
Deliberate version split
The CLI pins ai@6 + @ai-sdk/react@3, while the server and shared packages
use ai@7. Types cross the boundary through @coolcode/shared contracts.
Do not “align” these versions casually.
Server notes
- The server listens on port 3000 (hardcoded).
idleTimeout: 255is deliberately high so long LLM and tool runs are not cut off — do not lower it.
Development commands
bun run dev:server # Hono API on :3000
bun run dev:cli # TUI with watch
bun run build:cli # build to packages/cli/dist
bun run link:cli # build:cli, then bun linkLast updated on