@leejungkiin/awkit 1.7.0 → 1.7.4
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.
- package/bin/awk.js +576 -84
- package/core/CLAUDE.md +1 -1
- package/core/GEMINI.md +148 -167
- package/core/GEMINI.md.bak +149 -116
- package/core/skill-runtime-manifest.json +3 -0
- package/docs/Claude Fable 5.md +3826 -0
- package/docs/android_kotlin_system_instruction.md +210 -0
- package/docs/brainstorm_ponytail_integration.md +146 -0
- package/docs/brainstorm_smart_setup.md +113 -0
- package/docs/deep-research-report (1).md +293 -0
- package/docs/history/GEMINI.v1.md +135 -0
- package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
- package/docs/history/implementation_plan.v1.md +58 -0
- package/package.json +4 -1
- package/scripts/artifact-storage.js +130 -0
- package/scripts/automation-gate.js +40 -7
- package/scripts/claude-plan.js +76 -0
- package/scripts/dependency-manager.js +210 -0
- package/scripts/exec-rtk.js +11 -5
- package/scripts/i18n-helper.js +381 -0
- package/scripts/multi-model-pipeline.js +144 -0
- package/skill-packs/mobile-ios/pack.json +4 -2
- package/skill-packs/reverse-engineering/pack.json +1 -0
- package/skills/CATALOG.md +20 -0
- package/skills/GEMINI.md +9 -1
- package/skills/TRIGGER_INDEX.md +10 -0
- package/skills/ai-music/SKILL.md +275 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/animal-island-ui-style/SKILL.md +1450 -0
- package/skills/app-store-review-agent/SKILL.md +164 -0
- package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
- package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
- package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
- package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
- package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
- package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
- package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
- package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
- package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
- package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
- package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
- package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
- package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
- package/skills/awf-ponytail/SKILL.md +91 -0
- package/skills/awf-ponytail-review/SKILL.md +67 -0
- package/skills/awf-session-restore/SKILL.md +3 -3
- package/skills/brainstorm-agent/SKILL.md +11 -2
- package/skills/brainstorm-agent/templates/brief-template.md +8 -0
- package/skills/claude-planner/SKILL.md +47 -0
- package/skills/code-review/SKILL.md +87 -0
- package/skills/expo-game-development/SKILL.md +163 -0
- package/skills/flutter/LICENSE.txt +202 -0
- package/skills/flutter/SKILL.md +127 -0
- package/skills/flutter-project-creater/LICENSE.txt +202 -0
- package/skills/flutter-project-creater/SKILL.md +106 -0
- package/skills/game-developer/SKILL.md +163 -0
- package/skills/game-developer/references/ecs-patterns.md +501 -0
- package/skills/game-developer/references/multiplayer-networking.md +475 -0
- package/skills/game-developer/references/performance-optimization.md +422 -0
- package/skills/game-developer/references/unity-patterns.md +271 -0
- package/skills/game-developer/references/unreal-cpp.md +352 -0
- package/skills/generate-gui-assets/SKILL.md +305 -0
- package/skills/generate-gui-assets/agents/openai.yaml +4 -0
- package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
- package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
- package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
- package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
- package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
- package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
- package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
- package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
- package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
- package/skills/godot-game-development/SKILL.md +142 -0
- package/skills/hatch-pet/LICENSE.txt +201 -0
- package/skills/hatch-pet/SKILL.md +420 -0
- package/skills/hatch-pet/agents/openai.yaml +4 -0
- package/skills/hatch-pet/references/animation-rows.md +29 -0
- package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
- package/skills/hatch-pet/references/qa-rubric.md +60 -0
- package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
- package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
- package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
- package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
- package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
- package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
- package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
- package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
- package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
- package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
- package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
- package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
- package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
- package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
- package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
- package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
- package/skills/i18n-orchestrator/SKILL.md +37 -0
- package/skills/ios-simulator-skill/SKILL.md +390 -0
- package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
- package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
- package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
- package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
- package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
- package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
- package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
- package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
- package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
- package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
- package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
- package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
- package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
- package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
- package/skills/ios-simulator-skill/scripts/container.py +668 -0
- package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
- package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
- package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
- package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
- package/skills/ios-simulator-skill/scripts/location.py +467 -0
- package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
- package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
- package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
- package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
- package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
- package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
- package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
- package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
- package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
- package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
- package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
- package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
- package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
- package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
- package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
- package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
- package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
- package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
- package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
- package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
- package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
- package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
- package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
- package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
- package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
- package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
- package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
- package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
- package/skills/orchestrator/SKILL.md +0 -20
- package/skills/persistent-storage/SKILL.md +55 -0
- package/skills/short-maker/SKILL.md +23 -0
- package/skills/short-maker/scripts/effects.js +56 -0
- package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
- package/skills/short-maker/scripts/videomix.js +601 -0
- package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
- package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
- package/skills/smali-to-kotlin/SKILL.md +128 -0
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-kotlin/library-patterns.md +189 -0
- package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
- package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
- package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
- package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
- package/skills/smali-to-kotlin/phase-3-build.md +248 -0
- package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
- package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
- package/skills/smali-to-kotlin/templates/app-map.md +101 -0
- package/skills/smali-to-kotlin/templates/architecture.md +142 -0
- package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
- package/skills/spec-gate/SKILL.md +6 -2
- package/skills/symphony-enforcer/SKILL.md +8 -0
- package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
- package/skills/symphony-enforcer/examples/three-phase.md +16 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
- package/skills/unity-game-development/SKILL.md +231 -0
- package/skills/verification-gate/SKILL.md +4 -2
- package/skills/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/setup-mapping.json +48 -0
- package/templates/specs/design-template.md +161 -71
- package/templates/specs/requirements-template.md +65 -133
- package/templates/specs/task-spec-template.xml +3 -0
- package/workflows/_uncategorized/critic.md +40 -0
- package/workflows/_uncategorized/git-rebase-flow.md +81 -0
- package/workflows/_uncategorized/image-gen.md +118 -0
- package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
- package/workflows/_uncategorized/pixel-gen.md +86 -0
- package/workflows/_uncategorized/pixel-setup.md +90 -0
- package/workflows/_uncategorized/ponytail-review.md +59 -0
- package/workflows/_uncategorized/reverse-android-build.md +222 -0
- package/workflows/_uncategorized/reverse-android-design.md +139 -0
- package/workflows/_uncategorized/reverse-android-discover.md +150 -0
- package/workflows/_uncategorized/reverse-android-scan.md +158 -0
- package/workflows/_uncategorized/reverse-android.md +143 -0
- package/workflows/_uncategorized/reverse-ios-build.md +240 -0
- package/workflows/_uncategorized/reverse-ios-design.md +112 -0
- package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
- package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
- package/workflows/_uncategorized/reverse-ios.md +152 -0
- package/workflows/_uncategorized/safety-router.md +34 -0
- package/workflows/_uncategorized/teach.md +89 -0
- package/workflows/_uncategorized/verify-ui.md +53 -0
- package/workflows/_uncategorized/visualize-screenshots.md +34 -0
- package/workflows/ads/ads-analyst.md +201 -0
- package/workflows/ads/ads-audit.md +106 -0
- package/workflows/ads/ads-optimize.md +97 -0
- package/workflows/ads/ads-targeting.md +241 -0
- package/workflows/ads/adsExpert.md +160 -0
- package/workflows/ads/smali-ads-config.md +400 -0
- package/workflows/ads/smali-ads-flow.md +331 -0
- package/workflows/ads/smali-ads-interstitial.md +377 -0
- package/workflows/ads/smali-ads-native.md +382 -0
- package/workflows/context/teach.md +89 -0
- package/workflows/gitnexus.md +8 -8
- package/workflows/lifecycle/brainstorm.md +43 -0
- package/workflows/lifecycle/code.md +5 -0
- package/workflows/lifecycle/init.md +23 -5
- package/workflows/lifecycle/multi-model-pipeline.md +60 -0
- package/workflows/quality/ponytail-review.md +59 -0
- package/workflows/roles/critic.md +40 -0
- package/workflows/roles/safety-router.md +34 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
# 📐 Phase 2: Blueprint + UI Design (Per Feature) — Android
|
|
2
|
+
|
|
3
|
+
> **Zoom Level:** 2 — Feature Detail
|
|
4
|
+
> **Goal:** Design contracts AND code UI visual shell for ONE feature.
|
|
5
|
+
> **Input:** Architecture Blueprint (Phase 1) + user's chosen feature.
|
|
6
|
+
> **Output:** Approved contracts + Working UI shell with mock data.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## ⛔ OUTPUT RULE
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
PART A — Contracts (signatures only):
|
|
14
|
+
✅ Interface signatures, data class definitions, sealed classes
|
|
15
|
+
✅ Retrofit interface with @GET/@POST annotations (no body)
|
|
16
|
+
✅ UiState sealed class, Event sealed class, Action sealed class
|
|
17
|
+
❌ Function body implementations (use TODO())
|
|
18
|
+
|
|
19
|
+
PART B — UI (visual code):
|
|
20
|
+
✅ Full Jetpack Compose code for screen
|
|
21
|
+
✅ Hardcoded mock data (using UiState from Part A)
|
|
22
|
+
✅ Real resources (icons, colors, images extracted in 2.7)
|
|
23
|
+
✅ @Preview for ALL states (normal, loading, error, empty)
|
|
24
|
+
❌ Real ViewModel connection — use parameter defaults
|
|
25
|
+
❌ Real API calls
|
|
26
|
+
❌ Business logic
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 📋 Sub-steps
|
|
32
|
+
|
|
33
|
+
### 2.1: Deep Smali Reading
|
|
34
|
+
|
|
35
|
+
Read Smali/Java files for the chosen feature.
|
|
36
|
+
|
|
37
|
+
**What to extract:**
|
|
38
|
+
- Class hierarchy (extends, implements)
|
|
39
|
+
- Field declarations → model properties
|
|
40
|
+
- Method signatures → API contracts
|
|
41
|
+
- String constants → URLs, keys, messages
|
|
42
|
+
- Control flow → business rules (document, don't code)
|
|
43
|
+
|
|
44
|
+
**Smali Quick Ref:**
|
|
45
|
+
```
|
|
46
|
+
.field → class fields (properties)
|
|
47
|
+
.method → method start
|
|
48
|
+
.end method → method end
|
|
49
|
+
invoke-virtual → instance method call
|
|
50
|
+
invoke-static → static method call
|
|
51
|
+
const-string → string literal
|
|
52
|
+
new-instance → object creation
|
|
53
|
+
if-eqz/if-nez → conditional branches
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
See `smali-reading-guide.md` for comprehensive guide.
|
|
57
|
+
|
|
58
|
+
### 2.2: Domain Model Contracts
|
|
59
|
+
|
|
60
|
+
```kotlin
|
|
61
|
+
// Domain model
|
|
62
|
+
data class User(
|
|
63
|
+
val id: String,
|
|
64
|
+
val fullName: String,
|
|
65
|
+
val email: String,
|
|
66
|
+
val avatarUrl: String?,
|
|
67
|
+
val isVerified: Boolean
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
// DTO (from API)
|
|
71
|
+
@Serializable
|
|
72
|
+
data class UserDto(
|
|
73
|
+
@SerialName("user_id") val userId: String,
|
|
74
|
+
@SerialName("full_name") val fullName: String,
|
|
75
|
+
@SerialName("email") val email: String,
|
|
76
|
+
@SerialName("avatar_url") val avatarUrl: String?,
|
|
77
|
+
@SerialName("is_verified") val isVerified: Boolean
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 2.3: Repository Contract
|
|
82
|
+
|
|
83
|
+
```kotlin
|
|
84
|
+
interface AuthRepository {
|
|
85
|
+
suspend fun login(email: String, password: String): Result<User>
|
|
86
|
+
suspend fun register(name: String, email: String, password: String): Result<User>
|
|
87
|
+
suspend fun logout()
|
|
88
|
+
fun isLoggedIn(): Flow<Boolean>
|
|
89
|
+
fun getCurrentUser(): Flow<User?>
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2.4: API Contract
|
|
94
|
+
|
|
95
|
+
```kotlin
|
|
96
|
+
interface AuthApi {
|
|
97
|
+
@POST("auth/login")
|
|
98
|
+
suspend fun login(@Body request: LoginRequest): LoginResponse
|
|
99
|
+
|
|
100
|
+
@POST("auth/register")
|
|
101
|
+
suspend fun register(@Body request: RegisterRequest): RegisterResponse
|
|
102
|
+
|
|
103
|
+
@GET("auth/me")
|
|
104
|
+
suspend fun getCurrentUser(@Header("Authorization") token: String): UserDto
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 2.5: UseCase Signatures
|
|
109
|
+
|
|
110
|
+
```kotlin
|
|
111
|
+
class LoginUseCase(private val authRepo: AuthRepository) {
|
|
112
|
+
suspend operator fun invoke(email: String, password: String): Result<User>
|
|
113
|
+
// Implementation: TODO()
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 2.6: UI State Design
|
|
118
|
+
|
|
119
|
+
```kotlin
|
|
120
|
+
// State
|
|
121
|
+
data class LoginUiState(
|
|
122
|
+
val email: String = "",
|
|
123
|
+
val password: String = "",
|
|
124
|
+
val isLoading: Boolean = false,
|
|
125
|
+
val error: String? = null,
|
|
126
|
+
val isPasswordVisible: Boolean = false
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
// Events (one-time actions)
|
|
130
|
+
sealed interface LoginEvent {
|
|
131
|
+
data class NavigateToHome(val user: User) : LoginEvent
|
|
132
|
+
data class ShowSnackbar(val message: String) : LoginEvent
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Actions (user interactions)
|
|
136
|
+
sealed interface LoginAction {
|
|
137
|
+
data class UpdateEmail(val email: String) : LoginAction
|
|
138
|
+
data class UpdatePassword(val password: String) : LoginAction
|
|
139
|
+
data object TogglePasswordVisibility : LoginAction
|
|
140
|
+
data object Submit : LoginAction
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 2.7: Resource Extraction ⭐ (Before UI code!)
|
|
145
|
+
|
|
146
|
+
> **Why here?** UI code (2.8) needs real assets. If resources come later, UI will be full of placeholders — defeating the purpose of visual parity.
|
|
147
|
+
|
|
148
|
+
**Process:**
|
|
149
|
+
1. Analyze layout XML to list needed resources:
|
|
150
|
+
```bash
|
|
151
|
+
grep -o '@drawable/[a-z_]*' [apktool]/res/layout/activity_login.xml | sort -u
|
|
152
|
+
grep -o '@color/[a-z_]*' [apktool]/res/layout/activity_login.xml | sort -u
|
|
153
|
+
grep 'const-string' [apktool]/smali/.../LoginActivity.smali | grep -i string
|
|
154
|
+
```
|
|
155
|
+
2. Copy ONLY needed resources to new project
|
|
156
|
+
3. Verify all resources compile
|
|
157
|
+
|
|
158
|
+
**Output:**
|
|
159
|
+
```markdown
|
|
160
|
+
### 📦 Resources for [Screen]
|
|
161
|
+
- Drawables: [list]
|
|
162
|
+
- Colors: [list]
|
|
163
|
+
- Strings: [list]
|
|
164
|
+
- Dimens: [list]
|
|
165
|
+
✅ All accessible
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 2.8: UI Implementation — Visual Shell ⭐
|
|
169
|
+
|
|
170
|
+
> **Goal:** Code the screen with HARDCODED mock data. Pixel-perfect visual parity with original app.
|
|
171
|
+
|
|
172
|
+
**Rules:**
|
|
173
|
+
```
|
|
174
|
+
✅ MUST DO:
|
|
175
|
+
- Use UiState from 2.6 (hardcode sample values as defaults)
|
|
176
|
+
- Use REAL resources extracted in 2.7
|
|
177
|
+
- Display ALL visual elements from original app
|
|
178
|
+
- Match: spacing, font size, colors, icon placement
|
|
179
|
+
- Code ALL states: normal, loading, error, empty
|
|
180
|
+
- Create @Preview for each state
|
|
181
|
+
|
|
182
|
+
❌ MUST NOT:
|
|
183
|
+
- Connect real ViewModel (use parameter defaults)
|
|
184
|
+
- Call real APIs
|
|
185
|
+
- Code business logic
|
|
186
|
+
- Use DI/injection
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Pattern — Stateless Composable:**
|
|
190
|
+
```kotlin
|
|
191
|
+
@Composable
|
|
192
|
+
fun LoginScreenContent(
|
|
193
|
+
uiState: LoginUiState = LoginUiState(), // Hardcoded default
|
|
194
|
+
onAction: (LoginAction) -> Unit = {} // No-op default
|
|
195
|
+
) {
|
|
196
|
+
Scaffold { padding ->
|
|
197
|
+
Column(
|
|
198
|
+
modifier = Modifier
|
|
199
|
+
.fillMaxSize()
|
|
200
|
+
.padding(padding)
|
|
201
|
+
.padding(24.dp),
|
|
202
|
+
horizontalAlignment = Alignment.CenterHorizontally
|
|
203
|
+
) {
|
|
204
|
+
// Logo — real resource from 2.7
|
|
205
|
+
Image(
|
|
206
|
+
painter = painterResource(R.drawable.app_logo),
|
|
207
|
+
contentDescription = null,
|
|
208
|
+
modifier = Modifier.size(120.dp)
|
|
209
|
+
)
|
|
210
|
+
Spacer(Modifier.height(48.dp))
|
|
211
|
+
|
|
212
|
+
// Email
|
|
213
|
+
OutlinedTextField(
|
|
214
|
+
value = uiState.email,
|
|
215
|
+
onValueChange = { onAction(LoginAction.UpdateEmail(it)) },
|
|
216
|
+
label = { Text("Email") },
|
|
217
|
+
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
|
|
218
|
+
modifier = Modifier.fillMaxWidth()
|
|
219
|
+
)
|
|
220
|
+
Spacer(Modifier.height(16.dp))
|
|
221
|
+
|
|
222
|
+
// Password with toggle
|
|
223
|
+
OutlinedTextField(
|
|
224
|
+
value = uiState.password,
|
|
225
|
+
onValueChange = { onAction(LoginAction.UpdatePassword(it)) },
|
|
226
|
+
label = { Text("Password") },
|
|
227
|
+
visualTransformation = if (uiState.isPasswordVisible)
|
|
228
|
+
VisualTransformation.None else PasswordVisualTransformation(),
|
|
229
|
+
trailingIcon = {
|
|
230
|
+
IconButton(onClick = { onAction(LoginAction.TogglePasswordVisibility) }) {
|
|
231
|
+
Icon(
|
|
232
|
+
imageVector = if (uiState.isPasswordVisible)
|
|
233
|
+
Icons.Default.VisibilityOff else Icons.Default.Visibility,
|
|
234
|
+
contentDescription = "Toggle password"
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
modifier = Modifier.fillMaxWidth()
|
|
239
|
+
)
|
|
240
|
+
Spacer(Modifier.height(32.dp))
|
|
241
|
+
|
|
242
|
+
// Login Button
|
|
243
|
+
Button(
|
|
244
|
+
onClick = { onAction(LoginAction.Submit) },
|
|
245
|
+
enabled = !uiState.isLoading,
|
|
246
|
+
modifier = Modifier.fillMaxWidth().height(50.dp)
|
|
247
|
+
) {
|
|
248
|
+
if (uiState.isLoading) {
|
|
249
|
+
CircularProgressIndicator(
|
|
250
|
+
modifier = Modifier.size(24.dp),
|
|
251
|
+
color = MaterialTheme.colorScheme.onPrimary
|
|
252
|
+
)
|
|
253
|
+
} else {
|
|
254
|
+
Text("Login", style = MaterialTheme.typography.labelLarge)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ===== PREVIEWS =====
|
|
262
|
+
@Preview(showBackground = true)
|
|
263
|
+
@Composable
|
|
264
|
+
private fun NormalPreview() {
|
|
265
|
+
AppTheme { LoginScreenContent(LoginUiState(email = "user@example.com")) }
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@Preview(showBackground = true)
|
|
269
|
+
@Composable
|
|
270
|
+
private fun LoadingPreview() {
|
|
271
|
+
AppTheme { LoginScreenContent(LoginUiState(isLoading = true)) }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@Preview(showBackground = true)
|
|
275
|
+
@Composable
|
|
276
|
+
private fun ErrorPreview() {
|
|
277
|
+
AppTheme { LoginScreenContent(LoginUiState(error = "Invalid credentials")) }
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 2.9: Visual Parity Check ⭐
|
|
282
|
+
|
|
283
|
+
Compare UI shell with original app screenshot:
|
|
284
|
+
|
|
285
|
+
```markdown
|
|
286
|
+
### 📸 Visual Parity: [Screen Name]
|
|
287
|
+
|
|
288
|
+
Layout:
|
|
289
|
+
- [ ] Structure matches original (components, sections)
|
|
290
|
+
- [ ] Spacing between elements correct
|
|
291
|
+
- [ ] Alignment matches
|
|
292
|
+
|
|
293
|
+
Styling:
|
|
294
|
+
- [ ] Colors match (background, text, buttons, header)
|
|
295
|
+
- [ ] Typography matches (font size, weight)
|
|
296
|
+
- [ ] Icons/images correct and positioned
|
|
297
|
+
- [ ] Borders, shadows, rounded corners
|
|
298
|
+
|
|
299
|
+
States:
|
|
300
|
+
- [ ] Normal state displays correctly
|
|
301
|
+
- [ ] Loading state — progress in right position
|
|
302
|
+
- [ ] Error state — error message shows properly
|
|
303
|
+
- [ ] Empty state — guidance shown
|
|
304
|
+
|
|
305
|
+
Platform:
|
|
306
|
+
- [ ] Material 3 conventions followed
|
|
307
|
+
- [ ] Edge-to-edge / system bars handled
|
|
308
|
+
- [ ] Looks good on different screen sizes
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 📊 Output: Feature Blueprint + UI
|
|
314
|
+
|
|
315
|
+
Use template from `templates/blueprint.md`.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## ✅ Gate (MANDATORY)
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
"📐 Blueprint + UI cho [Feature] xong:
|
|
323
|
+
|
|
324
|
+
📝 Contracts:
|
|
325
|
+
- [N] domain models
|
|
326
|
+
- [N] repository interfaces
|
|
327
|
+
- [N] use case signatures
|
|
328
|
+
- [N] API endpoints
|
|
329
|
+
|
|
330
|
+
🎨 UI:
|
|
331
|
+
- [Screen] implemented with mock data
|
|
332
|
+
- Resources: [N] drawables, [N] strings, [N] colors
|
|
333
|
+
- Previews: [N] states (normal, loading, error, empty)
|
|
334
|
+
|
|
335
|
+
📸 Visual Parity: [OK / cần chỉnh X, Y, Z]
|
|
336
|
+
|
|
337
|
+
Anh xem UI + contracts ổn không?
|
|
338
|
+
→ ✅ Approve → Phase 3 (Logic Build)
|
|
339
|
+
→ 🎨 Adjust UI → fix then re-check
|
|
340
|
+
→ 📝 Adjust contracts → revise blueprint"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
> ⚠️ **DO NOT proceed to Phase 3 until user approves BOTH UI and contracts.**
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
*Phase 2: Blueprint + UI Design — See it before you code it*
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# 📐 Phase 2: Blueprint (Block View — per feature)
|
|
2
|
+
|
|
3
|
+
> **Zoom Level:** 2 — Feature Detail
|
|
4
|
+
> **Goal:** Design contracts, interfaces, and state for ONE specific feature.
|
|
5
|
+
> **Input:** Architecture Blueprint (Phase 1) + user's chosen feature.
|
|
6
|
+
> **Output:** Feature Blueprint with code signatures. **NO implementation bodies yet.**
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## ⛔ OUTPUT RULE
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
✅ ALLOWED: Interface/protocol signatures, data class definitions, sealed classes
|
|
14
|
+
✅ ALLOWED: Retrofit interface with @GET/@POST annotations (no body)
|
|
15
|
+
✅ ALLOWED: UiState sealed class, Event sealed class
|
|
16
|
+
❌ BLOCKED: Function body implementations (use TODO() or // ... )
|
|
17
|
+
❌ BLOCKED: Full ViewModel logic, full Composable implementations
|
|
18
|
+
⚠️ EXCEPTION: Simple data class fields are OK (they ARE the contract)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📋 Sub-steps (per feature)
|
|
24
|
+
|
|
25
|
+
### 2.1: Deep Smali Reading
|
|
26
|
+
|
|
27
|
+
Read the Smali/Java files specifically for the chosen feature.
|
|
28
|
+
|
|
29
|
+
**What to extract:**
|
|
30
|
+
- Class hierarchy (extends, implements)
|
|
31
|
+
- Field declarations → model properties
|
|
32
|
+
- Method signatures → API contracts
|
|
33
|
+
- String constants → URLs, keys, messages
|
|
34
|
+
- Control flow → business rules (document, don't code)
|
|
35
|
+
|
|
36
|
+
**Smali Reading Quick Ref:**
|
|
37
|
+
```
|
|
38
|
+
.field → class fields (properties)
|
|
39
|
+
.method → method start
|
|
40
|
+
.end method → method end
|
|
41
|
+
invoke-virtual → instance method call
|
|
42
|
+
invoke-static → static method call
|
|
43
|
+
const-string → string literal
|
|
44
|
+
new-instance → object creation
|
|
45
|
+
if-eqz/if-nez → conditional branches
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2.2: Domain Model Contracts
|
|
49
|
+
|
|
50
|
+
Define data classes with exact field mapping:
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
// Domain model
|
|
54
|
+
data class User(
|
|
55
|
+
val id: String,
|
|
56
|
+
val fullName: String,
|
|
57
|
+
val email: String,
|
|
58
|
+
val avatarUrl: String?,
|
|
59
|
+
val isVerified: Boolean
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
// DTO (from API)
|
|
63
|
+
@Serializable
|
|
64
|
+
data class UserDto(
|
|
65
|
+
@SerialName("user_id") val userId: String,
|
|
66
|
+
@SerialName("full_name") val fullName: String,
|
|
67
|
+
@SerialName("email") val email: String,
|
|
68
|
+
@SerialName("avatar_url") val avatarUrl: String?,
|
|
69
|
+
@SerialName("is_verified") val isVerified: Boolean
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2.3: Repository Contract
|
|
74
|
+
|
|
75
|
+
Define interfaces (NO implementation):
|
|
76
|
+
|
|
77
|
+
```kotlin
|
|
78
|
+
interface AuthRepository {
|
|
79
|
+
suspend fun login(email: String, password: String): Result<User>
|
|
80
|
+
suspend fun register(name: String, email: String, password: String): Result<User>
|
|
81
|
+
suspend fun logout()
|
|
82
|
+
fun isLoggedIn(): Flow<Boolean>
|
|
83
|
+
fun getCurrentUser(): Flow<User?>
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 2.4: API Contract
|
|
88
|
+
|
|
89
|
+
Define Retrofit interface:
|
|
90
|
+
|
|
91
|
+
```kotlin
|
|
92
|
+
interface AuthApi {
|
|
93
|
+
@POST("auth/login")
|
|
94
|
+
suspend fun login(@Body request: LoginRequest): LoginResponse
|
|
95
|
+
|
|
96
|
+
@POST("auth/register")
|
|
97
|
+
suspend fun register(@Body request: RegisterRequest): RegisterResponse
|
|
98
|
+
|
|
99
|
+
@GET("auth/me")
|
|
100
|
+
suspend fun getCurrentUser(@Header("Authorization") token: String): UserDto
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 2.5: UseCase Signatures
|
|
105
|
+
|
|
106
|
+
```kotlin
|
|
107
|
+
class LoginUseCase(private val authRepo: AuthRepository) {
|
|
108
|
+
suspend operator fun invoke(email: String, password: String): Result<User>
|
|
109
|
+
// Implementation: TODO()
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 2.6: UI State Design
|
|
114
|
+
|
|
115
|
+
This is CRITICAL — design UiState + Events BEFORE coding the ViewModel:
|
|
116
|
+
|
|
117
|
+
```kotlin
|
|
118
|
+
// State
|
|
119
|
+
data class LoginUiState(
|
|
120
|
+
val email: String = "",
|
|
121
|
+
val password: String = "",
|
|
122
|
+
val isLoading: Boolean = false,
|
|
123
|
+
val error: String? = null,
|
|
124
|
+
val isPasswordVisible: Boolean = false
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
// Events (one-time actions)
|
|
128
|
+
sealed interface LoginEvent {
|
|
129
|
+
data class NavigateToHome(val user: User) : LoginEvent
|
|
130
|
+
data class ShowSnackbar(val message: String) : LoginEvent
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Actions (user interactions)
|
|
134
|
+
sealed interface LoginAction {
|
|
135
|
+
data class UpdateEmail(val email: String) : LoginAction
|
|
136
|
+
data class UpdatePassword(val password: String) : LoginAction
|
|
137
|
+
data object TogglePasswordVisibility : LoginAction
|
|
138
|
+
data object Submit : LoginAction
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2.7: UI Wireframe
|
|
143
|
+
|
|
144
|
+
Describe the screen layout in structured text (NOT code):
|
|
145
|
+
|
|
146
|
+
```markdown
|
|
147
|
+
### LoginScreen Wireframe
|
|
148
|
+
┌──────────────────────┐
|
|
149
|
+
│ [App Logo] │
|
|
150
|
+
│ │
|
|
151
|
+
│ ┌──────────────────┐ │
|
|
152
|
+
│ │ Email TextField │ │
|
|
153
|
+
│ └──────────────────┘ │
|
|
154
|
+
│ ┌──────────────────┐ │
|
|
155
|
+
│ │ Password Field 👁│ │
|
|
156
|
+
│ └──────────────────┘ │
|
|
157
|
+
│ │
|
|
158
|
+
│ [═══ Login Button ══]│
|
|
159
|
+
│ │
|
|
160
|
+
│ Forgot Password? │
|
|
161
|
+
│ Don't have account?│
|
|
162
|
+
│ Register │
|
|
163
|
+
└──────────────────────┘
|
|
164
|
+
|
|
165
|
+
Behaviors:
|
|
166
|
+
- Email: validate format on focus lost
|
|
167
|
+
- Password: toggle visibility icon
|
|
168
|
+
- Button: disabled when loading, show progress
|
|
169
|
+
- Error: Snackbar at bottom
|
|
170
|
+
- Success: Navigate to HomeScreen
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 📊 Output: Feature Blueprint
|
|
176
|
+
|
|
177
|
+
Present a clean summary:
|
|
178
|
+
|
|
179
|
+
```markdown
|
|
180
|
+
## 📐 Blueprint: [Feature Name]
|
|
181
|
+
|
|
182
|
+
### Smali Analysis Summary
|
|
183
|
+
- Files analyzed: [list]
|
|
184
|
+
- Key observations: [patterns, encryption, special logic]
|
|
185
|
+
|
|
186
|
+
### Contracts
|
|
187
|
+
- Domain Models: [list with field count]
|
|
188
|
+
- Repository Interface: [method signatures]
|
|
189
|
+
- API Interface: [endpoint signatures]
|
|
190
|
+
- UseCases: [list]
|
|
191
|
+
|
|
192
|
+
### UI Design
|
|
193
|
+
- UiState: [field list]
|
|
194
|
+
- Events: [list]
|
|
195
|
+
- Actions: [list]
|
|
196
|
+
- Wireframe: [see above]
|
|
197
|
+
|
|
198
|
+
### Dependencies
|
|
199
|
+
- Depends on: [other features/modules]
|
|
200
|
+
- Depended by: [features that need this]
|
|
201
|
+
|
|
202
|
+
### Estimated Files
|
|
203
|
+
| File | Layer | Type |
|
|
204
|
+
|------|-------|------|
|
|
205
|
+
| User.kt | Domain/Model | Data class |
|
|
206
|
+
| AuthRepository.kt | Domain/Repository | Interface |
|
|
207
|
+
| AuthRepositoryImpl.kt | Data/Repository | Implementation |
|
|
208
|
+
| AuthApi.kt | Data/Remote | Retrofit interface |
|
|
209
|
+
| LoginUseCase.kt | Domain/UseCase | Class |
|
|
210
|
+
| LoginViewModel.kt | Presentation | ViewModel |
|
|
211
|
+
| LoginScreen.kt | Presentation | Composable |
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## ✅ Gate
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
"📐 Blueprint cho [Feature] xong. Anh xem contracts có ổn không?
|
|
220
|
+
Khi OK em sẽ bắt đầu implement (Phase 3)."
|
|
221
|
+
|
|
222
|
+
→ User approves → Proceed to Phase 3 (Implementation) for this feature
|
|
223
|
+
→ User wants changes → Adjust blueprint
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
*Phase 2: Blueprint — Contracts before code*
|