diff --git a/.claude/agents/better-auth-expert.md b/.claude/agents/better-auth-expert.md index 0d45a76..9eae857 100644 --- a/.claude/agents/better-auth-expert.md +++ b/.claude/agents/better-auth-expert.md @@ -1,11 +1,11 @@ --- name: better-auth-expert -description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 15."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 15."\n\n +description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 16."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 16."\n\n model: sonnet color: red --- -You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 15+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards. +You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 16+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards. ## Core Responsibilities @@ -16,7 +16,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc - Use the Web Search tool to find the latest Better Auth documentation - Use the Context 7 MCP server to retrieve up-to-date Better Auth patterns and examples - Cross-reference multiple sources to ensure accuracy - - Verify that recommendations are compatible with Next.js 15+ + - Verify that recommendations are compatible with Next.js 16+ 3. **Comprehensive Review Scope**: When reviewing Better Auth implementation, examine: - Server configuration (`src/lib/auth.ts`) @@ -38,7 +38,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc **Step 2: Fetch Current Documentation** - Use Web Search to find Better Auth's official documentation for the specific features being used -- Search for "Better Auth [feature] Next.js 15 best practices" +- Search for "Better Auth [feature] Next.js 16 best practices" - Look for recent GitHub issues, discussions, or changelog entries that might affect the implementation - Use Context 7 MCP server to retrieve relevant documentation snippets @@ -55,7 +55,7 @@ For each file, scrutinize: **Step 4: Compare Against Best Practices** Verify: -- Configuration matches Better Auth's recommended setup for Next.js 15 +- Configuration matches Better Auth's recommended setup for Next.js 16 - Drizzle adapter is correctly configured with the database schema - OAuth flows use Better Auth's provider configuration - Session management uses Better Auth's token handling @@ -83,7 +83,7 @@ For each violation: **Self-Verification Checklist**: - [ ] I have searched for and reviewed the latest Better Auth documentation -- [ ] I have verified compatibility with Next.js 15+ App Router patterns +- [ ] I have verified compatibility with Next.js 16+ App Router patterns - [ ] I have checked for any recent breaking changes in Better Auth - [ ] My recommendations use Better Auth's built-in functions, not custom implementations - [ ] I have provided code examples with proper imports and type safety diff --git a/.claude/agents/polar-payments-expert.md b/.claude/agents/polar-payments-expert.md index 59e9248..b9313fb 100644 --- a/.claude/agents/polar-payments-expert.md +++ b/.claude/agents/polar-payments-expert.md @@ -5,7 +5,7 @@ model: sonnet color: green --- -You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 15+ applications. +You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 16+ applications. ## Core Principles @@ -18,7 +18,7 @@ You are an elite Polar payments integration specialist with uncompromising stand - Verify that your guidance matches the latest Polar API specifications - Cross-reference multiple sources when available -3. **Next.js 15+ Compatibility**: All implementations must be compatible with Next.js 15 App Router patterns, including: +3. **Next.js 16+ Compatibility**: All implementations must be compatible with Next.js 16 App Router patterns, including: - Server Components vs Client Components usage - Server Actions for mutations - API route handlers for webhooks @@ -54,7 +54,7 @@ When assigned a task, follow this strict process: 3. Add detailed comments explaining security-critical sections 4. Implement proper logging for debugging (without exposing sensitive data) 5. Use TypeScript with strict typing -6. Follow Next.js 15+ conventions (Server Actions, route handlers) +6. Follow Next.js 16+ conventions (Server Actions, route handlers) 7. Ensure webhook endpoints are properly secured 8. Implement idempotency keys where required diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 9649562..058b2ff 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -12,7 +12,8 @@ "Bash(git add:*)", "Bash(git log:*)", "Bash(find:*)", - "Bash(git checkout:*)" + "Bash(git checkout:*)", + "Bash(cat:*)" ] }, "enableAllProjectMcpServers": true, diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..4e6d937 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '[BUG] ' +labels: bug +assignees: '' +--- + +## Describe the bug + +A clear and concise description of what the bug is. + +## To Reproduce + +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Expected behavior + +A clear and concise description of what you expected to happen. + +## Screenshots + +If applicable, add screenshots to help explain your problem. + +## Environment + +- OS: [e.g. Windows, macOS, Linux] +- Node.js version: [e.g. 20.10.0] +- Browser: [e.g. Chrome, Safari] +- Package manager: [e.g. pnpm, npm] + +## Additional context + +Add any other context about the problem here. + +## Possible Solution + +If you have suggestions on a fix for the bug, please describe it here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..627c8b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '[FEATURE] ' +labels: enhancement +assignees: '' +--- + +## Is your feature request related to a problem? + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Describe the solution you'd like + +A clear and concise description of what you want to happen. + +## Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've considered. + +## Additional context + +Add any other context or screenshots about the feature request here. + +## Implementation suggestion + +If you have suggestions on how to implement this feature, please describe it here. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7cff8fd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,88 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run ESLint + run: pnpm lint + + typecheck: + name: Type Check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run TypeScript type check + run: pnpm typecheck + + build: + name: Build + runs-on: ubuntu-latest + needs: [lint, typecheck] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build application + run: pnpm build + env: + # Provide minimal env vars for build (no actual secrets needed for build check) + POSTGRES_URL: "postgresql://user:pass@localhost:5432/db" + BETTER_AUTH_SECRET: "build-check-secret-32-characters!" + NEXT_PUBLIC_APP_URL: "http://localhost:3000" + # Skip database migration during CI build + SKIP_ENV_VALIDATION: "true" diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..5177fb2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,25 @@ +# Dependencies +node_modules/ +pnpm-lock.yaml + +# Build outputs +.next/ +dist/ +build/ + +# Database +drizzle/ + +# Generated files +*.min.js +*.min.css + +# Template (has its own formatting) +create-agentic-app/ + +# Cache +.cache/ + +# IDE +.idea/ +.vscode/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..a79b3d6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 100, + "bracketSpacing": true, + "arrowParens": "always", + "endOfLine": "lf", + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/CLAUDE.md b/CLAUDE.md index eabdb4e..c273a78 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,11 +2,11 @@ ## Project Overview -This is a Next.js 15 boilerplate for building AI-powered applications with authentication, database, and modern UI components. +This is a Next.js 16 boilerplate for building AI-powered applications with authentication, database, and modern UI components. ### Tech Stack -- **Framework**: Next.js 15 with App Router, React 19, TypeScript +- **Framework**: Next.js 16 with App Router, React 19, TypeScript - **AI Integration**: Vercel AI SDK 5 + OpenRouter (access to 100+ AI models) - **Authentication**: BetterAuth with Google OAuth - **Database**: PostgreSQL with Drizzle ORM @@ -182,7 +182,7 @@ The project includes technical documentation in `docs/`: - Use TypeScript with proper types 9. **API Routes** - - Follow Next.js 15 App Router conventions + - Follow Next.js 16 App Router conventions - Use Route Handlers (route.ts files) - Return Response objects - Handle errors appropriately diff --git a/README.md b/README.md index c72c33c..fb8e78d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A complete agentic coding boilerplate with authentication, PostgreSQL database, - **šŸ¤– AI Integration**: Vercel AI SDK with OpenRouter (access to 100+ AI models) - **šŸ“ File Storage**: Automatic local/Vercel Blob storage with seamless switching - **šŸŽØ UI Components**: shadcn/ui with Tailwind CSS -- **⚔ Modern Stack**: Next.js 15, React 19, TypeScript +- **⚔ Modern Stack**: Next.js 16, React 19, TypeScript - **šŸ“± Responsive**: Mobile-first design approach ## šŸŽ„ Video Tutorial diff --git a/create-agentic-app/README.md b/create-agentic-app/README.md index fb41055..9cfbc23 100644 --- a/create-agentic-app/README.md +++ b/create-agentic-app/README.md @@ -20,7 +20,7 @@ npx create-agentic-app@latest my-app This starter kit includes: -- **Next.js 15** with App Router and Turbopack +- **Next.js 16** with App Router and Turbopack - **Better Auth** for authentication (email/password, OAuth) - **AI SDK** by Vercel for AI chat functionality - **Drizzle ORM** with PostgreSQL database diff --git a/create-agentic-app/package-lock.json b/create-agentic-app/package-lock.json index 9057735..6681803 100644 --- a/create-agentic-app/package-lock.json +++ b/create-agentic-app/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-agentic-app", - "version": "1.1.18", + "version": "1.1.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-agentic-app", - "version": "1.1.18", + "version": "1.1.19", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/create-agentic-app/package.json b/create-agentic-app/package.json index a458c1b..1142959 100644 --- a/create-agentic-app/package.json +++ b/create-agentic-app/package.json @@ -1,6 +1,6 @@ { "name": "create-agentic-app", - "version": "1.1.18", + "version": "1.1.19", "description": "Scaffold a new agentic AI application with Next.js, Better Auth, and AI SDK", "type": "module", "bin": { diff --git a/create-agentic-app/template/.claude/agents/better-auth-expert.md b/create-agentic-app/template/.claude/agents/better-auth-expert.md index 0d45a76..9eae857 100644 --- a/create-agentic-app/template/.claude/agents/better-auth-expert.md +++ b/create-agentic-app/template/.claude/agents/better-auth-expert.md @@ -1,11 +1,11 @@ --- name: better-auth-expert -description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 15."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 15."\n\n +description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 16."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 16."\n\n model: sonnet color: red --- -You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 15+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards. +You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 16+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards. ## Core Responsibilities @@ -16,7 +16,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc - Use the Web Search tool to find the latest Better Auth documentation - Use the Context 7 MCP server to retrieve up-to-date Better Auth patterns and examples - Cross-reference multiple sources to ensure accuracy - - Verify that recommendations are compatible with Next.js 15+ + - Verify that recommendations are compatible with Next.js 16+ 3. **Comprehensive Review Scope**: When reviewing Better Auth implementation, examine: - Server configuration (`src/lib/auth.ts`) @@ -38,7 +38,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc **Step 2: Fetch Current Documentation** - Use Web Search to find Better Auth's official documentation for the specific features being used -- Search for "Better Auth [feature] Next.js 15 best practices" +- Search for "Better Auth [feature] Next.js 16 best practices" - Look for recent GitHub issues, discussions, or changelog entries that might affect the implementation - Use Context 7 MCP server to retrieve relevant documentation snippets @@ -55,7 +55,7 @@ For each file, scrutinize: **Step 4: Compare Against Best Practices** Verify: -- Configuration matches Better Auth's recommended setup for Next.js 15 +- Configuration matches Better Auth's recommended setup for Next.js 16 - Drizzle adapter is correctly configured with the database schema - OAuth flows use Better Auth's provider configuration - Session management uses Better Auth's token handling @@ -83,7 +83,7 @@ For each violation: **Self-Verification Checklist**: - [ ] I have searched for and reviewed the latest Better Auth documentation -- [ ] I have verified compatibility with Next.js 15+ App Router patterns +- [ ] I have verified compatibility with Next.js 16+ App Router patterns - [ ] I have checked for any recent breaking changes in Better Auth - [ ] My recommendations use Better Auth's built-in functions, not custom implementations - [ ] I have provided code examples with proper imports and type safety diff --git a/create-agentic-app/template/.claude/agents/polar-payments-expert.md b/create-agentic-app/template/.claude/agents/polar-payments-expert.md index 59e9248..b9313fb 100644 --- a/create-agentic-app/template/.claude/agents/polar-payments-expert.md +++ b/create-agentic-app/template/.claude/agents/polar-payments-expert.md @@ -5,7 +5,7 @@ model: sonnet color: green --- -You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 15+ applications. +You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 16+ applications. ## Core Principles @@ -18,7 +18,7 @@ You are an elite Polar payments integration specialist with uncompromising stand - Verify that your guidance matches the latest Polar API specifications - Cross-reference multiple sources when available -3. **Next.js 15+ Compatibility**: All implementations must be compatible with Next.js 15 App Router patterns, including: +3. **Next.js 16+ Compatibility**: All implementations must be compatible with Next.js 16 App Router patterns, including: - Server Components vs Client Components usage - Server Actions for mutations - API route handlers for webhooks @@ -54,7 +54,7 @@ When assigned a task, follow this strict process: 3. Add detailed comments explaining security-critical sections 4. Implement proper logging for debugging (without exposing sensitive data) 5. Use TypeScript with strict typing -6. Follow Next.js 15+ conventions (Server Actions, route handlers) +6. Follow Next.js 16+ conventions (Server Actions, route handlers) 7. Ensure webhook endpoints are properly secured 8. Implement idempotency keys where required diff --git a/create-agentic-app/template/.claude/settings.local.json b/create-agentic-app/template/.claude/settings.local.json index 9649562..058b2ff 100644 --- a/create-agentic-app/template/.claude/settings.local.json +++ b/create-agentic-app/template/.claude/settings.local.json @@ -12,7 +12,8 @@ "Bash(git add:*)", "Bash(git log:*)", "Bash(find:*)", - "Bash(git checkout:*)" + "Bash(git checkout:*)", + "Bash(cat:*)" ] }, "enableAllProjectMcpServers": true, diff --git a/create-agentic-app/template/.nvmrc b/create-agentic-app/template/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/create-agentic-app/template/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/create-agentic-app/template/.prettierignore b/create-agentic-app/template/.prettierignore new file mode 100644 index 0000000..5177fb2 --- /dev/null +++ b/create-agentic-app/template/.prettierignore @@ -0,0 +1,25 @@ +# Dependencies +node_modules/ +pnpm-lock.yaml + +# Build outputs +.next/ +dist/ +build/ + +# Database +drizzle/ + +# Generated files +*.min.js +*.min.css + +# Template (has its own formatting) +create-agentic-app/ + +# Cache +.cache/ + +# IDE +.idea/ +.vscode/ diff --git a/create-agentic-app/template/.prettierrc b/create-agentic-app/template/.prettierrc new file mode 100644 index 0000000..a79b3d6 --- /dev/null +++ b/create-agentic-app/template/.prettierrc @@ -0,0 +1,11 @@ +{ + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 100, + "bracketSpacing": true, + "arrowParens": "always", + "endOfLine": "lf", + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/create-agentic-app/template/CLAUDE.md b/create-agentic-app/template/CLAUDE.md index eabdb4e..c273a78 100644 --- a/create-agentic-app/template/CLAUDE.md +++ b/create-agentic-app/template/CLAUDE.md @@ -2,11 +2,11 @@ ## Project Overview -This is a Next.js 15 boilerplate for building AI-powered applications with authentication, database, and modern UI components. +This is a Next.js 16 boilerplate for building AI-powered applications with authentication, database, and modern UI components. ### Tech Stack -- **Framework**: Next.js 15 with App Router, React 19, TypeScript +- **Framework**: Next.js 16 with App Router, React 19, TypeScript - **AI Integration**: Vercel AI SDK 5 + OpenRouter (access to 100+ AI models) - **Authentication**: BetterAuth with Google OAuth - **Database**: PostgreSQL with Drizzle ORM @@ -182,7 +182,7 @@ The project includes technical documentation in `docs/`: - Use TypeScript with proper types 9. **API Routes** - - Follow Next.js 15 App Router conventions + - Follow Next.js 16 App Router conventions - Use Route Handlers (route.ts files) - Return Response objects - Handle errors appropriately diff --git a/create-agentic-app/template/README.md b/create-agentic-app/template/README.md index c72c33c..fb8e78d 100644 --- a/create-agentic-app/template/README.md +++ b/create-agentic-app/template/README.md @@ -9,7 +9,7 @@ A complete agentic coding boilerplate with authentication, PostgreSQL database, - **šŸ¤– AI Integration**: Vercel AI SDK with OpenRouter (access to 100+ AI models) - **šŸ“ File Storage**: Automatic local/Vercel Blob storage with seamless switching - **šŸŽØ UI Components**: shadcn/ui with Tailwind CSS -- **⚔ Modern Stack**: Next.js 15, React 19, TypeScript +- **⚔ Modern Stack**: Next.js 16, React 19, TypeScript - **šŸ“± Responsive**: Mobile-first design approach ## šŸŽ„ Video Tutorial diff --git a/create-agentic-app/template/docs/business/starter-prompt.md b/create-agentic-app/template/docs/business/starter-prompt.md index 86de00a..cf3366e 100644 --- a/create-agentic-app/template/docs/business/starter-prompt.md +++ b/create-agentic-app/template/docs/business/starter-prompt.md @@ -42,7 +42,7 @@ The only things to preserve are: ## Tech Stack -- Next.js 15 with App Router +- Next.js 16 with App Router - TypeScript - Tailwind CSS - Better Auth for authentication diff --git a/create-agentic-app/template/docs/technical/ai/streaming.md b/create-agentic-app/template/docs/technical/ai/streaming.md index 89af7d1..036f65d 100644 --- a/create-agentic-app/template/docs/technical/ai/streaming.md +++ b/create-agentic-app/template/docs/technical/ai/streaming.md @@ -11,9 +11,9 @@ If you are unfamiliar with the concepts of [Prompt Engineering](/docs/advanced/p To follow this quickstart, you'll need: - Node.js 18+ and pnpm installed on your local development machine. -- An OpenAI API key. +- An OpenRouter API key. -If you haven't obtained your OpenAI API key, you can do so by [signing up](https://platform.openai.com/signup/) on the OpenAI website. +If you haven't obtained your OpenRouter API key, you can do so by [signing up](https://openrouter.ai/) on the OpenRouter website and visiting [https://openrouter.ai/settings/keys](https://openrouter.ai/settings/keys). ## Create Your Application @@ -35,7 +35,7 @@ Navigate to the newly created directory: ### Install dependencies -Install `ai`, `@ai-sdk/react`, and `@ai-sdk/openai`, the AI package, AI SDK's React hooks, and AI SDK's [ OpenAI provider ](/providers/ai-sdk-providers/openai) respectively. +Install `ai`, `@ai-sdk/react`, and `@openrouter/ai-sdk-provider`, the AI package, AI SDK's React hooks, and the OpenRouter provider respectively. The AI SDK is designed to be a unified interface to interact with any large @@ -47,39 +47,39 @@ Install `ai`, `@ai-sdk/react`, and `@ai-sdk/openai`, the AI package, AI SDK's Re
- + - + - + - +
-### Configure OpenAI API key +### Configure OpenRouter API key -Create a `.env.local` file in your project root and add your OpenAI API Key. This key is used to authenticate your application with the OpenAI service. +Create a `.env.local` file in your project root and add your OpenRouter API Key. This key is used to authenticate your application with OpenRouter. Edit the `.env.local` file: ```env filename=".env.local" -OPENAI_API_KEY=xxxxxxxxx +OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxx +OPENROUTER_MODEL=openai/gpt-5-mini ``` -Replace `xxxxxxxxx` with your actual OpenAI API key. +Replace the API key with your actual OpenRouter API key from [https://openrouter.ai/settings/keys](https://openrouter.ai/settings/keys). - The AI SDK's OpenAI Provider will default to using the `OPENAI_API_KEY` - environment variable. + You can browse available models at [https://openrouter.ai/models](https://openrouter.ai/models) and set your preferred model via the `OPENROUTER_MODEL` environment variable. ## Create a Route Handler @@ -87,7 +87,7 @@ Replace `xxxxxxxxx` with your actual OpenAI API key. Create a route handler, `app/api/chat/route.ts` and add the following code: ```tsx filename="app/api/chat/route.ts" -import { openai } from "@ai-sdk/openai"; +import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { streamText, UIMessage, convertToModelMessages } from "ai"; // Allow streaming responses up to 30 seconds @@ -96,8 +96,13 @@ export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); + // Initialize OpenRouter with API key from environment + const openrouter = createOpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY, + }); + const result = streamText({ - model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"), + model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"), messages: convertToModelMessages(messages), }); @@ -108,7 +113,7 @@ export async function POST(req: Request) { Let's take a look at what is happening in this code: 1. Define an asynchronous `POST` request handler and extract `messages` from the body of the request. The `messages` variable contains a history of the conversation between you and the chatbot and provides the chatbot with the necessary context to make the next generation. The `messages` are of UIMessage type, which are designed for use in application UI - they contain the entire message history and associated metadata like timestamps. -2. Call [`streamText`](/docs/reference/ai-sdk-core/stream-text), which is imported from the `ai` package. This function accepts a configuration object that contains a `model` provider (imported from `@ai-sdk/openai`) and `messages` (defined in step 1). You can pass additional [settings](/docs/ai-sdk-core/settings) to further customise the model's behaviour. The `messages` key expects a `ModelMessage[]` array. This type is different from `UIMessage` in that it does not include metadata, such as timestamps or sender information. To convert between these types, we use the `convertToModelMessages` function, which strips the UI-specific metadata and transforms the `UIMessage[]` array into the `ModelMessage[]` format that the model expects. +2. Call [`streamText`](/docs/reference/ai-sdk-core/stream-text), which is imported from the `ai` package. This function accepts a configuration object that contains a `model` provider (created using `createOpenRouter` from `@openrouter/ai-sdk-provider`) and `messages` (defined in step 1). You can pass additional [settings](/docs/ai-sdk-core/settings) to further customise the model's behaviour. The `messages` key expects a `ModelMessage[]` array. This type is different from `UIMessage` in that it does not include metadata, such as timestamps or sender information. To convert between these types, we use the `convertToModelMessages` function, which strips the UI-specific metadata and transforms the `UIMessage[]` array into the `ModelMessage[]` format that the model expects. 3. The `streamText` function returns a [`StreamTextResult`](/docs/reference/ai-sdk-core/stream-text#result-object). This result object contains the [ `toUIMessageStreamResponse` ](/docs/reference/ai-sdk-core/stream-text#to-data-stream-response) function which converts the result to a streamed response object. 4. Finally, return the result to the client to stream the response. @@ -199,7 +204,7 @@ Let's enhance your chatbot by adding a simple weather tool. Modify your `app/api/chat/route.ts` file to include the new weather tool: ```tsx filename="app/api/chat/route.ts" highlight="2,13-27" -import { openai } from "@ai-sdk/openai"; +import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { streamText, UIMessage, convertToModelMessages, tool } from "ai"; import { z } from "zod"; @@ -208,8 +213,12 @@ export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); + const openrouter = createOpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY, + }); + const result = streamText({ - model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"), + model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"), messages: convertToModelMessages(messages), tools: { weather: tool({ @@ -320,7 +329,7 @@ To solve this, you can enable multi-step tool calls using `stopWhen`. By default Modify your `app/api/chat/route.ts` file to include the `stopWhen` condition: ```tsx filename="app/api/chat/route.ts" -import { openai } from "@ai-sdk/openai"; +import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { streamText, UIMessage, @@ -335,8 +344,12 @@ export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); + const openrouter = createOpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY, + }); + const result = streamText({ - model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"), + model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"), messages: convertToModelMessages(messages), stopWhen: stepCountIs(5), tools: { @@ -374,7 +387,7 @@ By setting `stopWhen: stepCountIs(5)`, you're allowing the model to use up to 5 Update your `app/api/chat/route.ts` file to add a new tool to convert the temperature from Fahrenheit to Celsius: ```tsx filename="app/api/chat/route.ts" highlight="34-47" -import { openai } from "@ai-sdk/openai"; +import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { streamText, UIMessage, @@ -389,8 +402,12 @@ export const maxDuration = 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); + const openrouter = createOpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY, + }); + const result = streamText({ - model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"), + model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"), messages: convertToModelMessages(messages), stopWhen: stepCountIs(5), tools: { diff --git a/create-agentic-app/template/eslint.config.mjs b/create-agentic-app/template/eslint.config.mjs index 4c1faba..d0c27e7 100644 --- a/create-agentic-app/template/eslint.config.mjs +++ b/create-agentic-app/template/eslint.config.mjs @@ -2,9 +2,74 @@ import nextConfig from "eslint-config-next/core-web-vitals"; const config = [ { - ignores: [".next/**", "node_modules/**", ".cache/**", "dist/**", "build/**"], + ignores: [ + ".next/**", + "node_modules/**", + ".cache/**", + "dist/**", + "build/**", + "create-agentic-app/**", + "drizzle/**", + "scripts/**", + ], }, ...nextConfig, + { + rules: { + // React rules + "react/jsx-no-target-blank": "error", + "react/no-unescaped-entities": "off", + + // React Hooks rules + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", + + // Import rules + "import/no-anonymous-default-export": "warn", + "import/order": [ + "warn", + { + groups: [ + "builtin", + "external", + "internal", + ["parent", "sibling"], + "index", + "type", + ], + pathGroups: [ + { + pattern: "react", + group: "builtin", + position: "before", + }, + { + pattern: "next/**", + group: "builtin", + position: "before", + }, + { + pattern: "@/**", + group: "internal", + position: "before", + }, + ], + pathGroupsExcludedImportTypes: ["react", "next"], + "newlines-between": "never", + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + }, + ], + + // Best practices + "no-console": ["warn", { allow: ["warn", "error"] }], + "prefer-const": "error", + "no-var": "error", + eqeqeq: ["error", "always", { null: "ignore" }], + }, + }, ]; export default config; diff --git a/create-agentic-app/template/next.config.ts b/create-agentic-app/template/next.config.ts index e9ffa30..189f2a2 100644 --- a/create-agentic-app/template/next.config.ts +++ b/create-agentic-app/template/next.config.ts @@ -1,7 +1,53 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + // Image optimization configuration + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "lh3.googleusercontent.com", + }, + { + protocol: "https", + hostname: "avatars.githubusercontent.com", + }, + ], + }, + + // Enable compression + compress: true, + + // Security headers + async headers() { + return [ + { + source: "/(.*)", + headers: [ + { + key: "X-Frame-Options", + value: "DENY", + }, + { + key: "X-Content-Type-Options", + value: "nosniff", + }, + { + key: "Referrer-Policy", + value: "strict-origin-when-cross-origin", + }, + { + key: "X-XSS-Protection", + value: "1; mode=block", + }, + { + key: "Permissions-Policy", + value: "camera=(), microphone=(), geolocation=()", + }, + ], + }, + ]; + }, }; export default nextConfig; diff --git a/create-agentic-app/template/package.json b/create-agentic-app/template/package.json index 963b74e..7adb8b1 100644 --- a/create-agentic-app/template/package.json +++ b/create-agentic-app/template/package.json @@ -2,11 +2,16 @@ "name": "agentic-coding-starter-kit", "version": "1.1.2", "scripts": { - "dev": "next dev", + "dev": "next dev --turbopack", "build": "pnpm run db:migrate && next build", "start": "next start", "lint": "eslint .", "typecheck": "tsc --noEmit", + "check": "pnpm lint && pnpm typecheck", + "format": "prettier --write .", + "format:check": "prettier --check .", + "setup": "npx tsx scripts/setup.ts", + "env:check": "node -e \"require('./src/lib/env.ts').checkEnv()\" || echo 'Run with tsx: npx tsx -e \"import { checkEnv } from './src/lib/env'; checkEnv();\"'", "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", "db:push": "drizzle-kit push", @@ -15,12 +20,12 @@ "db:reset": "drizzle-kit drop && drizzle-kit push" }, "dependencies": { - "@ai-sdk/openai": "^2.0.60", "@ai-sdk/react": "^2.0.86", "@openrouter/ai-sdk-provider": "^1.2.0", "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-slot": "^1.2.3", "@vercel/blob": "^2.0.0", "ai": "^5.0.86", @@ -36,6 +41,7 @@ "react": "19.2.0", "react-dom": "19.2.0", "react-markdown": "^10.1.0", + "sonner": "^2.0.7", "tailwind-merge": "^3.3.1", "zod": "^4.1.12" }, @@ -48,8 +54,11 @@ "drizzle-kit": "^0.31.6", "eslint": "^9.39.0", "eslint-config-next": "16.0.3", + "prettier": "^3.4.2", + "prettier-plugin-tailwindcss": "^0.6.9", "shadcn": "^3.5.0", "tailwindcss": "^4.1.16", + "tsx": "^4.19.2", "tw-animate-css": "^1.4.0", "typescript": "^5.9.3" }, diff --git a/create-agentic-app/template/scripts/setup.ts b/create-agentic-app/template/scripts/setup.ts new file mode 100644 index 0000000..446cdb4 --- /dev/null +++ b/create-agentic-app/template/scripts/setup.ts @@ -0,0 +1,274 @@ +#!/usr/bin/env npx tsx +/** + * Interactive setup wizard for the Agentic Coding Starter Kit. + * Run with: npx tsx scripts/setup.ts + */ + +import { existsSync, copyFileSync, readFileSync } from "fs"; +import { createInterface } from "readline"; +import { execSync } from "child_process"; +import { join } from "path"; + +const ROOT_DIR = join(import.meta.dirname, ".."); +const ENV_EXAMPLE = join(ROOT_DIR, "env.example"); +const ENV_FILE = join(ROOT_DIR, ".env"); + +// ANSI colors +const colors = { + reset: "\x1b[0m", + bright: "\x1b[1m", + green: "\x1b[32m", + yellow: "\x1b[33m", + red: "\x1b[31m", + cyan: "\x1b[36m", + dim: "\x1b[2m", +}; + +function log(message: string, color?: keyof typeof colors) { + const colorCode = color ? colors[color] : ""; + console.log(`${colorCode}${message}${colors.reset}`); +} + +function header(message: string) { + console.log(); + log(`${"=".repeat(60)}`, "cyan"); + log(` ${message}`, "bright"); + log(`${"=".repeat(60)}`, "cyan"); + console.log(); +} + +function success(message: string) { + log(`āœ“ ${message}`, "green"); +} + +function warn(message: string) { + log(`⚠ ${message}`, "yellow"); +} + +function error(message: string) { + log(`āœ— ${message}`, "red"); +} + +function info(message: string) { + log(` ${message}`, "dim"); +} + +async function prompt(question: string): Promise { + const rl = createInterface({ + input: process.stdin, + output: process.stdout, + }); + + return new Promise((resolve) => { + rl.question(`${colors.cyan}? ${colors.reset}${question} `, (answer) => { + rl.close(); + resolve(answer.trim()); + }); + }); +} + +async function confirm(question: string): Promise { + const answer = await prompt(`${question} (y/n)`); + return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes"; +} + +function checkNodeVersion(): boolean { + const requiredMajor = 20; + const currentVersion = process.version; + const currentMajor = parseInt(currentVersion.slice(1).split(".")[0] || "0", 10); + + if (currentMajor >= requiredMajor) { + success(`Node.js ${currentVersion} detected (requires v${requiredMajor}+)`); + return true; + } else { + error(`Node.js ${currentVersion} detected, but v${requiredMajor}+ is required`); + info("Please upgrade Node.js: https://nodejs.org/"); + return false; + } +} + +function copyEnvFile(): boolean { + if (existsSync(ENV_FILE)) { + warn(".env file already exists"); + return true; + } + + if (!existsSync(ENV_EXAMPLE)) { + error("env.example file not found"); + return false; + } + + try { + copyFileSync(ENV_EXAMPLE, ENV_FILE); + success("Created .env file from env.example"); + return true; + } catch (err) { + error(`Failed to create .env file: ${err}`); + return false; + } +} + +interface EnvStatus { + configured: string[]; + missing: string[]; + optional: string[]; +} + +function checkEnvVariables(): EnvStatus { + const required = ["POSTGRES_URL", "BETTER_AUTH_SECRET"]; + const optional = [ + "GOOGLE_CLIENT_ID", + "GOOGLE_CLIENT_SECRET", + "OPENROUTER_API_KEY", + "OPENROUTER_MODEL", + "BLOB_READ_WRITE_TOKEN", + "NEXT_PUBLIC_APP_URL", + ]; + + const status: EnvStatus = { + configured: [], + missing: [], + optional: [], + }; + + // Read .env file if it exists + let envContent = ""; + if (existsSync(ENV_FILE)) { + envContent = readFileSync(ENV_FILE, "utf-8"); + } + + // Parse env file (simple key=value parsing) + const envVars: Record = {}; + envContent.split("\n").forEach((line) => { + const trimmed = line.trim(); + if (trimmed && !trimmed.startsWith("#")) { + const [key, ...valueParts] = trimmed.split("="); + if (key) { + envVars[key] = valueParts.join("="); + } + } + }); + + // Check required variables + for (const key of required) { + const value = envVars[key]; + if (value && value.length > 0 && !value.startsWith("your-")) { + status.configured.push(key); + } else { + status.missing.push(key); + } + } + + // Check optional variables + for (const key of optional) { + const value = envVars[key]; + if (value && value.length > 0 && !value.startsWith("your-")) { + status.configured.push(key); + } else { + status.optional.push(key); + } + } + + return status; +} + +async function runDatabaseMigration(): Promise { + log("\nRunning database migration...", "cyan"); + + try { + execSync("pnpm db:migrate", { + cwd: ROOT_DIR, + stdio: "inherit", + }); + success("Database migration completed"); + return true; + } catch { + error("Database migration failed"); + info("Make sure your database is running and POSTGRES_URL is correct"); + return false; + } +} + +function printNextSteps(envStatus: EnvStatus) { + header("Next Steps"); + + const steps: string[] = []; + + if (envStatus.missing.length > 0) { + steps.push(`Configure required env vars in .env: ${envStatus.missing.join(", ")}`); + } + + if (envStatus.optional.includes("GOOGLE_CLIENT_ID")) { + steps.push("Set up Google OAuth at https://console.cloud.google.com/"); + } + + if (envStatus.optional.includes("OPENROUTER_API_KEY")) { + steps.push("Get an OpenRouter API key at https://openrouter.ai/settings/keys"); + } + + steps.push("Start the development server: pnpm dev"); + steps.push("Open http://localhost:3000 in your browser"); + + steps.forEach((step, index) => { + log(`${index + 1}. ${step}`); + }); + + console.log(); + log("Documentation:", "bright"); + info("- README.md - Project overview and setup"); + info("- CLAUDE.md - AI assistant guidelines"); + info("- docs/ - Technical documentation"); + console.log(); +} + +async function main() { + header("Agentic Coding Starter Kit - Setup Wizard"); + + // Step 1: Check Node version + log("Checking Node.js version...", "cyan"); + if (!checkNodeVersion()) { + process.exit(1); + } + + // Step 2: Create .env file + console.log(); + log("Setting up environment...", "cyan"); + copyEnvFile(); + + // Step 3: Check environment variables + console.log(); + log("Checking environment variables...", "cyan"); + const envStatus = checkEnvVariables(); + + if (envStatus.configured.length > 0) { + success(`Configured: ${envStatus.configured.join(", ")}`); + } + if (envStatus.missing.length > 0) { + warn(`Missing (required): ${envStatus.missing.join(", ")}`); + } + if (envStatus.optional.length > 0) { + info(`Optional (not set): ${envStatus.optional.join(", ")}`); + } + + // Step 4: Offer to run database migration + if (envStatus.missing.length === 0) { + console.log(); + const shouldMigrate = await confirm("Would you like to run database migrations now?"); + if (shouldMigrate) { + await runDatabaseMigration(); + } + } else { + console.log(); + warn("Skipping database migration - please configure required env vars first"); + } + + // Step 5: Print next steps + printNextSteps(envStatus); + + log("Setup complete!", "green"); +} + +main().catch((err) => { + error(`Setup failed: ${err}`); + process.exit(1); +}); diff --git a/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md b/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md new file mode 100644 index 0000000..394cbcf --- /dev/null +++ b/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md @@ -0,0 +1,165 @@ +# Next.js 16 Boilerplate Improvements - Implementation Plan + +## Phase 1: Critical Security & Stability (19 files) + +### Security Configuration +- [ ] Update `next.config.ts` - Add security headers, image config, compression +- [ ] Modify `package.json` - Remove `@ai-sdk/openai` dependency +- [ ] Create `src/proxy.ts` - Server-side auth protection using Next.js 16 proxy + BetterAuth +- [ ] Modify `src/app/api/chat/route.ts` - Add session authentication check +- [ ] Update `docs/technical/ai/streaming.md` - Fix OpenRouter references + +### Next.js 15 → 16 Updates (Main Project) +- [ ] Update `CLAUDE.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `README.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `docs/business/starter-prompt.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `src/components/starter-prompt-modal.tsx` - Change Next.js 15 to Next.js 16 +- [ ] Update `.claude/agents/polar-payments-expert.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `.claude/agents/better-auth-expert.md` - Change Next.js 15 to Next.js 16 + +### Next.js 15 → 16 Updates (create-agentic-app Template) +- [ ] Update `create-agentic-app/README.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/CLAUDE.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/README.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/docs/business/starter-prompt.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/src/components/starter-prompt-modal.tsx` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/.claude/agents/better-auth-expert.md` - Change Next.js 15 to Next.js 16 +- [ ] Update `create-agentic-app/template/.claude/agents/polar-payments-expert.md` - Change Next.js 15 to Next.js 16 + +--- + +## Phase 2: Core UX Components (12 files) + +### Error Handling +- [ ] Create `src/app/error.tsx` - Global error boundary +- [ ] Create `src/app/not-found.tsx` - Custom 404 page +- [ ] Create `src/app/chat/error.tsx` - Chat-specific error handling + +### Loading States +- [ ] Create `src/components/ui/skeleton.tsx` - Skeleton loading component (via shadcn) +- [ ] Create `src/components/ui/spinner.tsx` - Loading spinner component + +### Toast Notifications +- [ ] Install shadcn Sonner: `npx shadcn@latest add sonner` +- [ ] Modify `src/app/layout.tsx` - Add `` component + +### Form Components +- [ ] Install shadcn input: `npx shadcn@latest add input` +- [ ] Install shadcn textarea: `npx shadcn@latest add textarea` +- [ ] Install shadcn label: `npx shadcn@latest add label` + +### Chat UX Improvements +- [ ] Modify `src/app/chat/page.tsx`: + - [ ] Add message timestamps + - [ ] Add copy-to-clipboard for AI responses + - [ ] Add typing/thinking indicator during streaming + - [ ] Add error display for API failures + - [ ] Add message persistence (localStorage) + +### Database Schema +- [ ] Modify `src/lib/schema.ts` - Add missing indexes: + - [ ] Index on `session.user_id` + - [ ] Index on `session.token` + - [ ] Index on `account.user_id` + - [ ] Index on `account(provider_id, account_id)` + - [ ] Index on `user.email` +- [ ] Run `pnpm db:generate` to create migration +- [ ] Run `pnpm db:migrate` to apply migration + +--- + +## Phase 3: Polish & Security (8 files) + +### ESLint Configuration +- [ ] Modify `eslint.config.mjs`: + - [ ] Add import ordering rules + - [ ] Add TypeScript-eslint rules + - [ ] Add React hooks exhaustive-deps + - [ ] Add no-console warnings + +### API Hardening +- [ ] Modify `src/app/api/chat/route.ts`: + - [ ] Add rate limiting (10 requests/minute per user) + - [ ] Add Zod validation for messages + - [ ] Add message length limits +- [ ] Modify `src/app/api/diagnostics/route.ts` - Restrict to authenticated admins + +### SEO +- [ ] Modify `src/app/layout.tsx` - Add Open Graph metadata +- [ ] Create `src/app/sitemap.ts` - Dynamic sitemap +- [ ] Create `src/app/robots.ts` - Robots configuration + +### Accessibility +- [ ] Modify `src/components/site-header.tsx`: + - [ ] Add `