@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,23 +1,24 @@
1
- # 🤖 Kotlin + Android 품질 규칙
1
+ # Kotlin + Android Quality Rules
2
2
 
3
- ## 핵심 원칙 (core에서 상속)
3
+ ## Core Principles (inherited from core)
4
4
 
5
5
  ```markdown
6
- 단일 책임 (SRP)
7
- 중복 제거 (DRY)
8
- 재사용성
9
- ✅ 낮은 복잡도
10
- 함수 ≤ 30줄
11
- 중첩 3단계
12
- Cyclomatic complexity ≤ 10
6
+ # Core Principles (inherited from core)
7
+ Single Responsibility (SRP)
8
+ No Duplication (DRY)
9
+ Reusability
10
+ Low Complexity
11
+ Function <= 30 lines
12
+ Nesting <= 3 levels
13
+ Cyclomatic complexity <= 10
13
14
  ```
14
15
 
15
- ## Kotlin/Android 특화 규칙
16
+ ## Kotlin/Android Specific Rules
16
17
 
17
18
  ### 1. Jetpack Compose UI
18
19
 
19
20
  ```kotlin
20
- // Composable 함수
21
+ // Good: Composable function
21
22
  @Composable
22
23
  fun UserProfileScreen(
23
24
  viewModel: UserProfileViewModel = hiltViewModel(),
@@ -32,7 +33,7 @@ fun UserProfileScreen(
32
33
  )
33
34
  }
34
35
 
35
- // Stateless Composable (재사용 가능)
36
+ // Good: Stateless Composable (reusable)
36
37
  @Composable
37
38
  private fun UserProfileContent(
38
39
  uiState: UserProfileUiState,
@@ -43,10 +44,10 @@ private fun UserProfileContent(
43
44
  Scaffold(
44
45
  topBar = {
45
46
  TopAppBar(
46
- title = { Text("프로필") },
47
+ title = { Text("Profile") },
47
48
  navigationIcon = {
48
49
  IconButton(onClick = onNavigateBack) {
49
- Icon(Icons.Default.ArrowBack, contentDescription = "뒤로")
50
+ Icon(Icons.Default.ArrowBack, contentDescription = "Back")
50
51
  }
51
52
  }
52
53
  )
@@ -67,7 +68,7 @@ private fun UserProfileContent(
67
68
  }
68
69
  }
69
70
 
70
- // 재사용 가능한 컴포넌트
71
+ // Good: Reusable component
71
72
  @Composable
72
73
  fun UserCard(
73
74
  user: User,
@@ -86,7 +87,7 @@ fun UserCard(
86
87
  ) {
87
88
  AsyncImage(
88
89
  model = user.profileImage,
89
- contentDescription = "${user.name} 프로필",
90
+ contentDescription = "${user.name} profile",
90
91
  modifier = Modifier
91
92
  .size(48.dp)
92
93
  .clip(CircleShape)
@@ -111,7 +112,7 @@ fun UserCard(
111
112
  ### 2. ViewModel (MVVM)
112
113
 
113
114
  ```kotlin
114
- // UiState 정의 (Sealed Interface)
115
+ // Good: UiState definition (Sealed Interface)
115
116
  sealed interface UserListUiState {
116
117
  data object Loading : UserListUiState
117
118
  data class Success(
@@ -121,7 +122,7 @@ sealed interface UserListUiState {
121
122
  data class Error(val message: String) : UserListUiState
122
123
  }
123
124
 
124
- // ViewModel with Hilt
125
+ // Good: ViewModel with Hilt
125
126
  @HiltViewModel
126
127
  class UserListViewModel @Inject constructor(
127
128
  private val getUsersUseCase: GetUsersUseCase,
@@ -160,7 +161,7 @@ class UserListViewModel @Inject constructor(
160
161
  }
161
162
  .onFailure { error ->
162
163
  _uiState.value = UserListUiState.Error(
163
- error.message ?: "사용자 목록을 불러올 없습니다"
164
+ error.message ?: "Failed to load user list"
164
165
  )
165
166
  }
166
167
  }
@@ -181,7 +182,7 @@ class UserListViewModel @Inject constructor(
181
182
  .onSuccess { users ->
182
183
  _uiState.value = UserListUiState.Success(users, isRefreshing = false)
183
184
  }
184
- .onFailure { /* 에러 처리 */ }
185
+ .onFailure { /* Error handling */ }
185
186
  }
186
187
  }
187
188
  }
