@kood/claude-code 0.2.5 → 0.3.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 (130) hide show
  1. package/dist/index.js +13 -8
  2. package/package.json +1 -1
  3. package/templates/.claude/agents/code-reviewer.md +371 -19
  4. package/templates/.claude/agents/dependency-manager.md +197 -0
  5. package/templates/.claude/agents/deployment-validator.md +136 -0
  6. package/templates/.claude/agents/git-operator.md +147 -0
  7. package/templates/.claude/agents/implementation-executor.md +202 -0
  8. package/templates/.claude/agents/lint-fixer.md +155 -0
  9. package/templates/.claude/agents/refactor-advisor.md +339 -29
  10. package/templates/.claude/commands/agent-creator.md +355 -0
  11. package/templates/.claude/commands/docs-creator.md +404 -163
  12. package/templates/.claude/commands/docs-refactor.md +400 -113
  13. package/templates/.claude/commands/execute.md +357 -185
  14. package/templates/.claude/commands/git-all.md +65 -71
  15. package/templates/.claude/commands/git-session.md +80 -64
  16. package/templates/.claude/commands/git.md +68 -72
  17. package/templates/.claude/commands/lint-fix.md +224 -109
  18. package/templates/.claude/commands/lint-init.md +142 -168
  19. package/templates/.claude/commands/plan.md +300 -84
  20. package/templates/.claude/commands/prd.md +497 -214
  21. package/templates/.claude/commands/pre-deploy.md +242 -0
  22. package/templates/.claude/commands/subagent-creator.md +118 -0
  23. package/templates/.claude/commands/version-update.md +45 -57
  24. package/templates/hono/CLAUDE.md +99 -54
  25. package/templates/hono/docs/guides/conventions.md +352 -0
  26. package/templates/hono/docs/guides/env-setup.md +347 -0
  27. package/templates/hono/docs/guides/getting-started.md +239 -0
  28. package/templates/hono/docs/library/hono/error-handling.md +20 -29
  29. package/templates/hono/docs/library/hono/index.md +25 -52
  30. package/templates/hono/docs/library/hono/middleware.md +16 -75
  31. package/templates/hono/docs/library/hono/rpc.md +7 -35
  32. package/templates/hono/docs/library/hono/validation.md +25 -45
  33. package/templates/hono/docs/library/t3-env/index.md +374 -0
  34. package/templates/npx/CLAUDE.md +165 -65
  35. package/templates/npx/docs/library/commander/index.md +10 -73
  36. package/templates/npx/docs/library/fs-extra/index.md +21 -113
  37. package/templates/npx/docs/library/prompts/index.md +30 -176
  38. package/templates/npx/docs/references/patterns.md +75 -48
  39. package/templates/tanstack-start/CLAUDE.md +101 -77
  40. package/templates/tanstack-start/docs/architecture.md +427 -0
  41. package/templates/tanstack-start/docs/design.md +558 -0
  42. package/templates/tanstack-start/docs/guides/conventions.md +132 -32
  43. package/templates/tanstack-start/docs/guides/env-setup.md +127 -62
  44. package/templates/tanstack-start/docs/guides/getting-started.md +81 -20
  45. package/templates/tanstack-start/docs/guides/hooks.md +241 -36
  46. package/templates/tanstack-start/docs/guides/routes.md +213 -61
  47. package/templates/tanstack-start/docs/guides/services.md +260 -24
  48. package/templates/tanstack-start/docs/library/better-auth/index.md +469 -16
  49. package/templates/tanstack-start/docs/library/t3-env/index.md +307 -0
  50. package/templates/tanstack-start/docs/library/tanstack-query/index.md +12 -21
  51. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +22 -35
  52. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +7 -24
  53. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +26 -39
  54. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +23 -26
  55. package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +32 -147
  56. package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +25 -167
  57. package/templates/tanstack-start/docs/library/tanstack-router/index.md +39 -74
  58. package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +46 -116
  59. package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +35 -154
  60. package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +32 -171
  61. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +7 -15
  62. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +16 -23
  63. package/templates/tanstack-start/docs/library/zod/complex-types.md +12 -31
  64. package/templates/tanstack-start/docs/library/zod/index.md +18 -35
  65. package/templates/tanstack-start/docs/library/zod/transforms.md +11 -25
  66. package/templates/tanstack-start/docs/library/zod/validation.md +12 -34
  67. package/templates/.claude/agents/debug-detective.md +0 -37
  68. package/templates/.claude/agents/test-writer.md +0 -41
  69. package/templates/.claude/commands/feedback.md +0 -199
  70. package/templates/.claude/commands/ts-fix.md +0 -176
  71. package/templates/.claude/skills/command-creator/LICENSE.txt +0 -202
  72. package/templates/.claude/skills/command-creator/SKILL.md +0 -245
  73. package/templates/.claude/skills/command-creator/scripts/init_command.py +0 -244
  74. package/templates/.claude/skills/command-creator/scripts/package_command.py +0 -125
  75. package/templates/.claude/skills/command-creator/scripts/quick_validate.py +0 -143
  76. package/templates/.claude/skills/frontend-design/SKILL.md +0 -310
  77. package/templates/.claude/skills/frontend-design/references/animation-patterns.md +0 -446
  78. package/templates/.claude/skills/frontend-design/references/colors-2026.md +0 -244
  79. package/templates/.claude/skills/frontend-design/references/typography-2026.md +0 -302
  80. package/templates/.claude/skills/gemini-review/SKILL.md +0 -118
  81. package/templates/.claude/skills/gemini-review/references/checklists.md +0 -129
  82. package/templates/.claude/skills/gemini-review/references/prompt-templates.md +0 -274
  83. package/templates/.claude/skills/skill-creator/LICENSE.txt +0 -202
  84. package/templates/.claude/skills/skill-creator/SKILL.md +0 -184
  85. package/templates/.claude/skills/skill-creator/scripts/init_skill.py +0 -303
  86. package/templates/.claude/skills/skill-creator/scripts/package_skill.py +0 -110
  87. package/templates/.claude/skills/skill-creator/scripts/quick_validate.py +0 -65
  88. package/templates/hono/docs/library/ai-sdk/index.md +0 -190
  89. package/templates/hono/docs/library/ai-sdk/openrouter.md +0 -111
  90. package/templates/hono/docs/library/ai-sdk/providers.md +0 -102
  91. package/templates/hono/docs/library/ai-sdk/streaming.md +0 -146
  92. package/templates/hono/docs/library/ai-sdk/structured-output.md +0 -161
  93. package/templates/hono/docs/library/ai-sdk/tools.md +0 -144
  94. package/templates/hono/docs/library/drizzle/cloudflare-d1.md +0 -247
  95. package/templates/hono/docs/library/drizzle/config.md +0 -167
  96. package/templates/hono/docs/library/drizzle/index.md +0 -259
  97. package/templates/hono/docs/library/hono/env-setup.md +0 -169
  98. package/templates/hono/docs/library/pino/index.md +0 -146
  99. package/templates/tanstack-start/docs/architecture/architecture.md +0 -243
  100. package/templates/tanstack-start/docs/deployment/cloudflare.md +0 -132
  101. package/templates/tanstack-start/docs/deployment/index.md +0 -163
  102. package/templates/tanstack-start/docs/deployment/nitro.md +0 -110
  103. package/templates/tanstack-start/docs/deployment/railway.md +0 -147
  104. package/templates/tanstack-start/docs/deployment/vercel.md +0 -135
  105. package/templates/tanstack-start/docs/design/components.md +0 -175
  106. package/templates/tanstack-start/docs/design/index.md +0 -151
  107. package/templates/tanstack-start/docs/design/safe-area.md +0 -118
  108. package/templates/tanstack-start/docs/design/tailwind-setup.md +0 -156
  109. package/templates/tanstack-start/docs/library/ai-sdk/hooks.md +0 -472
  110. package/templates/tanstack-start/docs/library/ai-sdk/index.md +0 -264
  111. package/templates/tanstack-start/docs/library/ai-sdk/openrouter.md +0 -371
  112. package/templates/tanstack-start/docs/library/ai-sdk/providers.md +0 -403
  113. package/templates/tanstack-start/docs/library/ai-sdk/streaming.md +0 -320
  114. package/templates/tanstack-start/docs/library/ai-sdk/structured-output.md +0 -454
  115. package/templates/tanstack-start/docs/library/ai-sdk/tools.md +0 -473
  116. package/templates/tanstack-start/docs/library/better-auth/2fa.md +0 -48
  117. package/templates/tanstack-start/docs/library/better-auth/advanced.md +0 -55
  118. package/templates/tanstack-start/docs/library/better-auth/plugins.md +0 -34
  119. package/templates/tanstack-start/docs/library/better-auth/session.md +0 -47
  120. package/templates/tanstack-start/docs/library/better-auth/setup.md +0 -41
  121. package/templates/tanstack-start/docs/library/drizzle/cloudflare-d1.md +0 -147
  122. package/templates/tanstack-start/docs/library/drizzle/config.md +0 -118
  123. package/templates/tanstack-start/docs/library/drizzle/crud.md +0 -205
  124. package/templates/tanstack-start/docs/library/drizzle/index.md +0 -79
  125. package/templates/tanstack-start/docs/library/drizzle/relations.md +0 -202
  126. package/templates/tanstack-start/docs/library/drizzle/schema.md +0 -154
  127. package/templates/tanstack-start/docs/library/drizzle/setup.md +0 -96
  128. package/templates/tanstack-start/docs/library/drizzle/transactions.md +0 -127
  129. package/templates/tanstack-start/docs/library/pino/index.md +0 -320
  130. /package/templates/hono/docs/{architecture/architecture.md → architecture.md} +0 -0
