@smicolon/ai-kit 0.3.2 → 0.4.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 (155) hide show
  1. package/README.md +73 -40
  2. package/dist/index.js +312 -127
  3. package/package.json +5 -5
  4. package/.claude-plugin/marketplace.json +0 -369
  5. package/packs/architect/CHANGELOG.md +0 -17
  6. package/packs/architect/README.md +0 -58
  7. package/packs/architect/agents/system-architect.md +0 -768
  8. package/packs/architect/commands/diagram-create.md +0 -300
  9. package/packs/better-auth/.mcp.json +0 -14
  10. package/packs/better-auth/CHANGELOG.md +0 -26
  11. package/packs/better-auth/README.md +0 -125
  12. package/packs/better-auth/agents/auth-architect.md +0 -278
  13. package/packs/better-auth/commands/auth-provider-add.md +0 -265
  14. package/packs/better-auth/commands/auth-setup.md +0 -298
  15. package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
  17. package/packs/dev-loop/CHANGELOG.md +0 -69
  18. package/packs/dev-loop/README.md +0 -155
  19. package/packs/dev-loop/commands/cancel-dev.md +0 -21
  20. package/packs/dev-loop/commands/dev-loop.md +0 -72
  21. package/packs/dev-loop/commands/dev-plan.md +0 -351
  22. package/packs/dev-loop/hooks/hooks.json +0 -15
  23. package/packs/dev-loop/hooks/stop-hook.sh +0 -178
  24. package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
  25. package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
  26. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
  27. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
  28. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
  29. package/packs/django/CHANGELOG.md +0 -39
  30. package/packs/django/README.md +0 -92
  31. package/packs/django/agents/django-architect.md +0 -182
  32. package/packs/django/agents/django-builder.md +0 -250
  33. package/packs/django/agents/django-feature-based.md +0 -420
  34. package/packs/django/agents/django-reviewer.md +0 -253
  35. package/packs/django/agents/django-tester.md +0 -230
  36. package/packs/django/commands/api-endpoint.md +0 -285
  37. package/packs/django/commands/model-create.md +0 -178
  38. package/packs/django/commands/test-generate.md +0 -325
  39. package/packs/django/rules/migrations.md +0 -138
  40. package/packs/django/rules/models.md +0 -167
  41. package/packs/django/rules/serializers.md +0 -126
  42. package/packs/django/rules/services.md +0 -131
  43. package/packs/django/rules/tests.md +0 -140
  44. package/packs/django/rules/views.md +0 -102
  45. package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
  46. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
  47. package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
  48. package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
  49. package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
  50. package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
  51. package/packs/django/skills/security-first-validator/SKILL.md +0 -435
  52. package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
  53. package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
  54. package/packs/failure-log/CHANGELOG.md +0 -20
  55. package/packs/failure-log/README.md +0 -168
  56. package/packs/failure-log/commands/failure-add.md +0 -106
  57. package/packs/failure-log/commands/failure-list.md +0 -89
  58. package/packs/failure-log/hooks/hooks.json +0 -16
  59. package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
  60. package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
  61. package/packs/flutter/CHANGELOG.md +0 -19
  62. package/packs/flutter/README.md +0 -170
  63. package/packs/flutter/agents/flutter-architect.md +0 -166
  64. package/packs/flutter/agents/flutter-builder.md +0 -303
  65. package/packs/flutter/agents/release-manager.md +0 -355
  66. package/packs/flutter/commands/fastlane-setup.md +0 -188
  67. package/packs/flutter/commands/flutter-build.md +0 -90
  68. package/packs/flutter/commands/flutter-deploy.md +0 -133
  69. package/packs/flutter/commands/flutter-test.md +0 -117
  70. package/packs/flutter/commands/signing-setup.md +0 -209
  71. package/packs/flutter/hooks/hooks.json +0 -17
  72. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
  73. package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
  74. package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
  75. package/packs/hono/CHANGELOG.md +0 -19
  76. package/packs/hono/README.md +0 -143
  77. package/packs/hono/agents/hono-architect.md +0 -240
  78. package/packs/hono/agents/hono-builder.md +0 -285
  79. package/packs/hono/agents/hono-reviewer.md +0 -279
  80. package/packs/hono/agents/hono-tester.md +0 -346
  81. package/packs/hono/commands/middleware-create.md +0 -223
  82. package/packs/hono/commands/project-init.md +0 -306
  83. package/packs/hono/commands/route-create.md +0 -153
  84. package/packs/hono/commands/rpc-client.md +0 -263
  85. package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
  86. package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
  87. package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
  88. package/packs/hono/skills/zod-validation/SKILL.md +0 -332
  89. package/packs/nestjs/CHANGELOG.md +0 -29
  90. package/packs/nestjs/README.md +0 -75
  91. package/packs/nestjs/agents/nestjs-architect.md +0 -402
  92. package/packs/nestjs/agents/nestjs-builder.md +0 -301
  93. package/packs/nestjs/agents/nestjs-tester.md +0 -437
  94. package/packs/nestjs/commands/module-create.md +0 -369
  95. package/packs/nestjs/rules/controllers.md +0 -92
  96. package/packs/nestjs/rules/dto.md +0 -124
  97. package/packs/nestjs/rules/entities.md +0 -102
  98. package/packs/nestjs/rules/services.md +0 -106
  99. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
  100. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
  101. package/packs/nextjs/CHANGELOG.md +0 -36
  102. package/packs/nextjs/README.md +0 -76
  103. package/packs/nextjs/agents/frontend-tester.md +0 -680
  104. package/packs/nextjs/agents/frontend-visual.md +0 -820
  105. package/packs/nextjs/agents/nextjs-architect.md +0 -331
  106. package/packs/nextjs/agents/nextjs-modular.md +0 -433
  107. package/packs/nextjs/commands/component-create.md +0 -398
  108. package/packs/nextjs/rules/api-routes.md +0 -129
  109. package/packs/nextjs/rules/components.md +0 -106
  110. package/packs/nextjs/rules/hooks.md +0 -132
  111. package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
  112. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
  113. package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
  114. package/packs/nuxtjs/CHANGELOG.md +0 -30
  115. package/packs/nuxtjs/README.md +0 -56
  116. package/packs/nuxtjs/agents/frontend-tester.md +0 -680
  117. package/packs/nuxtjs/agents/frontend-visual.md +0 -820
  118. package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
  119. package/packs/nuxtjs/commands/component-create.md +0 -223
  120. package/packs/nuxtjs/rules/components.md +0 -101
  121. package/packs/nuxtjs/rules/composables.md +0 -118
  122. package/packs/nuxtjs/rules/server-routes.md +0 -127
  123. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
  124. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
  125. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
  126. package/packs/onboard/CHANGELOG.md +0 -22
  127. package/packs/onboard/README.md +0 -103
  128. package/packs/onboard/agents/onboard-guide.md +0 -118
  129. package/packs/onboard/commands/onboard.md +0 -313
  130. package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
  131. package/packs/tanstack-router/CHANGELOG.md +0 -30
  132. package/packs/tanstack-router/README.md +0 -113
  133. package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
  134. package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
  135. package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
  136. package/packs/tanstack-router/commands/form-create.md +0 -313
  137. package/packs/tanstack-router/commands/query-create.md +0 -263
  138. package/packs/tanstack-router/commands/route-create.md +0 -190
  139. package/packs/tanstack-router/commands/table-create.md +0 -413
  140. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
  141. package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
  142. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
  143. package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
  144. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
  145. package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
  146. package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
  147. package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
  148. package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
  149. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
  150. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
  151. package/packs/worktree/CHANGELOG.md +0 -45
  152. package/packs/worktree/README.md +0 -219
  153. package/packs/worktree/commands/wt.md +0 -93
  154. package/packs/worktree/scripts/wt.sh +0 -957
  155. package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
