@kood/claude-code 0.5.3 → 0.5.5

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 (125) hide show
  1. package/dist/index.js +552 -340
  2. package/package.json +1 -1
  3. package/templates/.claude/agents/document-writer.md +73 -306
  4. package/templates/.claude/instructions/agent-patterns/index.md +7 -7
  5. package/templates/.claude/instructions/document-templates/ralph-templates.md +71 -0
  6. package/templates/.claude/instructions/index.md +14 -14
  7. package/templates/.claude/instructions/multi-agent/agent-roster.md +14 -14
  8. package/templates/.claude/instructions/multi-agent/index.md +4 -4
  9. package/templates/.claude/skills/docs-creator/AGENTS.md +54 -176
  10. package/templates/.claude/skills/docs-creator/SKILL.md +98 -464
  11. package/templates/.claude/skills/docs-refactor/AGENTS.md +61 -190
  12. package/templates/.claude/skills/docs-refactor/SKILL.md +67 -443
  13. package/templates/.claude/skills/execute/SKILL.md +540 -13
  14. package/templates/.claude/skills/plan/SKILL.md +84 -18
  15. package/templates/.claude/skills/ralph/SKILL.md +17 -14
  16. package/templates/.claude/skills/refactor/AGENTS.md +269 -0
  17. package/templates/.claude/skills/refactor/SKILL.md +424 -66
  18. package/templates/.claude/skills/stitch-design/README.md +34 -0
  19. package/templates/.claude/skills/stitch-design/SKILL.md +213 -0
  20. package/templates/.claude/skills/stitch-design/examples/DESIGN.md +154 -0
  21. package/templates/.claude/skills/stitch-loop/README.md +54 -0
  22. package/templates/.claude/skills/stitch-loop/SKILL.md +316 -0
  23. package/templates/.claude/skills/stitch-loop/examples/SITE.md +73 -0
  24. package/templates/.claude/skills/stitch-loop/examples/next-prompt.md +25 -0
  25. package/templates/.claude/skills/stitch-loop/resources/baton-schema.md +61 -0
  26. package/templates/.claude/skills/stitch-loop/resources/site-template.md +104 -0
  27. package/templates/.claude/skills/stitch-react/README.md +36 -0
  28. package/templates/.claude/skills/stitch-react/SKILL.md +323 -0
  29. package/templates/.claude/skills/stitch-react/examples/gold-standard-card.tsx +88 -0
  30. package/templates/.claude/skills/stitch-react/package-lock.json +231 -0
  31. package/templates/.claude/skills/stitch-react/package.json +16 -0
  32. package/templates/.claude/skills/stitch-react/resources/architecture-checklist.md +15 -0
  33. package/templates/.claude/skills/stitch-react/resources/component-template.tsx +37 -0
  34. package/templates/.claude/skills/stitch-react/resources/stitch-api-reference.md +14 -0
  35. package/templates/.claude/skills/stitch-react/resources/style-guide.json +24 -0
  36. package/templates/.claude/skills/stitch-react/scripts/fetch-stitch.sh +30 -0
  37. package/templates/.claude/skills/stitch-react/scripts/validate.js +77 -0
  38. package/templates/hono/CLAUDE.md +28 -28
  39. package/templates/hono/docs/architecture.md +24 -24
  40. package/templates/hono/docs/deployment/cloudflare.md +18 -18
  41. package/templates/hono/docs/deployment/docker.md +13 -13
  42. package/templates/hono/docs/deployment/index.md +19 -19
  43. package/templates/hono/docs/deployment/railway.md +32 -32
  44. package/templates/hono/docs/deployment/vercel.md +29 -29
  45. package/templates/hono/docs/guides/conventions.md +57 -57
  46. package/templates/hono/docs/guides/env-setup.md +47 -47
  47. package/templates/hono/docs/guides/getting-started.md +27 -27
  48. package/templates/hono/docs/library/hono/error-handling.md +11 -11
  49. package/templates/hono/docs/library/hono/index.md +4 -4
  50. package/templates/hono/docs/library/hono/middleware.md +18 -18
  51. package/templates/hono/docs/library/hono/rpc.md +7 -7
  52. package/templates/hono/docs/library/hono/validation.md +6 -6
  53. package/templates/hono/docs/library/prisma/cloudflare-d1.md +29 -29
  54. package/templates/hono/docs/library/prisma/config.md +16 -16
  55. package/templates/hono/docs/library/prisma/index.md +32 -32
  56. package/templates/hono/docs/library/t3-env/index.md +22 -22
  57. package/templates/hono/docs/library/zod/index.md +31 -31
  58. package/templates/nextjs/CLAUDE.md +54 -54
  59. package/templates/nextjs/docs/architecture.md +146 -146
  60. package/templates/nextjs/docs/design.md +183 -183
  61. package/templates/nextjs/docs/guides/conventions.md +86 -86
  62. package/templates/nextjs/docs/guides/getting-started.md +28 -28
  63. package/templates/nextjs/docs/guides/routes.md +32 -32
  64. package/templates/nextjs/docs/library/better-auth/index.md +70 -70
  65. package/templates/nextjs/docs/library/nextjs/app-router.md +43 -43
  66. package/templates/nextjs/docs/library/nextjs/caching.md +73 -73
  67. package/templates/nextjs/docs/library/nextjs/index.md +51 -51
  68. package/templates/nextjs/docs/library/nextjs/middleware.md +41 -41
  69. package/templates/nextjs/docs/library/nextjs/route-handlers.md +31 -31
  70. package/templates/nextjs/docs/library/nextjs/server-actions.md +34 -34
  71. package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +20 -20
  72. package/templates/nextjs/docs/library/prisma/config.md +18 -18
  73. package/templates/nextjs/docs/library/prisma/crud.md +17 -17
  74. package/templates/nextjs/docs/library/prisma/index.md +18 -18
  75. package/templates/nextjs/docs/library/prisma/relations.md +16 -16
  76. package/templates/nextjs/docs/library/prisma/schema.md +23 -23
  77. package/templates/nextjs/docs/library/prisma/setup.md +6 -6
  78. package/templates/nextjs/docs/library/prisma/transactions.md +10 -10
  79. package/templates/nextjs/docs/library/tanstack-query/index.md +6 -6
  80. package/templates/nextjs/docs/library/tanstack-query/invalidation.md +20 -20
  81. package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +4 -4
  82. package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +15 -15
  83. package/templates/nextjs/docs/library/tanstack-query/use-query.md +22 -22
  84. package/templates/nextjs/docs/library/zod/complex-types.md +11 -11
  85. package/templates/nextjs/docs/library/zod/index.md +8 -8
  86. package/templates/nextjs/docs/library/zod/transforms.md +11 -11
  87. package/templates/nextjs/docs/library/zod/validation.md +9 -9
  88. package/templates/npx/CLAUDE.md +38 -38
  89. package/templates/npx/docs/library/commander/index.md +12 -12
  90. package/templates/npx/docs/library/fs-extra/index.md +9 -9
  91. package/templates/npx/docs/library/prompts/index.md +3 -3
  92. package/templates/npx/docs/references/patterns.md +12 -12
  93. package/templates/tanstack-start/CLAUDE.md +54 -54
  94. package/templates/tanstack-start/docs/architecture.md +128 -128
  95. package/templates/tanstack-start/docs/design.md +169 -169
  96. package/templates/tanstack-start/docs/guides/conventions.md +43 -43
  97. package/templates/tanstack-start/docs/guides/env-setup.md +35 -35
  98. package/templates/tanstack-start/docs/guides/getting-started.md +19 -19
  99. package/templates/tanstack-start/docs/guides/hooks.md +45 -45
  100. package/templates/tanstack-start/docs/guides/routes.md +54 -54
  101. package/templates/tanstack-start/docs/guides/services.md +45 -45
  102. package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +19 -19
  103. package/templates/tanstack-start/docs/library/prisma/config.md +16 -16
  104. package/templates/tanstack-start/docs/library/prisma/crud.md +17 -17
  105. package/templates/tanstack-start/docs/library/prisma/relations.md +16 -16
  106. package/templates/tanstack-start/docs/library/prisma/schema.md +23 -23
  107. package/templates/tanstack-start/docs/library/prisma/setup.md +6 -6
  108. package/templates/tanstack-start/docs/library/prisma/transactions.md +10 -10
  109. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +19 -19
  110. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +4 -4
  111. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +14 -14
  112. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +21 -21
  113. package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +9 -9
  114. package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +11 -11
  115. package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +17 -17
  116. package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +5 -5
  117. package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +10 -10
  118. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +8 -8
  119. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +9 -9
  120. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +6 -6
  121. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +18 -18
  122. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +4 -4
  123. package/templates/tanstack-start/docs/library/zod/complex-types.md +11 -11
  124. package/templates/tanstack-start/docs/library/zod/transforms.md +11 -11
  125. package/templates/tanstack-start/docs/library/zod/validation.md +9 -9