@@ -1,6 +1,6 @@
1
1
  # TanStack Start - 인증 패턴
2
2
 
3
- ## 기본 인증 함수
3
+ <patterns>
4
4
 
5
5
  ```typescript
6
6
  // 로그인
@@ -9,7 +9,6 @@ export const loginFn = createServerFn({ method: 'POST' })
9
9
  .handler(async ({ data }) => {
10
10
  const user = await authenticateUser(data.email, data.password)
11
11
  if (!user) return { error: 'Invalid credentials' }
12
-
13
12
  const session = await useAppSession()
14
13
  await session.update({ userId: user.id, email: user.email })
15
14
  throw redirect({ to: '/dashboard' })
@@ -30,11 +29,8 @@ export const getCurrentUserFn = createServerFn({ method: 'GET' })
30
29
  if (!session.data.userId) return null
31
30
  return getUserById(session.data.userId)
32
31
  })
33
- ```
34
-
35
- ## 인증 미들웨어
36
32
 
37
- ```typescript
33
+ // 인증 미들웨어
38
34
  export const authMiddleware = createMiddleware({ type: 'function' })
39
35
  .server(async ({ next }) => {
40
36
  const session = await useAppSession()
@@ -43,15 +39,12 @@ export const authMiddleware = createMiddleware({ type: 'function' })
43
39
  return next({ context: { user } })
44
40
  })
45
41
 
46
- // 사용
42
+ // Server Function에 적용
47
43
  export const protectedFn = createServerFn({ method: 'GET' })
48
44
  .middleware([authMiddleware])
49
45
  .handler(async ({ context }) => ({ user: context.user }))
50
- ```
51
46
 
