bootstrap-project
Invariants
- Use the canonical stack: Next.js 16 App Router, Sanity v5, Tailwind 4, shadcn/ui, TypeScript, npm. Do not offer alternatives.
- Source code comes from
eljun/kt-monorepo-template via git clone --depth 1. Do not generate boilerplate inline as a fallback if the clone fails.
- Design tokens are an INPUT (file path or paste-in). Do not invent or generate them.
- Stop and confirm before each irreversible cloud action: GitHub repo creation, Vercel project link, git push. Never auto-create Sanity projects.
- Do not run
npm run dev automatically — leave it for the user.
- Emit a one-line status message before each major step so the user sees progress.
Prerequisites
Run these checks first. If any fail, stop and report which one.
| Tool |
Check |
Expected |
| Node |
node --version |
v20.x or higher |
| npm |
npm --version |
v10.x or higher |
| gh |
gh auth status |
Logged in to github.com |
| vercel |
vercel whoami |
Returns a username |
| Sanity |
npx -y sanity@latest --version |
Returns a version (no global install needed) |
Inputs (ask the user, in order)
- Project slug — kebab-case, used for directory name and repo names. Example:
acme-wellness-spa.
- Project display name — used in copy and
package.json. Example: Acme Wellness Spa.
- Project directory — default:
~/Code/Personal/{slug}.
- Design tokens source — one of:
- Absolute path to a CSS file containing the
@theme block to inject into app/globals.css
skip — keep the template's placeholder palette
- GitHub visibility —
private (default) or public.
- Sanity project — one of:
existing — user provides project ID + dataset name
new — user creates a project at https://sanity.io/manage in a new tab, then provides the project ID + dataset name (skill never creates Sanity projects automatically)
- Vercel project name — default: same as slug.
Workflow
- Verify prerequisites. Run all checks. Stop on failure.
- Confirm inputs. Echo answers back as a summary. Wait for explicit "go" before any side effects.
- Clone template. Status: "Cloning kt-monorepo-template..."
git clone --depth 1 https://github.com/eljun/kt-monorepo-template.git {target_dir}
rm -rf {target_dir}/.git
- Substitute placeholders. Status: "Substituting project placeholders..."
- Find files containing placeholders:
grep -rl '{{PROJECT_' {target_dir}
- Replace
{{PROJECT_SLUG}}, {{PROJECT_NAME}}, {{PROJECT_DESCRIPTION}} across all matches.
- Inject design tokens. Status: "Injecting design tokens..." (skip if user chose
skip)
- Read user's tokens file.
- Replace the
@theme { ... } block in {target_dir}/app/globals.css with the user's contents. Preserve everything else in globals.css.
- Wire Sanity config. Status: "Wiring Sanity config..."
- Update
sanity/env.ts (or wherever the template stores the project ID/dataset) with the user-provided values.
- Write the same values to
.env.local if the template uses env vars (NEXT_PUBLIC_SANITY_PROJECT_ID, NEXT_PUBLIC_SANITY_DATASET).
- Install dependencies. Status: "Installing dependencies (this may take a minute)..."
cd {target_dir} && npm install
- Initial commit. Status: "Creating initial commit..."
cd {target_dir} && git init && git add . && git commit -m "feat: initial scaffold from kt-monorepo-template"
- Confirm GitHub repo creation. Show user: "About to run
gh repo create eljun/{slug} --{visibility} --source . --remote origin. OK?" Wait for explicit confirmation.
- Create GitHub repo. Status: "Creating GitHub repo..." Run the confirmed command.
- Confirm Vercel link. Show user: "About to run
vercel link (interactive, may ask scope and project name). OK?" Wait for confirmation.
- Link Vercel. Status: "Linking Vercel project..."
cd {target_dir} && vercel link
The CLI prompts the user for scope and project — do not try to script around it.
- Pull Vercel env.
cd {target_dir} && vercel env pull .env.local
The file may be empty if no env vars are set yet — that is fine.
- Confirm push. Show user: "About to push to GitHub. OK?" Wait for confirmation.
- Push to GitHub. Status: "Pushing to GitHub..."
cd {target_dir} && git push -u origin main
- Final report. Print a structured summary with these fields:
- Local directory
- GitHub URL:
https://github.com/eljun/{slug}
- Vercel project URL (from
vercel link output)
- Sanity project ID + dataset
- Sanity Studio URL:
http://localhost:3000/studio (once dev runs)
- Next steps:
cd {target_dir} && npm run dev
Status messages (emit before each step)
| Step |
Message |
| 1 |
Checking prerequisites... |
| 3 |
Cloning kt-monorepo-template... |
| 4 |
Substituting project placeholders... |
| 5 |
Injecting design tokens... |
| 6 |
Wiring Sanity config... |
| 7 |
Installing dependencies (this may take a minute)... |
| 8 |
Creating initial commit... |
| 10 |
Creating GitHub repo... |
| 12 |
Linking Vercel project... |
| 15 |
Pushing to GitHub... |
Failure handling
| Failure |
Action |
| Template clone fails |
The eljun/kt-monorepo-template repo may not exist or be private. Stop and tell the user — do not generate inline boilerplate as a fallback. |
| Placeholder substitution finds zero matches |
Warn but continue — template may have evolved past placeholders. |
npm install fails |
Stop. Leave the directory in place. Show the install error. |
gh repo create collision |
Stop and ask for an alternative slug. Do not auto-suffix. |
vercel link fails |
Skip step 13. Leave a TODO: vercel link note in the final report. The project is still functional locally. |
git push fails |
Stop. Local repo is intact. Show the push error so the user can debug (auth, branch protection, etc.). |
Out of scope (v1)
- Stack alternatives (Svelte, Supabase, Material UI, Pages Router, etc.)
- Automatic Sanity project creation
- Automatic dev server startup
- CI/CD workflow configuration
- Custom domain setup on Vercel
- Sanity content seeding or migration
Handoff
End with the structured report from step 16, plus:
Project bootstrapped: {target_dir}
Status: ready for first dev session
Next: cd {target_dir} && npm run dev