Skip to content
Back to skills

Scaffold

ASecurity

Lay out a Vue app on the local Supabase stack, served as static files by wrangler, with tests that run against the local stack.

  • 234 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 30, 2026
ai-agentstypescriptrustgosqlvuenodetestinggitapidatabase

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 30, 2026

npx -y skills add receptron/mulmoterminal --skill scaffold --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Scaffold?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Scaffold
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/receptron-scaffold-0cb2027c/badge)](https://www.skillsdirectory.com/skills/receptron-scaffold-0cb2027c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: blueprint-supabase-scaffold
description: "Lay out a Vue app on the local Supabase stack, served as static files by wrangler, with tests that run against the local stack."
---

# App skeleton

One folder, one `package.json`, TypeScript throughout, `yarn`. The later checks rely on this layout exactly:

```
supabase/config.toml    yarn supabase init; project_id is the app's name
supabase/migrations/    the schema, one timestamped .sql per change (yarn supabase migration new <name>)
supabase/seed.sql       rows for trying the app locally; the security check needs one in every table
index.html              the Vue entry (<div id="app">)
src/client/             Vue 3 + Vite; src/client/supabase.ts creates the one Supabase client
vite.config.ts          writes _headers into the build (see below)
wrangler.jsonc          serves the build as static files; there is no Worker code
scripts/local-env.mjs   writes .env.development.local from the running local stack
test/                   vitest against the local stack; one file per area: data, ui, auth
```

- Dev dependencies: `supabase`, `@supabase/supabase-js`, `vite`, `@vitejs/plugin-vue`, `vue`, `typescript@^6` (not 7:
  a later check reads test files through TypeScript's compiler API, which TypeScript 7 does not ship), `vitest`,
  `wrangler`.
- The browser gets two values and no others: `VITE_SUPABASE_URL` and `VITE_SUPABASE_PUBLISHABLE_KEY` (the
  publishable key, `sb_publishable_…`). The secret key never goes into `src/` or any `VITE_` variable.
- `scripts/local-env.mjs` runs `yarn -s supabase status -o json` and writes `API_URL` and `PUBLISHABLE_KEY` to
  `.env.development.local` as those two variables.
- `vite.config.ts`: on `vite build` only, read `VITE_SUPABASE_URL` with `loadEnv` (throw if it is missing) and emit a
  `_headers` asset for every path: `Content-Security-Policy: default-src 'self'; connect-src 'self' <that URL>;
  frame-ancestors 'none'; object-src 'none'; base-uri 'self'`, `X-Content-Type-Options: nosniff`,
  `Referrer-Policy: same-origin`. The CSP has to name the Supabase URL of the build it is in, or the browser blocks
  every call; a fixed `public/_headers` cannot, because the local and the production URL differ.
- `wrangler.jsonc`: `name`, `compatibility_date` (a date the installed wrangler supports — about a month before
  today), `"assets": { "directory": "./dist", "not_found_handling": "single-page-application" }`. No `main`.
- Scripts:
  - `db:start`: `supabase start -x studio,imgproxy,logflare,vector,edge-runtime,realtime,mailpit,supavisor,postgres-meta && node scripts/local-env.mjs`
    (leave out `mailpit` from `-x` if the spec signs people in by email link)
  - `build`: `vite build --mode development` — the local build, talking to the local stack
  - `start`: `yarn -s db:start >/dev/null && yarn -s build && wrangler dev --local --ip 127.0.0.1`. The checks run
    `yarn start --port <n>`, so extra arguments must reach `wrangler dev`.
  - `test`: `vitest run`
  - `deploy`: `vite build --mode production && wrangler deploy`
- `.gitignore`: `node_modules`, `dist`, `.wrangler`, `*.local`.
- `test/local-stack.ts`: reads `yarn -s supabase status -o json`; exports an admin client made with `SECRET_KEY`
  (tests only, never the app), a signed-out client made with `PUBLISHABLE_KEY`, and `signedIn()`, which creates a
  fresh user with `auth.admin.createUser({ email, password, email_confirm: true })` and returns a client signed in as
  them. Tests never reach a hosted project.
- Add one trivial passing test in `test/` that reaches the local stack, so the harness is proven.

The checks start the local stack themselves and reset its database to the migrations and the seed before testing, so
a test may not rely on rows another test left behind.

Done when the check passes: the layout exists, `yarn db:start` starts the stack, `yarn build` and `yarn test` succeed.

## Always

- Read `.blueprint/spec.md` first. It is the agreed specification; do not widen it.
- When you need a decision, ask it through the blueprint question tool and stop. Do not guess.
- Do not run `git init`: a new repository loses the folder's trust and the next unattended step stops at Claude
  Code's trust prompt. The user adds git themselves after the build if they want it.
- Say you are done by stopping; the executor runs the check. Do not claim success yourself.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.