52
- ## 보호된 라우트
53
-
54
- ```tsx
47
+ // 보호된 라우트
55
48
  export const Route = createFileRoute('/dashboard')({
56
49
  beforeLoad: async () => {
57
50
  const user = await getCurrentUserFn()
@@ -63,11 +56,8 @@ export const Route = createFileRoute('/dashboard')({
63
56
  return <h1>Welcome, {user.name}!</h1>
64
57
  },
65
58
  })
66
- ```
67
-
68
- ## Better Auth 통합
69
59
 
70
- ```typescript
60
+ // Better Auth 통합
71
61
  export const auth = betterAuth({
72
62
  database: prismaAdapter(prisma),
73
63
  emailAndPassword: { enabled: true },
@@ -76,3 +66,5 @@ export const auth = betterAuth({
76
66
  export const getSession = createServerFn({ method: 'GET' })
77
67
  .handler(async ({ request }) => auth.api.getSession({ headers: request.headers }))
78
68
  ```
69
+
70
+ </patterns>
@@ -1,22 +1,17 @@
1
1
  # TanStack Start - Routing
2
2
 
3
- 파일 기반 라우팅.
4
-
5
- ## 기본 패턴
3
+ <patterns>
6
4
 
7
5
  ```tsx
8
- // routes/about.tsx
9
- export const Route = createFileRoute('/about')({
10
- component: AboutPage,
11
- })
6
+ // 기본
7
+ export const Route = createFileRoute('/about')({ component: AboutPage })
12
8
 
13
9
  // Loader
14
10
  export const Route = createFileRoute('/')({
15
11
  component: Page,
16
12
  loader: async () => fetch('/api/posts').then(r => r.json()),
17
13
  })
18
-
19
- function Page() {
14
+ const Page = () => {
20
15
  const posts = Route.useLoaderData()
21
16
  return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
22
17
  }
@@ -29,19 +24,13 @@ export const Route = createFileRoute('/users/$id')({
29
24
  return <h1>{user.name}</h1>
30
25
  },
31
26
  })
32
- ```
33
-
34
- ## SSR 옵션
35
27
 
