create-claude-webapp 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.claude/agents/acceptance-test-generator.md +256 -0
  2. package/.claude/agents/auth-flow-designer.md +93 -0
  3. package/.claude/agents/code-reviewer.md +193 -0
  4. package/.claude/agents/code-verifier.md +194 -0
  5. package/.claude/agents/deployment-executor.md +90 -0
  6. package/.claude/agents/design-sync.md +226 -0
  7. package/.claude/agents/document-reviewer.md +304 -0
  8. package/.claude/agents/environment-validator.md +100 -0
  9. package/.claude/agents/integration-test-reviewer.md +196 -0
  10. package/.claude/agents/investigator.md +162 -0
  11. package/.claude/agents/prd-creator.md +220 -0
  12. package/.claude/agents/quality-fixer-frontend.md +323 -0
  13. package/.claude/agents/quality-fixer.md +280 -0
  14. package/.claude/agents/requirement-analyzer.md +149 -0
  15. package/.claude/agents/rls-policy-designer.md +86 -0
  16. package/.claude/agents/rule-advisor.md +123 -0
  17. package/.claude/agents/scope-discoverer.md +231 -0
  18. package/.claude/agents/solver.md +173 -0
  19. package/.claude/agents/supabase-migration-generator.md +85 -0
  20. package/.claude/agents/task-decomposer.md +246 -0
  21. package/.claude/agents/task-executor-frontend.md +264 -0
  22. package/.claude/agents/task-executor.md +261 -0
  23. package/.claude/agents/technical-designer-frontend.md +444 -0
  24. package/.claude/agents/technical-designer.md +370 -0
  25. package/.claude/agents/verifier.md +193 -0
  26. package/.claude/agents/work-planner.md +211 -0
  27. package/.claude/commands/add-integration-tests.md +116 -0
  28. package/.claude/commands/build.md +77 -0
  29. package/.claude/commands/db-migrate.md +96 -0
  30. package/.claude/commands/deploy.md +95 -0
  31. package/.claude/commands/design.md +75 -0
  32. package/.claude/commands/diagnose.md +202 -0
  33. package/.claude/commands/front-build.md +116 -0
  34. package/.claude/commands/front-design.md +61 -0
  35. package/.claude/commands/front-plan.md +53 -0
  36. package/.claude/commands/front-reverse-design.md +183 -0
  37. package/.claude/commands/front-review.md +89 -0
  38. package/.claude/commands/implement.md +80 -0
  39. package/.claude/commands/local-dev.md +94 -0
  40. package/.claude/commands/plan.md +61 -0
  41. package/.claude/commands/project-inject.md +76 -0
  42. package/.claude/commands/refine-skill.md +207 -0
  43. package/.claude/commands/reverse-engineer.md +301 -0
  44. package/.claude/commands/review.md +88 -0
  45. package/.claude/commands/setup-auth.md +68 -0
  46. package/.claude/commands/setup-supabase.md +66 -0
  47. package/.claude/commands/setup-vercel.md +71 -0
  48. package/.claude/commands/sync-skills.md +116 -0
  49. package/.claude/commands/task.md +13 -0
  50. package/.claude/skills/coding-standards/SKILL.md +246 -0
  51. package/.claude/skills/documentation-criteria/SKILL.md +184 -0
  52. package/.claude/skills/documentation-criteria/references/adr-template.md +64 -0
  53. package/.claude/skills/documentation-criteria/references/design-template.md +263 -0
  54. package/.claude/skills/documentation-criteria/references/plan-template.md +130 -0
  55. package/.claude/skills/documentation-criteria/references/prd-template.md +109 -0
  56. package/.claude/skills/documentation-criteria/references/task-template.md +38 -0
  57. package/.claude/skills/frontend/technical-spec/SKILL.md +147 -0
  58. package/.claude/skills/frontend/typescript-rules/SKILL.md +136 -0
  59. package/.claude/skills/frontend/typescript-testing/SKILL.md +129 -0
  60. package/.claude/skills/fullstack-integration/SKILL.md +466 -0
  61. package/.claude/skills/implementation-approach/SKILL.md +141 -0
  62. package/.claude/skills/integration-e2e-testing/SKILL.md +146 -0
  63. package/.claude/skills/interview/SKILL.md +345 -0
  64. package/.claude/skills/project-context/SKILL.md +53 -0
  65. package/.claude/skills/stack-auth/SKILL.md +519 -0
  66. package/.claude/skills/subagents-orchestration-guide/SKILL.md +218 -0
  67. package/.claude/skills/supabase/SKILL.md +289 -0
  68. package/.claude/skills/supabase-edge-functions/SKILL.md +386 -0
  69. package/.claude/skills/supabase-local/SKILL.md +328 -0
  70. package/.claude/skills/supabase-testing/SKILL.md +513 -0
  71. package/.claude/skills/task-analyzer/SKILL.md +131 -0
  72. package/.claude/skills/task-analyzer/references/skills-index.yaml +375 -0
  73. package/.claude/skills/technical-spec/SKILL.md +86 -0
  74. package/.claude/skills/typescript-rules/SKILL.md +121 -0
  75. package/.claude/skills/typescript-testing/SKILL.md +155 -0
  76. package/.claude/skills/vercel-deployment/SKILL.md +355 -0
  77. package/.claude/skills/vercel-edge/SKILL.md +407 -0
  78. package/README.md +4 -17
  79. package/package.json +1 -1