@@ -1,398 +0,0 @@
1
- ---
2
- name: component-create
3
- description: Create a new Next.js/React component following Smicolon conventions
4
- ---
5
-
6
- # Next.js Component Creation
7
-
8
- You are a Next.js/React component creation specialist. Your task is to create components that strictly follow Smicolon company standards.
9
-
10
- ## Core Requirements
11
-
12
- ### Component Standards
13
- - **TypeScript strict mode** (no `any` types)
14
- - **Functional components** with hooks
15
- - **Proper type definitions** for props
16
- - **Accessibility** (WCAG 2.1 AA)
17
- - **Responsive design** with Tailwind CSS
18
- - **Error boundaries** where appropriate
19
-
20
- ### File Structure
21
- ```
22
- src/components/
23
- ├── ui/ # Reusable UI components
24
- │ ├── Button.tsx
25
- │ ├── Input.tsx
26
- │ └── Card.tsx
27
- ├── features/ # Feature-specific components
28
- │ └── auth/
29
- │ ├── LoginForm.tsx
30
- │ └── SignupForm.tsx
31
- └── layouts/ # Layout components
32
- ├── Header.tsx
33
- └── Footer.tsx
34
- ```
35
-
36
- ## Component Types
37
-
38
- ### 1. UI Components (Reusable)
39
- ```typescript
40
- // src/components/ui/Button.tsx
41
- import { ButtonHTMLAttributes, forwardRef } from 'react'
42
- import { cn } from '@/lib/utils'
43
-
44
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
45
- variant?: 'primary' | 'secondary' | 'outline' | 'ghost'
46
- size?: 'sm' | 'md' | 'lg'
47
- isLoading?: boolean
48
- }
49
-
50
- export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
51
- (
52
- {
53
- className,
54
- variant = 'primary',
55
- size = 'md',
56
- isLoading = false,
57
- disabled,
58
- children,
59
- ...props
60
- },
61
- ref
62
- ) => {
63
- const baseStyles = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
64
-
65
- const variants = {
66
- primary: 'bg-blue-600 text-white hover:bg-blue-700 focus-visible:ring-blue-600',
67
- secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300 focus-visible:ring-gray-500',
68
- outline: 'border border-gray-300 bg-transparent hover:bg-gray-100 focus-visible:ring-gray-500',
69
- ghost: 'hover:bg-gray-100 focus-visible:ring-gray-500',
70
- }
71
-
72
- const sizes = {
73
- sm: 'h-9 px-3 text-sm',
74
- md: 'h-10 px-4',
75
- lg: 'h-11 px-8 text-lg',
76
- }
77
-
78
- return (
79
- <button
80
- ref={ref}
81
- className={cn(baseStyles, variants[variant], sizes[size], className)}
82
- disabled={disabled || isLoading}
83
- aria-busy={isLoading}
84
- {...props}
85
- >
86
- {isLoading && (
87
- <svg
88
- className="mr-2 h-4 w-4 animate-spin"
89
- xmlns="http://www.w3.org/2000/svg"
90
- fill="none"
91
- viewBox="0 0 24 24"
92
- aria-hidden="true"
93
- >
94
- <circle
95
- className="opacity-25"
96
- cx="12"
97
- cy="12"
98
- r="10"
99
- stroke="currentColor"
100
- strokeWidth="4"
101
- />
102
- <path
103
- className="opacity-75"
104
- fill="currentColor"
105
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
106
- />
107
- </svg>
108
- )}
109
- {children}
110
- </button>
111
- )
112
- }
113
- )
114
-
115
- Button.displayName = 'Button'
116
- ```
117
-
118
- ### 2. Form Components with Validation
119
- ```typescript
120
- // src/components/features/auth/LoginForm.tsx
121
- 'use client'
122
-
123
- import { useState } from 'react'
124
- import { useForm } from 'react-hook-form'
125
- import { zodResolver } from '@hookform/resolvers/zod'
126
- import { z } from 'zod'
127
- import { useMutation } from '@tanstack/react-query'
128
- import { Button } from '@/components/ui/Button'
129
- import { Input } from '@/components/ui/Input'
130
- import { useRouter } from 'next/navigation'
131
-
132
- const loginSchema = z.object({
133
- email: z.string().email('Invalid email address'),
134
- password: z.string().min(8, 'Password must be at least 8 characters'),
135
- })
136
-
137
- type LoginFormData = z.infer<typeof loginSchema>
138
-
139
- export function LoginForm() {
140
- const router = useRouter()
141
- const [errorMessage, setErrorMessage] = useState<string | null>(null)
142
-
143
- const {
144
- register,
145
- handleSubmit,
146
- formState: { errors },
147
- } = useForm<LoginFormData>({
148
- resolver: zodResolver(loginSchema),
149
- })
150
-
151
- const loginMutation = useMutation({
152
- mutationFn: async (data: LoginFormData) => {
153
- const response = await fetch('/api/auth/login', {
154
- method: 'POST',
155
- headers: { 'Content-Type': 'application/json' },
156
- body: JSON.stringify(data),
157
- })
158
-
159
- if (!response.ok) {
160
- const error = await response.json()
161
- throw new Error(error.message || 'Login failed')
162
- }
163
-
164
- return response.json()
165
- },
166
- onSuccess: () => {
167
- router.push('/dashboard')
168
- },
169
- onError: (error: Error) => {
170
- setErrorMessage(error.message)
171
- },
172
- })
173
-
174
- const onSubmit = (data: LoginFormData) => {
175
- setErrorMessage(null)
176
- loginMutation.mutate(data)
177
- }
178
-
179
- return (
180
- <form onSubmit={handleSubmit(onSubmit)} className="space-y-6" noValidate>
181
- <div>
182
- <label
183
- htmlFor="email"
184
- className="block text-sm font-medium text-gray-700"
185
- >
186
- Email address
187
- </label>
188
- <Input
189
- id="email"
190
- type="email"
191
- autoComplete="email"
192
- {...register('email')}
193
- aria-invalid={errors.email ? 'true' : 'false'}
194
- aria-describedby={errors.email ? 'email-error' : undefined}
195
- />
196
- {errors.email && (
197
- <p id="email-error" className="mt-1 text-sm text-red-600" role="alert">
198
- {errors.email.message}
199
- </p>
200
- )}
201
- </div>
202
-
203
- <div>
204
- <label
205
- htmlFor="password"
206
- className="block text-sm font-medium text-gray-700"
207
- >
208
- Password
209
- </label>
210
- <Input
211
- id="password"
212
- type="password"
213
- autoComplete="current-password"
214
- {...register('password')}
215
- aria-invalid={errors.password ? 'true' : 'false'}
216
- aria-describedby={errors.password ? 'password-error' : undefined}
217
- />
218
- {errors.password && (
219
- <p id="password-error" className="mt-1 text-sm text-red-600" role="alert">
220
- {errors.password.message}
221
- </p>
222
- )}
223
- </div>
224
-
225
- {errorMessage && (
226
- <div
227
- className="rounded-md bg-red-50 p-4"
228
- role="alert"
229
- aria-live="assertive"
230
- >
231
- <p className="text-sm text-red-800">{errorMessage}</p>
232
- </div>
233
- )}
234
-
235
- <Button
236
- type="submit"
237
- variant="primary"
238
- className="w-full"
239
- isLoading={loginMutation.isPending}
240
- >
241
- Sign in
242
- </Button>
243
- </form>
244
- )
245
- }
246
- ```
247
-
248
- ### 3. Server Components with Data Fetching
249
- ```typescript
250
- // src/components/features/products/ProductList.tsx
251
- import { Suspense } from 'react'
252
- import { ProductCard } from './ProductCard'
253
- import { ProductCardSkeleton } from './ProductCardSkeleton'
254
-
255
- interface Product {
256
- id: string
257
- name: string
258
- price: number
259
- imageUrl: string
260
- }
261
-
262
- async function getProducts(): Promise<Product[]> {
263
- const response = await fetch('https://api.example.com/products', {
264
- next: { revalidate: 60 }, // Revalidate every 60 seconds
265
- })
266
-
267
- if (!response.ok) {
268
- throw new Error('Failed to fetch products')
269
- }
270
-
271
- return response.json()
272
- }
273
-
274
- async function ProductListContent() {
275
- const products = await getProducts()
276
-
277
- if (products.length === 0) {
278
- return (
279
- <div className="py-12 text-center">
280
- <p className="text-gray-500">No products found</p>
281
- </div>
282
- )
283
- }
284
-
285
- return (
286
- <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
287
- {products.map((product) => (
288
- <ProductCard key={product.id} product={product} />
289
- ))}
290
- </div>
291
- )
292
- }
293
-
294
- export function ProductList() {
295
- return (
296
- <Suspense
297
- fallback={
298
- <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
299
- {Array.from({ length: 8 }).map((_, i) => (
300
- <ProductCardSkeleton key={i} />
301
- ))}
302
- </div>
303
- }
304
- >
305
- <ProductListContent />
306
- </Suspense>
307
- )
308
- }
309
- ```
310
-
311
- ### 4. Error Boundary
312
- ```typescript
313
- // src/components/ErrorBoundary.tsx
314
- 'use client'
315
-
316
- import { Component, ReactNode } from 'react'
317
- import { Button } from '@/components/ui/Button'
318
-
319
- interface Props {
320
- children: ReactNode
321
- fallback?: ReactNode
322
- }
323
-
324
- interface State {
325
- hasError: boolean
326
- error: Error | null
327
- }
328
-
329
- export class ErrorBoundary extends Component<Props, State> {
330
- constructor(props: Props) {
331
- super(props)
332
- this.state = { hasError: false, error: null }
333
- }
334
-
335
- static getDerivedStateFromError(error: Error): State {
336
- return { hasError: true, error }
337
- }
338
-
339
- componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
340
- console.error('Error caught by boundary:', error, errorInfo)
341
- }
342
-
343
- render() {
344
- if (this.state.hasError) {
345
- if (this.props.fallback) {
346
- return this.props.fallback
347
- }
348
-
349
- return (
350
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
351
- <div className="max-w-md space-y-4 text-center">
352
- <h2 className="text-2xl font-bold text-gray-900">
353
- Something went wrong
354
- </h2>
355
- <p className="text-gray-600">
356
- {this.state.error?.message || 'An unexpected error occurred'}
357
- </p>
358
- <Button
359
- onClick={() => this.setState({ hasError: false, error: null })}
360
- >
361
- Try again
362
- </Button>
363
- </div>
364
- </div>
365
- )
366
- }
367
-
368
- return this.props.children
369
- }
370
- }
371
- ```
372
-
373
- ## Accessibility Checklist
374
-
375
- - [ ] Semantic HTML elements
376
- - [ ] Proper ARIA labels and roles
377
- - [ ] Keyboard navigation support
378
- - [ ] Focus management
379
- - [ ] Error messages with `role="alert"`
380
- - [ ] Loading states with `aria-busy`
381
- - [ ] Form validation with `aria-invalid` and `aria-describedby`
382
- - [ ] Sufficient color contrast
383
- - [ ] Alt text for images
384
-
385
- ## Quality Checklist
386
-
387
- - [ ] TypeScript strict mode (no `any`)
388
- - [ ] Proper type definitions
389
- - [ ] Zod validation for forms
390
- - [ ] TanStack Query for API calls
391
- - [ ] Error and loading states
392
- - [ ] Responsive design
393
- - [ ] Tailwind CSS
394
- - [ ] WCAG 2.1 AA compliance
395
- - [ ] Server components where possible
396
- - [ ] Suspense boundaries for async content
397
-
398
- Now, ask the user what component they want to create!
@@ -1,129 +0,0 @@
1
- ---
2
- paths:
3
- - "**/app/api/**/*.ts"
4
- - "**/pages/api/**/*.ts"
5
- ---
6
-
7
- # Next.js API Route Standards
8
-
9
- ## Structure (App Router)
10
-
11
- ```typescript
12
- import { NextResponse } from 'next/server'
13
- import { z } from 'zod'
14
-
15
- const createUserSchema = z.object({
16
- email: z.string().email(),
17
- name: z.string().min(1),
18
- })
19
-
20
- export async function POST(request: Request) {
21
- try {
22
- const body = await request.json()
23
- const data = createUserSchema.parse(body)
24
-
25
- // Business logic
26
- const user = await createUser(data)
27
-
28
- return NextResponse.json(user, { status: 201 })
29
- } catch (error) {
30
- if (error instanceof z.ZodError) {
31
- return NextResponse.json(
32
- { errors: error.errors },
33
- { status: 400 }
34
- )
35
- }
36
- return NextResponse.json(
37
- { error: 'Internal server error' },
38
- { status: 500 }
39
- )
40
- }
41
- }
42
- ```
43
-
44
- ## Requirements
45
-
46
- - Zod validation for all inputs
47
- - Proper error handling
48
- - Typed responses
49
- - No secrets in responses
50
- - Rate limiting consideration
51
-
52
- ## HTTP Methods
53
-
54
- ```typescript
55
- // GET - Read
56
- export async function GET(request: Request) {
57
- const { searchParams } = new URL(request.url)
58
- const id = searchParams.get('id')
59
- // ...
60
- }
61
-
62
- // POST - Create
63
- export async function POST(request: Request) {
64
- const body = await request.json()
65
- // ...
66
- }
67
-
68
- // PUT/PATCH - Update
69
- export async function PATCH(
70
- request: Request,
71
- { params }: { params: { id: string } }
72
- ) {
73
- const body = await request.json()
74
- // ...
75
- }
76
-
77
- // DELETE - Remove
78
- export async function DELETE(
79
- request: Request,
80
- { params }: { params: { id: string } }
81
- ) {
82
- // ...
83
- }
84
- ```
85
-
86
- ## Error Handling Pattern
87
-
88
- ```typescript
89
- import { NextResponse } from 'next/server'
90
- import { z } from 'zod'
91
-
92
- class ApiError extends Error {
93
- constructor(
94
- message: string,
95
- public statusCode: number,
96
- public details?: unknown
97
- ) {
98
- super(message)
99
- }
100
- }
101
-
102
- function handleError(error: unknown) {
103
- if (error instanceof z.ZodError) {
104
- return NextResponse.json(
105
- { error: 'Validation error', details: error.errors },
106
- { status: 400 }
107
- )
108
- }
109
- if (error instanceof ApiError) {
110
- return NextResponse.json(
111
- { error: error.message, details: error.details },
112
- { status: error.statusCode }
113
- )
114
- }
115
- console.error('Unexpected error:', error)
116
- return NextResponse.json(
117
- { error: 'Internal server error' },
118
- { status: 500 }
119
- )
120
- }
121
- ```
122
-
123
- ## Forbidden Patterns
124
-
125
- - Unvalidated inputs
126
- - Exposing stack traces
127
- - Hardcoded secrets
128
- - Missing error handling
129
- - Any type in request/response
@@ -1,106 +0,0 @@
1
- ---
2
- paths:
3
- - "**/components/**/*.tsx"
4
- - "**/components/**/*.jsx"
5
- ---
6
-
7
- # Next.js Component Standards
8
-
9
- ## Accessibility (WCAG 2.1 AA)
10
-
11
- ```tsx
12
- // WRONG - No keyboard access
13
- <div onClick={handleClick}>Click me</div>
14
-
15
- // CORRECT - Semantic HTML
16
- <button type="button" onClick={handleClick}>
17
- Click me
18
- </button>
19
- ```
20
-
21
- ## Form Pattern (React Hook Form + Zod)
22
-
23
- ```tsx
24
- import { useForm } from 'react-hook-form'
25
- import { zodResolver } from '@hookform/resolvers/zod'
26
- import { z } from 'zod'
27
-
28
- const schema = z.object({
29
- email: z.string().email(),
30
- password: z.string().min(8),
31
- })
32
-
33
- type FormData = z.infer<typeof schema>
34
-
35
- export function LoginForm() {
36
- const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
37
- resolver: zodResolver(schema),
38
- })
39
-
40
- return (
41
- <form onSubmit={handleSubmit(onSubmit)}>
42
- <label htmlFor="email">Email</label>
43
- <input id="email" {...register('email')} aria-describedby="email-error" />
44
- {errors.email && <span id="email-error" role="alert">{errors.email.message}</span>}
45
- </form>
46
- )
47
- }
48
- ```
49
-
50
- ## Import Pattern
51
-
52
- ```tsx
53
- // CORRECT - Path aliases
54
- import { Button } from '@/components/ui/button'
55
- import { useAuth } from '@/hooks/useAuth'
56
-
57
- // WRONG - Deep relative paths
58
- import { Button } from '../../../components/ui/button'
59
- ```
60
-
61
- ## Requirements
62
-
63
- - TypeScript strict mode (no `any`)
64
- - Semantic HTML elements
65
- - ARIA attributes where needed
66
- - Error boundaries for async components
67
- - Loading states for data fetching
68
-
69
- ## Component Structure
70
-
71
- ```tsx
72
- import { type FC } from 'react'
73
-
74
- interface ButtonProps {
75
- children: React.ReactNode
76
- variant?: 'primary' | 'secondary'
77
- disabled?: boolean
78
- onClick?: () => void
79
- }
80
-
81
- export const Button: FC<ButtonProps> = ({
82
- children,
83
- variant = 'primary',
84
- disabled = false,
85
- onClick,
86
- }) => {
87
- return (
88
- <button
89
- type="button"
90
- className={`btn btn-${variant}`}
91
- disabled={disabled}
92
- onClick={onClick}
93
- >
94
- {children}
95
- </button>
96
- )
97
- }
98
- ```
99
-
100
- ## Forbidden Patterns
101
-
102
- - `any` type
103
- - Non-semantic interactive elements
104
- - Missing form labels
105
- - Inline styles (use Tailwind/CSS modules)
106
- - Missing error boundaries for async components