36
- ```typescript
28
+ // SSR 옵션
37
29
  ssr: true // 전체 SSR (기본값)
38
30
  ssr: false // 클라이언트만
39
- ssr: 'data-only' // 데이터만 서버, 렌더링은 클라이언트
40
- ```
41
-
42
- ## Server Routes (API)
31
+ ssr: 'data-only' // 데이터만 서버
43
32
 
44
- ```typescript
33
+ // Server Routes (API)
45
34
  export const Route = createFileRoute('/api/hello')({
46
35
  server: {
47
36
  handlers: {
@@ -55,12 +44,16 @@ export const Route = createFileRoute('/api/hello')({
55
44
  })
56
45
  ```
57
46
 
58
- ## 구조
47
+ </patterns>
48
+
49
+ <structure>
59
50
 
60
51
  ```
61
52
  routes/
62
- ├── __root.tsx Root layout
63
- ├── index.tsx /
64
- ├── users/$id.tsx /users/:id
65
- ├── $.tsx Catch-all (404)
53
+ ├── __root.tsx # Root layout
54
+ ├── index.tsx # /
55
+ ├── users/$id.tsx # /users/:id
56
+ ├── $.tsx # Catch-all (404)
66
57
  ```
58
+
59
+ </structure>
@@ -1,15 +1,15 @@
1
1
  # Zod - 복합 타입
2
2
 
3
- ## 객체
3
+ <patterns>
4
4
 
