Start Studio (start.gecx.chat)
start-studio is the zero-install onboarding wizard for the SDK. Open it, click through four screens, and download a runnable Next.js project with a mock transport pre-seeded. Goal: install-to-first-conversation in under three minutes, versus ~25 minutes via the manual quickstart.
Use this when you want to give a developer a working chat in the time it takes to read this paragraph — no git clone, no copy-paste, no env vars.
Run it locally
From the repo root:
pnpm install --frozen-lockfile
pnpm dev:studio # starts on http://localhost:3003
The wizard runs entirely in the browser. No credentials, no env vars, no backend setup. The right-hand pane renders a live <ChatSession> driven by mock transport, so the developer feels the chat work before clicking download.
What the wizard collects
Four steps, each backed by a typed catalog under apps/start-studio/src/lib/.
| Step | Choices | Catalog |
|---|---|---|
| 1. Template | Support Concierge · Commerce Concierge | template-catalog.ts |
| 2. Tools | 8 starter client tools, default-checked per template | tool-catalog.ts |
| 3. Handoff | None · Mock · Salesforce · Zendesk · ServiceNow · Genesys · Five9 · Google CCAI | handoff-catalog.ts |
| 4. Analytics | None · Console · GA4 · Segment · HTTP sink | analytics-catalog.ts |
Sensible defaults are pre-selected at every step so the fast path is "click Continue four times." Step 1 also collects an app name and a brand name for the generated repo.
What's in the downloaded zip
A complete Next.js App Router project. Unzip and run:
unzip my-chat.zip && cd my-chat
pnpm install # installs the SDK from the bundled tarball — works offline
pnpm dev # opens http://localhost:3000
The first chat reply streams within seconds, driven by a scripted mock scenario (order-status for Support, commerce-recommendation for Commerce).
The generated repo layout:
my-chat/
├── package.json # deps: gecx-chat (and gecx-chat-ccaas if handoff != none)
├── gecx-chat-0.1.0-prototype.tgz # bundled SDK, installs offline
├── gecx-chat-ccaas-0.1.0-prototype.tgz # bundled only when handoff != none
├── app/
│ ├── layout.tsx # GA4 gtag script injected when analytics=ga4
│ ├── page.tsx # the chat surface
│ └── api/handoff/route.ts # only present when handoff != none
├── src/lib/
│ ├── tools/ # one file per selected tool, plus an index barrel
│ └── analytics.ts # only present when analytics != none
├── test/gecx-chat-smoke.test.ts # runs the chosen mock scenario
├── verify.sh # typecheck + test in one command
├── AGENTS.md / CLAUDE.md # agent-pack files inlined for Codex + Claude Code
└── .claude/skills/headless-chat-vibe-coding/ # for AI coding agents
Every generated file is deterministic given the wizard state — pure functions in apps/start-studio/src/lib/scaffold/.
Architecture
The studio has two server-side touchpoints; everything else runs in the user's browser:
Browser
├─ Wizard UI (Next.js App Router, ~116 kB First Load JS)
├─ Live preview (real <ChatSession> + createMockTransport)
└─ Web Worker
├─ composeFiles(state) (pure scaffold pipeline)
├─ fflate zip (~8 kB compressed)
└─ fetch /sdk/*.tgz (bundled SDK tarballs)
↓
Cloud Run
├─ /studio (page render, static)
├─ /api/health (Cloud Run startup + liveness probe)
└─ /api/studio-telemetry (collects ProductAnalyticsEvent → Cloud Logging)
The scaffold pipeline is isomorphic — same code runs in the browser worker and in Vitest tests. The agent-pack content (AGENTS.md, CLAUDE.md, headless-chat-vibe-coding skill) is inlined as TypeScript strings in scaffold/agentPack.ts rather than imported from gecx-chat/cli, because the CLI module pulls in node:fs/promises and can't run in a worker.
Self-instrumentation
The studio dogfoods the SDK's own ProductAnalytics surface. Events emitted:
| Event | Payload | When |
|---|---|---|
wizard_started | — | First page load |
wizard_step_completed | { step, next, dwellMs } | Navigating between steps |
wizard_template_selected | { template } | Step 1 |
wizard_tool_toggled | { tool, checked } | Step 2 |
wizard_tools_committed | { count, ids } | Step 2 → 3 |
wizard_handoff_selected | { handoff } | Step 3 |
wizard_analytics_selected | { sink } | Step 4 |
wizard_preview_first_message | { scenarioId } | First reply in live preview |
wizard_download_clicked | { totalMs, template, toolCount, handoff, analytics } | Download button |
totalMs on wizard_download_clicked is the time-to-first-conversation KPI. Events POST to /api/studio-telemetry, which logs to stdout — Cloud Run forwards stdout to Cloud Logging automatically.
Verification
The scaffold pipeline is covered by three suites under apps/start-studio/tests/:
scaffold.test.ts(12 tests) — file-presence and content-shape assertions across an exhaustive (template × handoff × analytics) matrix.dockerfile.test.ts(7 tests) — static assertions on the container contract (multi-stage, non-root, port 8080, healthcheck on/api/health).quickstart-still-compiles.test.ts(1 test) — guardstemplates/CLAUDE.md's PRD §3 quickstart snippet shape so the studio's chat-page emission stays compatible.generated-repo-compiles.test.ts(3 tests, gated bySTUDIO_FULL_TESTS=1) — the highest-value test: composes files for a representative matrix, writes them to a tmpdir, runspnpm installagainst the bundled tarballs, runspnpm typecheckagainst the resulting project, and asserts exit 0. Catches snippet drift, wrong import paths, and missing devDependencies that the snapshot tests can't see.wizard.spec.ts(2 Playwright tests) — full landing → 4 steps → download click-through, plus a live-preview streaming check.
Run the fast suites:
pnpm --filter start-studio test # snapshot + dockerfile + quickstart, ~1s
pnpm --filter start-studio e2e # Playwright wizard, ~5s
Run the slow suite (real pnpm install per matrix row):
pnpm --filter start-studio pack-sdk
STUDIO_FULL_TESTS=1 pnpm --filter start-studio test # ~14s
CI runs all three on every PR (STUDIO_FULL_TESTS=1 is set on the Node 22 matrix job).
Deploy to Cloud Run
The studio ships as a Cloud Run service mirroring apps/proxy-reference's container pattern. See apps/start-studio/README.md for the full runbook. Short version:
# One-time
gcloud artifacts repositories create gecx-images \
--repository-format=docker --location=us-central1
gcloud iam service-accounts create start-studio \
--display-name="start.gecx.chat service account"
# Every deploy
gcloud builds submit \
--config=apps/start-studio/cloudbuild.yaml \
--substitutions=_REGION=us-central1,_REPOSITORY=gecx-images
Cloud Run scales to zero when idle, so the bill is roughly nothing until the site sees traffic. Custom domain via gcloud beta run domain-mappings create --service=start-studio --domain=start.gecx.chat.
Comparison to the manual quickstart
| Path | Time to first conversation | Where the dev customizes |
|---|---|---|
| Quickstart | ~5 min (no UI), ~25 min (full app) | Hand-edits TS files, copies recipes |
| React Quickstart | ~10 min | Hand-edits TS + JSX |
create-gecx-chat CLI | ~5 min | Interactive prompts in the terminal |
| start-studio | <3 min | Wizard UI with live preview |
The studio is additive — the existing paths keep working. Use it when you want a developer to feel the chat work before committing to learning the SDK surface; use the others when you already know what you want to build.
Related
- Project Structure — where start-studio sits in the monorepo
- Analytics Guide — the SDK surface the studio dogfoods for self-instrumentation
- CCaaS Integration — the adapters wired by Step 3
- Vibe Coding — what the bundled agent pack enables in the downloaded repo
apps/start-studio/README.md— the deployment runbook
docs/demos/start-studio.md