Part V: The Part of Fourteens (lists you'll come back to)B
Appendix BAppendix B
Appendix B: Every prompt, in order
Cut along the dotted line.
Copy-paste ready. Fill in anything in [brackets]. Generated from the chapters by scripts/build-prompt-pack.py, so edit the chapters, not this file.
Step 5: Set up the agent (and let it set up everything else)
Set this computer up so you can build, deploy and manage websites for me
end to end, without me pasting keys or clicking through dashboards. I want you
doing everything that can be done through a CLI or API. Only stop for me when a
human genuinely has to act (paying, accepting terms, a browser sign-in), and
when you do, tell me exactly what to click.
Where my keys are: Bitwarden Secrets Manager, project "websites". The machine
account access token is in my system keychain as "bitwarden-secrets-token"
(macOS Keychain generic password, or a Windows Credential Manager generic
credential). The machine account can read and write.
1. Tools: install whatever's missing: Node LTS, git, the GitHub CLI, wrangler,
and the Bitwarden Secrets Manager CLI (bws). If npm blocks install scripts
for packages like esbuild or workerd, approve them.
2. withkeys: create a helper command on my PATH called "withkeys" that reads
the access token from the keychain and runs any command with the
"websites" project's secrets as environment variables (bws run). It must
never print a secret value. Also give yourself a safe way to save a new
secret to the vault without the value appearing in the chat or in shell
history.
3. GitHub: sign me in with the GitHub CLI using the browser flow, with the
repo, workflow and delete_repo scopes. Tell me when to click Authorize.
4. Cloudflare: use CLOUDFLARE_BOOTSTRAP_TOKEN to create a new API token named
"claude-websites", valid for one year, with Edit access to everything a
website on Cloudflare can need: Workers (scripts, routes, builds, KV, R2,
D1, queues, images, observability), Pages, DNS, zone settings, SSL,
cache purge, email routing and email sending, Turnstile, and account
settings, for all my accounts and all zones. The bootstrap token can't
see my account ID, so use the account wildcard when you create it, then
use the new token to look up the account ID. Get the exact permission
group names from the API, don't guess them. Pipe the new token straight
into the vault as CLOUDFLARE_API_TOKEN without printing it, and save my
account ID as CLOUDFLARE_ACCOUNT_ID. Verify the new token can list my
zones, Workers, D1 databases and R2 buckets.
While the bootstrap token still exists, also create a second, narrower
token for automatic deploys from GitHub: just what deploying a Worker
needs (Workers scripts, routes, KV, D1, R2, account settings read). Save
it as CLOUDFLARE_DEPLOY_TOKEN. That's the one that goes into GitHub, so
the full-access token never leaves my vault. Then tell me the bootstrap
token can be deleted.
5. My domain is [YOUR DOMAIN].
- If it's already in my Cloudflare account, confirm it's active.
- If it isn't, add it to Cloudflare, import its existing DNS records
(check the MX, SPF and any verification records came across, so email
keeps working), and give me the two nameservers to paste at my current
registrar. Then keep checking until it's active.
6. Write a section into my global Claude instructions file
(~/.claude/CLAUDE.md) so every future session knows: where my keys are,
how to use withkeys, the secret names, my domain, and these rules:
- Do the work yourself through CLIs and APIs. Don't send me into a
dashboard for anything you can do.
- Never print a secret, never write one to a file inside a project, never
commit one. Secrets for deployed sites go into Cloudflare Worker secrets
or GitHub Actions secrets, set from the vault. GitHub only ever gets
CLOUDFLARE_DEPLOY_TOKEN, never CLOUDFLARE_API_TOKEN.
- If a key is missing or lacks a permission, tell me the exact fix instead
of working around it.
- Deploy to a staging address first. Production only after I say yes.
Report: what works, what's missing, and anything I need to do.Path A: Build the site
BUSINESS
What you do, in one or two sentences:
Where you are / who you serve:
What makes you different from the three competitors down the road:
VISITORS
Who's landing on this site:
The ONE thing you want them to do (call, book, order, get a quote, visit):
The questions they always ask you before buying:
PAGES
[e.g. Home, Menu, About, Catering, Contact. Or "one long page".]
THE FEEL
Three words for how it should feel (not "modern" and "clean", everyone says
that. Try "warm, flour-dusted, slightly chaotic" or "quiet, expensive, gallery"):
Sites you love (any industry) and what exactly you love about each:
1.
2.
3.
Sites or styles you hate:
Borrowing from someone else's look (a famous brand, a book series, a movie)?
Say "evoke it, don't copy it": no names, logos or characters that aren't yours.
Brand colours / fonts, if you have them (or "make them up"):
MOTION AND INTERACTION
[None / subtle / show off.] Any specific idea? ("the menu could be a
flippable card deck", "the hero reacts to the mouse", "scroll through the
steps of making sourdough")
LANGUAGES
[English only / English and French / ...]
MATERIAL
Everything is in this folder: [path]. Old site: [URL or none].Above is my brief. Build my website.
You're the designer here, not just the developer. Use the brief and the
material in this folder, then make real design decisions: a concept, a type
pairing, a colour system, a layout idea that belongs to THIS business. Push
it. I would rather you take a big swing I have to pull back than hand me
something safe. Write your design direction to DESIGN.md before you build,
and follow it.
Hard no's: generic gradient heroes, "Welcome to [business]" headlines, rows of
three identical cards with icons, emoji as icons, stock-photo people, fake
testimonials, lorem ipsum, and any copy that could be on a competitor's site.
Write real copy from my material, in plain language, specific to me. If you
need a fact you don't have (prices, hours, address), leave a clearly marked
TODO and list them all for me at the end. Don't invent them.
Build it properly:
- Latest Next.js, deployed to Cloudflare Workers with OpenNext. I'm on
Cloudflare's [Free / Paid] Workers plan: stay inside its limits, and tell
me before adding anything that needs Paid.
- Keep all the words and data in Markdown or data files, separate from the
design, so a redesign never touches the content.
- Fast: optimised and properly sized images, minimal JavaScript, and no
layout shift from web fonts (CLS under 0.1). It should score 90+ on mobile
Lighthouse for performance, accessibility and best practices on staging.
SEO gets checked on the live domain, since staging is noindex on purpose.
- Motion that fits the brief, and that respects reduced-motion settings.
- Fully responsive. Design the phone version on purpose, most visitors
will be on one.
- Accessible: real headings, alt text, keyboard navigation, readable
contrast.
- SEO basics: titles, descriptions, Open Graph images, sitemap, robots.txt,
schema.org structured data for my business.
Ship it:
- Create a private GitHub repo for it and push.
- Set up GitHub Actions so every push to main deploys to a staging address
on workers.dev. Staging must be noindex. Put CLOUDFLARE_DEPLOY_TOKEN and
CLOUDFLARE_ACCOUNT_ID into the repo's Actions secrets from my vault.
Never the full-access token.
- Deploy, open the staging site yourself, check every page on desktop and
phone sizes, and fix anything that looks off before you show me.
Then send me the staging link, a short summary of the design direction, and
the list of TODOs you need from me.Forms and email (all Cloudflare, no extra accounts)
Add a contact form to my site, and set up email on my domain. Do all of it
through the Cloudflare API and wrangler, using my keys.
Form:
- Fields: [name, email, phone, message, plus anything specific: event date,
budget, service type...]. Design it to match the site, including clear
error and success states.
- Protect it with Turnstile. Create the widget through the API, put the site
key in the site config and the secret in a Worker secret (save it to my
vault too as TURNSTILE_SECRET_KEY). Add rate limiting as well.
- Save every submission to a D1 database first, THEN send the email. If the
email fails, the submission must still be saved. Apply the database
migrations in the deploy workflow.
My Cloudflare Workers plan is [Free / Paid]. On Free, only send to my own
verified address and skip the visitor confirmation. On Paid, do both.
Sending:
- Set up sending from my domain. Add every DNS record
it needs (SPF, DKIM, DMARC, anything else) and verify the domain. If SPF or
DMARC records already exist, merge into them. Never create a second one,
and never replace or remove MX records.
- Send each submission to [YOUR EMAIL], from a no-reply address on my
domain, with reply-to set to the person who filled in the form so I can
just hit reply.
- [Paid plan only] Send the visitor a short, friendly confirmation email that sounds like the
rest of the site. It must not repeat anything they typed (otherwise
spammers use your form to send their message to strangers), and rate
limit it per recipient address.
Receiving:
- Set up Email Routing so [hello@MYDOMAIN] forwards to [YOUR EMAIL]. Tell me
when to click the verification email Cloudflare sends me. If MX records or
a rule for this address already exist, leave them alone, even if an API
status check says routing isn't configured.
Then test it end to end on staging: submit the form in a visible browser
window (Turnstile won't pass a hidden, automated one, so use Turnstile's test
keys if you automate it), confirm the submission is in D1, and confirm the
email was sent. Tell me to check my inbox (and spam
folder).I send email as [hello@MYDOMAIN] from Gmail using smtp.gmail.com (Send mail
as). Update my domain's SPF record to include Google (merge with what's
there, never a second SPF record), and make sure my DMARC policy won't
reject these emails (relaxed alignment, p=none or quarantine). Don't touch
the MX records. Then tell me how to check it works: send a test to a
mail-tester style address and read me the score.Path B: The site plus a CMS
Above is my brief. Build my website WITH a CMS, so [who: me / my staff] can
edit content without code.
Everything in the Path A approach still applies: you're the designer, take a
real swing, write DESIGN.md first, no generic AI layouts, real copy from my
material, TODOs instead of invented facts.
CMS setup:
- Payload CMS (latest v3) inside the Next.js app, deployed to Cloudflare
Workers with OpenNext. Database on Cloudflare D1, media on R2. Create the
D1 database and R2 buckets yourself.
- Generate PAYLOAD_SECRET and save it to my vault. Set it as a Worker secret.
- Pages built from blocks. Design a block library for THIS site, not a
generic one. Think: hero, rich text, media with text, gallery, feature
grid, testimonials, FAQ, call to action, form, [plus site-specific ones:
menu section, price list, team, process steps, before/after...]. Every block
should look great with any reasonable content, handle missing images, and
have a preview image in the admin so editors can see what they're picking.
- Collections for what actually repeats on this site: [e.g. menu items,
services, products, projects, blog posts, testimonials, team members].
Plus Media, Forms, Form submissions, Redirects, Users.
- Globals for Header, Footer and Site settings (contact details, hours,
social links, analytics IDs).
- Drafts, and live preview on everything editable, with click-to-edit from
the preview to the right field.
- Publishing is instant: pages are cached for speed, and publishing clears
exactly the pages that changed.
- SEO fields (title, description, social image) on every page and post.
- Forms built in the CMS, protected with Turnstile, saved to the database
before any email is sent (see chapter 8 of the guide I'm following).
- Keep the admin simple for a non-technical editor: hide fields they
shouldn't touch, use plain labels and help text, sensible defaults.
- Seed the CMS with all the real content, so the site is complete on day one.
Ship it:
- Private GitHub repo. GitHub Actions deploys to a staging Worker on
workers.dev on every push to main, and runs database migrations before
deploying. Staging is noindex. Set CLOUDFLARE_DEPLOY_TOKEN and
CLOUDFLARE_ACCOUNT_ID as Actions secrets from my vault, never the
full-access token.
- Set up automatic daily D1 backups.
- Create an admin login for [EMAIL], with a strong random password saved to
my vault as PAYLOAD_ADMIN_PASSWORD.
- Open the staging site and the admin yourself, check it all works,
including editing a page and publishing it.
Send me the staging link, the admin link, a two-minute "how to edit your
site" guide written for [who], and your TODO list.Path C: The site plus a store
Add a store to my site using Stripe. STRIPE_SECRET_KEY in my vault is a test
mode key. Do everything through the Stripe API.
What I sell: [products, prices, options like sizes or flavours].
How it gets to them: [shipping (where, how much) / local pickup (where, which
days, how much notice) / delivery radius / digital download].
Taxes: [e.g. "I'm in BC, charge GST and PST" / "set up Stripe Tax"].
Build:
- Product pages and a cart that match the site's design, not a bolted-on
template. [If there's a CMS: products are managed in the CMS and synced to
Stripe automatically when I publish.]
- Checkout with Stripe Checkout (hosted). Never handle card details on my
site.
- Create the products and prices in Stripe yourself.
- A webhook endpoint on my site for completed payments. Create it in Stripe
through the API, verify its signature, and save the signing secret to my
vault as STRIPE_WEBHOOK_SECRET and as a Worker secret. The webhook, not
the redirect back from checkout, is what marks an order as paid.
- Save every order to the database and email me a new-order notification.
- Customer emails: [Free Cloudflare plan: turn on Stripe's own email
receipts through the API / Paid plan: send the customer a branded
confirmation that sounds like my site with Cloudflare Email Service, and
leave Stripe's receipts off so they don't get two].
- [Pickup: let customers choose a pickup date, respecting my notice period and
closed days.]
- Success and cancelled pages that make sense.
Test it end to end on staging with Stripe test cards: a successful payment,
a declined card, and an abandoned checkout. Show me the order in the
database and the emails that were sent.
Finally, give me a launch checklist for switching to live mode.Path D: Events, bookings, and everything else
I want to add [the thing: RSVPs for my event / class bookings / a members
area / a waitlist / ...] to my site.
How it works for visitors:
[Step by step, in plain words. What they see, what they click, what they
get afterwards. Example: "They pick a class from the schedule, enter their
name and email, and get a confirmation. They can cancel from a link in that
email."]
How it works for me:
[What you need to see or do. Example: "I see a list of who's booked into
each class, I can cancel a class and everyone booked gets told, I get an
email when a class is full."]
Rules and limits:
[Numbers and edge cases. Example: "12 spots per class, a waitlist after
that, bookings close 2 hours before, no double-booking the same person."]
Payments: [none / Stripe, $X per ticket, refunds up to 48 hours before].
Use what's already on my Cloudflare account (and Stripe, for payments)
unless there's a strong reason not to. Before you build anything, reply with:
1. A one-paragraph plan in plain language.
2. Which Cloudflare pieces you'll use and why, one line each.
3. What it costs on my plan, and whether anything needs the $5 Workers plan.
4. Anything that needs me (a Stripe account, a DNS change, a click).
5. The edge cases you thought of that I didn't.
Wait for my yes. Then build it on staging, design it to match the rest of
the site, and test it end to end as a visitor and as me, including the edge
cases. Show me the staging link and walk me through it.I want RSVPs for my sourdough workshop on my site.
For visitors: a workshop page with the date, time, what's included and how
many spots are left. They enter their name, email and any dietary needs and
pay $85 through Stripe. They get a confirmation email with the address and
an "add to calendar" link, and a reminder the day before.
For me: a private page that lists everyone who's paid, with their dietary
needs, and a button to email everyone at once. An email to me when it's
full.
Rules: 16 spots, then a waitlist. If someone cancels more than 48 hours
before, refund them and email the first person on the waitlist. No refunds
after that.
Use what's already on my Cloudflare account and Stripe. Plan first, wait for
my yes, then build on staging and test it, including two people buying the
last spot at the same time.Analytics: GA4, Tag Manager and Search Console
Set up analytics and Search Console for [DOMAIN], doing everything you can
through gcloud and the Google APIs. Only stop for me where Google requires a
human, and when you do, give me the exact link, copy anything I need to paste
to my clipboard, and tell me precisely what to click.
1. Google Cloud: sign me in with gcloud (browser flow, my Google account
[EMAIL]). Create a project called "websites" (or reuse it if it exists).
Enable: Google Analytics Admin API, Google Analytics Data API, Tag Manager
API, Search Console API, Site Verification API.
2. Service account: create one called "claude-websites", create a JSON key,
save the whole JSON to my vault as GOOGLE_SERVICE_ACCOUNT_JSON, and delete
the key file from disk. Never print it.
3. Search Console (no clicks from me): as the service account, get a DNS
verification token from the Site Verification API for the domain, add the
TXT record through the Cloudflare API, verify, and add the domain property
to Search Console. Then add [EMAIL] as an owner so I can see it in my own
Google account.
4. The two human steps. Walk me through them one at a time and wait for me:
a. GA4: send me to create a Google Analytics account for [BUSINESS NAME]
and accept the terms. The wizard insists on a property too: tell me to
name it after the site and click through the rest with any answers,
you'll fix the settings. Then have me add the service account email
(copy it to my clipboard) as an Administrator under Account access
management.
b. GTM: send me to create a Tag Manager account for [BUSINESS NAME] with a
Web container for [DOMAIN] and accept the terms. Then have me add the
service account email with BOTH: account Administrator, and Publish on
the container. (Account Administrator alone can't edit or publish the
container.)
5. GA4 via API: set the property's time zone to [TIME ZONE] and currency to
[CAD/USD], create a web data stream for https://[DOMAIN] with enhanced
measurement on, and add [EMAIL] as an Administrator.
6. GTM via API: in the container, create a Google tag with the GA4
measurement ID firing on all pages, and GA4 event tags for what matters on
this site: form submissions as generate_lead, [phone and email clicks,
booking link clicks, purchases...]. Fire the form event from a data layer
push in the site code, not a click trigger that breaks on the next
redesign. Publish the container with a clear version name.
7. Site: add GTM to the site properly for Next.js, production only. Add a
cookie consent banner with Google Consent Mode v2, analytics denied by
default until the visitor accepts, styled to match the site.
8. Mark generate_lead (and purchase, if the site sells) as key events.
9. Make sure sitemap.xml and robots.txt are right, and submit the sitemap
to Search Console.
10. Deploy, load the live site, accept cookies, trigger the form event, and
prove GA4 received it with the realtime report API.
Report: GA4 measurement ID, GTM container ID and published version, events
tracked, Search Console status, and the key's name in my vault.Going live on your domain
Launch this site on [DOMAIN]. Keep the workers.dev address working as staging.
1. Attach [DOMAIN] and www.[DOMAIN] to the production Worker as custom domains.
Pick one as the main address ([DOMAIN] without www, unless I say otherwise)
and redirect the other to it.
2. Make sure HTTPS is forced everywhere.
3. Then run a full launch check on the live domain and fix anything that fails:
- Every page loads, no broken links, no 404s from the navigation or footer
- Every page has a unique title and meta description, one H1, and a
proper Open Graph image for link previews
- sitemap.xml and robots.txt are correct for the live domain, and staging is
set to noindex so Google doesn't index it twice
- Favicon and app icons exist
- Images are properly sized and lazy loaded
- Mobile layout works at 375px wide, no horizontal scrolling
- Keyboard navigation and colour contrast pass basic accessibility checks
- Lighthouse scores for performance, accessibility, best practices and SEO,
on mobile. Fix anything under 90.
- Contact form sends, email arrives, spam protection works
- Analytics fires on the live domain
- Structured data (schema.org LocalBusiness or Organization) with my real
business name, address, phone and hours: [DETAILS]
4. If Search Console is set up, submit the live sitemap.
Report what you fixed and the final Lighthouse scores.Before launching, this domain currently hosts my old site. Crawl it (and its
sitemap if it has one), list every URL, and set up 301 redirects from each old
URL to the closest matching page on the new site. Nothing that used to exist
should 404.How do I change my site after it's live?
Update the opening hours on the contact page and in the footer to:
Tue to Sat 8am to 4pm, closed Sun and Mon. Update the structured data too.
Deploy to staging, send me the link, and deploy to production after I say yes.Add a new menu item: "Lemon Pistachio Loaf", $14, photo is in
~/Downloads/loaf.jpg. Match the style of the existing items.I want to add a catering section: a landing page, three package tiers, and an
enquiry form that asks for date, guest count and dietary needs. It should feel
like the rest of the site, not bolted on. Look at how the menu page is
designed and push it a bit further. Staging first.[Describe what's wrong, where, and what you expected.]
Figure out why before you change anything, fix the cause not the symptom, and
tell me what it was in one sentence.On a phone, swipe left and right to turn pages.