5
5
  ```typescript
6
+ // 객체
6
7
  const UserSchema = z.object({
7
8
  name: z.string(),
8
9
  email: z.email(),
9
10
  age: z.number().optional(),
10
11
  })
11
12
 
12
- // 메서드
13
13
  UserSchema.partial() // 모든 필드 optional
14
14
  UserSchema.required() // 모든 필드 required
15
15
  UserSchema.pick({ name: true }) // 특정 필드만
@@ -17,57 +17,36 @@ UserSchema.omit({ email: true }) // 특정 필드 제외
17
17
  UserSchema.extend({ role: z.enum(['admin', 'user']) })
18
18
  UserSchema.merge(AnotherSchema)
19
19
 
20
- // v4 Strict/Loose
21
- z.strictObject({ name: z.string() }) // 추가 키 에러
22
- z.looseObject({ name: z.string() }) // 추가 키 통과
23
- ```
24
-
25
- ## 배열/튜플
20
+ z.strictObject({ name: z.string() }) // v4: 추가 키 에러
21
+ z.looseObject({ name: z.string() }) // v4: 추가 키 통과
26
22
 
27
- ```typescript
23
+ // 배열/튜플
28
24
  z.array(z.string())
29
25
  z.array(z.number()).min(1).max(10).length(5).nonempty()
30
-
31
26
  z.tuple([z.string(), z.number()]) // [string, number]
32
- ```
33
27
 
34
- ## 유니온
35
-
36
- ```typescript
28
+ // 유니온
37
29
  z.union([z.string(), z.number()])
38
30
  z.string().or(z.number())
39
31
 
40
- // Discriminated Union
41
32
  z.discriminatedUnion('type', [
42
33
  z.object({ type: z.literal('circle'), radius: z.number() }),
43
34
  z.object({ type: z.literal('rectangle'), width: z.number(), height: z.number() }),
44
35
  ])
45
- ```
46
-
47
- ## Enum
48
36
 
49
- ```typescript
37
+ // Enum
50
38
  const Status = z.enum(['pending', 'done', 'cancelled'])
51
39
  type Status = z.infer<typeof Status> // 'pending' | 'done' | 'cancelled'
52
40
 
53
- // Native enum
54
41
  enum Fruits { Apple, Banana }
55
42
  z.nativeEnum(Fruits)
56
- ```
57
-
58
- ## Record/Map/Set
59
-
60
- ```typescript
61
- z.record(z.string(), z.object({ name: z.string() }))
62
- // { [key: string]: { name: string } }
63
43
 
44
+ // Record/Map/Set
45
+ z.record(z.string(), z.object({ name: z.string() })) // { [key: string]: { name: string } }
64
46
  z.map(z.string(), z.number()) // Map<string, number>
65
47
  z.set(z.number()) // Set<number>
66
- ```
67
-
68
- ## 재귀 스키마
69
48
 
70
- ```typescript
49
+ // 재귀
71
50
  type Json = string | number | boolean | null | { [key: string]: Json } | Json[]
72
51
 
73
52
  const jsonSchema: z.ZodType<Json> = z.lazy(() =>
@@ -78,3 +57,5 @@ const jsonSchema: z.ZodType<Json> = z.lazy(() =>
78
57
  ])
79
58
  )
80
59
  ```
60
+
61
+ </patterns>
@@ -1,6 +1,6 @@
1
1
  # Zod
2
2
 
3
- > **v4** | TypeScript Schema Validation
3
+ > v4 | TypeScript Schema Validation
4
4
 
5
5
  @complex-types.md
6
6
  @transforms.md
@@ -8,66 +8,49 @@
8
8
 
9
9
  ---
10
10
 
11
- ## Quick Reference
11
+ <quick_reference>
12
12
 
13
13
  ```typescript
14
- // 기본 스키마
14
+ // 기본
15
15
  const schema = z.object({
16
- email: z.email(), // v4! (string().email() 아님)
16
+ email: z.email(), // v4!
17
17
  name: z.string().min(1).trim(),
18
- website: z.url().optional(), // v4! (string().url() 아님)
18
+ website: z.url().optional(), // v4!
19
19
  age: z.number().int().positive(),
20
20
  })
21
-
22
21
  type Input = z.infer<typeof schema>
23
22
 
24
- // 파싱
25
23
  schema.parse(data) // 실패 시 throw
26
24
  schema.safeParse(data) // { success, data/error }
27
25
 
28
- // TanStack Start 연동
26
+ // TanStack Start
29
27
  export const createUser = createServerFn({ method: 'POST' })
30
28
  .inputValidator(schema)
31
29
  .handler(async ({ data }) => prisma.user.create({ data }))
32
30
  ```
