create-software
Skill32 starsChanged 23 days agoMITView on GitHub
Create and deploy a public web app on Cloudflare with TanStack Start, shadcn/ui, Convex, Better Auth, Lumail and optional Stripe, with an admin area, API and CLI so AI controls it. Use when asked to build or ship a SaaS, course platform, membership or client portal people sign up to or pay for.
- Reads credentials
- Installs packages
- Sends data out
In this repository42 other files it gives its agents.
- skills/setup-my-hermes-dashboard/template/AGENTS.mdAGENTS.md
- audit-safetySkill
- betterSkill
- cleanupSkill
- create-projectSkill
- doneSkill
- dreamSkill
- projectsSkill
- setup-brainSkill
- cloudflareSkill
- code-debugSkill
- codex-imagesSkill
- connect-googleSkill
- connect-instagram-developer-platformSkill
- connect-toolSkill
- connect-vpsSkill
- connect-youtube-developer-platformSkill
- convexSkill
- create-internal-appSkill
- create-landingSkill
- dev-browserSkill
- grill-meSkill
- initializeSkill
- install-skillsSkill
- lumailSkill
- safe-shipSkill
- setup-cloudflareSkill
- setup-convexSkill
- setup-dev-browserSkill
- setup-githubSkill
- setup-lumailSkill
- dashboardSkill
- setup-my-hermes-dashboardSkill
- setup-nodeSkill
- setup-stripeSkill
- setup-vpsSkill
- show-meSkill
- skill-managerSkill
- stripe-checkoutSkill
- use-styleSkill
- verifySkill
- wait-whatSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 13
Keep this stack unless the user asks to swap a layer:
- Very specific: line 30
Check access and fix what fails with the matching setup skill (setup-github, setup-cloudflare, setup-convex, setup-lumail, setup-node when …
- Very specific: line 40
Always write the confirmed brief to SPEC.md at the app root, before any code, so every later conversation starts from it:
- Very specific: line 45
Add an AGENTS.md at the app root that says: read SPEC.md before any change.
- Distinctive: line 62
Keep double opt-in only for a cold form (newsletter or waitlist where the email is not verified).
- Very specific: line 63
Create the sending domain with lumail domain --help and add the DNS records it returns in Cloudflare yourself (unproxied).
- Very specific: line 67
If the app sells, start with a fake checkout until the user gives Stripe test keys, then real Checkout and a signed webhook in …
- Distinctive: line 68
Add a clean error page, a 404 page, a favicon and page titles.
≈ “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
Build a working web app on the user's own accounts and put it live on their Cloudflare domain. Do every step yourself with the CLIs and only ask for what needs a human (a browser login, a device code, a payment, a secret key). Talk to the user in their language, short messages, no jargon. For a private tool only the user and their agent use, switch to create-internal-app; for a page with no sign-in, switch to create-landing.
If you got this skill from a link instead of a local folder, install nothing else from the repo: download a file it links only when a step needs it, with curl -fsSL https://raw.githubusercontent.com/Melvynx/ai-maxxing-skills/main/skills/create-software/<path> -o <scratch>/<file> (for example references/fast-app.md), and read another skill it names only when you reach it, from https://raw.githubusercontent.com/Melvynx/ai-maxxing-skills/main/skills/<skill-name>/SKILL.md.
Keep this stack unless the user asks to swap a layer:
- App, routing, server functions: TanStack Start (React, TypeScript, Vite).
- UI: shadcn/ui on Base UI + Tailwind CSS v4,
lucide-reacticons,sonnertoasts. - Database, backend, files, crons: Convex for everything, no other database or API server.
- Auth: Better Auth through
@convex-dev/better-auth, email OTP by default. - Marketing and login emails: Lumail through
@lumail/convex. - Payments, only if the app sells: Stripe Checkout with the
stripe-checkoutskill. - Video: Tella embeds from the URL the user pastes.
- Hosting, domain, DNS: Cloudflare Workers with
@cloudflare/vite-plugin, deployed withcf. - Code: Git and one private GitHub repo.
- Control by AI: an admin area at
/admin, an API at/api/v1with API keys, and a CLI named after the app with its<app>-cliskill.
Every app is built so the user's AI can run it, not only the user's mouse. Always build, and always explain to the user in one plain sentence, the admin part: an /admin area for the owner, a clean API reached with API keys, and a CLI plus skill so their agent controls the whole app from the terminal, like Lumail (admin pages, /api/admin/*, admin keys, the lumail CLI). Anything the owner can do in /admin, the API and the CLI can do too. This is never optional and never cut from v1. Details in references/admin-api-cli.md.
Reach for the TanStack library before any other package for client jobs: @tanstack/react-query + @convex-dev/react-query (convexQuery(api.x.y, args)) for fetching and cache, @tanstack/react-table for lists, sorting, filters and pagination, @tanstack/react-virtual for long lists, @tanstack/react-form + zod for forms, @tanstack/markdown to render markdown, @tanstack/react-hotkeys for shortcuts (cmd+k, j/k, esc), @tanstack/react-pacer to debounce search and throttle saves, @tanstack/ai-react for AI chat or generation. Check each package's current API (npm view <pkg> version, then its README or find-docs) instead of writing it from memory.
Check access and fix what fails with the matching setup skill (
setup-github,setup-cloudflare,setup-convex,setup-lumail,setup-nodewhennpxis missing) before writing code. When a login needs the browser, give the exact link or code and wait for "done".git --version && gh auth status # GitHub cf --version && cf auth whoami # Cloudflare (npm i -g cf, then cf auth login) npx convex --version # Convex (npx convex login when building) npx lumail@latest auth test # Lumail (npx lumail@latest setup --authenticate)- Decide first, with the user: does this app need organizations (multi-tenant)? Team members, shared data, roles, invitations, billing per company or API keys per workspace mean yes; a single-user tool means no. Yes changes every table, query and URL from day 1, so follow references/organizations.md. Then run the
grill-meskill and build only once the user confirms the brief; skip it only if a brief was already confirmed in this conversation. Defaults: landing at/, app at/app(/:org/...with organizations), admin at/admin, English UI, OTP sign-in, the user is the only admin. When you show the brief, tell the user the app comes with an admin area, an API and a CLI so their AI can manage everything, and ask what they will want their AI to do in it (for example "list today's sales", "refund an order", "ban a user"). - Always write the confirmed brief to
SPEC.mdat the app root, before any code, so every later conversation starts from it:- The brief: goal, who uses it, the user story screen by screen, every screen, the data objects and their fields, what is out of v1, and what "done" means for the user.
- An
## Admin, API, CLIsection: every admin page, every API route (GET /api/v1/admin/users...) and the CLI command that matches it, from what the user wants their AI to do. - A
## Taskschecklist, very precise: one small change per box, named by its route, screen, field or Convex function, each with aCheck:line saying how to prove it works on the real app. Write- [ ] /app/lessons lists lessons in a table, newest first, 20 per page. Check: with 25 lessons, page 2 shows 5, never- [ ] lessons page. - Go through references/product-rules.md (URLs, access, search, composer, tags, agents, webhooks, email rendering, deploy) and add a task for every rule that applies.
- Add an
AGENTS.mdat the app root that says: readSPEC.mdbefore any change; for a new feature or fix, add its tasks toSPEC.mdfirst, then build; after building or changing any screen, runbetter; never stop until every task matches.
- Scaffold TanStack Start + Tailwind +
npx shadcn@latest init(Base UI flavor) and add components withnpx shadcn@latest add.git init, thengh repo create <name> --private --source . --push. - Run
npx convex dev --onceto create the project and.env.local. Write oneschema.tswith an index for every query. Every public function checks the signed-in user and ownership server-side, anything only the server calls isinternal*, and reads are bounded with.take(n)or.paginate(). With organizations, every table hasorgIdand every function checks membership and role. See theconvexskill. - Wire Better Auth: register both components in
convex/convex.config.ts(app.use(betterAuth),app.use(lumail)),createAuthwithauthComponent.adapter(ctx), theemailOTPplugin and theconvex({ authConfig })plugin, routes viaauthComponent.registerRoutes(http, createAuth),BETTER_AUTH_SECRETandSITE_URLas Convex env vars. Protect/appin the routebeforeLoadand again in every Convex function. - Wire Lumail in one
convex/email.tsthat holds every call. CreateLUMAIL_API_KEYyourself withlumail tokens --help; it never reaches the browser.- Login codes:
sendVerificationOTPschedules an internal mutation that callslumail.sendEmail(ctx, { ..., transactional: true }). Without a key, log the code to the Convex console so local dev still works. - Signups: in Better Auth
databaseHooks.user.create.after, upsert the person withlumail.upsertSubscriber(ctx, { email, tags: ["<app-slug>-user"], triggerWorkflows: true }). Skip double opt-in for anyone who signs in or buys, since the OTP or the payment proves they own the email: they go straight to "subscribed" and tag workflows fire right away. The component cannot pass that flag, so also call the API from an internal action:
await fetch("https://lumail.io/api/v1/subscribers", { method: "POST", headers: { Authorization: `Bearer ${process.env.LUMAIL_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ email, skipDoubleOptIn: true }), });- Keep double opt-in only for a cold form (newsletter or waitlist where the email is not verified).
- Create the sending domain with
lumail domain --helpand add the DNS records it returns in Cloudflare yourself (unproxied). More in thelumailskill.
- Login codes:
- Put data on screen with
useSuspenseQuery(convexQuery(...))so the UI updates live, lists in TanStack Table, forms in TanStack Form calling Convex mutations, toasts on success and error. Build every screen, admin included, to references/design-system-rules.md. After building any screen, run thebetterskill on it, in light and dark, and finish its screenshot loop before moving on. - Build the admin area, API keys, API and CLI with references/admin-api-cli.md: each action is one internal Convex function called by the admin page and by the API, keys stored hashed and shown once,
/api/v1on the app domain,cli/<app>.mjsinstalled withnpm install -g ./cli, then the<app>-cliskill in~/.agents/skills. Every new feature later gets its admin view, route and CLI command in the same change. - Make it fast on every page with references/fast-app.md:
defaultPreload: "intent", a 30 s query cache, a loader on detail pages, a custompendingComponentskeleton on every route that matches the real layout, a loading state on every async button, indexed and bounded Convex reads. An app without these is not done. - If the app sells, start with a fake checkout until the user gives Stripe test keys, then real Checkout and a signed webhook in
convex/http.tsthat grants access. Test card4242 4242 4242 4242, live keys only once the test flow works. See thestripe-checkoutskill. - Add a clean error page, a 404 page, a favicon and page titles.
- Deploy on Cloudflare.
wrangler.jsoncgetsmain: "@tanstack/react-start/server-entry",compatibility_flags: ["nodejs_compat"],SITE_URLinvarsand the custom domain inrouteswithcustom_domain: true. Runnpx convex deploy, set prod env vars withnpx convex env set --prod, and put the prodVITE_CONVEX_URL/VITE_CONVEX_SITE_URLin the build env. Build and deploy withcf(cf build,cf deploy, orcf cli search "deploy worker"), never by hand in the dashboard; see thecloudflareskill. Deploy from a clean checkout of the pushed commit, never a dirty tree, and always ship both Convex and the Worker. Once the first deploy works, add a GitHub Actions workflow that deploys on every push tomain. If the domain is not in the user's Cloudflare account, tell them to move the name servers or buy it there. - Open the live URL and walk the real flows: landing, sign in with a real OTP email, the main action, a list with real rows, a test purchase if the app sells, a keyboard shortcut, sign out, the 404 page. Then the admin: create an admin key in
/admin/api-keys,<app> login,<app> whoami, list a resource with--jsonand compare it with the admin page, make one write through the CLI and see it in Activity, and check that no key or a revoked key gets refused. Check the person shows up in Lumail as subscribed with the right tag. Fix every error you see, then runaudit-safetyon auth, data access, API keys, admin routes and payments. - Re-read
SPEC.mdand run every task'sCheck:on the live URL. Tick a box only once its check passes there, never because the code is written. Do not stop and do not reply while one box is unticked or the live app differs from the spec: fix it, redeploy, check again, and repeat until everything matches. A task blocked only by a human step (a login, a key, a payment) stays unticked with the reason written next to it; finish all the others first.
Secrets go only in .env.local, npx convex env set, Cloudflare secrets or GitHub Actions secrets, never in a committed file, a log or the chat. Reply with what is live, the URL, the admin URL, the CLI command and the /<app>-cli skill their agent can now use (with one sentence to try, like "ask your AI: how many people signed up this week?"), the SPEC.md tasks all ticked, and only the human steps left to do.
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.

