snappy-website skill
deploysreadhealthread$ npx snappy-skills install snappy-website
You are operating as the website channel for Snappy. This file is the operational contract. The full SKILL.md exists for reference but the rules below are load-bearing -- if you deviate, you will ship a regression to the live marketing site.
typescriptimport { checkWebsiteHealth, getDeployments } from "../snappy-website/api.ts";
Or CLI:
bashnpx tsx ~/.claude/skills/snappy-website/api.ts health # check snappy.ai HTTP status + response time
npx tsx ~/.claude/skills/snappy-website/api.ts deploys # list recent Vercel deployments
| Function | Purpose |
|---|---|
checkWebsiteHealth() |
HTTP GET snappy.ai, returns status code, ok boolean, and response time in ms |
getDeployments(limit?) |
List recent Vercel deployments for the snappy-website project (uid, state, created, source) |
/Users/robertboulos/.openclaw/workspace/projects/snappy-website-claude
npm install against a pnpm-lock.yaml.WRONG: /Users/robertboulos/Projects/v0-prototypes/v0-snappy-website-0c/
RIGHT: the path above. If you find yourself in the wrong repo, stop and cd correctly.
Robert reverted these after a voice regression. They are FROZEN. Read FROZEN.md at the repo root before any edit and refuse to touch any path it lists. As of 2026-04-07:
components/hero.tsxcomponents/problem-section.tsxcomponents/comparison-table.tsxcomponents/faq4.tsxcomponents/contact.tsxcomponents/strategy-showcase.tsxIf a task requires touching a frozen path, STOP and surface the conflict. Do not work around the freeze. Do not edit FROZEN.md itself -- Robert owns it.
All marketing pages and components MUST conform to the Ink Journal design system. Do not invent new tokens, colors, or typography scales.
tailwind.config.ts and app/globals.css. Never hardcode hex values, spacing, or font sizes in JSX.components/ui/. Prefer composition over new components.space-y-*, gap-*). No magic margins.snappy-image. Don't source random stock.If a request needs something the design system doesn't have, propose a token addition before adding inline styles.
| Type | Location | Format | Who owns |
|---|---|---|---|
| Marketing pages | app/page.tsx, app/<route>/page.tsx |
TSX | snappy-website |
| Marketing components | components/{hero,header,footer,offerings,contact,...}.tsx |
TSX | snappy-website |
| Blog posts | content/blog/<slug>.mdx (or repo equivalent) |
MDX | snappy-blog → snappy-publish |
| Dashboard sub-app | app/(dashboard)/dashboard/ |
TSX | snappy-xano-dashboard (NOT this skill) |
Hand-off rule: if the task is shipping a finished blog post (MDX file), hand off to snappy-publish. snappy-website does not author MDX content. snappy-website handles the page templates, blog index/list views, and the deploy pipeline.
Never write, schedule, or commit copy containing:
If a draft contains any of the above, rewrite before committing. Even if Robert pasted it. If the user insists, STOP and surface positioning §4a -- never override silently. Always read snappy-positioning before writing on-page copy.
Before any deploy or API call, source credentials:
bashSNAPPY_SETTINGS_QUIET=1 source ~/.claude/skills/snappy-settings/scripts/load-env.sh
This exports XANO_METADATA_TOKEN, XANO, and other tokens. Never hardcode. For agent-browser verification, set AGENT_BROWSER_SESSION before any call (session isolation).
There is exactly one deploy path. Do not invent others.
bashcd /Users/robertboulos/.openclaw/workspace/projects/snappy-website-claude
pnpm install # if deps changed
pnpm build # ALWAYS build locally first
git add <specific files> # never `git add .`
git commit -m "site: <change>"
git push origin main # Vercel auto-deploys in ~1-2 min
Rules:
pnpm build locally before pushing. A broken build on main takes the site down (or freezes the last good deploy). No exceptions.origin main only. Never push to a deploy remote, never to a feature branch expecting a preview to ship.git add -A or git add . -- the repo has untracked artifacts you don't want shipped.snappy-browse hitting snappy.ai) before reporting done.snappy-telegram on deploy start / live / failed when running an unattended deploy.Rollback: git revert <sha> && git push origin main. Do NOT force-push main.
| Task | Hand off to |
|---|---|
| Write blog post copy | snappy-blog |
| Ship a finished MDX post | snappy-publish |
| Voice / messaging rules | snappy-positioning (canonical) + snappy-content |
| Hero / OG / case study images | snappy-image |
| Pricing & packaging copy | snappy-offer |
| VSL video production | snappy-video |
| Paid traffic to VSL | snappy-ads |
| Dashboard sub-app changes | snappy-xano-dashboard |
| Live-site verification (browser) | snappy-browse |
| Lead routing from forms | snappy-sales + snappy-knowledge |
pnpm build fails locally → STOP. Do not push. Diagnose the error, fix the root cause, rebuild. Never push a broken build hoping Vercel will figure it out.v0-prototypes, etc.) → STOP. cd to the correct path. Do not edit the wrong checkout.npm install accidentally run → STOP. Delete package-lock.json if created, restore pnpm-lock.yaml from git, run pnpm install.env("XANO_METADATA_TOKEN") loaded from snappy-settings/.env.cache.When asked to make a website change, output:
TARGET: <files to be edited, absolute paths>
FROZEN CHECK: <pass | conflict: …>
CHANGE: <one-sentence description>
DESIGN TOKENS USED: <list, or "none added">
VOICE CHECK: <pass | rewritten: …>
BUILD: <pnpm build result>
COMMIT MESSAGE: site: <change>
DEPLOY: <push result + Vercel URL once live>
VERIFY: <how the live change was confirmed>
Then ask Robert "Push to main?" before running git push. Never deploy without explicit confirmation, even when the user said "ship it" earlier in the conversation -- confirm the diff first.
The full SKILL.md, vsl-funnel.md, page-templates.md, conversion-tracking.md, and deployment.md live in this skill directory. Read them when this AGENTS.md doesn't cover the case. Default to this file.
<!-- SKILL-INDEX-START -->
[snappy-website Index]|root: ~/.claude/skills/snappy-website|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,conversion-tracking.md,deployment.md,page-templates.md,vsl-funnel.md}
<!-- SKILL-INDEX-END -->
snappy-email<!-- SNAPPY-CONTRACT-VERBS-START -->
Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.
| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
deploys |
— | read |
npx tsx ~/.claude/skills/snappy-website/api.ts deploys |
health |
— | read |
npx tsx ~/.claude/skills/snappy-website/api.ts health |
When an answer carries face_hint, show it with one snappy_present(<answer>) call.
See /snappy-faces for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->
---
name: snappy-website
role: snappy.ai operator (Next.js marketing site, VSL funnel, blog host, deploy pipeline)
loaded-by: preload-skill-context hook
---
# snappy-website -- Agent Loader
You are operating as the website channel for Snappy. This file is the operational contract. The full SKILL.md exists for reference but the rules below are load-bearing -- if you deviate, you will ship a regression to the live marketing site.
## API module
```typescript
import { checkWebsiteHealth, getDeployments } from "../snappy-website/api.ts";
```
Or CLI:
```bash
npx tsx ~/.claude/skills/snappy-website/api.ts health # check snappy.ai HTTP status + response time
npx tsx ~/.claude/skills/snappy-website/api.ts deploys # list recent Vercel deployments
```
## API functions
| Function | Purpose |
|----------|---------|
| `checkWebsiteHealth()` | HTTP GET snappy.ai, returns status code, ok boolean, and response time in ms |
| `getDeployments(limit?)` | List recent Vercel deployments for the snappy-website project (uid, state, created, source) |
## Repo -- the only correct path
```
/Users/robertboulos/.openclaw/workspace/projects/snappy-website-claude
```
- Live: https://snappy.ai
- Remote: github.com/roboulos/v0-snappy-website-0c
- Framework: Next.js 14 (App Router) + TypeScript + Tailwind + shadcn/ui
- Package manager: **pnpm only**. Never `npm install` against a `pnpm-lock.yaml`.
WRONG: `/Users/robertboulos/Projects/v0-prototypes/v0-snappy-website-0c/`
RIGHT: the path above. If you find yourself in the wrong repo, stop and `cd` correctly.
## Frozen files -- refuse to edit
Robert reverted these after a voice regression. They are FROZEN. Read `FROZEN.md` at the repo root before any edit and refuse to touch any path it lists. As of 2026-04-07:
- `components/hero.tsx`
- `components/problem-section.tsx`
- `components/comparison-table.tsx`
- `components/faq4.tsx`
- `components/contact.tsx`
- `components/strategy-showcase.tsx`
If a task requires touching a frozen path, STOP and surface the conflict. Do not work around the freeze. Do not edit `FROZEN.md` itself -- Robert owns it.
## Design system -- Ink Journal identity
All marketing pages and components MUST conform to the Ink Journal design system. Do not invent new tokens, colors, or typography scales.
- **Tokens**: pull from `tailwind.config.ts` and `app/globals.css`. Never hardcode hex values, spacing, or font sizes in JSX.
- **Components**: reuse existing shadcn/ui primitives in `components/ui/`. Prefer composition over new components.
- **Typography**: Ink Journal serif/sans pairing already configured. Don't import new fonts.
- **Spacing & rhythm**: use Tailwind scale (`space-y-*`, `gap-*`). No magic margins.
- **Imagery**: hero/case study/OG images come from `snappy-image`. Don't source random stock.
If a request needs something the design system doesn't have, propose a token addition before adding inline styles.
## Content routing -- pages vs posts
| Type | Location | Format | Who owns |
|---|---|---|---|
| Marketing pages | `app/page.tsx`, `app/<route>/page.tsx` | TSX | snappy-website |
| Marketing components | `components/{hero,header,footer,offerings,contact,...}.tsx` | TSX | snappy-website |
| Blog posts | `content/blog/<slug>.mdx` (or repo equivalent) | MDX | snappy-blog → snappy-publish |
| Dashboard sub-app | `app/(dashboard)/dashboard/` | TSX | snappy-xano-dashboard (NOT this skill) |
**Hand-off rule**: if the task is shipping a finished blog post (MDX file), hand off to `snappy-publish`. snappy-website does not author MDX content. snappy-website handles the page templates, blog index/list views, and the deploy pipeline.
## Voice -- banned phrases (inherits from snappy-positioning §4a)
Never write, schedule, or commit copy containing:
- "10x" / "Nx" multiplier claims
- "the operating system for X"
- "unlock"
- "supercharge"
- "revolutionize" / "revolutionary"
- "game-changer" / "game-changing"
- "leverage" (as a verb)
- "synergy"
- "AI-powered" as a standalone adjective
- Em-dash sandwiches in ChatGPT default cadence
- Three-bullet "Here's why:" framings
If a draft contains any of the above, rewrite before committing. Even if Robert pasted it. If the user insists, STOP and surface positioning §4a -- never override silently. Always read `snappy-positioning` before writing on-page copy.
## Required environment
Before any deploy or API call, source credentials:
```bash
SNAPPY_SETTINGS_QUIET=1 source ~/.claude/skills/snappy-settings/scripts/load-env.sh
```
This exports `XANO_METADATA_TOKEN`, `XANO`, and other tokens. Never hardcode. For agent-browser verification, set `AGENT_BROWSER_SESSION` before any call (session isolation).
## Deploy flow -- push to main, Vercel auto-deploys
There is exactly one deploy path. Do not invent others.
```bash
cd /Users/robertboulos/.openclaw/workspace/projects/snappy-website-claude
pnpm install # if deps changed
pnpm build # ALWAYS build locally first
git add <specific files> # never `git add .`
git commit -m "site: <change>"
git push origin main # Vercel auto-deploys in ~1-2 min
```
Rules:
- **Always `pnpm build` locally before pushing.** A broken build on `main` takes the site down (or freezes the last good deploy). No exceptions.
- Push to `origin main` only. Never push to a `deploy` remote, never to a feature branch expecting a preview to ship.
- Stage specific files. Never `git add -A` or `git add .` -- the repo has untracked artifacts you don't want shipped.
- After push, verify the deploy in Vercel (or via `snappy-browse` hitting snappy.ai) before reporting done.
- Notify `snappy-telegram` on deploy start / live / failed when running an unattended deploy.
Rollback: `git revert <sha> && git push origin main`. Do NOT force-push main.
## Hand-off matrix
| Task | Hand off to |
|---|---|
| Write blog post copy | `snappy-blog` |
| Ship a finished MDX post | `snappy-publish` |
| Voice / messaging rules | `snappy-positioning` (canonical) + `snappy-content` |
| Hero / OG / case study images | `snappy-image` |
| Pricing & packaging copy | `snappy-offer` |
| VSL video production | `snappy-video` |
| Paid traffic to VSL | `snappy-ads` |
| Dashboard sub-app changes | `snappy-xano-dashboard` |
| Live-site verification (browser) | `snappy-browse` |
| Lead routing from forms | `snappy-sales` + `snappy-knowledge` |
## Rules
- **`pnpm build` fails locally** → STOP. Do not push. Diagnose the error, fix the root cause, rebuild. Never push a broken build hoping Vercel will figure it out.
- **Vercel deploy fails after push** → STOP. Pull the build log via Vercel, surface it to Robert, and propose a revert. Do not retry the same push.
- **Frozen file in the diff** → STOP. Refuse the edit. Surface the conflict to Robert.
- **Banned phrase in committed copy** → STOP. Rewrite or surface §4a. Never ship.
- **Wrong repo path detected** (`v0-prototypes`, etc.) → STOP. `cd` to the correct path. Do not edit the wrong checkout.
- **`npm install` accidentally run** → STOP. Delete `package-lock.json` if created, restore `pnpm-lock.yaml` from git, run `pnpm install`.
- **Auth state expired for snappy-browse verification** → STOP. Ask Robert to refresh the relevant auth.json. Do not retry.
- **Charlotte MCP suggested for API calls** → refuse. Use direct Xano with `env("XANO_METADATA_TOKEN")` loaded from `snappy-settings/.env.cache`.
## What you produce as output
When asked to make a website change, output:
```
TARGET: <files to be edited, absolute paths>
FROZEN CHECK: <pass | conflict: …>
CHANGE: <one-sentence description>
DESIGN TOKENS USED: <list, or "none added">
VOICE CHECK: <pass | rewritten: …>
BUILD: <pnpm build result>
COMMIT MESSAGE: site: <change>
DEPLOY: <push result + Vercel URL once live>
VERIFY: <how the live change was confirmed>
```
Then ask Robert "Push to main?" before running `git push`. Never deploy without explicit confirmation, even when the user said "ship it" earlier in the conversation -- confirm the diff first.
## Reference (read only if needed)
The full SKILL.md, vsl-funnel.md, page-templates.md, conversion-tracking.md, and deployment.md live in this skill directory. Read them when this AGENTS.md doesn't cover the case. Default to this file.
<!-- SKILL-INDEX-START -->
[snappy-website Index]|root: ~/.claude/skills/snappy-website|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,conversion-tracking.md,deployment.md,page-templates.md,vsl-funnel.md}
<!-- SKILL-INDEX-END -->
## Used by
- `snappy-email`
<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs
Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.
| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `deploys` | — | `read` | `npx tsx ~/.claude/skills/snappy-website/api.ts deploys` |
| `health` | — | `read` | `npx tsx ~/.claude/skills/snappy-website/api.ts health` |
## Show the result
When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->