33
31
 
34
- ### ⚠️ v4 새 API
32
+ </quick_reference>
33
+
34
+ <v4_changes>
35
35
 
36
36
  ```typescript
37
- // ✅ v4
38
- z.email() z.url() z.uuid()
39
- z.iso.date() z.iso.datetime()
37
+ // ✅ v4 새 API
38
+ z.email() z.url() z.uuid()
39
+ z.iso.date() z.iso.datetime() z.iso.duration()
40
+ z.stringbool() // "true"/"yes"/"1" → true
40
41
 
41
42
  // ❌ v3 deprecated
42
43
  z.string().email() z.string().url()
43
- ```
44
44
 
45
- ### v4 주요 변경
46
-
47
- ```typescript
48
- // 에러 커스텀: message → error
49
- z.string().min(5, { error: "Too short." })
50
-
51
- // Strict/Loose 객체
45
+ // 변경사항
46
+ z.string().min(5, { error: "Too short." }) // message → error
52
47
  z.strictObject({ name: z.string() }) // 추가 키 에러
53
48
  z.looseObject({ name: z.string() }) // 추가 키 통과
54
-
55
- // Refinement 체이닝 가능
56
- z.string().refine(val => val.includes("@")).min(5) // ✅ v4
57
- ```
58
-
59
- ### v4 추가 API
60
-
61
- ```typescript
62
- // 문자열 불리언 (환경변수용)
63
- z.stringbool() // "true"/"yes"/"1" → true
64
-
65
- // 날짜/시간 ISO 포맷
66
- z.iso.date() // 2024-01-15
67
- z.iso.datetime() // ISO 날짜시간
68
- z.iso.duration() // P1D, PT1H
49
+ z.string().refine(val => val.includes("@")).min(5) // refinement 체이닝
69
50
 
70
51
  // 템플릿 리터럴
71
52
  const css = z.templateLiteral([z.number(), z.enum(["px", "em", "rem"])])
72
53
  // `${number}px` | `${number}em` | `${number}rem`
73
54
  ```
55
+
56
+ </v4_changes>
@@ -1,29 +1,24 @@
1
1
  # Zod - 변환
2
2
 
3
- ## Transform
3
+ <patterns>
4
4
 
5
5
  ```typescript
6
+ // Transform
6
7
  const stringToLength = z.string().transform((val) => val.length)
7
8
  stringToLength.parse('hello') // => 5
8
9
 
9
10
  type In = z.input<typeof stringToLength> // string
10
11
  type Out = z.output<typeof stringToLength> // number
11
- ```
12
-
13
- ## Pipe (검증 후 변환)
14
12
 
15
- ```typescript
13
+ // Pipe (검증 후 변환)
16
14
  const stringToNumber = z.string()
17
15
  .transform((val) => parseInt(val, 10))
18
16
  .pipe(z.number().min(0).max(100))
19
17
 
20
18
  stringToNumber.parse('50') // => 50
21
19
  stringToNumber.parse('150') // throws
22
- ```
23
-
24
- ## Coerce (강제 변환)
25
20
 
26
- ```typescript
21
+ // Coerce (강제 변환)
27
22
  z.coerce.string() // 모든 값 → 문자열
28
23
  z.coerce.number() // 모든 값 → 숫자
29
24
  z.coerce.boolean() // 모든 값 → 불리언
@@ -33,33 +28,24 @@ z.coerce.bigint() // 모든 값 → BigInt
33
28
  z.coerce.number().parse("42") // => 42
34
29
  z.coerce.date().parse("2021-01-01") // => Date
35
30
 
36
- // ⚠️ v4: 입력 타입이 unknown으로 변경됨
31
+ // v4: 입력 타입이 unknown으로 변경
37
32
  type In = z.input<typeof z.coerce.string()> // unknown
38
- ```
39
33
 
