@su-record/vibe 2.4.72 → 2.4.76

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 (164) hide show
  1. package/CLAUDE.md +216 -215
  2. package/README.md +4 -4
  3. package/agents/research/best-practices-agent.md +13 -13
  4. package/agents/research/codebase-patterns-agent.md +33 -33
  5. package/agents/research/framework-docs-agent.md +23 -23
  6. package/agents/research/security-advisory-agent.md +29 -29
  7. package/agents/review/architecture-reviewer.md +31 -31
  8. package/agents/review/complexity-reviewer.md +21 -21
  9. package/agents/review/data-integrity-reviewer.md +29 -29
  10. package/agents/review/git-history-reviewer.md +24 -24
  11. package/agents/review/performance-reviewer.md +29 -29
  12. package/agents/review/python-reviewer.md +53 -53
  13. package/agents/review/rails-reviewer.md +40 -40
  14. package/agents/review/react-reviewer.md +40 -40
  15. package/agents/review/security-reviewer.md +29 -29
  16. package/agents/review/simplicity-reviewer.md +24 -24
  17. package/agents/review/test-coverage-reviewer.md +31 -31
  18. package/agents/review/typescript-reviewer.md +41 -41
  19. package/commands/vibe.analyze.md +103 -7
  20. package/commands/vibe.reason.md +106 -0
  21. package/commands/vibe.review.md +123 -38
  22. package/commands/vibe.run.md +286 -223
  23. package/commands/vibe.spec.md +425 -186
  24. package/commands/vibe.utils.md +104 -3
  25. package/commands/vibe.verify.md +179 -86
  26. package/dist/cli/detect.js +40 -40
  27. package/dist/cli/detect.js.map +1 -1
  28. package/dist/cli/index.d.ts +1 -1
  29. package/dist/cli/index.js +1 -1
  30. package/dist/cli/llm.js +5 -5
  31. package/dist/cli/llm.js.map +1 -1
  32. package/dist/cli/setup.js +3 -3
  33. package/dist/cli/setup.js.map +1 -1
  34. package/dist/lib/ContextCompressor.js +1 -1
  35. package/dist/lib/ContextCompressor.js.map +1 -1
  36. package/dist/lib/MemoryManager.d.ts +13 -155
  37. package/dist/lib/MemoryManager.d.ts.map +1 -1
  38. package/dist/lib/MemoryManager.js +52 -617
  39. package/dist/lib/MemoryManager.js.map +1 -1
  40. package/dist/lib/gemini-api.js +12 -12
  41. package/dist/lib/gemini-api.js.map +1 -1
  42. package/dist/lib/gemini-oauth.js +22 -22
  43. package/dist/lib/gemini-oauth.js.map +1 -1
  44. package/dist/lib/gemini-storage.js +3 -3
  45. package/dist/lib/gemini-storage.js.map +1 -1
  46. package/dist/lib/gpt-api.js +11 -11
  47. package/dist/lib/gpt-api.js.map +1 -1
  48. package/dist/lib/gpt-oauth.js +28 -28
  49. package/dist/lib/gpt-oauth.js.map +1 -1
  50. package/dist/lib/gpt-storage.js +3 -3
  51. package/dist/lib/gpt-storage.js.map +1 -1
  52. package/dist/lib/memory/KnowledgeGraph.d.ts +34 -0
  53. package/dist/lib/memory/KnowledgeGraph.d.ts.map +1 -0
  54. package/dist/lib/memory/KnowledgeGraph.js +216 -0
  55. package/dist/lib/memory/KnowledgeGraph.js.map +1 -0
  56. package/dist/lib/memory/KnowledgeGraph.test.d.ts +2 -0
  57. package/dist/lib/memory/KnowledgeGraph.test.d.ts.map +1 -0
  58. package/dist/lib/memory/KnowledgeGraph.test.js +189 -0
  59. package/dist/lib/memory/KnowledgeGraph.test.js.map +1 -0
  60. package/dist/lib/memory/MemorySearch.d.ts +25 -0
  61. package/dist/lib/memory/MemorySearch.d.ts.map +1 -0
  62. package/dist/lib/memory/MemorySearch.js +85 -0
  63. package/dist/lib/memory/MemorySearch.js.map +1 -0
  64. package/dist/lib/memory/MemorySearch.test.d.ts +2 -0
  65. package/dist/lib/memory/MemorySearch.test.d.ts.map +1 -0
  66. package/dist/lib/memory/MemorySearch.test.js +149 -0
  67. package/dist/lib/memory/MemorySearch.test.js.map +1 -0
  68. package/dist/lib/memory/MemoryStorage.d.ts +77 -0
  69. package/dist/lib/memory/MemoryStorage.d.ts.map +1 -0
  70. package/dist/lib/memory/MemoryStorage.js +278 -0
  71. package/dist/lib/memory/MemoryStorage.js.map +1 -0
  72. package/dist/lib/memory/MemoryStorage.test.d.ts +2 -0
  73. package/dist/lib/memory/MemoryStorage.test.d.ts.map +1 -0
  74. package/dist/lib/memory/MemoryStorage.test.js +198 -0
  75. package/dist/lib/memory/MemoryStorage.test.js.map +1 -0
  76. package/dist/lib/memory/index.d.ts +4 -0
  77. package/dist/lib/memory/index.d.ts.map +1 -0
  78. package/dist/lib/memory/index.js +8 -0
  79. package/dist/lib/memory/index.js.map +1 -0
  80. package/dist/orchestrator/orchestrator.d.ts.map +1 -1
  81. package/dist/orchestrator/orchestrator.js +4 -6
  82. package/dist/orchestrator/orchestrator.js.map +1 -1
  83. package/dist/tools/convention/analyzeComplexity.d.ts +3 -1
  84. package/dist/tools/convention/analyzeComplexity.d.ts.map +1 -1
  85. package/dist/tools/convention/analyzeComplexity.js +102 -4
  86. package/dist/tools/convention/analyzeComplexity.js.map +1 -1
  87. package/dist/tools/convention/analyzeComplexity.test.d.ts +2 -0
  88. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +1 -0
  89. package/dist/tools/convention/analyzeComplexity.test.js +207 -0
  90. package/dist/tools/convention/analyzeComplexity.test.js.map +1 -0
  91. package/dist/tools/convention/applyQualityRules.js +1 -1
  92. package/dist/tools/convention/applyQualityRules.js.map +1 -1
  93. package/dist/tools/convention/checkCouplingCohesion.js +2 -2
  94. package/dist/tools/convention/checkCouplingCohesion.js.map +1 -1
  95. package/dist/tools/convention/suggestImprovements.js +1 -1
  96. package/dist/tools/convention/suggestImprovements.js.map +1 -1
  97. package/dist/tools/convention/validateCodeQuality.d.ts +3 -1
  98. package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
  99. package/dist/tools/convention/validateCodeQuality.js +145 -2
  100. package/dist/tools/convention/validateCodeQuality.js.map +1 -1
  101. package/dist/tools/convention/validateCodeQuality.test.d.ts +2 -0
  102. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +1 -0
  103. package/dist/tools/convention/validateCodeQuality.test.js +230 -0
  104. package/dist/tools/convention/validateCodeQuality.test.js.map +1 -0
  105. package/dist/tools/memory/autoSaveContext.js +1 -1
  106. package/dist/tools/memory/autoSaveContext.js.map +1 -1
  107. package/dist/tools/memory/createMemoryTimeline.js +27 -27
  108. package/dist/tools/memory/createMemoryTimeline.js.map +1 -1
  109. package/dist/tools/memory/deleteMemory.js +1 -1
  110. package/dist/tools/memory/deleteMemory.js.map +1 -1
  111. package/dist/tools/memory/getMemoryGraph.js +24 -24
  112. package/dist/tools/memory/getMemoryGraph.js.map +1 -1
  113. package/dist/tools/memory/getSessionContext.js +36 -36
  114. package/dist/tools/memory/getSessionContext.js.map +1 -1
  115. package/dist/tools/memory/linkMemories.js +21 -21
  116. package/dist/tools/memory/linkMemories.js.map +1 -1
  117. package/dist/tools/memory/prioritizeMemory.js +1 -1
  118. package/dist/tools/memory/prioritizeMemory.js.map +1 -1
  119. package/dist/tools/memory/restoreSessionContext.js +1 -1
  120. package/dist/tools/memory/restoreSessionContext.js.map +1 -1
  121. package/dist/tools/memory/searchMemories.js +1 -1
  122. package/dist/tools/memory/searchMemories.js.map +1 -1
  123. package/dist/tools/memory/searchMemoriesAdvanced.js +42 -42
  124. package/dist/tools/memory/searchMemoriesAdvanced.js.map +1 -1
  125. package/dist/tools/memory/startSession.js +2 -2
  126. package/dist/tools/memory/startSession.js.map +1 -1
  127. package/dist/tools/memory/updateMemory.js +1 -1
  128. package/dist/tools/memory/updateMemory.js.map +1 -1
  129. package/dist/tools/semantic/analyzeDependencyGraph.js +38 -38
  130. package/dist/tools/semantic/analyzeDependencyGraph.js.map +1 -1
  131. package/dist/tools/semantic/findReferences.js +1 -1
  132. package/dist/tools/semantic/findReferences.js.map +1 -1
  133. package/dist/tools/semantic/findSymbol.js +1 -1
  134. package/dist/tools/semantic/findSymbol.js.map +1 -1
  135. package/dist/tools/time/getCurrentTime.js +1 -1
  136. package/dist/tools/time/getCurrentTime.js.map +1 -1
  137. package/dist/tools/ui/previewUiAscii.js +2 -2
  138. package/dist/tools/ui/previewUiAscii.js.map +1 -1
  139. package/hooks/hooks.json +11 -2
  140. package/hooks/scripts/llm-orchestrate.js +1 -1
  141. package/hooks/scripts/utils.js +31 -6
  142. package/languages/csharp-unity.md +82 -83
  143. package/languages/dart-flutter.md +89 -88
  144. package/languages/go.md +76 -75
  145. package/languages/java-spring.md +85 -84
  146. package/languages/kotlin-android.md +64 -63
  147. package/languages/python-django.md +83 -82
  148. package/languages/python-fastapi.md +82 -81
  149. package/languages/rust.md +75 -74
  150. package/languages/swift-ios.md +73 -72
  151. package/languages/typescript-electron.md +70 -71
  152. package/languages/typescript-nextjs.md +93 -92
  153. package/languages/typescript-node.md +64 -63
  154. package/languages/typescript-nuxt.md +113 -112
  155. package/languages/typescript-react-native.md +82 -81
  156. package/languages/typescript-react.md +76 -75
  157. package/languages/typescript-tauri.md +74 -75
  158. package/languages/typescript-vue.md +73 -72
  159. package/package.json +1 -1
  160. package/skills/git-worktree.md +25 -25
  161. package/skills/multi-llm-orchestration.md +4 -6
  162. package/skills/priority-todos.md +39 -39
  163. package/skills/vibe-capabilities.md +2 -2
  164. package/vibe/config.json +2 -2