@@ -190,7 +191,7 @@ class UserListViewModel @Inject constructor(
190
191
  ### 3. UseCase (Clean Architecture)
191
192
 
192
193
  ```kotlin
193
- // UseCase 정의
194
+ // Good: UseCase definition
194
195
  class GetUsersUseCase @Inject constructor(
195
196
  private val userRepository: UserRepository,
196
197
  private val dispatcher: CoroutineDispatcher = Dispatchers.IO
@@ -215,7 +216,7 @@ class CreateUserUseCase @Inject constructor(
215
216
  private val validator: UserValidator
216
217
  ) {
217
218
  suspend operator fun invoke(request: CreateUserRequest): Result<User> {
218
- // 유효성 검사
219
+ // Validation
219
220
  validator.validate(request).onFailure { return Result.failure(it) }
220
221
 
221
222
  return runCatching {
@@ -225,10 +226,10 @@ class CreateUserUseCase @Inject constructor(
225
226
  }
226
227
  ```
227
228
 
228
- ### 4. Repository 패턴
229
+ ### 4. Repository Pattern
229
230
 
230
231
  ```kotlin
231
- // Repository Interface
232
+ // Good: Repository Interface
232
233
  interface UserRepository {
233
234
  suspend fun getUsers(): List<User>
234
235
  suspend fun getUser(id: String): User
@@ -237,7 +238,7 @@ interface UserRepository {
237
238
  suspend fun deleteUser(id: String)
238
239
  }
239
240
 
240
- // Repository 구현
241
+ // Good: Repository implementation
241
242
  class UserRepositoryImpl @Inject constructor(
242
243
  private val apiService: UserApiService,
243
244
  private val userDao: UserDao,
@@ -246,16 +247,16 @@ class UserRepositoryImpl @Inject constructor(
246
247
 
247
248
  override suspend fun getUsers(): List<User> = withContext(dispatcher) {
248
249
  try {
249
- // API에서 데이터 가져오기
250
+ // Fetch data from API
250
251
  val response = apiService.getUsers()
251
252
  val users = response.map { it.toDomain() }
252
253
 
253
- // 로컬 캐시 업데이트
254
+ // Update local cache
254
255
  userDao.insertAll(users.map { it.toEntity() })
255
256
 
256
257
  users
257
258
  } catch (e: Exception) {
258
- // 오프라인: 로컬 데이터 반환
259
+ // Offline: Return local data
259
260
  userDao.getAll().map { it.toDomain() }
260
261
  }
261
262
  }
@@ -267,22 +268,22 @@ class UserRepositoryImpl @Inject constructor(
267
268
  }
268
269
  ```
269
270
 
270
- ### 5. 에러 처리
271
+ ### 5. Error Handling
271
272
 
272
273
  ```kotlin
273
- // 커스텀 예외
274
+ // Good: Custom exception
274
275
  sealed class AppException(message: String) : Exception(message) {
275
- class NetworkException(message: String = "네트워크 연결을 확인해주세요") : AppException(message)
276
- class UnauthorizedException(message: String = "로그인이 필요합니다") : AppException(message)
276
+ class NetworkException(message: String = "Please check your network connection") : AppException(message)
277
+ class UnauthorizedException(message: String = "Login required") : AppException(message)
277
278
  class NotFoundException(
278
279
  val resource: String,
279
280
  val id: String
280
- ) : AppException("${resource}을(를) 찾을 없습니다 (ID: $id)")
281
+ ) : AppException("$resource not found (ID: $id)")
281
282
  class ServerException(message: String) : AppException(message)
282
283
  class ValidationException(message: String) : AppException(message)
283
284
  }
284
285
 
285
- // Result 확장 함수
286
+ // Good: Result extension functions
286
287
  inline fun <T> Result<T>.onSuccess(action: (T) -> Unit): Result<T> {
287
288
  getOrNull()?.let(action)
288
289
  return this
@@ -293,7 +294,7 @@ inline fun <T> Result<T>.onFailure(action: (Throwable) -> Unit): Result<T> {
293
294
  return this
294
295
  }
295
296
 
296
- // API 응답 처리
297
+ // Good: API response handling
297
298
  suspend fun <T> safeApiCall(
298
299
  dispatcher: CoroutineDispatcher = Dispatchers.IO,
299
300
  apiCall: suspend () -> T
@@ -305,8 +306,8 @@ suspend fun <T> safeApiCall(
305
306
  is HttpException -> {
306
307
  when (throwable.code()) {
307
308
  401 -> throw AppException.UnauthorizedException()
308
- 404 -> throw AppException.NotFoundException("리소스", "unknown")
309
- else -> throw AppException.ServerException("서버 오류: ${throwable.code()}")
309
+ 404 -> throw AppException.NotFoundException("Resource", "unknown")
310
+ else -> throw AppException.ServerException("Server error: ${throwable.code()}")
310
311
  }
311
312
  }
312
313
  is IOException -> throw AppException.NetworkException()
@@ -316,10 +317,10 @@ suspend fun <T> safeApiCall(
316
317
  }
317
318
  ```
318
319
 
319
- ### 6. Hilt 의존성 주입
320
+ ### 6. Hilt Dependency Injection
320
321
 
321
322
  ```kotlin
322
- // Module 정의
323
+ // Good: Module definition
323
324
  @Module
324
325
  @InstallIn(SingletonComponent::class)
325
326
  object NetworkModule {
@@ -364,10 +365,10 @@ abstract class RepositoryModule {
364
365
  }
365
366
  ```
366
367
 
367
- ### 7. 테스트
368
+ ### 7. Testing
368
369
 
369
370
  ```kotlin
370
- // ViewModel 테스트
371
+ // Good: ViewModel test
371
372
  @OptIn(ExperimentalCoroutinesApi::class)
372
373
  class UserListViewModelTest {
373
374
 
@@ -386,11 +387,11 @@ class UserListViewModelTest {
386
387
  }
387
388
 
388
389
  @Test
389
- fun `loadUsers 성공시 Success 상태가 된다`() = runTest {
390
+ fun `loadUsers success results in Success state`() = runTest {
390
391
  // Given
391
392
  val expectedUsers = listOf(
392
- User(id = "1", name = "테스트1", email = "test1@example.com"),
393
- User(id = "2", name = "테스트2", email = "test2@example.com")
393
+ User(id = "1", name = "Test1", email = "test1@example.com"),
394
+ User(id = "2", name = "Test2", email = "test2@example.com")
394
395
  )
395
396
  fakeUserRepository.setUsers(expectedUsers)
396
397
 
@@ -404,7 +405,7 @@ class UserListViewModelTest {
404
405
  }
405
406
 
406
407
  @Test
407
- fun `loadUsers 실패시 Error 상태가 된다`() = runTest {
408
+ fun `loadUsers failure results in Error state`() = runTest {
408
409
  // Given
409
410
  fakeUserRepository.setShouldReturnError(true)
410
411
 
@@ -417,7 +418,7 @@ class UserListViewModelTest {
417
418
  }
418
419
  }
419
420
 
420
- // Fake Repository
421
+ // Good: Fake Repository
421
422
  class FakeUserRepository : UserRepository {
422
423
  private var users = mutableListOf<User>()
423
424
  private var shouldReturnError = false
@@ -435,37 +436,37 @@ class FakeUserRepository : UserRepository {
435
436
  return users
436
437
  }
437
438
 
438
- // ... 다른 메서드
439
+ // ... other methods
439
440
  }
440
441
  ```
441
442
 
442
- ## 파일 구조
443
+ ## File Structure
443
444
 
444
445
  ```
445
446
  app/
446
447
  ├── src/main/java/com/example/app/
447
- │ ├── di/ # Hilt 모듈
448
+ │ ├── di/ # Hilt modules
448
449
  │ │ ├── NetworkModule.kt
449
450
  │ │ └── RepositoryModule.kt
450
451
  │ ├── data/
451
- │ │ ├── api/ # API 서비스
452
+ │ │ ├── api/ # API services
452
453
  │ │ │ └── UserApiService.kt
453
454
  │ │ ├── local/ # Room DAO
454
455
  │ │ │ └── UserDao.kt
455
456
  │ │ ├── model/ # DTO
456
457
  │ │ │ └── UserDto.kt
457
- │ │ └── repository/ # Repository 구현
458
+ │ │ └── repository/ # Repository implementation
458
459
  │ │ └── UserRepositoryImpl.kt
459
460
  │ ├── domain/
460
- │ │ ├── model/ # 도메인 모델
461
+ │ │ ├── model/ # Domain models
461
462
  │ │ │ └── User.kt
462
- │ │ ├── repository/ # Repository 인터페이스
463
+ │ │ ├── repository/ # Repository interfaces
463
464
  │ │ │ └── UserRepository.kt
464
465
  │ │ └── usecase/ # UseCase
465
466
  │ │ └── GetUsersUseCase.kt
466
467
  │ └── presentation/
467
468
  │ ├── ui/
468
- │ │ ├── components/ # 공통 Composable
469
+ │ │ ├── components/ # Common Composables
469
470
  │ │ └── theme/ # Material Theme
470
471
  │ └── feature/
471
472
  │ └── user/
@@ -479,13 +480,13 @@ app/
479
480
  └── UserListViewModelTest.kt
480
481
  ```
481
482
 
482
- ## 체크리스트
483
+ ## Checklist
483
484
 
484
- - [ ] Jetpack Compose 사용 (XML 레이아웃 지양)
485
- - [ ] StateFlow로 UI 상태 관리
486
- - [ ] Sealed Interface로 UiState 정의
487
- - [ ] Hilt 의존성 주입
488
- - [ ] UseCase로 비즈니스 로직 분리
489
- - [ ] Repository 패턴으로 데이터 계층 추상화
490
- - [ ] Result/runCatching으로 에러 처리
491
- - [ ] collectAsStateWithLifecycle() 사용
485
+ - [ ] Use Jetpack Compose (avoid XML layouts)
486
+ - [ ] Manage UI state with StateFlow
487
+ - [ ] Define UiState with Sealed Interface
488
+ - [ ] Use Hilt for dependency injection
489
+ - [ ] Separate business logic with UseCase
490
+ - [ ] Abstract data layer with Repository pattern
491
+ - [ ] Handle errors with Result/runCatching
492
+ - [ ] Use collectAsStateWithLifecycle()