40
- ### 환경변수 불리언 (v4 권장)
34
+ // v4 환경변수 불리언
35
+ z.stringbool() // "true"/"yes"/"1" → true, "false"/"no"/"0" → false
41
36
 
42
- ```typescript
43
- z.stringbool() // "true"/"yes"/"1" → true
44
- // "false"/"no"/"0" → false
45
- ```
46
-
47
- ## Preprocess
48
-
49
- ```typescript
37
+ // Preprocess
50
38
  const trimmed = z.preprocess(
51
39
  (val) => typeof val === 'string' ? val.trim() : val,
52
40
  z.string()
53
41
  )
54
- ```
55
42
 
56
- ## 입력/출력 타입 분리
57
-
58
- ```typescript
43
+ // 입력/출력 타입 분리
59
44
  const Schema = z.object({
60
45
  createdAt: z.string().transform((str) => new Date(str)),
61
46
  })
62
-
63
47
  type SchemaInput = z.input<typeof Schema> // { createdAt: string }
64
48
  type SchemaOutput = z.output<typeof Schema> // { createdAt: Date }
65
49
  ```
50
+
51
+ </patterns>
@@ -1,25 +1,21 @@
1
1
  # Zod - 검증
2
2
 
3
- ## Refinement
3
+ <patterns>
4
4
 
5
5
  ```typescript
6
- // v4: message → error
6
+ // Refinement (v4: message → error)
7
7
  const PasswordSchema = z.string()
8
8
  .min(8)
9
9
  .refine((val) => /[A-Z]/.test(val), { error: '대문자 필수' })
10
10
  .refine((val) => /[0-9]/.test(val), { error: '숫자 필수' })
11
11
 
12
- // v4: refinement 후 체이닝 가능
13
- z.string().refine(val => val.includes("@")).min(5) // ✅
12
+ z.string().refine(val => val.includes("@")).min(5) // v4: refinement 후 체이닝
14
13
 
15
14
  // Async
16
15
  const schema = z.string().refine(async (val) => val.length <= 8)
17
16
  await schema.parseAsync('hello')
18
- ```
19
-
20
- ## Superrefine (고급)
21
17
 
22
- ```typescript
18
+ // Superrefine
23
19
  z.object({
24
20
  password: z.string(),
25
21
  confirmPassword: z.string(),
@@ -31,41 +27,25 @@ z.object({
31
27
  path: ['confirmPassword'],
32
28
  })
33
29
  }
34
- })
35
- // ⚠️ v4: ctx.path 사용 불가
36
- ```
37
-
38
- ## 커스텀 스키마
30
+ }) // v4: ctx.path 사용 불가
39
31
 
40
- ```typescript
32
+ // 커스텀
41
33
  const px = z.custom<`${number}px`>((val) =>
42
34
  typeof val === 'string' && /^\d+px$/.test(val)
43
35
  )
44
-
45
36
  px.parse('42px') // ✅
46
37
  px.parse('42vw') // throws
47
- ```
48
38
 
49
- ## 에러 처리
50
-
51
- ```typescript
39
+ // 에러 처리
52
40
  const result = schema.safeParse(data)
53
-
54
41
  if (!result.success) {
55
42
  result.error.errors.forEach((err) => {
56
43
  console.log(err.path, err.message, err.code)
57
44
  })
58
-
59
- // 평면화
60
- const flat = result.error.flatten()
61
- // { fieldErrors: { email: ['Invalid email'] } }
45
+ const flat = result.error.flatten() // { fieldErrors: { email: ['Invalid email'] } }
62
46
  }
63
- ```
64
47
 