@@ -1,36 +1,37 @@
1
- # 🟢 TypeScript + Nuxt 3 품질 규칙
1
+ # TypeScript + Nuxt 3 Quality Rules
2
2
 
3
- ## 핵심 원칙 (Vue에서 상속)
3
+ ## Core Principles (inherited from Vue)
4
4
 
5
5
  ```markdown
6
- 단일 책임 (SRP)
7
- 중복 제거 (DRY)
8
- 재사용성
9
- ✅ 낮은 복잡도
10
- 함수 ≤ 30줄, Template ≤ 100줄
11
- 중첩 3단계
12
- Composition API + script setup
6
+ # Core Principles (inherited from Vue)
7
+ Single Responsibility (SRP)
8
+ No Duplication (DRY)
9
+ Reusability
10
+ Low Complexity
11
+ Function <= 30 lines, Template <= 100 lines
12
+ Nesting <= 3 levels
13
+ Composition API + script setup
13
14
  ```
14
15
 
15
- ## Nuxt 3 특화 규칙
16
+ ## Nuxt 3 Specific Rules
16
17
 
17
- ### 1. Auto-imports 활용
18
+ ### 1. Auto-imports Usage
18
19
 
19
20
  ```typescript
20
- // Nuxt 3 자동 import (명시적 import 불필요)
21
+ // Good: Nuxt 3 auto-imports (no explicit import needed)
21
22
  <script setup lang="ts">
22
- // ref, computed, watch Vue API 자동 import
23
+ // ref, computed, watch etc Vue API auto-imported
23
24
  const count = ref(0);
24
25
  const doubled = computed(() => count.value * 2);
25
26
 
26
- // useFetch, useAsyncData Nuxt composables 자동 import
27
+ // useFetch, useAsyncData etc Nuxt composables auto-imported
27
28
  const { data } = await useFetch('/api/users');
28
29
 
29
- // components/ 폴더의 컴포넌트 자동 import
30
- // <UserCard /> 바로 사용 가능
30
+ // Components from components/ folder auto-imported
31
+ // <UserCard /> can be used directly
31
32
  </script>
32
33
 
33
- // 불필요한 import
34
+ // Bad: Unnecessary imports
34
35
  import { ref, computed } from 'vue';
35
36
  import { useFetch } from '#app';
36
37
  ```
@@ -38,21 +39,21 @@ import { useFetch } from '#app';
38
39
  ### 2. Server API Routes
39
40
 
40
41
  ```typescript
41
- // server/api/users/index.get.ts (GET /api/users)
42
+ // Good: server/api/users/index.get.ts (GET /api/users)
42
43
  export default defineEventHandler(async (event) => {
43
44
  const users = await prisma.user.findMany();
44
45
  return users;
45
46
  });
46
47
 
47
- // server/api/users/index.post.ts (POST /api/users)
48
+ // Good: server/api/users/index.post.ts (POST /api/users)
48
49
  export default defineEventHandler(async (event) => {
49
50
  const body = await readBody(event);
50
51
 
51
- // 유효성 검사
52
+ // Validation
52
53
  if (!body.email || !body.name) {
53
54
  throw createError({
54
55
  statusCode: 400,
55
- message: '이메일과 이름은 필수입니다',
56
+ message: 'Email and name are required',
56
57
  });
57
58
  }
58
59
 
@@ -60,7 +61,7 @@ export default defineEventHandler(async (event) => {
60
61
  return user;
61
62
  });
62
63
 
63
- // server/api/users/[id].get.ts (GET /api/users/:id)
64
+ // Good: server/api/users/[id].get.ts (GET /api/users/:id)
64
65
  export default defineEventHandler(async (event) => {
65
66
  const id = getRouterParam(event, 'id');
66
67
 
@@ -69,14 +70,14 @@ export default defineEventHandler(async (event) => {
69
70
  if (!user) {
70
71
  throw createError({
71
72
  statusCode: 404,
72
- message: '사용자를 찾을 수 없습니다',
73
+ message: 'User not found',
73
74
  });
74
75
  }
75
76
 
76
77
  return user;
77
78
  });
78
79
 
79
- // server/api/users/[id].put.ts (PUT /api/users/:id)
80
+ // Good: server/api/users/[id].put.ts (PUT /api/users/:id)
80
81
  export default defineEventHandler(async (event) => {
81
82
  const id = getRouterParam(event, 'id');
82
83
  const body = await readBody(event);
@@ -89,7 +90,7 @@ export default defineEventHandler(async (event) => {
89
90
  return user;
90
91
  });
91
92
 
92
- // server/api/users/[id].delete.ts (DELETE /api/users/:id)
93
+ // Good: server/api/users/[id].delete.ts (DELETE /api/users/:id)
93
94
  export default defineEventHandler(async (event) => {
94
95
  const id = getRouterParam(event, 'id');
95
96
  await prisma.user.delete({ where: { id } });
@@ -97,45 +98,45 @@ export default defineEventHandler(async (event) => {
97
98
  });
98
99
  ```
