Skip to content

dapinitial/spacelabstudio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spacelab Studio

AI-assisted HTML email design studio. Chat with Claude to design rich, campaign-grade HTML emails — with AI-generated images (Imagen) and video (Veo 3) — then send them, schedule them, embed live polls, and track results. Output is tuned to render beautifully in Apple Mail (semantic system colors for automatic dark mode, CSS-only interactivity, native <video> support) while staying compatible with other clients.

Bring your own keys. AI features run on your Anthropic key (design chat) and your Google AI Studio key (image/video generation). Keys travel per-request as headers and are never persisted server-side.

Features

  • AI design chat — Claude generates and surgically edits email HTML/CSS, with intent-aware editing (edit vs. replace vs. redesign) and structure-preserving rules
  • AI media — request images (Imagen 4) and videos (Veo 3.x) inline; optimistic shimmer placeholders hot-swap when generation completes
  • Visual editor — Shadow-DOM preview canvas, drag-and-drop sections, inline toolbar, Monaco code editor, snippet library
  • Data-to-email skill — drop a CSV/PDF/XLSX/JSON/Markdown file on the chat and get a status dashboard, KPI grid, timeline, or transcript summary email
  • Send pipeline — CID-embedded images and videos (Apple Mail plays <video src="cid:…"> natively), fail-loud on missing assets, send preflight, per-user rate limiting
  • Campaigns — scheduled & recurring sends, recipient lists, embedded polls with one-click signed vote links, send analytics
  • Teams & RBAC — every template/list/schedule/poll is team-scoped; personal team auto-created per user; owner/member roles; team invites
  • Admin — audit log, send history, security alerts, AI token usage telemetry

Stack

Next.js 15 · React 19 · TypeScript · Tailwind + Radix/shadcn · Zustand · Drizzle ORM + Postgres · Anthropic SDK (Claude) · Gemini API (Imagen + Veo) · nodemailer · Puppeteer screenshots · Vitest + Playwright

Quickstart

Prereqs: Node 20+, Docker, Supabase CLI.

# 1. Database (local Postgres on :54322 via Supabase CLI)
supabase start

# 2. App
cd application
cp .env.example .env.local       # defaults work out of the box
npm install
npm run db:migrate               # apply Drizzle migrations

# 3. Local mailbox — sent emails land here instead of the real world
docker run -d -p 1025:1025 -p 8025:8025 axllent/mailpit

# 4. Run
npm run dev                      # → http://localhost:3000

Local dev uses open mode (SUPERCOMPOSER_OPEN_MODE=true): a mock user, no auth proxy needed. Sent emails appear at http://localhost:8025 (Mailpit).

AI keys (BYOK)

Feature Key Where to get it
Design chat ANTHROPIC_API_KEY console.anthropic.com
Image + video gen GEMINI_API_KEY aistudio.google.com

Add keys in-app via the key icon in the chat header — they're stored only in your browser's localStorage and sent per-request as x-anthropic-key / x-gemini-key headers. For local dev you can also set them in .env.local. Bonus: with no key set in dev, chat falls back to your authenticated claude CLI if installed (text-only).

Project Structure

├── application/              # Next.js App Router app
│   ├── app/
│   │   ├── api/              # 60+ API routes (templates, send, schedule, polls, teams, admin, chat, …)
│   │   ├── admin/            # Admin dashboard (super-admin only)
│   │   ├── components/       # React components (editor, gallery, teams, chat, …)
│   │   ├── store/            # Zustand state (editorStore)
│   │   └── lib/
│   │       ├── db/           # Drizzle schema (single source of truth)
│   │       ├── dal/          # Data access: templates, revisions, sendLog, auditLog,
│   │       │                 # recipientLists, scheduledSends, polls, teams, …
│   │       ├── teamAuth.ts   # Route-level team membership gate
│   │       ├── emailPipeline.ts  # CID embed, fail-loud on missing assets
│   │       └── skills/       # data-to-email skill prompt + detection
│   ├── e2e/                  # Playwright E2E tests
│   ├── drizzle/              # Generated SQL migrations
│   └── Dockerfile
├── supabase/                 # Local Supabase CLI config
├── samples/                  # Drag-and-drop sample data for the data-to-email skill
└── CLAUDE.md                 # Project constitution (rules, architecture, conventions)

Architecture

Browser ──→ Next.js App
              ├── Middleware (CSRF origin check + 50MB size limit)
              ├── App Router (editor, gallery, /admin) + 60+ API routes
              ├── ShadowPreview (email canvas in Shadow DOM)
              ├── /api/chat ──→ Anthropic API (user's key)
              │       └──→ Gemini API: Imagen images + Veo videos (user's key)
              ├── Team gate (requireTemplateOwner / assertRowTeamAccess)
              ├── DAL ──→ Drizzle ──→ Postgres
              ├── Filesystem (uploads, screenshots)
              └── nodemailer ──→ SMTP relay (Mailpit in dev)

Key concepts

  • ShadowPreview — renders email HTML in a Shadow DOM for CSS isolation
  • buildEmailForSend — assembles final email HTML: inlines CSS, rewrites URLs, optionally inlines images as base64
  • Fail-loud sends — if any referenced asset can't be resolved, /api/send returns 422 with the file list; broken images never ship to recipients
  • DAL — all DB access goes through app/lib/dal/ modules, never raw queries in routes
  • Team scoping — every list/read/write on team-owned tables passes a membership gate

Testing

cd application
npx vitest run        # unit tests
npm run test:e2e      # Playwright (needs dev server)

CI (GitHub Actions) runs typecheck, unit tests, and a production build on every push/PR.

Security

  • SSRF protectionapp/lib/urlSafety.ts blocks fetches to private IPs, localhost, link-local, and cloud metadata endpoints
  • XSS — all HTML rendered via innerHTML passes through DOMPurify
  • Path traversal — asset serving rejects .. segments at any position
  • Header injection — sender fields sanitized; subjects reject control characters
  • Send policy — optional ALLOWED_RECIPIENT_DOMAINS / ALLOWED_REPLY_DOMAINS allowlists; non-admin senders are locked to their own identity
  • Zod validation — every API route validates input at the boundary
  • BYOK — AI keys are per-user and per-request; never logged, never stored

Deploy

The app is a standard Next.js server: npm run build + next start behind any auth proxy that sets x-oidc-* identity headers, or adapt app/lib/auth.ts to your auth provider. Dockerfile / Dockerfile.base build a production image with Chromium + ffmpeg for screenshots and video conversion. Cloud deployment (Supabase Auth + Storage + hosted Postgres) is on the roadmap.

Documentation

Doc Purpose
CLAUDE.md Project constitution — rules, architecture, conventions
.claude/docs/CASE_STUDY.md Decision log + lessons learned
.claude/docs/ROADMAP.md What's next
samples/README.md Sample data for the data-to-email skill

License

MIT

About

AI design studio — chat with Claude to design on-brand, campaign-grade HTML webpages and emails, generate images & video with Imagen/Veo, then send, schedule, and poll. BYOK. A little more fun than using a Claude Skill... but there's a skill for this too...

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages