HTML email skills for Claude Code, Codex & Cursor

Your preview isn’t the inbox.

Your agent says the email looks great, then the Gmail app turns the header pale and the logo never loads. The Email Pack makes it prove the email against the built output and a real send, whatever sends it: Postmark, SureContact, Supabase Auth, WordPress, FluentCRM or anything else that sends custom HTML email.

$39. Every pack, now and later: $149.

Works with

  • Claude Code
  • Codex
  • Gemini CLI
  • Cursor
  • Windsurf
  • Aider

Fit check

Is this for you?

It’s for you if

  • An AI agent builds the emails your product or your clients send.
  • An email looked right in the preview, then broke in Gmail, Apple Mail or dark mode.
  • Your app sends sign-up, login or password emails through Supabase Auth.

You’ll need

  • An AI coding agent: Claude Code, Codex, Cursor or Gemini CLI.
  • Node.js 18 or newer, and Playwright for the checks that render in a browser.
  • For Supabase’s emails, a Supabase access token you supply.

Skip it if

  • You want a tool that sends email. This builds and checks it; it never sends.
  • Your emails are made only in a drag-and-drop editor, never as HTML.

Sound familiar?

Has this ever happened to you?

Tap every one you’ve lived through.

Nothing yet? Check your phone in dark mode.

Why it keeps happening

It can’t see the inbox.

An agent checks email where it can see it: the source, and a browser preview in light and dark. Apple Mail and the Gmail app repaint colors on their own, and every image loads from your host. It isn’t lying. It checked the preview and reported on the inbox.

So you become the test inbox. You send it to your phone, switch to dark mode, find the header gone gray, and explain it again. And a reviewer who sees a missing logo reads it as a broken email, not a missing deploy.

What the code claimed

The generator shipped color-scheme: light only, with a comment claiming it prevented inversion.

What arrived

macOS Mail inverted it anyway. The #0A0D12 header band arrived mid-gray, with a system-link-blue wordmark.

Proven in macOS Mail on 2026-08-30. The tag and its comment kept shipping for nearly two weeks after.

The fix

Make it prove the email.

The Email Pack is two skills your agent loads and seven scripts it runs. The guards read the built email, not the source, and the Supabase build refuses to write a single file that would break in a real inbox.

  1. Dark mode that holds

    Readable in light and dark mode, in Apple Mail and the Gmail app. The header band is carried as an image, so an inverting client can’t repaint it, and the body inverts with its text.

  2. Guards that can fail

    Four guards check the logo, the header lock, contrast in both schemes and every image, each with a self-test that must catch a planted defect.

  3. One generator, one design

    All thirteen Supabase Auth emails come from one file in your repo, pushed with a partial update that changes nothing else, then read back. Your CRM’s drips, Postmark templates and WordPress’s account mail can come from the same generator, so they share one design.

Proof

Three runs, straight from the zip.

Three runs of the shipped download, from a fresh unzip. Two guards catch every defect planted in their self-tests, and the Supabase generator refuses a brand color as link text and writes nothing.

