Stack

Tech and dependencies

Pure TypeScript on Node, ESM throughout. React 19 dashboard. SQLite for persistence. Three inference providers behind one abstraction.

Backend (root package.json)

PackageWhy
@anthropic-ai/claude-agent-sdk 0.2.38Per-session agent loop, MCP server hosting
@anthropic-ai/sdk ^0.78Direct Claude calls (assembler, briefing, challenge)
openai ^4.85Used by the local-Ollama and Mistral OpenAI-compatible paths
fastify ^5.7 + @fastify/*HTTP server, cors, helmet, multipart, rate-limit, static, websocket
better-sqlite3 ^12.6Embedded DB; auth, sessions, archive, knowledge base FTS5
zod ^4Schema validation for tool args + API routes
pdf-parse · mammoth · marked · docxParse PDF/DOCX/MD; emit DOCX
puppeteer · satori · @resvg/resvg-jsHTML → image rendering (OG images, scorecards)
stripe · @stripe/stripe-jsBillable-hours subscription (gated behind LAVERN_AUTH_ENABLED)
resendTransactional email
prompts · pino-prettyCLI prompts + log formatting

Dev: typescript 6, tsx, vitest 4.

Frontend (viz/package.json)

PackageWhy
react 19 · react-dom 19SPA
vite 6Bundler + dev server
tailwindcss 4 + @tailwindcss/viteEditorial design system, utility layer
motion 12Animations (Working view, gates, dashboards)
recharts 3Cost gauges, scorecards, claw portfolio
pdfjs-dist 5Client-side PDF preview
canvas-confettiTasteful confetti on delivery
@sentry/react 10Error reporting
@stripe/stripe-js 9Billing checkout (when auth enabled)

Test: vitest 4 + @testing-library/react + jsdom.

Providers

Other moving parts

Key environment knobs

ANTHROPIC_API_KEY=…           # Anthropic, optional in demo
MISTRAL_API_KEY=…             # Required if LAVERN_PROVIDER=mistral
LAVERN_PROVIDER=anthropic     # anthropic | mistral | local
LAVERN_AUTH_ENABLED=false     # cookie auth + Stripe + Google OAuth
SHEM_PORT=3000
SHEM_DEFAULT_BUDGET=5.0       # USD per session
LAVERN_MANAGED_AGENTS_BRIDGE=0