99
100
 
100
- ### 3. Data Fetching (SSR 지원)
101
+ ### 3. Data Fetching (SSR Supported)
101
102
 
102
103
  ```typescript
103
- // useFetch - 기본 데이터 페칭
104
+ // Good: useFetch - basic data fetching
104
105
  <script setup lang="ts">
105
106
  const { data: user, pending, error, refresh } = await useFetch<User>(
106
107
  `/api/users/${props.userId}`
107
108
  );
108
109
 
109
- // 옵션 사용
110
+ // With options
110
111
  const { data: posts } = await useFetch('/api/posts', {
111
112
  query: { limit: 10, offset: 0 },
112
113
  headers: { 'X-Custom': 'value' },
113
- pick: ['id', 'title'], // 필요한 필드만 선택
114
- transform: (data) => data.items, // 응답 변환
114
+ pick: ['id', 'title'], // Select only needed fields
115
+ transform: (data) => data.items, // Transform response
115
116
  });
116
117
  </script>
117
118
 
118
- // useAsyncData - 커스텀 페칭 로직
119
+ // Good: useAsyncData - custom fetching logic
119
120
  <script setup lang="ts">
120
121
  const { data, pending } = await useAsyncData(
121
- 'user-posts', // 캐시
122
+ 'user-posts', // Cache key
122
123
  () => $fetch(`/api/users/${props.userId}/posts`),
123
124
  {
124
- default: () => [], // 기본값
125
- lazy: true, // 클라이언트에서만 실행
126
- server: false, // SSR 비활성화
125
+ default: () => [], // Default value
126
+ lazy: true, // Execute only on client
127
+ server: false, // Disable SSR
127
128
  }
128
129
  );
129
130
  </script>
130
131
 
131
- // useLazyFetch - 지연 로딩 (Suspense 없이)
132
+ // Good: useLazyFetch - lazy loading (without Suspense)
132
133
  <script setup lang="ts">
133
134
  const { data, pending } = useLazyFetch('/api/heavy-data');
134
135
 
135
- // pending 상태 처리
136
+ // Handle pending state
136
137
  </script>
137
138
  <template>
138
- <div v-if="pending">로딩 중...</div>
139
+ <div v-if="pending">Loading...</div>
139
140
  <div v-else>{{ data }}</div>
140
141
  </template>
141
142
  ```
@@ -143,9 +144,9 @@ const { data, pending } = useLazyFetch('/api/heavy-data');
143
144
  ### 4. State Management
144
145
 
145
146
  ```typescript
146
- // useState - 서버/클라이언트 공유 상태
147
+ // Good: useState - server/client shared state
147
148
  <script setup lang="ts">
148
- // 모든 컴포넌트에서 공유되는 상태
149
+ // State shared across all components
149
150
  const counter = useState('counter', () => 0);
150
151
 
151
152
  function increment() {
@@ -153,7 +154,7 @@ function increment() {
153
154
  }
154
155
  </script>
155
156
 
156
- // Pinia Store (복잡한 상태)
157
+ // Good: Pinia Store (complex state)
157
158
  // stores/user.ts
158
159
  export const useUserStore = defineStore('user', () => {
159
160
  const user = ref<User | null>(null);
@@ -179,17 +180,17 @@ export const useUserStore = defineStore('user', () => {
179
180
  ### 5. Middleware
180
181
 
181
182
  ```typescript
182
- // middleware/auth.ts (Named middleware)
183
+ // Good: middleware/auth.ts (Named middleware)
183
184
  export default defineNuxtRouteMiddleware((to, from) => {
184
185
  const { isLoggedIn } = useUserStore();
185
186
 
186
- // 로그인 필요한 페이지 보호
187
+ // Protect pages requiring login
187
188
  if (!isLoggedIn && to.meta.requiresAuth) {
188
189
  return navigateTo('/login');
189
190
  }
190
191
  });
191
192
 
192
- // 페이지에서 사용
193
+ // Usage in page
193
194
  <script setup lang="ts">
194
195
  definePageMeta({
195
196
  middleware: 'auth',
@@ -197,12 +198,12 @@ definePageMeta({
197
198
  });
198
199
  </script>
199
200
 
200
- // middleware/auth.global.ts (Global middleware)
201
+ // Good: middleware/auth.global.ts (Global middleware)
201
202
  export default defineNuxtRouteMiddleware((to, from) => {
202
- // 모든 라우트에 적용
203
+ // Applies to all routes
203
204
  });
204
205
 
205
- // Server middleware
206
+ // Good: Server middleware
206
207
  // server/middleware/auth.ts
207
208
  export default defineEventHandler((event) => {
208
209
  const token = getCookie(event, 'auth-token');
@@ -210,7 +211,7 @@ export default defineEventHandler((event) => {
210
211
  if (!token && event.path.startsWith('/api/protected')) {
211
212
  throw createError({
212
213
  statusCode: 401,
213
- message: '인증이 필요합니다',
214
+ message: 'Authentication required',
214
215
  });
215
216
  }
216
217
  });
@@ -219,7 +220,7 @@ export default defineEventHandler((event) => {
219
220
  ### 6. Layouts & Pages
220
221
 
221
222
  ```typescript
222
- // layouts/default.vue
223
+ // Good: layouts/default.vue
223
224
  <template>
224
225
  <div class="layout">
225
226
  <AppHeader />
@@ -230,7 +231,7 @@ export default defineEventHandler((event) => {
230
231
  </div>
231
232
  </template>
232
233
 
233
- // layouts/admin.vue
234
+ // Good: layouts/admin.vue
234
235
  <template>
235
236
  <div class="admin-layout">
236
237
  <AdminSidebar />
@@ -240,7 +241,7 @@ export default defineEventHandler((event) => {
240
241
  </div>
241
242
  </template>
242
243
 
243
- // pages/admin/index.vue
244
+ // Good: pages/admin/index.vue
244
245
  <script setup lang="ts">
245
246
  definePageMeta({
246
247
  layout: 'admin',
@@ -248,7 +249,7 @@ definePageMeta({
248
249
  });
249
250
  </script>
250
251
 
251
- // pages/users/[id].vue (동적 라우트)
252
+ // Good: pages/users/[id].vue (dynamic route)
252
253
  <script setup lang="ts">
253
254
  const route = useRoute();
254
255
  const userId = route.params.id;
@@ -256,7 +257,7 @@ const userId = route.params.id;
256
257
  const { data: user } = await useFetch(`/api/users/${userId}`);
257
258
  </script>
258
259
 
259
- // pages/posts/[...slug].vue (Catch-all 라우트)
260
+ // Good: pages/posts/[...slug].vue (Catch-all route)
260
261
  <script setup lang="ts">
261
262
  const route = useRoute();
262
263
  const slugParts = route.params.slug; // ['a', 'b', 'c']
@@ -266,7 +267,7 @@ const slugParts = route.params.slug; // ['a', 'b', 'c']
266
267
  ### 7. SEO & Meta
267
268
 
268
269
  ```typescript
269
- // 페이지별 메타 설정
270
+ // Good: Per-page meta configuration
270
271
  <script setup lang="ts">
271
272
  const { data: post } = await useFetch(`/api/posts/${route.params.id}`);
272
273
 
@@ -279,7 +280,7 @@ useHead({
279
280
  ],
280
281
  });
281
282
 
282
- // 또는 useSeoMeta
283
+ // Or useSeoMeta
283
284
  useSeoMeta({
284
285
  title: post.value?.title,
285
286
  ogTitle: post.value?.title,
@@ -289,7 +290,7 @@ useSeoMeta({
289
290
  });
290
291
  </script>
291
292
 
292
- // nuxt.config.ts 전역 설정
293
+ // Good: nuxt.config.ts global configuration
293
294
  export default defineNuxtConfig({
294
295
  app: {
295
296
  head: {
@@ -308,7 +309,7 @@ export default defineNuxtConfig({
308
309
  ### 8. Plugins & Modules
309
310
 
310
311
  ```typescript
311
- // plugins/api.ts
312
+ // Good: plugins/api.ts
312
313
  export default defineNuxtPlugin(() => {
313
314
  const api = $fetch.create({
314
315
  baseURL: '/api',
@@ -333,11 +334,11 @@ export default defineNuxtPlugin(() => {
333
334
  };
334
335
  });
335
336
 
336
- // 사용
337
+ // Usage
337
338
  const { $api } = useNuxtApp();
338
339
  const users = await $api('/users');
339
340
 
340
- // plugins/dayjs.client.ts (클라이언트 전용)
341
+ // Good: plugins/dayjs.client.ts (client only)
341
342
  import dayjs from 'dayjs';
342
343
  import relativeTime from 'dayjs/plugin/relativeTime';
343
344
 
@@ -350,7 +351,7 @@ export default defineNuxtPlugin(() => {
350
351
  ### 9. Composables
351
352
 
352
353
  ```typescript
353
- // composables/useAuth.ts
354
+ // Good: composables/useAuth.ts
354
355
  export function useAuth() {
355
356
  const user = useState<User | null>('auth-user', () => null);
356
357
  const isLoggedIn = computed(() => !!user.value);
@@ -372,7 +373,7 @@ export function useAuth() {
372
373
  return { user, isLoggedIn, login, logout };
373
374
  }
374
375
 
375
- // composables/usePagination.ts
376
+ // Good: composables/usePagination.ts
376
377
  export function usePagination<T>(
377
378
  fetchFn: (page: number) => Promise<{ items: T[]; total: number }>
378
379
  ) {
@@ -401,7 +402,7 @@ export function usePagination<T>(
401
402
  ### 10. Error Handling
402
403
 
403
404
  ```typescript
404
- // error.vue (전역 에러 페이지)
405
+ // Good: error.vue (global error page)
405
406
  <script setup lang="ts">
406
407
  const props = defineProps<{
407
408
  error: {
@@ -417,11 +418,11 @@ const handleError = () => clearError({ redirect: '/' });
417
418
  <div class="error-page">
418
419
  <h1>{{ error.statusCode }}</h1>
419
420
  <p>{{ error.message }}</p>
420
- <button @click="handleError">홈으로</button>
421
+ <button @click="handleError">Go Home</button>
421
422
  </div>
422
423
  </template>
423
424
 
424
- // 컴포넌트 레벨 에러 처리
425
+ // Good: Component level error handling
425
426
  <script setup lang="ts">
426
427
  const { data, error } = await useFetch('/api/data');
427
428
 
@@ -433,89 +434,89 @@ if (error.value) {
433
434
  }
434
435
  </script>
435
436
 
436
- // NuxtErrorBoundary 사용
437
+ // Good: NuxtErrorBoundary usage
437
438
  <template>
438
439
  <NuxtErrorBoundary @error="logError">
439
440
  <SomeComponent />
440
441
  <template #error="{ error, clearError }">
441
- <p>오류 발생: {{ error.message }}</p>
442
- <button @click="clearError">다시 시도</button>
442
+ <p>Error occurred: {{ error.message }}</p>
443
+ <button @click="clearError">Retry</button>
443
444
  </template>
444
445
  </NuxtErrorBoundary>
445
446
  </template>
446
447
  ```
447
448
 
448
- ## 파일 구조 (Nuxt 3)
449
+ ## File Structure (Nuxt 3)
449
450
 
450
- ```
451
+ ```text
451
452
  project/
452
- ├── .nuxt/ # 빌드 산출물 (git 제외)
453
- ├── assets/ # 빌드에 포함되는 에셋
454
- ├── components/ # 자동 import 컴포넌트
455
- │ ├── ui/ # 기본 UI 컴포넌트
456
- │ ├── features/ # 기능별 컴포넌트
457
- │ └── App*.vue # 공통 컴포넌트
458
- ├── composables/ # 자동 import composables
459
- ├── layouts/ # 레이아웃
460
- ├── middleware/ # 라우트 미들웨어
461
- ├── pages/ # 파일 기반 라우팅
462
- ├── plugins/ # Nuxt 플러그인
463
- ├── public/ # 정적 파일
453
+ ├── .nuxt/ # Build output (git ignored)
454
+ ├── assets/ # Assets included in build
455
+ ├── components/ # Auto-imported components
456
+ │ ├── ui/ # Base UI components
457
+ │ ├── features/ # Feature-specific components
458
+ │ └── App*.vue # App common components
459
+ ├── composables/ # Auto-imported composables
460
+ ├── layouts/ # Layouts
461
+ ├── middleware/ # Route middleware
462
+ ├── pages/ # File-based routing
463
+ ├── plugins/ # Nuxt plugins
464
+ ├── public/ # Static files
464
465
  ├── server/
465
- │ ├── api/ # API 라우트
466
- │ ├── middleware/ # 서버 미들웨어
467
- │ └── utils/ # 서버 유틸리티
468
- ├── stores/ # Pinia 스토어
469
- ├── types/ # TypeScript 타입
470
- ├── utils/ # 유틸리티 함수
471
- ├── app.vue # 루트
472
- ├── nuxt.config.ts # Nuxt 설정
473
- └── tsconfig.json # TypeScript 설정
466
+ │ ├── api/ # API routes
467
+ │ ├── middleware/ # Server middleware
468
+ │ └── utils/ # Server utilities
469
+ ├── stores/ # Pinia stores
470
+ ├── types/ # TypeScript types
471
+ ├── utils/ # Utility functions
472
+ ├── app.vue # App root
473
+ ├── nuxt.config.ts # Nuxt configuration
474
+ └── tsconfig.json # TypeScript configuration
474
475
  ```
475
476
 
476
- ## 안티패턴
477
+ ## Anti-patterns
477
478
 
478
479
  ```typescript
479
- // 클라이언트에서 직접 DB 접근
480
+ // Bad: Direct DB access from client
480
481
  <script setup>
481
482
  import { PrismaClient } from '@prisma/client';
482
- const prisma = new PrismaClient(); // 클라이언트에서 실행 불가
483
+ const prisma = new PrismaClient(); // Cannot run on client
483
484
  </script>
484
485
 
485
- // Server API 통해 접근
486
+ // Good: Access through Server API
486
487
  const { data } = await useFetch('/api/users');
487
488
 
488
- // useFetch를 조건부로 사용
489
+ // Bad: Conditional useFetch
489
490
  if (someCondition) {
490
- const { data } = await useFetch('/api/data'); // 에러 발생
491
+ const { data } = await useFetch('/api/data'); // Error
491
492
  }
492
493
 
493
- // enabled 옵션 사용
494
+ // Good: Use enabled option
494
495
  const { data } = await useFetch('/api/data', {
495
496
  immediate: someCondition,
496
497
  });
497
498
 
498
- // navigateTo setup 밖에서 사용
499
+ // Bad: Using navigateTo outside setup
499
500
  function handleClick() {
500
- navigateTo('/page'); // 가능하지만 비권장
501
+ navigateTo('/page'); // Possible but not recommended
501
502
  }
502
503
 
503
- // useRouter 사용
504
+ // Good: Use useRouter
504
505
  const router = useRouter();
505
506
  function handleClick() {
506
507
  router.push('/page');
507
508
  }
508
509
  ```
509
510
 
510
- ## 체크리스트
511
-
512
- - [ ] Auto-imports 활용 (불필요한 import 제거)
513
- - [ ] Server API 파일 네이밍 규칙 준수 (*.get.ts, *.post.ts)
514
- - [ ] useFetch/useAsyncData로 SSR 지원 데이터 페칭
515
- - [ ] useState로 서버/클라이언트 상태 공유
516
- - [ ] definePageMeta로 페이지별 메타 설정
517
- - [ ] 미들웨어로 라우트 보호
518
- - [ ] NuxtErrorBoundary로 에러 처리
519
- - [ ] useHead/useSeoMeta로 SEO 최적화
520
- - [ ] Composables로 로직 재사용
521
- - [ ] TypeScript 엄격 모드 사용
511
+ ## Checklist
512
+
513
+ - [ ] Use auto-imports (remove unnecessary imports)
514
+ - [ ] Follow Server API file naming convention (*.get.ts, *.post.ts)
515
+ - [ ] SSR-supported data fetching with useFetch/useAsyncData
516
+ - [ ] Server/client state sharing with useState
517
+ - [ ] Per-page meta with definePageMeta
518
+ - [ ] Route protection with middleware
519
+ - [ ] Error handling with NuxtErrorBoundary
520
+ - [ ] SEO optimization with useHead/useSeoMeta
521
+ - [ ] Logic reuse with Composables
522
+ - [ ] Use TypeScript strict mode