From tytos-standards
Scaffold a new Tytos project with standard structure, Docker, Supabase, HeroUI, and Prisma
npx claudepluginhub ke-netizen-oops/tytos-standards<project-name># Init Project Scaffold a new Tytos project following team standards. Creates a complete Next.js project with Supabase Auth, HeroUI, Prisma, Docker, and all enforcement infrastructure. ## Step 1: Gather Project Info Ask the user for: - **Project name** (kebab-case, e.g., `my-app`) — use $ARGUMENTS if provided - **Brief description** (one line) - **Supabase project URL** (or "create later") - **Port number** (default: 3000) ## Step 2: Create Next.js Project ## Step 3: Install Approved Dependencies ## Step 4: Copy Standards Infrastructure Copy the following from the tytos/standards...
/init-projectInitializes new project with essential directory structure, git repo, README, framework-specific configs (React/Vue/Angular/Express/FastAPI/etc.), TypeScript/linting/testing/build tools, and GitHub Actions CI/CD.
/init-projectInitializes new project with essential directory structure, git repo, README, framework-specific configs (React/Vue/Angular/Express/FastAPI/etc.), TypeScript/linting/testing/build tools, and GitHub Actions CI/CD.
/init-projectInitializes project by interactively generating CLAUDE.md (overview and stack), spec.md (features), prompt_plan.md (phases). Detects tech stack; optional [name] [--type next|vite|go|python|rust].
/init-projectScans current codebase to auto-generate project-level CLAUDE.md with detected stack, conventions, domain context, team rules, and clarifying questions.
/init-projectConfigures repo for Obsidian PKM: detects/links vault project folder, scaffolds index if needed, updates CLAUDE.md with PKM path annotation and integration section.
/init-projectInitialize project with constitution, standards, and docs structure for AI-augmented development
Scaffold a new Tytos project following team standards. Creates a complete Next.js project with Supabase Auth, HeroUI, Prisma, Docker, and all enforcement infrastructure.
Ask the user for:
my-app) — use $ARGUMENTS if providedbunx create-next-app@latest $PROJECT_NAME --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --use-bun
cd $PROJECT_NAME
# Core
bun add @supabase/supabase-js @supabase/ssr @heroui/react @heroui/system @heroui/theme framer-motion @prisma/client zod zustand @tanstack/react-query
# Dev
bun add -d prisma tsx
Copy the following from the tytos/standards repo (or generate them):
Copy the master CLAUDE.md template to project root. Replace [PROJECT_NAME] with the actual project name.
Create .claude/ with:
settings.json — hooks config + permission deny rules (copy from standards/project-template/.claude/settings.json)rules/standards.md — always-loaded standardsrules/testing.md — testing disciplinerules/frontend.md — path-scoped frontend rulesrules/backend.md — path-scoped backend ruleshooks/check-mock-data.sh — mock data detectionhooks/check-custom-auth.sh — auth violation detectionhooks/check-custom-components.sh — custom UI detectionhooks/check-seed-in-migration.sh — migration seed detectionMake all hook scripts executable: chmod +x .claude/hooks/*.sh
Create prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
Create prisma/seed.ts:
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
async function main() {
console.log("Seeding database...")
// Add seed data here
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
Create src/lib/supabase/client.ts:
import { createBrowserClient } from "@supabase/ssr"
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
Create src/lib/supabase/server.ts:
import { createServerClient } from "@supabase/ssr"
import { cookies } from "next/headers"
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method is called from a Server Component
}
},
},
}
)
}
Create src/middleware.ts:
import { createServerClient } from "@supabase/ssr"
import { NextResponse, type NextRequest } from "next/server"
export async function middleware(request: NextRequest) {
let supabaseResponse = NextResponse.next({ request })
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) =>
request.cookies.set(name, value)
)
supabaseResponse = NextResponse.next({ request })
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
},
},
}
)
await supabase.auth.getUser()
return supabaseResponse
}
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
],
}
Create Dockerfile:
FROM node:20-alpine AS base
# Install bun
RUN npm install -g bun
# Dependencies
FROM base AS deps
WORKDIR /app
COPY package.json bun.lock* ./
RUN bun install --frozen-lockfile
# Build
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN bun run build
# Runner
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]
Create docker-compose.yml:
services:
app:
build: .
ports:
- "${PORT:-3000}:3000"
env_file:
- .env.local
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: app
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
volumes:
pgdata:
Create .dockerignore:
node_modules
.next
.git
.env.local
Create .env.example:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Database (Supabase connection pooler)
DATABASE_URL=postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres?pgbouncer=true
DIRECT_URL=postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:5432/postgres
# App
PORT=3000
NODE_ENV=development
Create .mcp.json:
{
"mcpServers": {
"supabase": {
"type": "http",
"url": "https://mcp.supabase.com/mcp"
}
}
}
Create these directories:
src/
app/
(auth)/login/ # Public auth pages
(dashboard)/ # Protected pages
api/ # API routes
components/
layouts/ # Layout components
lib/
supabase/ # Already created above
services/ # Business logic
stores/ # Zustand stores
utils/ # Utility functions
hooks/ # Custom React hooks
types/ # TypeScript type definitions
Add/update these scripts in package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "prisma generate",
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev",
"db:migrate:deploy": "prisma migrate deploy",
"db:push": "prisma db push",
"db:seed": "prisma db seed",
"db:studio": "prisma studio"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
Ensure next.config.ts has standalone output for Docker:
const nextConfig = {
output: "standalone",
}
git init
git add .
git commit -m "feat: initial project setup with Tytos standards"
✓ Project scaffolded: $PROJECT_NAME
✓ Standards: CLAUDE.md + .claude/rules/ + .claude/hooks/ + .claude/settings.json
✓ Auth: Supabase client/server/middleware configured
✓ Database: Prisma schema + seed script
✓ Docker: Dockerfile (multi-stage) + docker-compose.yml
✓ UI: HeroUI v3 installed
Next steps:
1. Copy .env.example to .env.local and fill in Supabase credentials
2. Run `bun run db:migrate` after setting DATABASE_URL
3. Run `bun run dev` to verify setup
4. Run `/audit-project` to confirm compliance