65
- ## TanStack Start 연동
66
-
67
- ```typescript
68
- // Server Function
48
+ // TanStack Start
69
49
  export const createUser = createServerFn({ method: 'POST' })
70
50
  .inputValidator(zodValidator(createUserSchema))
71
51
  .handler(async ({ data }) => prisma.user.create({ data }))
@@ -81,12 +61,10 @@ const env = z.object({
81
61
  const workspaceMiddleware = createMiddleware({ type: 'function' })
82
62
  .inputValidator(zodValidator(z.object({ workspaceId: z.string() })))
83
63
  .server(({ next, data }) => next())
84
- ```
85
-
86
- ## Zod Mini (v4 경량)
87
64
 
88
- ```typescript
65
+ // Zod Mini (v4)
89
66
  import * as z from "zod/mini"
90
-
91
67
  z.string().check(z.minLength(5), z.maxLength(10), z.trim())
92
68
  ```
69
+
70
+ </patterns>
@@ -1,37 +0,0 @@
1
- ---
2
- name: debug-detective
3
- description: 디버깅 전문가. 버그 원인 분석 및 수정안 제시. "에러", "버그", "안돼" 요청 시 사용.
4
- model: inherit
5
- color: yellow
6
- tools: ["Read", "Grep", "Glob", "Bash"]
7
- ---
8
-
9
- You are a debugging specialist.
10
-
11
- ## Responsibilities
12
-
13
- 1. 에러 분석 - 스택 트레이스, 로그, 재현 조건
14
- 2. 원인 추적 - 코드 흐름 따라 근본 원인 탐지
15
- 3. 수정안 제시 - 최소 변경으로 해결
16
-
17
- ## Process
18
-
19
- 1. 증상 파악 (에러 메시지, 재현 단계)
20
- 2. 가설 수립 (가능한 원인 목록)
21
- 3. 코드 분석으로 가설 검증
22
- 4. 근본 원인 수정
23
-
24
- ## Common Patterns
25
-
26
- | 패턴 | 증상 | 확인 |
27
- |------|------|------|
28
- | Null Reference | TypeError | 옵셔널 체이닝 |
29
- | Race Condition | 간헐적 실패 | async/await |
30
- | Off-by-One | 잘못된 인덱스 | 반복문 경계 |
31
- | State Mutation | 예상외 변경 | 불변성 |
32
-
33
- ## Rules
34
-
35
- - 추측 금지, 코드 근거 필수
36
- - 최소 변경 원칙
37
- - Before/After 코드 제시
@@ -1,41 +0,0 @@
1
- ---
2
- name: test-writer
3
- description: 테스트 작성. 함수/컴포넌트 테스트 생성. "테스트 추가", "테스트 작성" 요청 시 사용.
4
- model: inherit
5
- color: green
6
- tools: ["Read", "Write", "Grep", "Glob"]
7
- ---
8
-
9
- You are a testing specialist.
10
-
11
- ## Responsibilities
12
-
13
- 1. 유닛 테스트 - 함수, 클래스 단위
14
- 2. 통합 테스트 - API, 서비스 상호작용
15
- 3. 엣지 케이스 - 경계값, 에러, 빈 입력
16
-
17
- ## Process
18
-
19
- 1. 대상 코드 분석 (입력/출력, 의존성)
20
- 2. 테스트 케이스 도출 (정상, 엣지, 에러)
21
- 3. 프로젝트 테스트 패턴 확인
22
- 4. 테스트 코드 작성
23
-
24
- ## Coverage Priority
25
-
26
- | 우선순위 | 케이스 |
27
- |----------|--------|
28
- | 필수 | happy path |
29
- | 필수 | 에러 핸들링 |
30
- | 권장 | 경계값 |
31
- | 권장 | null/undefined |
32
-
33
- ## Structure
34
-
35
- ```typescript
36
- describe('[대상]', () => {
37
- it('should [동작] when [조건]', () => {
38
- // Arrange → Act → Assert
39
- });
40
- });
41
- ```