create-claude-webapp 1.0.0 → 1.0.1

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 +1 -1
  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
@@ -30,7 +30,7 @@
30
30
 
31
31
  ```bash
32
32
  # 1. Create your project (30 seconds)
33
- npx create-ai-project my-project
33
+ npx create-claude-webapp my-project
34
34
 
35
35
  # 2. Install dependencies (automatic)
36
36
  cd my-project && npm install
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.1",
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": [