@@ -9,7 +9,7 @@
9
9
  <Link to="/products" search={{ page: 1, sort: 'newest' }}>Products</Link>
10
10
  <Link to="/products" search={prev => ({ ...prev, page: 2 })}>Next</Link>
11
11
 
12
- // Active styles
12
+ // Active 스타일
13
13
  <Link
14
14
  to="/about"
15
15
  activeProps={{ className: 'text-blue-500 font-bold' }}
@@ -33,11 +33,11 @@ const Component = () => {
33
33
  }
34
34
 
35
35
  // Preloading
36
- <Link to="/posts" preload="intent">Posts</Link> // On hover
37
- <Link to="/dashboard" preload="render">Dash</Link> // On render
38
- <Link to="/products" preload="viewport">Prod</Link> // On viewport entry
36
+ <Link to="/posts" preload="intent">Posts</Link> // hover
37
+ <Link to="/dashboard" preload="render">Dash</Link> // 렌더링
38
+ <Link to="/products" preload="viewport">Prod</Link> // viewport 진입 시
39
39
 
40
- // Conditional navigation
40
+ // 조건부 네비게이션
41
41
  const SubmitButton = () => {
42
42
  const navigate = useNavigate()
43
43
  const [isPending, startTransition] = useTransition()
@@ -57,24 +57,24 @@ const SubmitButton = () => {
57
57
 
58
58
  <options>
59
59
 
60
- | Link Props | Type | Description |
60
+ | Link Props | 타입 | 설명 |
61
61
  |------------|------|------|
62
- | `to` | string | Destination path |
63
- | `params` | object | Path parameters |
62
+ | `to` | string | 목적지 경로 |
63
+ | `params` | object | Path 파라미터 |
64
64
  | `search` | object \| function | Search params |
65
65
  | `hash` | string | Hash |
66
- | `replace` | boolean | Use history replace |
67
- | `preload` | 'intent' \| 'render' \| 'viewport' | Preload strategy |
68
- | `activeProps` | object | Props when active |
69
- | `inactiveProps` | object | Props when inactive |
66
+ | `replace` | boolean | history replace |
67
+ | `preload` | 'intent' \| 'render' \| 'viewport' | Preload 전략 |
68
+ | `activeProps` | object | Active props |
69
+ | `inactiveProps` | object | Inactive props |
70
70
 
71
- | navigate Options | Type | Description |
71
+ | navigate 옵션 | 타입 | 설명 |
72
72
  |---------------|------|------|
73
- | `to` | string | Destination path |
74
- | `params` | object | Path parameters |
73
+ | `to` | string | 목적지 경로 |
74
+ | `params` | object | Path 파라미터 |
75
75
  | `search` | object \| function | Search params |
76
76
  | `hash` | string | Hash |
77
- | `replace` | boolean | Use history.replace |
78
- | `resetScroll` | boolean | Reset scroll |
77
+ | `replace` | boolean | history.replace 사용 |
78
+ | `resetScroll` | boolean | 스크롤 리셋 |
79
79
 
80
80
  </options>
@@ -3,7 +3,7 @@
3
3
  <patterns>
4
4
 
5
5
  ```tsx
6
- // beforeLoad: auth check + add context
6
+ // beforeLoad: 인증 체크 + context 추가
7
7
  export const Route = createFileRoute('/dashboard')({
8
8
  beforeLoad: async ({ context, location }) => {
9
9
  if (!context.auth.isAuthenticated) {
@@ -30,7 +30,7 @@ export const Route = createFileRoute('/_authed/dashboard')({
30
30
  component: DashboardPage,
31
31
  })
32
32
  const DashboardPage = () => {
33
- const { user } = Route.useRouteContext() // Context from _authed
33
+ const { user } = Route.useRouteContext() // _authed에서 전달된 context
34
34
  return <h1>Welcome, {user.name}!</h1>
35
35
  }
36
36
 
@@ -75,10 +75,10 @@ routes/
75
75
 
76
76
  <usage>
77
77
 
78
- | Location | Access Method |
78
+ | 위치 | 접근 방법 |
79
79
  |------|----------|
80
- | beforeLoad | `{ context }` parameter |
81
- | loader | `{ context }` parameter |
80
+ | beforeLoad | `{ context }` 파라미터 |
81
+ | loader | `{ context }` 파라미터 |
82
82
  | component | `Route.useRouteContext()` |
83
83
 
84
84
  </usage>
@@ -3,20 +3,20 @@
3
3
  <patterns>
4
4
 
5
5
  ```tsx
6
- // Zod schema + route
6
+ // Zod 스키마 + 라우트
7
7
  const searchSchema = z.object({
8
- page: z.number().catch(1), // Default value
9
- search: z.string().optional(), // Optional
8
+ page: z.number().catch(1), // 기본값
9
+ search: z.string().optional(), // 선택
10
10
  sort: z.enum(['newest', 'price']).catch('newest'),
11
- tags: z.array(z.string()).catch([]), // Array
11
+ tags: z.array(z.string()).catch([]), // 배열
12
12
  inStock: z.boolean().catch(true), // Boolean
13
- from: z.string().date().optional(), // Date
14
- minPrice: z.number().min(0).catch(0), // Range
13
+ from: z.string().date().optional(), // 날짜
14
+ minPrice: z.number().min(0).catch(0), // 범위
15
15
  })
16
16
 
17
17
  export const Route = createFileRoute('/products')({
18
18
  validateSearch: searchSchema,
19
- loaderDeps: ({ search }) => ({ search }), // Re-run loader on search change
19
+ loaderDeps: ({ search }) => ({ search }), // search 변경 loader 재실행
20
20
  loader: async ({ deps: { search } }) => fetchProducts(search),
21
21
  component: ProductsPage,
22
22
  })
@@ -26,11 +26,11 @@ const ProductsPage = () => {
26
26
  return <div>Page: {page}, Sort: {sort}</div>
27
27
  }
28
28
 
29
- // Update via Link
29
+ // Link로 업데이트
30
30
  <Link to="/products" search={{ page: 1, sort: 'newest' }}>Reset</Link>
31
31
  <Link to="/products" search={prev => ({ ...prev, page: 2 })}>Next</Link>
32
32
 
33
- // Update via useNavigate
33
+ // useNavigate로 업데이트
34
34
  const Pagination = () => {
35
35
  const navigate = useNavigate()
36
36
  const { page } = Route.useSearch()
@@ -48,7 +48,7 @@ const Pagination = () => {
48
48
  )
49
49
  }
50
50
 
51
- // Real-world: Filter + Sort + Pagination
51
+ // 실전: 필터 + 정렬 + 페이지네이션
52
52
  const PostsPage = () => {
53
53
  const { page, search, category, sort } = Route.useSearch()
54
54
  const posts = Route.useLoaderData()
@@ -1,9 +1,9 @@
1
- # TanStack Start - Auth Patterns
1
+ # TanStack Start - 인증 패턴
2
2
 
3
3
  <patterns>
4
4
 
5
5
  ```typescript
6
- // Login
6
+ // 로그인
7
7
  export const loginFn = createServerFn({ method: 'POST' })
8
8
  .inputValidator((data: { email: string; password: string }) => data)
9
9
  .handler(async ({ data }) => {
@@ -14,7 +14,7 @@ export const loginFn = createServerFn({ method: 'POST' })
14
14
  throw redirect({ to: '/dashboard' })
15
15
  })
16
16
 
17
- // Logout
17
+ // 로그아웃
18
18
  export const logoutFn = createServerFn({ method: 'POST' })
19
19
  .handler(async () => {
20
20
  const session = await useAppSession()
@@ -22,7 +22,7 @@ export const logoutFn = createServerFn({ method: 'POST' })
22
22
  throw redirect({ to: '/' })
23
23
  })
24
24
 
25
- // Get current user
25
+ // 현재 사용자
26
26
  export const getCurrentUserFn = createServerFn({ method: 'GET' })
27
27
  .handler(async () => {
28
28
  const session = await useAppSession()
@@ -30,7 +30,7 @@ export const getCurrentUserFn = createServerFn({ method: 'GET' })
30
30
  return getUserById(session.data.userId)
31
31
  })
32
32
 
33
- // Auth middleware
33
+ // 인증 미들웨어
34
34
  export const authMiddleware = createMiddleware({ type: 'function' })
35
35
  .server(async ({ next }) => {
36
36
  const session = await useAppSession()
@@ -39,12 +39,12 @@ export const authMiddleware = createMiddleware({ type: 'function' })
39
39
  return next({ context: { user } })
40
40
  })
41
41
 
42
- // Apply to Server Function
42
+ // Server Function에 적용
43
43
  export const protectedFn = createServerFn({ method: 'GET' })
44
44
  .middleware([authMiddleware])
45
45
  .handler(async ({ context }) => ({ user: context.user }))
46
46
 
47
- // Protected route
47
+ // 보호된 라우트
48
48
  export const Route = createFileRoute('/dashboard')({
49
49
  beforeLoad: async () => {
50
50
  const user = await getCurrentUserFn()
@@ -57,7 +57,7 @@ export const Route = createFileRoute('/dashboard')({
57
57
  },
58
58
  })
59
59
 
60
- // Better Auth integration
60
+ // Better Auth 통합
61
61
  export const auth = betterAuth({
62
62
  database: prismaAdapter(prisma),
63
63
  emailAndPassword: { enabled: true },
@@ -1,24 +1,24 @@
1
1
  # TanStack Start - Middleware
2
2
 
3
- Apply common logic to Server Functions and routes.
3
+ Server Function 라우트에 공통 로직 적용.
4
4
 
5
- ## Basic Pattern
5
+ ## 기본 패턴
6
6
 
7
7
  ```typescript
8
- // Middleware definition
8
+ // 미들웨어 정의
9
9
  const loggingMiddleware = createMiddleware({ type: 'function' })
10
10
  .server(({ next }) => {
11
11
  console.log('Processing request')
12
12
  return next()
13
13
  })
14
14
 
15
- // Apply
15
+ // 적용
16
16
  const fn = createServerFn()
17
17
  .middleware([loggingMiddleware])
18
18
  .handler(async () => ({ message: 'Hello' }))
19
19
  ```
20
20
 
21
- ## Auth Middleware
21
+ ## 인증 미들웨어
22
22
 
23
23
  ```typescript
24
24
  const authMiddleware = createMiddleware({ type: 'function' })
@@ -28,7 +28,7 @@ const authMiddleware = createMiddleware({ type: 'function' })
28
28
  return next({ context: { user: session.user } })
29
29
  })
30
30
 
31
- // Usage
31
+ // 사용
32
32
  export const protectedFn = createServerFn({ method: 'GET' })
33
33
  .middleware([authMiddleware])
34
34
  .handler(async ({ context }) => ({ user: context.user }))
@@ -47,8 +47,8 @@ const workspaceMiddleware = createMiddleware({ type: 'function' })
47
47
  ```typescript
48
48
  // src/start.ts
49
49
  export const startInstance = createStart(() => ({
50
- requestMiddleware: [globalMiddleware], // All requests
51
- functionMiddleware: [loggingMiddleware], // All Server Functions
50
+ requestMiddleware: [globalMiddleware], // 모든 요청
51
+ functionMiddleware: [loggingMiddleware], // 모든 Server Function
52
52
  }))
53
53
  ```
54
54
 
@@ -57,7 +57,7 @@ export const startInstance = createStart(() => ({
57
57
  ```typescript
58
58
  export const Route = createFileRoute('/hello')({
59
59
  server: {
60
- middleware: [authMiddleware], // All handlers
60
+ middleware: [authMiddleware], // 모든 핸들러
61
61
  handlers: { GET: async ({ request }) => new Response('Hello') },
62
62
  },
63
63
  })
@@ -3,7 +3,7 @@
3
3
  <patterns>
4
4
 
5
5
  ```tsx
6
- // Basic
6
+ // 기본
7
7
  export const Route = createFileRoute('/about')({ component: AboutPage })
8
8
 
9
9
  // Loader
@@ -16,7 +16,7 @@ const Page = () => {
16
16
  return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
17
17
  }
18
18
 
19
- // Dynamic routes
19
+ // 동적 라우트
20
20
  export const Route = createFileRoute('/users/$id')({
21
21
  loader: async ({ params }) => ({ user: await getUserById(params.id) }),
22
22
  component: () => {
@@ -25,10 +25,10 @@ export const Route = createFileRoute('/users/$id')({
25
25
  },
26
26
  })
27
27
 
28
- // SSR options
29
- ssr: true // Full SSR (default)
30
- ssr: false // Client-only
31
- ssr: 'data-only' // Data only on server
28
+ // SSR 옵션
29
+ ssr: true // 전체 SSR (기본값)
30
+ ssr: false // 클라이언트만
31
+ ssr: 'data-only' // 데이터만 서버
32
32
 
33
33
  // Server Routes (API)
34
34
  export const Route = createFileRoute('/api/hello')({
@@ -1,13 +1,13 @@
1
1
  # TanStack Start - Server Functions
2
2
 
3
- Type-safe functions that run only on the server.
3
+ 서버에서만 실행되는 타입 안전한 함수.
4
4
 
5
- ## ⚠️ Required: Use TanStack Query
5
+ ## ⚠️ 필수: TanStack Query 사용
6
6
 
7
- Always use useQuery/useMutation when calling from client.
8
- - Auto caching, deduplication, loading/error states, invalidateQueries sync
7
+ 클라이언트 호출 시 반드시 useQuery/useMutation 사용.
8
+ - 자동 캐싱, 중복 요청 제거, 로딩/에러 상태 관리, invalidateQueries 동기화
9
9
 
10
- ## Basic Patterns
10
+ ## 기본 패턴
11
11
 
12
12
  ```typescript
13
13
  // GET
@@ -25,31 +25,31 @@ export const createUser = createServerFn({ method: 'POST' })
25
25
  .handler(async ({ data }) => prisma.user.create({ data }))
26
26
  ```
27
27
 
28
- ## Calling from Components
28
+ ## 컴포넌트에서 호출
29
29
 
30
30
  ```tsx
31
- // ✅ useQuery (read)
31
+ // ✅ useQuery (조회)
32
32
  const { data, isLoading } = useQuery({
33
33
  queryKey: ['posts'],
34
34
  queryFn: () => getServerPosts(),
35
35
  })
36
36
 
37
- // ✅ useMutation (write)
37
+ // ✅ useMutation (변경)
38
38
  const mutation = useMutation({
39
39
  mutationFn: createPost,
40
40
  onSuccess: () => queryClient.invalidateQueries({ queryKey: ['posts'] }),
41
41
  })
42
42
 
43
- // ❌ Direct calls forbidden (no caching, no sync)
43
+ // ❌ 직접 호출 금지 (캐싱 없음, 동기화 안됨)
44
44
  ```
45
45
 
46
- ## Function Separation Rules
46
+ ## 함수 분리 규칙
47
47
 
48
48
  ```typescript
49
- // Internal helper (don't export!)
49
+ // 내부 헬퍼 (export 금지!)
50
50
  const validateUserData = async (email: string) => { ... }
51
51
 
52
- // Server Function (exportable)
52
+ // Server Function (export 가능)
53
53
  export const createUser = createServerFn({ method: 'POST' })
54
54
  .inputValidator(createUserSchema)
55
55
  .handler(async ({ data }) => {
@@ -57,19 +57,19 @@ export const createUser = createServerFn({ method: 'POST' })
57
57
  return prisma.user.create({ data })
58
58
  })
59
59
 
60
- // index.ts: Export only Server Functions
60
+ // index.ts: Server Function만 export
61
61
  export { createUser } from './mutations'
62
- // ❌ export { validateUserData } forbidden
62
+ // ❌ export { validateUserData } 금지
63
63
  ```
64
64
 
65
- ## Security
65
+ ## 보안
66
66
 
67
67
  ```tsx
68
- // ❌ Environment variables in loader (exposed)
68
+ // ❌ loader에서 환경변수 직접 사용 (노출됨)
69
69
  loader: () => { const secret = process.env.SECRET }
70
70
 
71
- // ✅ Use Server Functions
71
+ // ✅ Server Function 사용
72
72
  const fn = createServerFn().handler(() => {
73
- const secret = process.env.SECRET // server-only
73
+ const secret = process.env.SECRET // 서버에서만
74
74
  })
75
75
  ```
@@ -1,13 +1,13 @@
1
- # TanStack Start - Installation and Setup
1
+ # TanStack Start - 설치 설정
2
2
 
3
- ## Installation
3
+ ## 설치
4
4
 
5
5
  ```bash
6
6
  yarn add @tanstack/react-start @tanstack/react-router vinxi
7
7
  yarn add -D vite @vitejs/plugin-react vite-tsconfig-paths
8
8
  ```
9
9
 
10
- ## Configuration
10
+ ## 설정
11
11
 
12
12
  ```typescript
13
13
  // vite.config.ts
@@ -36,7 +36,7 @@ export default defineConfig({
36
36
  }
37
37
  ```
38
38
 
39
- ## Environment Variable Validation
39
+ ## 환경 변수 검증
40
40
 
41
41
  ```typescript
42
42
  // lib/env.ts
@@ -1,31 +1,31 @@
1
- # Zod - Complex Types
1
+ # Zod - 복합 타입
2
2
 
3
3
  <patterns>
4
4
 
5
5
  ```typescript
6
- // Object
6
+ // 객체
7
7
  const UserSchema = z.object({
8
8
  name: z.string(),
9
9
  email: z.email(),
10
10
  age: z.number().optional(),
11
11
  })
12
12
 
13
- UserSchema.partial() // All fields optional
14
- UserSchema.required() // All fields required
15
- UserSchema.pick({ name: true }) // Only specific fields
16
- UserSchema.omit({ email: true }) // Exclude specific fields
13
+ UserSchema.partial() // 모든 필드 optional
14
+ UserSchema.required() // 모든 필드 required
15
+ UserSchema.pick({ name: true }) // 특정 필드만
16
+ UserSchema.omit({ email: true }) // 특정 필드 제외
17
17
  UserSchema.extend({ role: z.enum(['admin', 'user']) })
18
18
  UserSchema.merge(AnotherSchema)
19
19
 
20
- z.strictObject({ name: z.string() }) // v4: error on extra keys
21
- z.looseObject({ name: z.string() }) // v4: allow extra keys
20
+ z.strictObject({ name: z.string() }) // v4: 추가 에러
21
+ z.looseObject({ name: z.string() }) // v4: 추가 통과
22
22
 
23
- // Array/Tuple
23
+ // 배열/튜플
24
24
  z.array(z.string())
25
25
  z.array(z.number()).min(1).max(10).length(5).nonempty()
26
26
  z.tuple([z.string(), z.number()]) // [string, number]
27
27
 
28
- // Union
28
+ // 유니온
29
29
  z.union([z.string(), z.number()])
30
30
  z.string().or(z.number())
31
31
 
@@ -46,7 +46,7 @@ z.record(z.string(), z.object({ name: z.string() })) // { [key: string]: { name
46
46
  z.map(z.string(), z.number()) // Map<string, number>
47
47
  z.set(z.number()) // Set<number>
48
48
 
49
- // Recursive
49
+ // 재귀
50
50
  type Json = string | number | boolean | null | { [key: string]: Json } | Json[]
51
51
 
52
52
  const jsonSchema: z.ZodType<Json> = z.lazy(() =>
@@ -1,4 +1,4 @@
1
- # Zod - Transforms
1
+ # Zod - 변환
2
2
 
3
3
  <patterns>
4
4
 
@@ -10,7 +10,7 @@ stringToLength.parse('hello') // => 5
10
10
  type In = z.input<typeof stringToLength> // string
11
11
  type Out = z.output<typeof stringToLength> // number
12
12
 
13
- // Pipe (validate then transform)
13
+ // Pipe (검증 변환)
14
14
  const stringToNumber = z.string()
15
15
  .transform((val) => parseInt(val, 10))
16
16
  .pipe(z.number().min(0).max(100))
@@ -18,20 +18,20 @@ const stringToNumber = z.string()
18
18
  stringToNumber.parse('50') // => 50
19
19
  stringToNumber.parse('150') // throws
20
20
 
21
- // Coerce (force conversion)
22
- z.coerce.string() // anystring
23
- z.coerce.number() // anynumber
24
- z.coerce.boolean() // anyboolean
25
- z.coerce.date() // anyDate
26
- z.coerce.bigint() // any → BigInt
21
+ // Coerce (강제 변환)
22
+ z.coerce.string() // 모든 문자열
23
+ z.coerce.number() // 모든 숫자
24
+ z.coerce.boolean() // 모든 불리언
25
+ z.coerce.date() // 모든 날짜
26
+ z.coerce.bigint() // 모든 → BigInt
27
27
 
28
28
  z.coerce.number().parse("42") // => 42
29
29
  z.coerce.date().parse("2021-01-01") // => Date
30
30
 
31
- // v4: input type changed to unknown
31
+ // v4: 입력 타입이 unknown으로 변경
32
32
  type In = z.input<typeof z.coerce.string()> // unknown
33
33
 
34
- // v4 environment boolean
34
+ // v4 환경변수 불리언
35
35
  z.stringbool() // "true"/"yes"/"1" → true, "false"/"no"/"0" → false
36
36
 
37
37
  // Preprocess
@@ -40,7 +40,7 @@ const trimmed = z.preprocess(
40
40
  z.string()
41
41
  )
42
42
 
43
- // Separate input/output types
43
+ // 입력/출력 타입 분리
44
44
  const Schema = z.object({
45
45
  createdAt: z.string().transform((str) => new Date(str)),
46
46
  })
@@ -1,4 +1,4 @@
1
- # Zod - Validation
1
+ # Zod - 검증
2
2
 
3
3
  <patterns>
4
4
 
@@ -6,10 +6,10 @@
6
6
  // Refinement (v4: message → error)
7
7
  const PasswordSchema = z.string()
8
8
  .min(8)
9
- .refine((val) => /[A-Z]/.test(val), { error: 'Uppercase required' })
10
- .refine((val) => /[0-9]/.test(val), { error: 'Number required' })
9
+ .refine((val) => /[A-Z]/.test(val), { error: '대문자 필수' })
10
+ .refine((val) => /[0-9]/.test(val), { error: '숫자 필수' })
11
11
 
12
- z.string().refine(val => val.includes("@")).min(5) // v4: chaining after refinement
12
+ z.string().refine(val => val.includes("@")).min(5) // v4: refinement 체이닝
13
13
 
14
14
  // Async
15
15
  const schema = z.string().refine(async (val) => val.length <= 8)
@@ -23,20 +23,20 @@ z.object({
23
23
  if (data.password !== data.confirmPassword) {
24
24
  ctx.addIssue({
25
25
  code: z.ZodIssueCode.custom,
26
- message: 'Passwords do not match',
26
+ message: '비밀번호 불일치',
27
27
  path: ['confirmPassword'],
28
28
  })
29
29
  }
30
- }) // v4: ctx.path cannot be used
30
+ }) // v4: ctx.path 사용 불가
31
31
 
32
- // Custom
32
+ // 커스텀
33
33
  const px = z.custom<`${number}px`>((val) =>
34
34
  typeof val === 'string' && /^\d+px$/.test(val)
35
35
  )
36
36
  px.parse('42px') // ✅
37
37
  px.parse('42vw') // throws
38
38
 
39
- // Error handling
39
+ // 에러 처리
40
40
  const result = schema.safeParse(data)
41
41
  if (!result.success) {
42
42
  result.error.errors.forEach((err) => {
@@ -50,7 +50,7 @@ export const createUser = createServerFn({ method: 'POST' })
50
50
  .inputValidator(zodValidator(createUserSchema))
51
51
  .handler(async ({ data }) => prisma.user.create({ data }))
52
52
 
53
- // Environment variables
53
+ // 환경 변수
54
54
  const env = z.object({
55
55
  NODE_ENV: z.enum(['development', 'production', 'test']),
56
56
  DATABASE_URL: z.string().url(),