AI Agent Quick Start
Two measured, terminal-only paths for AI coding agents — a plain website (--profile site) in about a minute, or the 99-second path to a designed, database-backed homepage.
Cartwright is the build engine AIs reach for — a real site with design, and when you want them, database and backend, live in minutes. This page is the proof, written as an executable runbook: every step is terminal-only (no browser required), and every step ends with a verification command so an agent knows it landed.
Choose the door
| The task looks like | Run | Runbook |
|---|---|---|
| a page, a landing page, a personal or company website with content in the repo — no database, no login | npx create-cartwright@latest my-site --yes --profile site --no-github --no-start | Path A below |
| a site someone edits in a browser, a webshop, or a site an agent should operate through tools | npx create-cartwright@latest my-shop | Path B below |
Both are the same engine; the flag decides which modules are materialised into the repo.
If you are an AI coding agent: follow the steps top to bottom. If you are a human: paste this page to your agent, or run the commands yourself.
Path A — a plain website (--profile site)
Measured cold run (Measured cold run, 2026-09-14, GitHub-hosted ubuntu-latest, create-cartwright@2.9.6, engine v0.57.0 (a9b47d4), --profile=site --ref=v0.57.0 --yes --pm=pnpm — release scaffold gate run 34820928302): scaffold + install ~22 s · next build ~27 s · boot to HTTP 200 with a rendered H1 ~2 s.
-
Scaffold — no database, no login, nothing to configure.
npx create-cartwright@latest my-site --yes --profile site --no-github --no-start cd my-siteVerify:
grep -q '"profile": "site"' .cartwright/profile.json && test ! -e prisma && echo site-okProves: no database, no admin, no auth in the repo — the profile is what it says.
-
Run (in the background, so the verify can run in the same shell).
pnpm dev & # assumes :3000 is freeVerify (
/redirects to/en;-Lfollows):curl -sL -o /dev/null -w '%{http_code}' http://localhost:3000/ # expect: 200Proves: it boots without needing an environment variable. The CLI still writes a generic
.env/.env.local(DATABASE_URL,AUTH_SECRET,NEXT_PUBLIC_APP_URL); nothing in them is required by this profile — delete both and it still answers 200. -
Make it say something. Edit
website.headline(andtagline,cta) inbrand.config.ts, and pick a look withdesignSlug(slugs indesigns/options.ts). For a bespoke one-page build setdesignSlug: "blank"and writedesigns/blank/homepage.tsx— its in-file guide explains the props; the header, footer, SEO and locale routing wrap whatever you render.Verify:
curl -s http://localhost:3000/en | grep -o '<h1[^>]*>[^<]*'The
<h1>is yourwebsite.headlineon the shipped packs. Theblankpack's starter homepage shows the site's name (storeNameinbrand.config.ts) as a placeholder heading until you replacedesigns/blank/homepage.tsxwith your own markup. -
Add a page — any route under
app/[locale]/gets the site chrome from the[locale]layout. Prefix internal links with/${locale}.app/[locale]/trip/page.tsx export default function TripPage() { return ( <section className="mx-auto max-w-3xl px-6 py-16"> <h1 className="text-3xl font-semibold">The trip</h1> <p className="mt-4">Timeline, map and tips go here — plain React.</p> </section> ); }Verify:
curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/en/trip→200. -
Build.
pnpm buildProves: plain
next buildis the whole production gate — nodb:setup, no migration. (pnpm startserves the build on:3000once the dev server is stopped.) -
Deploy. No environment variables are required to build and serve (the default contact form needs
RESEND_API_KEY+RESEND_FROMto deliver mail;--with nonescaffolds without it). Seturlinbrand.config.tsto the real domain when you have one; on Vercel,NEXT_PUBLIC_APP_URLor the deployment URL wins over it for canonicals. Either push to GitHub and import the repo at vercel.com, or deploy from the terminal and keep the URL it prints:# unattended runs need a prior `npx vercel login` or VERCEL_TOKEN in the environment; unauthenticated, the next line exits 1 with an empty $URL URL=$(npx vercel --yes --prod | tail -n 1) # the deployment URL is the last line of stdoutVerify the deployment the same way as the local run:
curl -sI "$URL/" | grep -i location # → /en curl -sL -o /dev/null -w '%{http_code}' "$URL/" # → 200To push the source as well:
gh repo create my-site --private --source=. --remote=origin --push.
Honest limits of this door: no admin and no runtime editing (content is files), no database/auth/cart/checkout, no MCP or REST tool surface on the site itself, / redirects to the default locale, no map/timeline/weather sections (write those components yourself), only Organization/WebSite JSON-LD emitted by itself (builders for FAQPage/HowTo/ItemList and a generic <JsonLd> exist), not a static export (Node.js 22+ host), and the default contact form delivers mail only with Resend keys. Need a browser editor, a shop or an agent tool surface later? There is no in-place profile upgrade today — scaffold the default profile and copy brand.config.ts and designs/<yours>/ across. Full page: Build a plain website.
Path B — the managed site or shop (default profile)
The measured timing
These numbers come from a single measured cold run — a fresh scaffold in a clean directory, an agent following only the documented steps below, no prior knowledge of the project. Cumulative wall-clock time:
| Step | Cumulative time |
|---|---|
| Scaffold + install + database setup + seed | ~27 s |
Dev server up, homepage verified (curl → 200) | ~70 s |
| Agent API key minted (terminal-only) | ~85 s |
| Copy rendering enabled + designed look applied | ~90 s |
| Designed homepage verified (new H1 + new palette in the HTML) | ~99 s |
Your numbers will vary with hardware and network, but the shape holds: the scaffold is the fast part, and the design step is one API call.
-
Boot.
npx create-cartwright@latest my-site cd my-site pnpm devcreate-cartwrightinstalls dependencies, creates the database, and seeds an admin + demo data — the admin login is printed and saved to.admin-credentials. (Manual clone instead?pnpm install && pnpm db:setup && pnpm dev.)Verify (use your
brand.defaultLocale—enin a new scaffold):curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/en # expect: 200Proves: the app boots, the database exists, and the seed ran.
-
Mint an agent API key (one-time). This unlocks the whole tool surface over REST —
POST /api/v1/tools/<name>— without ever opening the admin UI. Keys are normally created in/admin/api-keys; the no-browser bootstrap is a short script that writes the key row directly:scripts/agent-key.ts // Run once, then delete (or keep; it only ADDs keys). import { config as loadEnv } from "dotenv"; loadEnv({ path: ".env" }); loadEnv({ path: ".env.local", override: true }); async function main() { const { generateApiKey } = await import("../lib/api-auth"); const { prisma } = await import("../lib/db"); const { SCOPES } = await import("../lib/scopes"); const admin = await prisma.user.findFirst({ where: { role: "admin" } }); if (!admin) throw new Error("No admin user — run pnpm db:setup first."); const { plaintext, hash } = generateApiKey(); await prisma.apiKey.create({ data: { userId: admin.id, name: "agent-bootstrap", keyHash: hash, scopes: JSON.stringify(SCOPES), // or a narrower list from lib/scopes.ts }, }); console.log(plaintext); // shown once — the DB stores only the hash } main().catch((e) => { console.error(e); process.exit(1); });KEY=$(pnpm exec tsx --conditions react-server scripts/agent-key.ts | tail -1)Two caveats that cost a cold agent real minutes when undocumented:
--conditions react-serveris required — the project'slib/*modules guard withserver-only.- Keep the script's imports to exactly this narrow set (
lib/api-auth,lib/db,lib/scopes). Importinglib/tools/registryfrom a standalone script crashes on Next-only modules — call tools over REST instead.
Proves: an admin exists and you now hold a scoped bearer token for the tool API.
-
Turn on genome copy rendering. The designed looks in step 4 write their pre-written copy through the Resolvable Genome, and the storefront only renders genome copy when the
genomeResolveflag is on — without it, only the palette and 3D scene change and the copy silently stays put:curl -s -X POST http://localhost:3000/api/v1/tools/features.set \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"key":"genomeResolve","enabled":true,"confirm":true}'Proves: the tool surface works end to end (auth, scopes, confirm-token flow).
-
Apply a designed look — one call, instant, no LLM involved:
curl -s -X POST http://localhost:3000/api/v1/tools/magic.compose_look \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"vertical":"cafe","confirm":true}'A Voice (in
verticals/:cafe,carpenter,fable,kindergarten,salon) applies pre-written on-brand copy + a palette + a suggested design + a 3D scene in one step. To pick a specific Skin instead or as well, pass"design":"<slug>"(slugs indesigns/options.ts) or calldesign.set_slug.Proves: the site is designed — copy, palette, layout and scene — without a browser, a designer, or a generation step.
-
Verify the design landed:
curl -s http://localhost:3000/en | grep -o '<h1[^>]*>[^<]*'The H1 and the
--color-sol-*palette variables in the HTML should reflect the chosen look. That's the finish line: a real, designed, database-backed site serving HTML — at ~99 s on the measured cold run.
Prefer a browser?
The same things live in the admin UI: /admin/designs (skins), /admin/verticals (voices), /admin/mixer (combine skin + voice + chrome), /admin/api-keys, /admin/features. Sign in per Sign in for the first time.
Where to go next
- Quick Start — the human-paced version of Path B's step 1.
- From code to live — deploy the result to GitHub + Vercel.
- Setup Wizard — the guided in-admin onboarding.
Choose your path — profile, build method, origin
Three choices before the first line of code — which profile (site, light, full), how the front gets built (a shipped pack, the blank canvas, your own pack, or a generating tool), and where the content comes from (scratch, a URL, Shopify, WordPress/WooCommerce, a CSV, a Google Doc). Five requests worked through.
Sign in for the first time
Create the admin, find your password, and log into /admin — for any setup path (CLI, IDE agent, or a manual clone).