ship-email
Skill0 starsChanged 5 months agoMITView on GitHub
Turns a shipped release into audience-tailored announcement assets — a customer email (themed HTML + plain-text), an in-app "What's new" modal snippet, and a short social post — all in the product's brand voice, written separately for homeowners vs. investors vs. crew (or any custom audience). Reads docs/SHIPPING-LOG.md for what shipped and docs/brand.json for colors + fonts, and writes everything to docs/announcements/<version>/. Use when the user wants to announce a release, write a launch or update email, a "what's new" email or modal, release-announcement copy, a customer/investor update, or a social post for a feature — or says "announce this", "email about the release", "tell our customers what shipped", "what's new email". Part of the /ship-* pack.
In this repository13 other files it gives its agents.
- logo-packSkill
- screenshot-captureSkill
- ship-brandSkill
- ship-demoSkill
- ship-faqSkill
- ship-feedSkill
- ship-helpbotSkill
- ship-onboardingSkill
- shipping-logSkill
- ship-pitchSkill
- ship-pressSkill
- ship-promoSkill
- user-guide-builderSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 2 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 47
If there's no shipping log yet, run /ship-changelog first — that's the upstream source of truth.
- Distinctive: line 53
Never guess the version or invent history.
- Distinctive: line 66
Do not fabricate features.
- Very specific: line 74
Ask if unstated. Read references/audiences-and-voice.md — it has a profile (lead value, vocabulary, proof, CTA, tone) for homeowner, …
- Very specific: line 81
Read the brand voice from docs/brand.json (tagline, any voice/tone fields) and honor every brand rule (e.g.
- Very specific: line 84
Read the target version's body from docs/SHIPPING-LOG.md (the scan gave you its location).
- Very specific: line 91
Write plain text in every field (the renderer escapes HTML for you).
- Very specific: line 123
Evidence-based: Every claim traces to a real entry in docs/SHIPPING-LOG.md.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Ship Email
Purpose
A release is "done" in git but not in the world until the people who care hear about it — in their terms. This skill takes one version's shipping-log entry and re-tells it for a chosen audience, producing four ready-to-send assets:
| Asset | File | What it's for |
| Customer email (HTML) | email.html | Branded, email-client-safe HTML (table layout). |
| Customer email (text) | email.txt | Plain-text fallback — deliverability + accessibility. |
| In-app "What's new" | whats-new.html | Drop-in modal snippet, themed via CSS variables. |
| Social post | social.txt | Short post + char count + hashtags + link. |
The point is audience tailoring: a homeowner, an investor, and a crew lead get genuinely different copy from the same release — not the same blast with the names swapped.
Part of the /ship-* pack
This skill consumes what the rest of the pack produces and shares the docs/VERSION anchor:
docs/VERSION ← single source of truth (semver)
docs/brand.json ← colors + fonts (brand-as-data) — themes every output
docs/SHIPPING-LOG.md ← what shipped, per version (this skill's INPUT)
├─ ship-changelog (shipping-log) → writes the shipping log this skill reads
├─ ship-guide (user-guide-builder) → "how it now works" (link it in the email)
├─ ship-screenshots (screenshot-capture) → feature art you can attach/reference
├─ ship-logos (logo-pack) / ship-brand → establish brand.json tokens + the wordmark
└─ ship-promo → a promo-video plan for the same releaseIf there's no shipping log yet, run /ship-changelog first — that's the upstream source of truth.
Workflow
1. Discover what exists (always first)
Never guess the version or invent history. Run the bundled scan from the repo root:
node "<skill-dir>/scripts/scan-release.mjs" --json # or omit --json for a readable summary
node "<skill-dir>/scripts/scan-release.mjs" --version 0.8.0 # announce a specific versionIt reports: the resolved version (from docs/VERSION or --version), the matching
docs/SHIPPING-LOG.md entry and its body, whether docs/brand.json exists, any prior
announcements under docs/announcements/, and a warnings[] list. Read it before acting.
Handle what it tells you honestly:
- No shipping log / no matching entry → run
/ship-changelog(or ask the user for the notes). Do not fabricate features. - No
docs/brand.json→ the renderer falls back to a neutral, non-purple theme; offer to run/ship-logosor/ship-brandto set real tokens. Never invent a palette. - Target folder already populated → confirm before overwriting; or render an audience-suffixed variant alongside (see the schema reference).
2. Pick the audience(s)
Ask if unstated. Read references/audiences-and-voice.md — it has a profile (lead value,
vocabulary, proof, CTA, tone) for homeowner, investor, and crew, plus how to derive a custom
audience from the same four moves. One audience per content file. If the user wants several,
produce one content file (and one set of assets) per audience — don't blend them.
3. Load the voice + the real release content
- Read the brand voice from
docs/brand.json(tagline, anyvoice/tonefields) and honor every brand rule (e.g. no purple, ever). Match the product's existing register, not a generic newsletter voice. - Read the target version's body from
docs/SHIPPING-LOG.md(the scan gave you its location). Translate, don't transcribe: turn each shipped bullet into the chosen audience's stakes.
4. Write the content file
Copy assets/content.example.json to docs/announcements/<version>/content.json and fill it for
the audience. Schema + a full input→output worked example: references/content-schema-and-example.md.
Write plain text in every field (the renderer escapes HTML for you). Aim for 2–5 items[],
benefit-first; a specific, ≤55-char subject; a preheader that complements (not repeats) it.
5. Render the assets
node "<skill-dir>/scripts/render-email.mjs" \
--in docs/announcements/<version>/content.json \
--outdir docs/announcements/<version> \
--brand docs/brand.jsonWrites email.html, email.txt, whats-new.html, social.txt. The script themes everything from
brand.json. Because email renders on a light card, it keeps the brand's accent/brand color but
forces body/heading/muted ink to a readable dark value whenever a brand token is too light for a
white background (the common dark-theme case — e.g. a light text token with no surface), so
copy is never near-white-on-white. It prints a summary: theme colors, any ink it had to swap, the
social char count, and warnings if items[] is empty or unsubscribeUrl is missing.
6. Review against the quality bar + report
Open email.html to eyeball it (it's a single self-contained file). Run the anti-generic checklist
in the voice reference. Then report to the user: the version + audience, the four file paths, the
subject line, and the social char count. If anything was staged/un-merged, say so plainly — don't
imply staged work is live. Offer to render another audience, or to run /ship-promo for a video.
Quality bar
A draft ships only if all of these hold:
- Audience-true. A homeowner email and an investor email for the same release read differently — different lead value, vocabulary, proof, and CTA. If you could send one copy to all three, redo it.
- Evidence-based. Every claim traces to a real entry in
docs/SHIPPING-LOG.md. No invented features, no invented metrics, no implied security breach. Unclear impact → inspect or omit. - Benefit-first, jargon-free. Lead with what the reader can now do, not the implementation. "Refactored finance module" → "See exactly where your budget is going."
- Specific subject. Passes the ≤55-char, benefit-first test; would NOT fit any other product.
- Honest about ship status. Un-merged/un-deployed work is "rolling out", never "live."
- On-brand + safe HTML. Themed from
brand.json(never purple by default);email.htmlandwhats-new.htmlare self-contained, themeable via:root/scoped CSS variables, and use nobackdrop-filterand no SVGfeTurbulence(both hang renderers / get stripped by mail clients). - Deliverable. A plain-text part exists alongside the HTML; bulk mail includes an unsubscribe.
Cross-project notes
- Generic by design. Nothing is hardcoded to one app. The scan probes common locations
(
docs/VERSION,docs/SHIPPING-LOG.md/CHANGELOG.md,docs/brand.json) and degrades gracefully when they're absent. Works in any repo. - Tool-agnostic delivery. This skill produces files; it does not assume an ESP is installed.
To actually send, hand
email.html+email.txtto whatever the user has via an adapter — paste into Mailchimp/Resend/Customer.io/SendGrid, attach to a Gmail draft, or commit the modal snippet into the app. Reference those tools; never assume them. - Re-runnable. Regenerate any time the release notes or brand change — outputs are deterministic
from
content.json+brand.json.
Files in this skill
scripts/scan-release.mjs— discovery: resolves version, finds the shipping-log entry + brand, flags prior announcements and missing inputs. Dependency-free. Run it first.scripts/render-email.mjs— renders the four assets fromcontent.json, themed bybrand.json. Dependency-free, email-client-safe, no purple / nobackdrop-filter/ nofeTurbulence. Forces body/heading/muted ink to a readable dark value when a brand token is too light for the white email card (dark-theme brands), and warns on emptyitems[]or a missingunsubscribeUrl.assets/content.example.json— ready-to-edit content file (the worked example's input).references/audiences-and-voice.md— audience profiles, the four tailoring moves, brand-voice rules, and the anti-generic + subject-line checklists.references/content-schema-and-example.md— thecontent.jsonschema and a full input→output worked example for all four assets.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