@@ -0,0 +1,407 @@
1
+ ---
2
+ name: vercel-edge
3
+ description: Vercel Edge runtime, middleware patterns, and Edge Functions. Use when implementing edge logic, middleware, or geo-routing.
4
+ ---
5
+
6
+ # Vercel Edge Runtime
7
+
8
+ ## Edge Runtime Constraints
9
+
10
+ ### What's NOT Available
11
+ The Edge runtime uses V8 isolates, not Node.js. These APIs are unavailable:
12
+
13
+ | Unavailable | Alternative |
14
+ |-------------|-------------|
15
+ | `fs` module | Use fetch for remote files |
16
+ | `path` module | String manipulation |
17
+ | `crypto` (Node.js) | Web Crypto API |
18
+ | `Buffer` (full) | Use Uint8Array |
19
+ | Native modules | Pure JS alternatives |
20
+ | Long-running processes | Use serverless functions |
21
+
22
+ ### What IS Available
23
+ - Web standard APIs (fetch, Request, Response)
24
+ - Web Crypto API
25
+ - TextEncoder/TextDecoder
26
+ - URL and URLSearchParams
27
+ - setTimeout (limited)
28
+ - console methods
29
+
30
+ ### Execution Limits
31
+ | Limit | Value |
32
+ |-------|-------|
33
+ | Memory | 128 MB |
34
+ | CPU time | 50ms (Hobby), unlimited (Pro) |
35
+ | Duration | 30s |
36
+ | Response body | 4 MB |
37
+
38
+ ## Middleware Patterns
39
+
40
+ ### Basic Middleware Structure
41
+ ```typescript
42
+ // middleware.ts (at project root)
43
+ import { NextResponse } from 'next/server'
44
+ import type { NextRequest } from 'next/server'
45
+
46
+ export function middleware(request: NextRequest) {
47
+ // Your logic here
48
+ return NextResponse.next()
49
+ }
50
+
51
+ // Configure which paths trigger middleware
52
+ export const config = {
53
+ matcher: [
54
+ /*
55
+ * Match all request paths except:
56
+ * - _next/static (static files)
57
+ * - _next/image (image optimization)
58
+ * - favicon.ico (favicon file)
59
+ * - public files
60
+ */
61
+ '/((?!_next/static|_next/image|favicon.ico|.*\\..*$).*)',
62
+ ],
63
+ }
64
+ ```
65
+
66
+ ### Authentication Middleware
67
+ ```typescript
68
+ // middleware.ts
69
+ import { NextResponse } from 'next/server'
70
+ import type { NextRequest } from 'next/server'
71
+
72
+ const protectedPaths = ['/dashboard', '/settings', '/api/protected']
73
+
74
+ export function middleware(request: NextRequest) {
75
+ const { pathname } = request.nextUrl
76
+
77
+ // Check if path is protected
78
+ const isProtected = protectedPaths.some(path => pathname.startsWith(path))
79
+
80
+ if (!isProtected) {
81
+ return NextResponse.next()
82
+ }
83
+
84
+ // Check for auth token
85
+ const token = request.cookies.get('auth-token')?.value
86
+
87
+ if (!token) {
88
+ // Redirect to login
89
+ const loginUrl = new URL('/login', request.url)
90
+ loginUrl.searchParams.set('redirect', pathname)
91
+ return NextResponse.redirect(loginUrl)
92
+ }
93
+
94
+ // Verify token (simplified - use proper JWT verification)
95
+ try {
96
+ // Token validation logic
97
+ return NextResponse.next()
98
+ } catch {
99
+ // Invalid token, redirect to login
100
+ const response = NextResponse.redirect(new URL('/login', request.url))
101
+ response.cookies.delete('auth-token')
102
+ return response
103
+ }
104
+ }
105
+
106
+ export const config = {
107
+ matcher: ['/dashboard/:path*', '/settings/:path*', '/api/protected/:path*'],
108
+ }
109
+ ```
110
+
111
+ ### Geo-Routing Middleware
112
+ ```typescript
113
+ // middleware.ts
114
+ import { NextResponse } from 'next/server'
115
+ import type { NextRequest } from 'next/server'
116
+
117
+ const COUNTRY_REDIRECTS: Record<string, string> = {
118
+ DE: '/de',
119
+ FR: '/fr',
120
+ ES: '/es',
121
+ }
122
+
123
+ export function middleware(request: NextRequest) {
124
+ const country = request.geo?.country || 'US'
125
+
126
+ // Skip if already on localized path
127
+ const { pathname } = request.nextUrl
128
+ if (pathname.startsWith('/de') || pathname.startsWith('/fr') || pathname.startsWith('/es')) {
129
+ return NextResponse.next()
130
+ }
131
+
132
+ // Redirect to localized version
133
+ const redirect = COUNTRY_REDIRECTS[country]
134
+ if (redirect && pathname === '/') {
135
+ return NextResponse.redirect(new URL(redirect, request.url))
136
+ }
137
+
138
+ return NextResponse.next()
139
+ }
140
+
141
+ export const config = {
142
+ matcher: '/',
143
+ }
144
+ ```
145
+
146
+ ### A/B Testing Middleware
147
+ ```typescript
148
+ // middleware.ts
149
+ import { NextResponse } from 'next/server'
150
+ import type { NextRequest } from 'next/server'
151
+
152
+ const EXPERIMENT_COOKIE = 'ab-experiment'
153
+ const VARIANTS = ['control', 'variant-a', 'variant-b']
154
+
155
+ export function middleware(request: NextRequest) {
156
+ // Check for existing experiment assignment
157
+ let variant = request.cookies.get(EXPERIMENT_COOKIE)?.value
158
+
159
+ // Assign variant if not already assigned
160
+ if (!variant || !VARIANTS.includes(variant)) {
161
+ variant = VARIANTS[Math.floor(Math.random() * VARIANTS.length)]
162
+ }
163
+
164
+ // Rewrite to variant path
165
+ const url = request.nextUrl.clone()
166
+ url.pathname = `/${variant}${url.pathname}`
167
+
168
+ const response = NextResponse.rewrite(url)
169
+
170
+ // Set cookie for consistent experience
171
+ response.cookies.set(EXPERIMENT_COOKIE, variant, {
172
+ maxAge: 60 * 60 * 24 * 30, // 30 days
173
+ httpOnly: true,
174
+ sameSite: 'lax',
175
+ })
176
+
177
+ return response
178
+ }
179
+
180
+ export const config = {
181
+ matcher: '/landing-page',
182
+ }
183
+ ```
184
+
185
+ ### Rate Limiting Middleware
186
+ ```typescript
187
+ // middleware.ts
188
+ import { NextResponse } from 'next/server'
189
+ import type { NextRequest } from 'next/server'
190
+
191
+ // Note: For production, use Edge Config or external store
192
+ const rateLimitMap = new Map<string, { count: number; timestamp: number }>()
193
+
194
+ const RATE_LIMIT = 100 // requests
195
+ const WINDOW_MS = 60 * 1000 // 1 minute
196
+
197
+ export function middleware(request: NextRequest) {
198
+ const ip = request.ip ?? request.headers.get('x-forwarded-for') ?? 'unknown'
199
+
200
+ const now = Date.now()
201
+ const record = rateLimitMap.get(ip)
202
+
203
+ if (!record || now - record.timestamp > WINDOW_MS) {
204
+ rateLimitMap.set(ip, { count: 1, timestamp: now })
205
+ return NextResponse.next()
206
+ }
207
+
208
+ if (record.count >= RATE_LIMIT) {
209
+ return new NextResponse('Too Many Requests', {
210
+ status: 429,
211
+ headers: {
212
+ 'Retry-After': String(Math.ceil((WINDOW_MS - (now - record.timestamp)) / 1000)),
213
+ },
214
+ })
215
+ }
216
+
217
+ record.count++
218
+ return NextResponse.next()
219
+ }
220
+
221
+ export const config = {
222
+ matcher: '/api/:path*',
223
+ }
224
+ ```
225
+
226
+ ## Edge Functions
227
+
228
+ ### Creating Edge API Routes
229
+ ```typescript
230
+ // app/api/edge-example/route.ts
231
+ export const runtime = 'edge'
232
+
233
+ export async function GET(request: Request) {
234
+ const { searchParams } = new URL(request.url)
235
+ const name = searchParams.get('name') || 'World'
236
+
237
+ return Response.json({ message: `Hello ${name}!` })
238
+ }
239
+
240
+ export async function POST(request: Request) {
241
+ const body = await request.json()
242
+
243
+ return Response.json({ received: body })
244
+ }
245
+ ```
246
+
247
+ ### Edge Function with Geo Data
248
+ ```typescript
249
+ // app/api/geo/route.ts
250
+ export const runtime = 'edge'
251
+
252
+ export async function GET(request: Request) {
253
+ // Access geo data from headers (Vercel sets these)
254
+ const country = request.headers.get('x-vercel-ip-country') || 'Unknown'
255
+ const city = request.headers.get('x-vercel-ip-city') || 'Unknown'
256
+ const region = request.headers.get('x-vercel-ip-country-region') || 'Unknown'
257
+
258
+ return Response.json({
259
+ country,
260
+ city,
261
+ region,
262
+ })
263
+ }
264
+ ```
265
+
266
+ ## Edge Config
267
+
268
+ ### Setup
269
+ ```bash
270
+ # Create Edge Config store in Vercel Dashboard
271
+ # Project > Storage > Create Edge Config
272
+
273
+ # Install SDK
274
+ npm install @vercel/edge-config
275
+ ```
276
+
277
+ ### Using Edge Config
278
+ ```typescript
279
+ // app/api/feature-flags/route.ts
280
+ export const runtime = 'edge'
281
+
282
+ import { get } from '@vercel/edge-config'
283
+
284
+ export async function GET() {
285
+ const flags = await get('featureFlags')
286
+
287
+ return Response.json({ flags })
288
+ }
289
+ ```
290
+
291
+ ### Feature Flags Pattern
292
+ ```typescript
293
+ // lib/features.ts
294
+ import { get } from '@vercel/edge-config'
295
+
296
+ export interface FeatureFlags {
297
+ newDashboard: boolean
298
+ betaFeatures: boolean
299
+ maintenanceMode: boolean
300
+ }
301
+
302
+ export async function getFeatureFlags(): Promise<FeatureFlags> {
303
+ const flags = await get<FeatureFlags>('featureFlags')
304
+
305
+ return flags ?? {
306
+ newDashboard: false,
307
+ betaFeatures: false,
308
+ maintenanceMode: false,
309
+ }
310
+ }
311
+
312
+ // Usage in Edge middleware
313
+ import { getFeatureFlags } from '@/lib/features'
314
+
315
+ export async function middleware(request: NextRequest) {
316
+ const flags = await getFeatureFlags()
317
+
318
+ if (flags.maintenanceMode) {
319
+ return NextResponse.rewrite(new URL('/maintenance', request.url))
320
+ }
321
+
322
+ return NextResponse.next()
323
+ }
324
+ ```
325
+
326
+ ### Updating Edge Config
327
+ ```typescript
328
+ // Via API (from serverless function, not edge)
329
+ import { createClient } from '@vercel/edge-config'
330
+
331
+ const client = createClient(process.env.EDGE_CONFIG)
332
+
333
+ // Read
334
+ const value = await client.get('key')
335
+
336
+ // Note: Writing requires Vercel API
337
+ // Use Vercel dashboard or API for updates
338
+ ```
339
+
340
+ ## Caching at the Edge
341
+
342
+ ### Cache Headers
343
+ ```typescript
344
+ export const runtime = 'edge'
345
+
346
+ export async function GET() {
347
+ const data = await fetchData()
348
+
349
+ return Response.json(data, {
350
+ headers: {
351
+ 'Cache-Control': 's-maxage=3600, stale-while-revalidate=86400',
352
+ },
353
+ })
354
+ }
355
+ ```
356
+
357
+ ### Cache Strategies
358
+
359
+ | Strategy | Header | Use Case |
360
+ |----------|--------|----------|
361
+ | Static | `s-maxage=31536000, immutable` | Assets that never change |
362
+ | Revalidate | `s-maxage=60, stale-while-revalidate=3600` | Frequently updated content |
363
+ | No cache | `no-store` | Personalized/dynamic data |
364
+
365
+ ## Best Practices
366
+
367
+ ### Performance
368
+ - Keep middleware fast (<50ms)
369
+ - Avoid heavy computations
370
+ - Use Edge Config for configuration data
371
+ - Cache responses where possible
372
+
373
+ ### Security
374
+ - Validate all inputs
375
+ - Use secure cookie settings
376
+ - Implement proper CORS
377
+ - Rate limit sensitive endpoints
378
+
379
+ ### Error Handling
380
+ ```typescript
381
+ export const runtime = 'edge'
382
+
383
+ export async function GET(request: Request) {
384
+ try {
385
+ const data = await riskyOperation()
386
+ return Response.json(data)
387
+ } catch (error) {
388
+ console.error('Edge function error:', error)
389
+
390
+ return Response.json(
391
+ { error: 'Internal server error' },
392
+ { status: 500 }
393
+ )
394
+ }
395
+ }
396
+ ```
397
+
398
+ ### Debugging
399
+ ```typescript
400
+ // Log request details
401
+ console.log('Request URL:', request.url)
402
+ console.log('Headers:', Object.fromEntries(request.headers))
403
+ console.log('Geo:', {
404
+ country: request.headers.get('x-vercel-ip-country'),
405
+ city: request.headers.get('x-vercel-ip-city'),
406
+ })
407
+ ```
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # AI Coding Project Boilerplate 🤖
2
2
 
