Static site ship
Hermesskills — a curated marketplace & repository of AI-agent skills. OpenClaw-compatible catalog at /catalog/v1/skills.json. 30% of commissions fund public-good AI.
npx -y skills add Pdbjork/hermosskills-site --skill static-site-shipAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 29 days oldThe repository was created 29 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Ship a redesigned (or new) static website end-to-end on a VPS — design the site, build it, validate it, deploy to a static mirror under /var/www or equivalent, smoke-test nginx (with the right Host header) AND the backend capture service, write a handoff report, and ping the user. Load when the user asks to "redesign", "build", "ship", "deploy", or "publish" a website, especially a research/education/foundation/nonprofit public-facing site where privacy-by-default, consent-first forms, and "no false claims" discipline matter. Skip for SPA / SSR app deploys (Next.js, Vite, etc.) — those have their own build pipelines. Skip for hosted-platform-only deploys (Vercel/Netlify/Cloudflare Pages with no VPS mirror).
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.2 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it
Static Site Ship
Ship a redesigned or new public-facing static website end-to-end. The loop is: design → build → validate → deploy to VPS mirror → smoke-test nginx + backend → handoff report → user ping.
This skill assumes the deliverable is a plain-HTML/CSS/JS site (no build step) deployed to a VPS static mirror under /var/www/<domain>/ (or equivalent) served by nginx. The mirror may or may not be the production host — sometimes it's a fallback while Vercel/Netlify handles the live domain.
When to load
Load this skill when the user asks to:
- redesign a foundation / nonprofit / research / education / public-good website
- publish a new landing page, manifesto page, or project site
- ship a privacy-by-default site (consent-first forms, no third-party tracking)
- deploy static HTML/CSS/JS to a VPS mirror at a known domain
- produce a handoff report for an operator to redeploy on Vercel/Netlify
Do NOT load for: SPA / SSR app deploys (use the framework-specific skill); pure-design mockups without deploy (use claude-design); token-spec authoring (use design-md).
Operating loop (10 steps)
-
Read the brief completely. Brand identity, mission, values, strategic themes, palette, typography, constraints. Note any "do not claim X" rules (e.g. "do not claim 501(c)(3) until incorporated").
-
Survey what already exists on the VPS and in any related repo. Read the brand file, the current site files, the express/server capture service if any, the nginx config for the domain, and any archives. Build a mental model of the deploy topology BEFORE writing any HTML.
-
Confirm scope and tone with the user only if truly ambiguous. If the user has given enough direction (palette, themes, constraints), do NOT ask an A/B/C menu — ship it. Default behavior is to ship. Ask only when the gap materially changes the deliverable.
-
Design the system, then build the pages.
- Palette + type stack + spacing + radii as CSS variables in one
gbf.css-style file. - Logo mark as inline SVG (no raster). Sacred-scientific / geometric / emblem-style works well for foundation sites.
- 7–9 pages: index, about, themes (or strategic areas), participate, interest form, thanks, faq, privacy, 404.
- "Forming" / "seeks" / "explores" language until the org is formally established. Avoid: 501(c)(3) claim, named board members, confirmed donors, named partners, confirmed events, tax-deductible status. Use explicit "not tax-deductible" disclaimers where relevant.
- Palette + type stack + spacing + radii as CSS variables in one
-
Preserve or improve the existing interest-capture flow. Posts JSON to
/api/interest(Vercel/serverless). Falls back toPOST /interestfor VPS express capture. Use consent-first (requiredconsentToContactcheckbox), hidden honeypot for bots, no third-party tracking, no analytics pixels. -
Validate locally before deploy. Run a script that:
- walks every
href=andsrc=and confirms internal targets resolve - confirms all
var(--xxx)CSS references are defined - confirms every form-field name in the HTML is read by the JS handler
- audits text for forbidden claims (501(c)(3), named donors, tax-deductible-as-fact, etc.)
See
references/validation-script.mdfor the template.
- walks every
-
Deploy to the VPS mirror. Backup the existing mirror first, then
cp -athe new tree over it. Preserve any files you don't know about (find … -mindepth 1 -deleteis wrong if there's something custom). -
Smoke-test the live mirror — the gotcha: nginx serves name-based virtual hosts, so
curl http://127.0.0.1/...returns the default vhost (404), not the mirror's vhost. Always pass-H "Host: <domain>":curl -sS -H "Host: guardianbuilder.org" \ -o /dev/null -w "%{http_code}\n" http://127.0.0.1/Walk every page and every asset. Then test the backend capture service directly (port from nginx config
proxy_passline):curl -sS -X POST http://127.0.0.1:<port>/api/interest \ -H "Content-Type: application/json" \ -d '{"name":"...","email":"...","interestAreas":[...],"consentToContact":true}'See
references/deploy-ritual.mdfor the full sequence with expected outputs. -
Build the deployable package. A clean
dist/tree (HTML + css/js/assets, no dev-time README) AND a zipped archive. Use Python'szipfileifzipCLI is missing. -
Write the handoff report to
/root/HermesVault/<Project>-Redesign-YYYY-MM-DD.md. Sections: what shipped (file table with bytes), design choices, validation results, deployment status, blockers, next actions for the user. End with a short Telegram-style summary in the chat reply.
Status-check discipline (most important pitfall)
Never trust a session_log / session_search snippet as evidence of on-disk state. The session log can be truncated mid-stream; the agent may have shipped far more than the last visible tool call shows. Before answering any "where are we?" or "what's the status?" question:
ls -la <project-dir>to see actual files and timestamps.wc -c <project-dir>/*.htmlto confirm file sizes.- Cross-check against the session log; flag mismatches openly.
If the on-disk state is further along than the session log shows, say so and correct your prior summary. Don't double-down on the stale read.
Also: when the user asks "where are we?" mid-stream, don't ask an A/B menu of next actions. State the verified status, name what's left, and propose to ship. The user picks "ship it now" by default.
Pitfalls
- Nginx Host header gotcha —
curl http://127.0.0.1/returns the default vhost, not yours. Always-H "Host: <domain>"for local smoke tests. - Backup the mirror before
find -mindepth 1 -delete— there may be files the redesign doesn't know about.cp -afirst, then rebuild. - Form-field drift — the HTML form names and the JS
data.get(...)calls must match. Run a consistency check. var(--xxx)drift — defined-but-unused is fine; used-but-undefined is a bug. Scan with a regex.- False-claim bleed — drafting in foundation/education tone invites invented credentials. Audit against a forbidden-phrase list and require explicit "not Y" disclaimers.
- JS reads multi-value fields with
data.getAll(), notdata.get()— easy to miss in the field-consistency check. zipCLI is often missing on minimal VPS images. Use Python'szipfilemodule./api/*proxy_pass — nginx forwards to the express service on a local port. Theproxy_passline in the nginx site config tells you the port; smoke-test that port directly to verify the backend works independent of nginx.
Templates
templates/interest-form.html— consent-first interest form scaffold (honeypot, areas fieldset, consent checkbox, status region, privacy note). Copy and rename fields.templates/interest-form.js— submit handler with/api/interestprimary +/interestfallback, honeypot trap, status states.
References
references/deploy-ritual.md— the exact deploy + smoke-test sequence with real shell output examples (Host header, nginx config discovery, backend round-trip).references/validation-script.md— the Python validator that walks links, vars, and form fields.references/handoff-report-template.md— the report skeleton used for/root/HermesVault/<Project>-Redesign-YYYY-MM-DD.md.
Verification before claiming done
The site is NOT shipped until ALL of the following are true:
- All planned pages exist on disk at the expected sizes.
- Validator reports zero broken links, zero missing assets, zero CSS var drift, zero false claims.
- VPS mirror returns HTTP 200 for every page and every asset (with the correct Host header).
- Backend capture service returns success for a smoke-test POST.
- Handoff report exists at
/root/HermesVault/.... - Telegram-style summary in the chat reply.
If any one of those fails, say so explicitly. Don't paper over with "should work" claims.
Final response shape
Short. Plain text. No markdown headers in the chat reply — this is a CLI terminal.
Include:
- one-line status ("shipped" / "blocked on X" / "degraded: Y works, Z doesn't")
- the deployable artifact path
- the handoff-report path
- any next action that needs the user