[ Range card ] // What we aimed for, what came back
  1. [ Shot 01 ]

    band-lock-guard.mjs --selftest

    Aimed: planted header defects and correct fixes; each must land as designed

    ok live text in the band: refused

    ok accent border on a locked button cell: refused

    ok the locked frame pattern, label as an image, passes: passed

    37 cases behaved as designed

    Landed where it was aimed // exit 0

  2. [ Shot 02 ]

    build-email-templates.mjs, link #C8A84B

    Aimed: a brass brand color as link text; the build must refuse it

    build-email-templates: refused, nothing written.

    - light: link on card is 2.29:1 (#C8A84B on #FFFFFF), needs 4.5:1

    Landed where it was aimed // exit 1

  3. [ Shot 03 ]

    hosted-asset-guard.mjs --selftest

    Aimed: missing and fake images on a local server; each must be refused

    ok 404 refused

    ok 200 HTML from a catch-all refused

    ok zero-byte image refused

    18 cases behaved as designed

    Landed where it was aimed // exit 0

Who it’s for

Built for people who ship email with agents.

For
Developers, freelancers and small studios who have an AI coding agent (Claude Code, Codex, Cursor, Gemini CLI) build the HTML email their product or their clients send.
Best fit
Branded email that has to hold up in dark mode, sent by a CRM, Postmark, WordPress or Supabase Auth, where an agent says “done” from a preview.
Works with
Any email provider or CRM, since the checks read the built email, not the service that sends it. Every script needs Node 18 or newer, and the contrast sweep’s browser pass needs Playwright. The push needs a Supabase access token you supply.
Not for
Sending itself: the pack builds and checks email but never sends one. Its one push script is for Supabase Auth; for Postmark, WordPress mail and a hosted store, it has written guides, not scripts.

Every rule here was paid for.

Two skills, one job each. Start with the craft, which works with any sender, and add the Supabase transport if Supabase sends your auth mail.

Explain it
  1. polarity-sweep.mjs --selftest

    ok browser: unhooked chip fails in the dark: 1.05:1, 1.05:1

    ok browser: live text inside a locked band fails only in the Gmail pass: gmail-sim,gmail-sim

    selftest behaved as designed

    Pass

    The email survives the inbox

    Dark mode that holds in Apple Mail and in the Gmail app, a logo that sits flush on its header, text you can read in both color schemes, and every image live on your host before the first test send.

    • html-email
  2. build-email-templates.mjs (guards not copied)

    - scripts/band-lock-guard.mjs is missing. Copy it (and lockup-guard.mjs, which it imports) from the html-email skill

    - scripts/hosted-asset-guard.mjs is missing. Copy it from the html-email skill

    Fail

    Auth mail from the same generator

    The thirteen emails Supabase Auth sends, from sign-up to security notices, come from the same generator as the rest of your mail. The build refuses anything that would break in an inbox, and the push changes those templates and nothing else.

    • supabase-email-templates

What’s in the pack

Both skills, each with its job in one line. The craft styles email for any sender, with guides for Postmark, WordPress mail and a hosted store; the Supabase transport builds and pushes your auth mail.

  • html-email

    Email that survives inboxes

    Dark mode, a flush logo, readable contrast and live images, for any sender, proven on the built email and a real send.

  • supabase-email-templates

    Supabase Auth emails

    All thirteen from one generator, pushed with a partial update and read back field by field.

Where it lands, and what it proves.

One download: two skills for Claude Code, the same instructions to paste into any tool that reads AGENTS.md, and checks that prove the built email, its images and your Supabase templates are what you think they are.

email-pack/

  • .claude-plugin/
    • plugin.json
  • ci/
    • email-skills.mjs
    • pack.json
    • skill-frontmatter.mjs
    • verify.sh
  • CHANGELOG.md
  • install.sh
  • LICENSE
  • README.md
The files in email-pack/, as the download ships them.

Install it, then prove the pack works

install.sh copies both skills into ~/.claude/skills/, or you can load the whole folder as a Claude Code plugin. It copies, never links, and moves an existing folder aside with a timestamp instead of overwriting it.

ci/email-skills.mjs is the pack’s own proof. It runs every guard’s self-test, builds all thirteen Supabase templates in a throwaway folder, holds each to the guards, and plants a failing link color the build must refuse.

Every guard can fail on purpose.

A check that has never failed is a green light with extra steps. Each guard here ships a self-test that plants the defects it exists to catch. Run those first: if a guard calls a planted defect fine, don’t trust it on your real email either.

Two new checks found real bugs on their first runs. One was in our own generator.

  1. A border on the buttonIn twelve of our thirteen Supabase templates. Gmail repaints borders, so the edge is now a locked frame, and the band lock refuses a border.
  2. A tile that 404’dIn six built emails. The band lock only looked at the band, so the image guard now requests every URL, whatever its class.
Show the commands and what they print

Run the self-tests first

Shell
# run from the project you are checking, with the Email Pack unzipped at /path/to/email-packnode /path/to/email-pack/skills/html-email/scripts/lockup-guard.mjs --selftest   # must refuse a logo baked one digit off the bandnode /path/to/email-pack/skills/html-email/scripts/polarity-sweep.mjs --selftest   # must fail a code chip with no dark rule, in the darknode /path/to/email-pack/skills/html-email/scripts/hosted-asset-guard.mjs --selftest   # must refuse a missing image served as a 200 web pagecd /path/to/email-pack && node ci/email-skills.mjs   # must refuse a brand color as link text and write nothing

We call these negative controls: a planted defect the check has to fail on. The self-tests plant a logo one digit off its band, a code chip with no dark rule and a missing image served as a 200 page, and each must go red. The harness builds all thirteen Supabase templates, then must refuse a planted link color.

A guard that has never refused anything is not evidence.

Works with the agent you already use.

The skills are plain text files your agent reads. The scripts are short, commented, and run only on your computer.

  • Claude Code
  • Codex
  • Gemini CLI
  • Cursor
  • Windsurf
  • Aider
Shell
claude --plugin-dir /path/to/email-pack

The skills need nothing at all. Every script runs on Node 18 or newer alone, except the contrast sweep’s browser pass, which needs Playwright in your project, and the label drawer, which needs Playwright and sharp:

Shell
npm i -D playwright sharp && npx playwright install chromium

Everything the scripts touch

Your built email
The guards read the HTML and images you built, on your disk, and say what they found.
Your image host
One request per image URL in your built email, to prove each is live and really an image. The sweep’s browser loads them too. Static mode requests nothing.
Your Supabase project
Only when you run the push, with a token you supply. A dry run by default; it sends only the fields it built and reads each one back.
The network
No tracking, no license check, nothing phoning home. Nothing else sends anything anywhere.

Short scripts with comments, and nothing compressed into a blob. A product that says “don't trust a report you can't read” has to be readable itself.

One payment. Yours forever.

All-Access Bundle

Every pack, now and later.

Spotter Round, the Agent Setup Pack, the Email Pack, the WordPress Pack, the App Stack Pack and the Campaign Tracker Pack, plus every pack added after them, each with every future version.

$149.

The six separately: $234

Get every pack — $149

Questions before you buy.

Does this work with Codex, Cursor, Gemini CLI, Aider, Windsurf?

Yes. The skills are plain text files and the checks are plain Node scripts, so any agent can run them. Claude Code loads the skills from its skills folder. Codex, Cursor and the rest take a skill pasted into your repository's AGENTS.md, and Gemini CLI reads that file once its settings name it.

Does it work with FluentCRM?

Yes. FluentCRM sends the custom HTML you give it, and the method is the same for any CRM, in WordPress or outside it, that sends custom HTML templates: the checks read the email you built, not the service that sends it. A FluentCRM guide with a worked example is in the pipeline.

I don’t use Supabase. Is it still for me?

Yes, if you send HTML email. html-email is the craft and sends nothing, so it works with whatever sends your mail, and its guides cover Postmark, WordPress’s own account mail and a hosted store’s emails. supabase-email-templates is the transport for Supabase Auth. If you send through SureContact, the App Stack Pack’s SureContact skill sends the email you build here, byte for byte.

Why not just use supabase config push?

It builds your whole [auth] section from config.toml, fills every key you didn’t declare with a local default, and sends all of it. A file that only declares templates overwrites your Site URL (with http://127.0.0.1:3000), redirect list, rate limits and MFA settings, and its confirmation prompt defaults to yes when it isn’t attached to a terminal. The push here sends only the fields it built, then reads each one back.

Can’t I just check Gmail’s dark mode in a browser?

No. A browser’s dark mode shows what a client that honors your color scheme does, and the Gmail app repaints colors on its own. polarity-sweep.mjs --gmail-sim applies a model of that repainting, measured in the app, to every color it reads, but the real test is still a send to a Gmail address, read in the app with the phone in dark mode.

Does it send anything anywhere?

No tracking, no license check, no analytics, nothing phoning home. The image guard, and the contrast sweep’s browser, request only the image URLs in your built email. The push talks to your Supabase project only when you run it, with a token you supply. You can confirm that yourself: the scripts are short enough to read.

How do I know the checks themselves work?

Run each guard’s --selftest: it plants the defects the guard exists to catch, and fails if one slips through. ci/email-skills.mjs runs all four, builds the thirteen Supabase templates as a buyer would, and plants a failing color the build must refuse. That's the answer we would want from anybody selling us this.

What do updates look like?

Numbered downloads with a list of what changed. Every future version of the Email Pack is included at no charge, so you never pay for a new version, and you are never forced to update.

Can I use it for client work?

Yes — that's what it's for. One company covers every project that company delivers.

Refunds?

Fourteen days, no questions. A product about checking things that argued with you over a refund would be a poor advertisement for itself.

Stop taking its word. Check the inbox.

Sold separately

Five more packs. One job or stack each.

Each pack is sold on its own and ships its own checks, the same way this one does.

Spotter Round$39
Agent Setup Pack$39
WordPress Pack$39
App Stack Pack$39
Campaign Tracker Pack$39
All-Access Bundle$149

Spotter Round

$39

The layout, the pixels, the speed and the live deploy: your agent’s work, proven before it says it’s done.

1 / 6