3
- *Read this in other languages: [日本語](README.ja.md)*
4
-
5
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue?logo=typescript)](https://www.typescriptlang.org/)
6
4
  [![Node.js](https://img.shields.io/badge/Node.js-20%2B-green?logo=node.js)](https://nodejs.org/)
7
5
  [![Claude Code](https://img.shields.io/badge/Claude%20Code-Optimized-purple)](https://claude.ai/code)
8
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
7
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/svenmalvik/claude-boilerplate-4-web/pulls)
10
8
 
9
+ > 🔱 This is an opinionated version of [shinpr/ai-coding-project-boilerplate](https://github.com/shinpr/ai-coding-project-boilerplate)
10
+
11
11
  ⚡ **This boilerplate is for developers who want to:**
12
12
  - Build **production-ready TypeScript projects** faster with AI
13
13
  - Avoid **context exhaustion** in long AI coding sessions
@@ -23,14 +23,13 @@
23
23
  7. [Development Workflow](#-claude-code-workflow)
24
24
  8. [Project Structure](#-project-structure)
25
25
  9. [Package Manager Configuration](#-package-manager-configuration)
26
- 10. [Multilingual Support](#-multilingual-support)
27
- 11. [FAQ](#-faq)
26
+ 10. [FAQ](#-faq)
28
27
 
29
28
  ## ⚡ Quick Start (3 Steps)
30
29
 
31
30
  ```bash
32
31
  # 1. Create your project (30 seconds)
33
- npx create-ai-project my-project
32
+ npx create-claude-webapp my-project
34
33
 
35
34
  # 2. Install dependencies (automatic)
36
35
  cd my-project && npm install
@@ -247,18 +246,6 @@ The above are representative examples. The following scripts are referenced in r
247
246
 
248
247
  `build`, `build:frontend`, `dev`, `preview`, `type-check`, `test`, `test:coverage`, `test:coverage:fresh`, `test:safe`, `cleanup:processes`, `check`, `check:fix`, `check:code`, `check:unused`, `check:deps`, `check:all`, `format`, `format:check`, `lint`, `lint:fix`
249
248
 
250
- ## 🌐 Multilingual Support
251
-
252
- Full support for English and Japanese:
253
-
254
- ```bash
255
- npm run lang:en # Switch to English
256
- npm run lang:ja # Switch to Japanese
257
- npm run lang:status # Check current language
258
- ```
259
-
260
- Automatically updates all configurations, rules, and agent definitions.
261
-
262
249
  ## 🤔 FAQ
263
250
 
264
251
  **Q: How do sub agents work?**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-webapp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "packageManager": "npm@10.8.2",
5
5
  "description": "TypeScript boilerplate with skills and sub-agents for Claude Code. Prevents context exhaustion through role-based task splitting.",
6
6
  "keywords": [