Scaffolds
Prompts that run the current official CLIs the way I always want them — not a template repo to go stale. Open one in Cursor, press enter, get a project. Back to the story.
Next.js app
TypeScript, Biome or ESLint, React Compiler, Tailwind, App Router, pnpm — no src/.
Official
create-next-app— pick Biome or ESLint and the prompt updates.Read the prompt
Scaffold a new Next.js app. If a project name isn't obvious from context, ask me for one. Run the CLI non-interactively — never hang waiting for prompts. 1. Create the app with the current create-next-app (prefer `pnpm create next-app@latest` so flags match today's CLI): pnpm create next-app@latest <project-name> \ --typescript \ --biome \ --react-compiler \ --tailwind \ --app \ --no-src-dir \ --import-alias "@/*" \ --use-pnpm \ --agents-md If a flag has been renamed or removed, check `create-next-app --help` (or the live Next.js docs) and keep the same intent: TypeScript, Biome, React Compiler, Tailwind, App Router, no src/, @/* imports, pnpm, keep AGENTS.md. 2. cd into the project. 3. Confirm the lint script runs (`pnpm lint` or whatever the scaffold generated). Fix only if the scaffold itself is broken. 4. Do not add a backend, database, auth, UI kit, or other packages beyond this. Keep the generated AGENTS.md — you'll add to it below, not overwrite it. ## Standing project practices Add this section to AGENTS.md: ## Engineering practices ### Ship cadence - Slices are vertical, not horizontal: each one cuts end-to-end through every layer it touches (e.g. UI → logic → storage) and lands a thin piece of real, demonstrable behavior — not "build all the models" then "all the services" then "all the UI" as separate slices. A vertical slice is independently testable and reviewable on its own; a horizontal one isn't until everything else lands too. - Smallest coherent vertical slice; commit regularly. - A slice that adds real behavior ships with tests. Exempt only for pure docs/config or trivial static markup — say so in the commit message when skipped. - Before each commit: run the tests for what changed. If the change affects runtime or UI, run the app and exercise the affected path — don't claim a UI change works without having opened it. ### Code review - Review at checkpoints, not every commit: end of a feature, before opening/merging a PR, and immediately for anything touching security-sensitive surface (secrets, auth, credential storage, process/command spawning, IPC or trust boundaries). - Small refactors or docs-only slices: a careful self-read of the diff is enough, no formal review needed. ### Commits - A commit that changes behavior states the why in 1-3 sentences in the body. Enforced by a commit-msg hook — don't bypass it. ### Structural learnings - When a structural or architectural mistake surfaces (duplicated source of truth, boundary violation, bad seam), ask whether it should become a regression test and/or an ADR before writing prose about it elsewhere. Only write the ADR if the decision is hard-to-reverse AND surprising AND a genuine tradeoff — all three. ### CONTEXT.md - Glossary only — term names and meanings, never decisions or implementation detail. Scaffolded empty at project init; add a term the first time it needs a name. ### plans/handoff.md - Living state file: current task, what's done, what's next, open decisions. Overwrite in place, under ~40 lines — it's not a log. ### Module boundaries - The moment this project gains more than one internal module/package boundary (a new package/, apps/*, packages/*, or a seam worth guarding), add or extend a dependency-cruiser config enforcing entry-point-only imports and no cycles — do this the moment the boundary appears, don't wait to be asked. ### Guard verification - Any deterministic guard added to this repo (git hook, lint rule, dependency-cruiser rule, commit-msg check, etc.) must be proven before being considered installed: trigger the violation it's meant to catch, confirm it's blocked, revert, confirm a clean run passes. State this in the commit that adds the guard — including guards added later, not just during initial setup. Now set up standing project practices. Work from what you just scaffolded — don't ask questions the stack already answered. 5. Write the "Engineering practices" section above into AGENTS.md verbatim (create the file if the CLI didn't scaffold one, append if it did). 6. Install a git safety hook blocking `git push` (incl. `--force`), `git reset --hard`, `git clean -f`/`-fd`, `git branch -D`, `git checkout .` / `git restore .`. This is a Claude Code `PreToolUse` hook on the `Bash` tool, not a native git hook — it stops the agent from running these, it doesn't lock the user out of their own terminal, and there's no bypass phrase; the user runs the command themselves if they really want it. - Write `.claude/hooks/block-dangerous-git.sh`: ```bash #!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command') DANGEROUS_PATTERNS=( "git push" "git reset --hard" "git clean -fd" "git clean -f" "git branch -D" "git checkout \." "git restore \." "push --force" "reset --hard" ) for pattern in "${DANGEROUS_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qE "$pattern"; then echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2 exit 2 fi done exit 0 ``` `chmod +x .claude/hooks/block-dangerous-git.sh` - Merge into `.claude/settings.json` (project scope — don't overwrite other keys already in the file): ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh" } ] } ] } } ``` 7. Install a pre-commit chain (current, non-legacy commands — Husky v9+ has no `husky-init`/`husky set`/`husky add`; hooks are plain scripts written into `.husky/`): ```bash pnpm add -D husky lint-staged pnpm exec husky init ``` `husky init` creates `.husky/pre-commit` (default contents `pnpm test`) and adds a `prepare` script to `package.json`. Replace the generated `.husky/pre-commit` body with: ```bash pnpm exec lint-staged ``` Add a `lint-staged` key to `package.json` wired to this stack's formatter/linter and typecheck, e.g.: ```json "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } ``` (swap in the stack's actual formatter/linter — Biome's `biome check --write`, etc.) Add `.husky/commit-msg` rejecting an empty body when the diff touches non-trivial files (skip for docs/config-only commits): ```bash #!/bin/bash commit_msg_file="$1" body=$(tail -n +3 "$commit_msg_file" | grep -v '^#' | grep -v '^\s*$') if [ -z "$body" ]; then changed=$(git diff --cached --name-only | grep -vE '\.(md)$|^docs/') if [ -n "$changed" ]; then echo "BLOCKED: commit body is empty but the diff touches non-trivial files. State the why in 1-3 sentences." >&2 exit 1 fi fi exit 0 ``` `chmod +x .husky/commit-msg` 8. Create docs/adr/ with a one-paragraph README stating the gate from the AGENTS.md section above. 9. Create CONTEXT.md, empty except a one-line header noting it's a project glossary (term → meaning), no terms yet. 10. Create plans/handoff.md from the template described above. 11. If the project already has more than one internal module boundary at scaffold time, set up dependency-cruiser now. `depcruise --init` is interactive (asks questions, no flag to answer them non-interactively) — don't run it from an agent. Install and write the config directly instead: ```bash pnpm add -D dependency-cruiser ``` `.dependency-cruiser.cjs`, extending the maintained preset rather than hand-writing rules from scratch: ```js /** @type {import('dependency-cruiser').IConfiguration} */ module.exports = { extends: "dependency-cruiser/configs/recommended", forbidden: [ // add entry-point-only / no-cross-boundary-import rules for this // project's actual boundaries here ], options: { tsPreCompilationDeps: true, }, }; ``` Add a `lint:deps` (or similar) script running `depcruise --config .dependency-cruiser.cjs <src-dirs>` and wire it into the pre-commit chain from step 7. Otherwise leave it — the AGENTS.md rule above means it gets added automatically whenever a boundary appears later, without needing this prompt again. 12. Prove every guard installed in steps 6-7 (and 11, if run): trigger the violation, confirm blocked, revert, confirm clean. Report what was installed, what was deferred and why, and confirm each guard was proven.CLI command
pnpm create next-app@latest <project-name> \ --typescript \ --biome \ --react-compiler \ --tailwind \ --app \ --no-src-dir \ --import-alias "@/*" \ --use-pnpm \ --agents-md
Next.js + Convex
Same Next base, then Convex — plus install the Convex Cursor plugin once.
Same official
create-next-appbase as the Next.js recipe, then Convex — pick Biome or ESLint and the prompt updates.Read the prompt
Scaffold a new Next.js app with Convex. If a project name isn't obvious from context, ask me for one. Prefer official CLIs over copying templates. Never hang forever on interactive prompts — if login or project creation needs me, pause and say what to do. ## A. Next.js (same base as my Next-only recipe) 1. Create the app: pnpm create next-app@latest <project-name> \ --typescript \ --biome \ --react-compiler \ --tailwind \ --app \ --no-src-dir \ --import-alias "@/*" \ --use-pnpm \ --agents-md If a flag has been renamed or removed, check `create-next-app --help` (or the live Next.js docs) and keep the same intent: TypeScript, Biome, React Compiler, Tailwind, App Router, no src/, @/* imports, pnpm, keep AGENTS.md. 2. cd into the project. Confirm the lint script runs; fix only if the scaffold itself is broken. ## B. Convex 3. Install the package with the project's package manager: `pnpm add convex`. 4. Initialize against a Convex deployment with the current CLI (prefer `pnpm exec convex` so the command matches today): `pnpm exec convex dev --once` On first run this may ask me to log in and pick/create a project. Pause for that, then re-run with `--once` so it writes config, the `convex/` folder, env vars, and generated types without leaving a watcher running. 5. Wire the React client the way the current Convex Next.js docs say (provider + `NEXT_PUBLIC_CONVEX_URL`). Put the provider in `components/` if the app already uses that layout; otherwise follow the docs. Do not add sample todo/tasks UI unless I ask. ## C. Cursor (so the agent knows Convex) 6. After scaffolding, tell me to install the official Convex plugin in Cursor if I don't already have it — once is enough for all projects: - In Agent chat: `/add-plugin convex` - Or: Customize → search “Convex” → Add Don't try to install the plugin from the terminal; that's a Cursor UI step. ## D. Wrap up Phase 1 7. Do not add auth, UI kits, or extra packages beyond this. Remind me about the Convex plugin if I still need it, and that day-to-day I should run `pnpm exec convex dev` alongside the Next dev server. ## Standing project practices Add this section to AGENTS.md: ## Engineering practices ### Ship cadence - Slices are vertical, not horizontal: each one cuts end-to-end through every layer it touches (e.g. UI → logic → storage) and lands a thin piece of real, demonstrable behavior — not "build all the models" then "all the services" then "all the UI" as separate slices. A vertical slice is independently testable and reviewable on its own; a horizontal one isn't until everything else lands too. - Smallest coherent vertical slice; commit regularly. - A slice that adds real behavior ships with tests. Exempt only for pure docs/config or trivial static markup — say so in the commit message when skipped. - Before each commit: run the tests for what changed. If the change affects runtime or UI, run the app and exercise the affected path — don't claim a UI change works without having opened it. ### Code review - Review at checkpoints, not every commit: end of a feature, before opening/merging a PR, and immediately for anything touching security-sensitive surface (secrets, auth, credential storage, process/command spawning, IPC or trust boundaries). - Small refactors or docs-only slices: a careful self-read of the diff is enough, no formal review needed. ### Commits - A commit that changes behavior states the why in 1-3 sentences in the body. Enforced by a commit-msg hook — don't bypass it. ### Structural learnings - When a structural or architectural mistake surfaces (duplicated source of truth, boundary violation, bad seam), ask whether it should become a regression test and/or an ADR before writing prose about it elsewhere. Only write the ADR if the decision is hard-to-reverse AND surprising AND a genuine tradeoff — all three. ### CONTEXT.md - Glossary only — term names and meanings, never decisions or implementation detail. Scaffolded empty at project init; add a term the first time it needs a name. ### plans/handoff.md - Living state file: current task, what's done, what's next, open decisions. Overwrite in place, under ~40 lines — it's not a log. ### Module boundaries - The moment this project gains more than one internal module/package boundary (a new package/, apps/*, packages/*, or a seam worth guarding), add or extend a dependency-cruiser config enforcing entry-point-only imports and no cycles — do this the moment the boundary appears, don't wait to be asked. ### Guard verification - Any deterministic guard added to this repo (git hook, lint rule, dependency-cruiser rule, commit-msg check, etc.) must be proven before being considered installed: trigger the violation it's meant to catch, confirm it's blocked, revert, confirm a clean run passes. State this in the commit that adds the guard — including guards added later, not just during initial setup. Now set up standing project practices. Work from what you just scaffolded — don't ask questions the stack already answered. 8. Write the "Engineering practices" section above into AGENTS.md verbatim (create the file if the CLI didn't scaffold one, append if it did). 9. Install a git safety hook blocking `git push` (incl. `--force`), `git reset --hard`, `git clean -f`/`-fd`, `git branch -D`, `git checkout .` / `git restore .`. This is a Claude Code `PreToolUse` hook on the `Bash` tool, not a native git hook — it stops the agent from running these, it doesn't lock the user out of their own terminal, and there's no bypass phrase; the user runs the command themselves if they really want it. - Write `.claude/hooks/block-dangerous-git.sh`: ```bash #!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command') DANGEROUS_PATTERNS=( "git push" "git reset --hard" "git clean -fd" "git clean -f" "git branch -D" "git checkout \." "git restore \." "push --force" "reset --hard" ) for pattern in "${DANGEROUS_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qE "$pattern"; then echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2 exit 2 fi done exit 0 ``` `chmod +x .claude/hooks/block-dangerous-git.sh` - Merge into `.claude/settings.json` (project scope — don't overwrite other keys already in the file): ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh" } ] } ] } } ``` 10. Install a pre-commit chain (current, non-legacy commands — Husky v9+ has no `husky-init`/`husky set`/`husky add`; hooks are plain scripts written into `.husky/`): ```bash pnpm add -D husky lint-staged pnpm exec husky init ``` `husky init` creates `.husky/pre-commit` (default contents `pnpm test`) and adds a `prepare` script to `package.json`. Replace the generated `.husky/pre-commit` body with: ```bash pnpm exec lint-staged ``` Add a `lint-staged` key to `package.json` wired to this stack's formatter/linter and typecheck, e.g.: ```json "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } ``` (swap in the stack's actual formatter/linter — Biome's `biome check --write`, etc.) Add `.husky/commit-msg` rejecting an empty body when the diff touches non-trivial files (skip for docs/config-only commits): ```bash #!/bin/bash commit_msg_file="$1" body=$(tail -n +3 "$commit_msg_file" | grep -v '^#' | grep -v '^\s*$') if [ -z "$body" ]; then changed=$(git diff --cached --name-only | grep -vE '\.(md)$|^docs/') if [ -n "$changed" ]; then echo "BLOCKED: commit body is empty but the diff touches non-trivial files. State the why in 1-3 sentences." >&2 exit 1 fi fi exit 0 ``` `chmod +x .husky/commit-msg` 11. Create docs/adr/ with a one-paragraph README stating the gate from the AGENTS.md section above. 12. Create CONTEXT.md, empty except a one-line header noting it's a project glossary (term → meaning), no terms yet. 13. Create plans/handoff.md from the template described above. 14. If the project already has more than one internal module boundary at scaffold time, set up dependency-cruiser now. `depcruise --init` is interactive (asks questions, no flag to answer them non-interactively) — don't run it from an agent. Install and write the config directly instead: ```bash pnpm add -D dependency-cruiser ``` `.dependency-cruiser.cjs`, extending the maintained preset rather than hand-writing rules from scratch: ```js /** @type {import('dependency-cruiser').IConfiguration} */ module.exports = { extends: "dependency-cruiser/configs/recommended", forbidden: [ // add entry-point-only / no-cross-boundary-import rules for this // project's actual boundaries here ], options: { tsPreCompilationDeps: true, }, }; ``` Add a `lint:deps` (or similar) script running `depcruise --config .dependency-cruiser.cjs <src-dirs>` and wire it into the pre-commit chain from step 10. Otherwise leave it — the AGENTS.md rule above means it gets added automatically whenever a boundary appears later, without needing this prompt again. 15. Prove every guard installed in steps 9-10 (and 14, if run): trigger the violation, confirm blocked, revert, confirm clean. Report what was installed, what was deferred and why, and confirm each guard was proven.CLI command
pnpm create next-app@latest <project-name> \ --typescript \ --biome \ --react-compiler \ --tailwind \ --app \ --no-src-dir \ --import-alias "@/*" \ --use-pnpm \ --agents-md
TanStack Start
Pick a linter and add-ons (Query, Convex, auth, deploy…), get a prompt — Intent on by default.
Locked base: React, pnpm, Start (not router-only), no demo examples. Pick a toolchain and add-ons — the prompt updates.
Read the prompt
Scaffold a new TanStack Start app. If a project name isn't obvious from context, ask me for one. Prefer the official TanStack CLI over copying a template. Never hang forever on interactive prompts — if login or project creation needs me, pause and say what to do. 1. Create the app with the current CLI (prefer `pnpm dlx @tanstack/cli@latest` so flags match today; always `--package-manager pnpm`): pnpm dlx @tanstack/cli@latest create <project-name> \ --framework React \ --package-manager pnpm \ --toolchain biome \ --no-examples \ --intent \ --add-ons tanstack-query \ -y If a flag or add-on id has been renamed or removed, check `pnpm dlx @tanstack/cli@latest create --help` and `--list-add-ons`, then map to the same intent: React, pnpm, Biome toolchain, no demo examples, TanStack Intent on, add-ons: tanstack-query. 2. cd into the project. Confirm the app starts (`pnpm dev` or the generated script). Fix only if the scaffold itself is broken. 3. Intent was requested. If the create step didn't fully wire agent skill guidance, run the current Intent consumer setup (`pnpm dlx @tanstack/intent@latest install` or whatever `--help` shows) so AGENTS.md (or the project's agent config) can load skills from installed packages on demand. 4. Do not add packages or add-ons beyond what I selected. ## Standing project practices Add this section to AGENTS.md: ## Engineering practices ### Ship cadence - Slices are vertical, not horizontal: each one cuts end-to-end through every layer it touches (e.g. UI → logic → storage) and lands a thin piece of real, demonstrable behavior — not "build all the models" then "all the services" then "all the UI" as separate slices. A vertical slice is independently testable and reviewable on its own; a horizontal one isn't until everything else lands too. - Smallest coherent vertical slice; commit regularly. - A slice that adds real behavior ships with tests. Exempt only for pure docs/config or trivial static markup — say so in the commit message when skipped. - Before each commit: run the tests for what changed. If the change affects runtime or UI, run the app and exercise the affected path — don't claim a UI change works without having opened it. ### Code review - Review at checkpoints, not every commit: end of a feature, before opening/merging a PR, and immediately for anything touching security-sensitive surface (secrets, auth, credential storage, process/command spawning, IPC or trust boundaries). - Small refactors or docs-only slices: a careful self-read of the diff is enough, no formal review needed. ### Commits - A commit that changes behavior states the why in 1-3 sentences in the body. Enforced by a commit-msg hook — don't bypass it. ### Structural learnings - When a structural or architectural mistake surfaces (duplicated source of truth, boundary violation, bad seam), ask whether it should become a regression test and/or an ADR before writing prose about it elsewhere. Only write the ADR if the decision is hard-to-reverse AND surprising AND a genuine tradeoff — all three. ### CONTEXT.md - Glossary only — term names and meanings, never decisions or implementation detail. Scaffolded empty at project init; add a term the first time it needs a name. ### plans/handoff.md - Living state file: current task, what's done, what's next, open decisions. Overwrite in place, under ~40 lines — it's not a log. ### Module boundaries - The moment this project gains more than one internal module/package boundary (a new package/, apps/*, packages/*, or a seam worth guarding), add or extend a dependency-cruiser config enforcing entry-point-only imports and no cycles — do this the moment the boundary appears, don't wait to be asked. ### Guard verification - Any deterministic guard added to this repo (git hook, lint rule, dependency-cruiser rule, commit-msg check, etc.) must be proven before being considered installed: trigger the violation it's meant to catch, confirm it's blocked, revert, confirm a clean run passes. State this in the commit that adds the guard — including guards added later, not just during initial setup. Now set up standing project practices. Work from what you just scaffolded — don't ask questions the stack already answered. 5. Write the "Engineering practices" section above into AGENTS.md verbatim (create the file if the CLI didn't scaffold one, append if it did). 6. Install a git safety hook blocking `git push` (incl. `--force`), `git reset --hard`, `git clean -f`/`-fd`, `git branch -D`, `git checkout .` / `git restore .`. This is a Claude Code `PreToolUse` hook on the `Bash` tool, not a native git hook — it stops the agent from running these, it doesn't lock the user out of their own terminal, and there's no bypass phrase; the user runs the command themselves if they really want it. - Write `.claude/hooks/block-dangerous-git.sh`: ```bash #!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command') DANGEROUS_PATTERNS=( "git push" "git reset --hard" "git clean -fd" "git clean -f" "git branch -D" "git checkout \." "git restore \." "push --force" "reset --hard" ) for pattern in "${DANGEROUS_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qE "$pattern"; then echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2 exit 2 fi done exit 0 ``` `chmod +x .claude/hooks/block-dangerous-git.sh` - Merge into `.claude/settings.json` (project scope — don't overwrite other keys already in the file): ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh" } ] } ] } } ``` 7. Install a pre-commit chain (current, non-legacy commands — Husky v9+ has no `husky-init`/`husky set`/`husky add`; hooks are plain scripts written into `.husky/`): ```bash pnpm add -D husky lint-staged pnpm exec husky init ``` `husky init` creates `.husky/pre-commit` (default contents `pnpm test`) and adds a `prepare` script to `package.json`. Replace the generated `.husky/pre-commit` body with: ```bash pnpm exec lint-staged ``` Add a `lint-staged` key to `package.json` wired to this stack's formatter/linter and typecheck, e.g.: ```json "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } ``` (swap in the stack's actual formatter/linter — Biome's `biome check --write`, etc.) Add `.husky/commit-msg` rejecting an empty body when the diff touches non-trivial files (skip for docs/config-only commits): ```bash #!/bin/bash commit_msg_file="$1" body=$(tail -n +3 "$commit_msg_file" | grep -v '^#' | grep -v '^\s*$') if [ -z "$body" ]; then changed=$(git diff --cached --name-only | grep -vE '\.(md)$|^docs/') if [ -n "$changed" ]; then echo "BLOCKED: commit body is empty but the diff touches non-trivial files. State the why in 1-3 sentences." >&2 exit 1 fi fi exit 0 ``` `chmod +x .husky/commit-msg` 8. Create docs/adr/ with a one-paragraph README stating the gate from the AGENTS.md section above. 9. Create CONTEXT.md, empty except a one-line header noting it's a project glossary (term → meaning), no terms yet. 10. Create plans/handoff.md from the template described above. 11. If the project already has more than one internal module boundary at scaffold time, set up dependency-cruiser now. `depcruise --init` is interactive (asks questions, no flag to answer them non-interactively) — don't run it from an agent. Install and write the config directly instead: ```bash pnpm add -D dependency-cruiser ``` `.dependency-cruiser.cjs`, extending the maintained preset rather than hand-writing rules from scratch: ```js /** @type {import('dependency-cruiser').IConfiguration} */ module.exports = { extends: "dependency-cruiser/configs/recommended", forbidden: [ // add entry-point-only / no-cross-boundary-import rules for this // project's actual boundaries here ], options: { tsPreCompilationDeps: true, }, }; ``` Add a `lint:deps` (or similar) script running `depcruise --config .dependency-cruiser.cjs <src-dirs>` and wire it into the pre-commit chain from step 7. Otherwise leave it — the AGENTS.md rule above means it gets added automatically whenever a boundary appears later, without needing this prompt again. 12. Prove every guard installed in steps 6-7 (and 11, if run): trigger the violation, confirm blocked, revert, confirm clean. Report what was installed, what was deferred and why, and confirm each guard was proven.CLI command
pnpm dlx @tanstack/cli@latest create <project-name> \ --framework React \ --package-manager pnpm \ --toolchain biome \ --no-examples \ --intent \ --add-ons tanstack-query \ -y
Electron
Electron Forge TypeScript + React, Biome or ESLint — Vite (default) or Webpack, pnpm. Official CLI, not a stale boilerplate.
Official Electron Forge via
create-electron-app— pick a TypeScript bundler template and a linter, then the prompt adds React on top. The prompt updates.Read the prompt
Scaffold a new Electron desktop app with Electron Forge + React + Biome. If a project name isn't obvious from context, ask me for one. Prefer official CLIs, `pnpm`, and package install commands over cloning third-party boilerplates or hand-rolling setup. Never hang forever on interactive prompts. 1. Create the app with the current Forge CLI (prefer `pnpm create electron-app@latest` so the template and package manager match today): pnpm create electron-app@latest <project-name> --template=vite-typescript If the template name has been renamed or removed, check `pnpm create electron-app@latest --help` and the live Electron Forge docs, then map to the same intent: TypeScript + Vite (`vite-typescript`), pnpm. Notes on the two TypeScript templates: - `vite-typescript` — modern default; Forge's Vite plugin is still marked experimental. - `webpack-typescript` — more battle-tested Forge path. Forge + pnpm: set `node-linker=hoisted` in the project's `.npmrc` (Forge's documented requirement). 2. cd into the project. Confirm it starts (`pnpm start` or the generated script). Fix only if the scaffold itself is broken. 3. Add React to the renderer. Forge's templates are vanilla — React is not included. Prefer `pnpm add` and the current Vite React docs over hand-editing `package.json` or inventing config. `pnpm add react react-dom` `pnpm add -D @vitejs/plugin-react` Then wire the renderer the way the current Vite + React docs say (`@vitejs/plugin-react` in the renderer Vite config, a minimal React root). Keep it bare — no router, UI kit, or sample screens. Confirm `pnpm start` still works. 4. Add Biome for lint + format. Prefer install + init commands over hand-writing config. `pnpm add -D -E @biomejs/biome` `pnpm exec biome init` If those commands have changed, follow the current Biome getting-started docs with pnpm. Add `lint` / `format` (or `check`) scripts that run Biome. Confirm `pnpm lint` (or the script you added) runs. If the Forge template shipped ESLint/Prettier, remove those in favor of Biome — don't leave two linters fighting. 5. Keep Electron security defaults. Do not turn off `contextIsolation` or `sandbox`, and do not enable `nodeIntegration` in renderer windows, unless I explicitly ask. 6. Do not add a UI kit, auto-updater, or packaging tweaks beyond this. ## Standing project practices Add this section to AGENTS.md: ## Engineering practices ### Ship cadence - Slices are vertical, not horizontal: each one cuts end-to-end through every layer it touches (e.g. UI → logic → storage) and lands a thin piece of real, demonstrable behavior — not "build all the models" then "all the services" then "all the UI" as separate slices. A vertical slice is independently testable and reviewable on its own; a horizontal one isn't until everything else lands too. - Smallest coherent vertical slice; commit regularly. - A slice that adds real behavior ships with tests. Exempt only for pure docs/config or trivial static markup — say so in the commit message when skipped. - Before each commit: run the tests for what changed. If the change affects runtime or UI, run the app and exercise the affected path — don't claim a UI change works without having opened it. ### Code review - Review at checkpoints, not every commit: end of a feature, before opening/merging a PR, and immediately for anything touching security-sensitive surface (secrets, auth, credential storage, process/command spawning, IPC or trust boundaries). - Small refactors or docs-only slices: a careful self-read of the diff is enough, no formal review needed. ### Commits - A commit that changes behavior states the why in 1-3 sentences in the body. Enforced by a commit-msg hook — don't bypass it. ### Structural learnings - When a structural or architectural mistake surfaces (duplicated source of truth, boundary violation, bad seam), ask whether it should become a regression test and/or an ADR before writing prose about it elsewhere. Only write the ADR if the decision is hard-to-reverse AND surprising AND a genuine tradeoff — all three. ### CONTEXT.md - Glossary only — term names and meanings, never decisions or implementation detail. Scaffolded empty at project init; add a term the first time it needs a name. ### plans/handoff.md - Living state file: current task, what's done, what's next, open decisions. Overwrite in place, under ~40 lines — it's not a log. ### Module boundaries - The moment this project gains more than one internal module/package boundary (a new package/, apps/*, packages/*, or a seam worth guarding), add or extend a dependency-cruiser config enforcing entry-point-only imports and no cycles — do this the moment the boundary appears, don't wait to be asked. ### Guard verification - Any deterministic guard added to this repo (git hook, lint rule, dependency-cruiser rule, commit-msg check, etc.) must be proven before being considered installed: trigger the violation it's meant to catch, confirm it's blocked, revert, confirm a clean run passes. State this in the commit that adds the guard — including guards added later, not just during initial setup. Now set up standing project practices. Work from what you just scaffolded — don't ask questions the stack already answered. 7. Write the "Engineering practices" section above into AGENTS.md verbatim (create the file if the CLI didn't scaffold one, append if it did). 8. Install a git safety hook blocking `git push` (incl. `--force`), `git reset --hard`, `git clean -f`/`-fd`, `git branch -D`, `git checkout .` / `git restore .`. This is a Claude Code `PreToolUse` hook on the `Bash` tool, not a native git hook — it stops the agent from running these, it doesn't lock the user out of their own terminal, and there's no bypass phrase; the user runs the command themselves if they really want it. - Write `.claude/hooks/block-dangerous-git.sh`: ```bash #!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command') DANGEROUS_PATTERNS=( "git push" "git reset --hard" "git clean -fd" "git clean -f" "git branch -D" "git checkout \." "git restore \." "push --force" "reset --hard" ) for pattern in "${DANGEROUS_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qE "$pattern"; then echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2 exit 2 fi done exit 0 ``` `chmod +x .claude/hooks/block-dangerous-git.sh` - Merge into `.claude/settings.json` (project scope — don't overwrite other keys already in the file): ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh" } ] } ] } } ``` 9. Install a pre-commit chain (current, non-legacy commands — Husky v9+ has no `husky-init`/`husky set`/`husky add`; hooks are plain scripts written into `.husky/`): ```bash pnpm add -D husky lint-staged pnpm exec husky init ``` `husky init` creates `.husky/pre-commit` (default contents `pnpm test`) and adds a `prepare` script to `package.json`. Replace the generated `.husky/pre-commit` body with: ```bash pnpm exec lint-staged ``` Add a `lint-staged` key to `package.json` wired to this stack's formatter/linter and typecheck, e.g.: ```json "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } ``` (swap in the stack's actual formatter/linter — Biome's `biome check --write`, etc.) Add `.husky/commit-msg` rejecting an empty body when the diff touches non-trivial files (skip for docs/config-only commits): ```bash #!/bin/bash commit_msg_file="$1" body=$(tail -n +3 "$commit_msg_file" | grep -v '^#' | grep -v '^\s*$') if [ -z "$body" ]; then changed=$(git diff --cached --name-only | grep -vE '\.(md)$|^docs/') if [ -n "$changed" ]; then echo "BLOCKED: commit body is empty but the diff touches non-trivial files. State the why in 1-3 sentences." >&2 exit 1 fi fi exit 0 ``` `chmod +x .husky/commit-msg` 10. Create docs/adr/ with a one-paragraph README stating the gate from the AGENTS.md section above. 11. Create CONTEXT.md, empty except a one-line header noting it's a project glossary (term → meaning), no terms yet. 12. Create plans/handoff.md from the template described above. 13. If the project already has more than one internal module boundary at scaffold time, set up dependency-cruiser now. `depcruise --init` is interactive (asks questions, no flag to answer them non-interactively) — don't run it from an agent. Install and write the config directly instead: ```bash pnpm add -D dependency-cruiser ``` `.dependency-cruiser.cjs`, extending the maintained preset rather than hand-writing rules from scratch: ```js /** @type {import('dependency-cruiser').IConfiguration} */ module.exports = { extends: "dependency-cruiser/configs/recommended", forbidden: [ // add entry-point-only / no-cross-boundary-import rules for this // project's actual boundaries here ], options: { tsPreCompilationDeps: true, }, }; ``` Add a `lint:deps` (or similar) script running `depcruise --config .dependency-cruiser.cjs <src-dirs>` and wire it into the pre-commit chain from step 9. Otherwise leave it — the AGENTS.md rule above means it gets added automatically whenever a boundary appears later, without needing this prompt again. 14. Prove every guard installed in steps 8-9 (and 13, if run): trigger the violation, confirm blocked, revert, confirm clean. Report what was installed, what was deferred and why, and confirm each guard was proven.CLI command
pnpm create electron-app@latest <project-name> --template=vite-typescript
Expo
default@sdk-57 — Expo Router, native tabs, Biome or ESLint, project Expo Skills for Cursor.
Official
create-expo-app— pick Biome or ESLint (the template's own default) and the prompt updates.Read the prompt
Scaffold a new Expo app with Biome. If a project name isn't obvious from context, ask me for one. Prefer the official create-expo-app CLI over cloning a third-party boilerplate. Never hang forever on interactive prompts. 1. Create the app with the current CLI (prefer `pnpm create expo-app@latest` so the template matches today): pnpm create expo-app@latest <project-name> --template default@sdk-57 -y If the template tag or flag has been renamed or removed, check `pnpm create expo-app@latest --help` and the live Expo docs, then map to the same intent: official `default` template on the current SDK (SDK 57 or whatever `default@sdk-*` the docs recommend now), TypeScript, Expo Router, keep the generated AGENTS.md / agent files (do **not** pass `--no-agents-md`). The default template ships Expo Router with native tabs (`expo-router/unstable-native-tabs` on native). That is expected — do not swap them for the older JS `Tabs` layout unless I ask. 2. cd into the project. Confirm it starts (`pnpm start` / `pnpm exec expo start`). Prefer a **development build** / simulator or `pnpm exec expo run:ios` / `pnpm exec expo run:android` over Expo Go. Fix only if the scaffold itself is broken. 3. Install official Expo Skills into **this project** (not globally) so Cursor cloud agents that clone the repo get them. There is no Expo plugin on the Cursor Marketplace — skills via the official CLI are the supported path: pnpm dlx skills add expo/skills --skill '*' --agent cursor -y If that CLI syntax has changed, check https://docs.expo.dev/skills/ and https://github.com/expo/skills, then install the official `expo/skills` set for Cursor into the project. Commit the generated skill files (and any skills lockfile) with the app. If I explicitly say I want skills only on this machine and not in the repo, use the same command with `-g` / `--global` instead — and do not commit skill files. 4. Swap the default `expo lint` setup for Biome. Prefer install + init commands over hand-writing config. `pnpm add -D -E @biomejs/biome` `pnpm exec biome init` If those commands have changed, follow the current Biome getting-started docs with pnpm. Point the `lint` script at Biome instead of `expo lint` (and add a `format`/`check` script if useful). Confirm `pnpm lint` runs. Don't let the template's lazy ESLint setup trigger — if `expo lint` was already run and installed `eslint-config-expo`, remove it so there's only one linter. 5. Do not add EAS config, auth, UI kits, NativeWind, or extra packages beyond this. Keep the generated AGENTS.md — you'll add to it below, not overwrite it. ## Standing project practices Add this section to AGENTS.md: ## Engineering practices ### Ship cadence - Slices are vertical, not horizontal: each one cuts end-to-end through every layer it touches (e.g. UI → logic → storage) and lands a thin piece of real, demonstrable behavior — not "build all the models" then "all the services" then "all the UI" as separate slices. A vertical slice is independently testable and reviewable on its own; a horizontal one isn't until everything else lands too. - Smallest coherent vertical slice; commit regularly. - A slice that adds real behavior ships with tests. Exempt only for pure docs/config or trivial static markup — say so in the commit message when skipped. - Before each commit: run the tests for what changed. If the change affects runtime or UI, run the app and exercise the affected path — don't claim a UI change works without having opened it. ### Code review - Review at checkpoints, not every commit: end of a feature, before opening/merging a PR, and immediately for anything touching security-sensitive surface (secrets, auth, credential storage, process/command spawning, IPC or trust boundaries). - Small refactors or docs-only slices: a careful self-read of the diff is enough, no formal review needed. ### Commits - A commit that changes behavior states the why in 1-3 sentences in the body. Enforced by a commit-msg hook — don't bypass it. ### Structural learnings - When a structural or architectural mistake surfaces (duplicated source of truth, boundary violation, bad seam), ask whether it should become a regression test and/or an ADR before writing prose about it elsewhere. Only write the ADR if the decision is hard-to-reverse AND surprising AND a genuine tradeoff — all three. ### CONTEXT.md - Glossary only — term names and meanings, never decisions or implementation detail. Scaffolded empty at project init; add a term the first time it needs a name. ### plans/handoff.md - Living state file: current task, what's done, what's next, open decisions. Overwrite in place, under ~40 lines — it's not a log. ### Module boundaries - The moment this project gains more than one internal module/package boundary (a new package/, apps/*, packages/*, or a seam worth guarding), add or extend a dependency-cruiser config enforcing entry-point-only imports and no cycles — do this the moment the boundary appears, don't wait to be asked. ### Guard verification - Any deterministic guard added to this repo (git hook, lint rule, dependency-cruiser rule, commit-msg check, etc.) must be proven before being considered installed: trigger the violation it's meant to catch, confirm it's blocked, revert, confirm a clean run passes. State this in the commit that adds the guard — including guards added later, not just during initial setup. Now set up standing project practices. Work from what you just scaffolded — don't ask questions the stack already answered. 6. Write the "Engineering practices" section above into AGENTS.md verbatim (create the file if the CLI didn't scaffold one, append if it did). 7. Install a git safety hook blocking `git push` (incl. `--force`), `git reset --hard`, `git clean -f`/`-fd`, `git branch -D`, `git checkout .` / `git restore .`. This is a Claude Code `PreToolUse` hook on the `Bash` tool, not a native git hook — it stops the agent from running these, it doesn't lock the user out of their own terminal, and there's no bypass phrase; the user runs the command themselves if they really want it. - Write `.claude/hooks/block-dangerous-git.sh`: ```bash #!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command') DANGEROUS_PATTERNS=( "git push" "git reset --hard" "git clean -fd" "git clean -f" "git branch -D" "git checkout \." "git restore \." "push --force" "reset --hard" ) for pattern in "${DANGEROUS_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qE "$pattern"; then echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2 exit 2 fi done exit 0 ``` `chmod +x .claude/hooks/block-dangerous-git.sh` - Merge into `.claude/settings.json` (project scope — don't overwrite other keys already in the file): ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh" } ] } ] } } ``` 8. Install a pre-commit chain (current, non-legacy commands — Husky v9+ has no `husky-init`/`husky set`/`husky add`; hooks are plain scripts written into `.husky/`): ```bash pnpm add -D husky lint-staged pnpm exec husky init ``` `husky init` creates `.husky/pre-commit` (default contents `pnpm test`) and adds a `prepare` script to `package.json`. Replace the generated `.husky/pre-commit` body with: ```bash pnpm exec lint-staged ``` Add a `lint-staged` key to `package.json` wired to this stack's formatter/linter and typecheck, e.g.: ```json "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } ``` (swap in the stack's actual formatter/linter — Biome's `biome check --write`, etc.) Add `.husky/commit-msg` rejecting an empty body when the diff touches non-trivial files (skip for docs/config-only commits): ```bash #!/bin/bash commit_msg_file="$1" body=$(tail -n +3 "$commit_msg_file" | grep -v '^#' | grep -v '^\s*$') if [ -z "$body" ]; then changed=$(git diff --cached --name-only | grep -vE '\.(md)$|^docs/') if [ -n "$changed" ]; then echo "BLOCKED: commit body is empty but the diff touches non-trivial files. State the why in 1-3 sentences." >&2 exit 1 fi fi exit 0 ``` `chmod +x .husky/commit-msg` 9. Create docs/adr/ with a one-paragraph README stating the gate from the AGENTS.md section above. 10. Create CONTEXT.md, empty except a one-line header noting it's a project glossary (term → meaning), no terms yet. 11. Create plans/handoff.md from the template described above. 12. If the project already has more than one internal module boundary at scaffold time, set up dependency-cruiser now. `depcruise --init` is interactive (asks questions, no flag to answer them non-interactively) — don't run it from an agent. Install and write the config directly instead: ```bash pnpm add -D dependency-cruiser ``` `.dependency-cruiser.cjs`, extending the maintained preset rather than hand-writing rules from scratch: ```js /** @type {import('dependency-cruiser').IConfiguration} */ module.exports = { extends: "dependency-cruiser/configs/recommended", forbidden: [ // add entry-point-only / no-cross-boundary-import rules for this // project's actual boundaries here ], options: { tsPreCompilationDeps: true, }, }; ``` Add a `lint:deps` (or similar) script running `depcruise --config .dependency-cruiser.cjs <src-dirs>` and wire it into the pre-commit chain from step 8. Otherwise leave it — the AGENTS.md rule above means it gets added automatically whenever a boundary appears later, without needing this prompt again. 13. Prove every guard installed in steps 7-8 (and 12, if run): trigger the violation, confirm blocked, revert, confirm clean. Report what was installed, what was deferred and why, and confirm each guard was proven.CLI command
pnpm create expo-app@latest <project-name> --template default@sdk-57 -y
The Next.js recipes intentionally leave out Next.js, React, and Vercel agent skills. I don’t usually start from optimization playbooks. If you want those, start at Vercel’s agent skills. TanStack Start is different: pick add-ons in the builder, and Intent loads library skills from the packages you install.
Expo has no plugin on the Cursor Marketplace (unlike Convex). The Expo recipe installs official Expo Skills into the project so Cursor cloud agents that clone the repo can use them; use a global skills install only if you rarely run cloud agents.