@leejungkiin/awkit 1.7.1 → 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 +35 -2
- 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/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/project-identity/android.json +2 -2
- package/templates/project-identity/backend-nestjs.json +2 -2
- package/templates/project-identity/expo.json +2 -2
- package/templates/project-identity/ios.json +2 -2
- package/templates/project-identity/web-nextjs.json +2 -2
- 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,310 @@
|
|
|
1
|
+
# 🔬 Smali Reading Guide for AI
|
|
2
|
+
|
|
3
|
+
> Quick reference for interpreting Smali bytecode when reverse engineering Android apps.
|
|
4
|
+
> Used by the `smali-to-kotlin` skill during Steps 1-6.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📝 Smali Basics
|
|
9
|
+
|
|
10
|
+
### File Structure
|
|
11
|
+
```smali
|
|
12
|
+
.class public Lcom/example/app/MyClass;
|
|
13
|
+
.super Ljava/lang/Object;
|
|
14
|
+
.source "MyClass.java"
|
|
15
|
+
|
|
16
|
+
# interfaces
|
|
17
|
+
.implements Ljava/io/Serializable;
|
|
18
|
+
|
|
19
|
+
# static fields
|
|
20
|
+
.field private static final TAG:Ljava/lang/String; = "MyClass"
|
|
21
|
+
|
|
22
|
+
# instance fields
|
|
23
|
+
.field private name:Ljava/lang/String;
|
|
24
|
+
.field private age:I
|
|
25
|
+
|
|
26
|
+
# direct methods (constructors, static, private)
|
|
27
|
+
.method public constructor <init>()V
|
|
28
|
+
...
|
|
29
|
+
.end method
|
|
30
|
+
|
|
31
|
+
# virtual methods (public, protected, package-private)
|
|
32
|
+
.method public getName()Ljava/lang/String;
|
|
33
|
+
...
|
|
34
|
+
.end method
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Type Descriptors
|
|
38
|
+
```
|
|
39
|
+
V → void
|
|
40
|
+
Z → boolean
|
|
41
|
+
B → byte
|
|
42
|
+
S → short
|
|
43
|
+
C → char
|
|
44
|
+
I → int
|
|
45
|
+
J → long (2 registers)
|
|
46
|
+
F → float
|
|
47
|
+
D → double (2 registers)
|
|
48
|
+
L___; → object (e.g., Ljava/lang/String;)
|
|
49
|
+
[ → array (e.g., [I = int[], [Ljava/lang/String; = String[])
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Register Naming
|
|
53
|
+
```
|
|
54
|
+
p0, p1, p2... → parameter registers (p0 = 'this' for instance methods)
|
|
55
|
+
v0, v1, v2... → local variable registers
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🔑 Common Patterns → Kotlin Translation
|
|
61
|
+
|
|
62
|
+
### 1. String Constants & Field Access
|
|
63
|
+
```smali
|
|
64
|
+
# Smali
|
|
65
|
+
const-string v0, "https://api.example.com"
|
|
66
|
+
sput-object v0, Lcom/example/Config;->BASE_URL:Ljava/lang/String;
|
|
67
|
+
```
|
|
68
|
+
```kotlin
|
|
69
|
+
// Kotlin
|
|
70
|
+
object Config {
|
|
71
|
+
const val BASE_URL = "https://api.example.com"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Method Calls
|
|
76
|
+
```smali
|
|
77
|
+
# Static method call
|
|
78
|
+
invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
|
|
79
|
+
|
|
80
|
+
# Virtual method call (on instance)
|
|
81
|
+
invoke-virtual {p0, v0}, Lcom/example/MyClass;->setName(Ljava/lang/String;)V
|
|
82
|
+
|
|
83
|
+
# Interface method call
|
|
84
|
+
invoke-interface {v0}, Ljava/util/List;->size()I
|
|
85
|
+
|
|
86
|
+
# Direct method call (private/constructor)
|
|
87
|
+
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
|
88
|
+
```
|
|
89
|
+
```kotlin
|
|
90
|
+
// Kotlin equivalents
|
|
91
|
+
Log.d(tag, message)
|
|
92
|
+
myObject.setName(name) // or myObject.name = name
|
|
93
|
+
list.size
|
|
94
|
+
super()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Conditionals (if-else)
|
|
98
|
+
```smali
|
|
99
|
+
# if (v0 == 0) goto :label
|
|
100
|
+
if-eqz v0, :cond_0
|
|
101
|
+
|
|
102
|
+
# if (v0 != v1) goto :label
|
|
103
|
+
if-ne v0, v1, :cond_1
|
|
104
|
+
|
|
105
|
+
# if (v0 >= v1) goto :label
|
|
106
|
+
if-ge v0, v1, :cond_2
|
|
107
|
+
```
|
|
108
|
+
```
|
|
109
|
+
Conditional opcodes:
|
|
110
|
+
if-eqz → == 0 if-eq → ==
|
|
111
|
+
if-nez → != 0 if-ne → !=
|
|
112
|
+
if-ltz → < 0 if-lt → <
|
|
113
|
+
if-gez → >= 0 if-ge → >=
|
|
114
|
+
if-gtz → > 0 if-gt → >
|
|
115
|
+
if-lez → <= 0 if-le → <=
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 4. Try-Catch
|
|
119
|
+
```smali
|
|
120
|
+
.method public doNetwork()V
|
|
121
|
+
.registers 4
|
|
122
|
+
|
|
123
|
+
:try_start_0
|
|
124
|
+
# ... risky code ...
|
|
125
|
+
:try_end_0
|
|
126
|
+
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0
|
|
127
|
+
|
|
128
|
+
goto :goto_0
|
|
129
|
+
|
|
130
|
+
:catch_0
|
|
131
|
+
move-exception v0
|
|
132
|
+
# ... handle error ...
|
|
133
|
+
|
|
134
|
+
:goto_0
|
|
135
|
+
return-void
|
|
136
|
+
.end method
|
|
137
|
+
```
|
|
138
|
+
```kotlin
|
|
139
|
+
fun doNetwork() {
|
|
140
|
+
try {
|
|
141
|
+
// ... risky code ...
|
|
142
|
+
} catch (e: IOException) {
|
|
143
|
+
// ... handle error ...
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 5. Loops
|
|
149
|
+
```smali
|
|
150
|
+
# for loop pattern
|
|
151
|
+
const/4 v0, 0x0 # i = 0
|
|
152
|
+
|
|
153
|
+
:goto_0
|
|
154
|
+
array-length v1, v2 # v1 = array.length
|
|
155
|
+
if-ge v0, v1, :cond_0 # if (i >= length) break
|
|
156
|
+
|
|
157
|
+
# ... loop body using v0 as index ...
|
|
158
|
+
|
|
159
|
+
add-int/lit8 v0, v0, 0x1 # i++
|
|
160
|
+
goto :goto_0
|
|
161
|
+
|
|
162
|
+
:cond_0
|
|
163
|
+
# ... after loop ...
|
|
164
|
+
```
|
|
165
|
+
```kotlin
|
|
166
|
+
for (i in array.indices) {
|
|
167
|
+
// loop body
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 6. Switch/When
|
|
172
|
+
```smali
|
|
173
|
+
packed-switch v0, :pswitch_data_0
|
|
174
|
+
|
|
175
|
+
# ... default case ...
|
|
176
|
+
goto :goto_0
|
|
177
|
+
|
|
178
|
+
:pswitch_0 # case 0
|
|
179
|
+
...
|
|
180
|
+
:pswitch_1 # case 1
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
:pswitch_data_0
|
|
184
|
+
.packed-switch 0x0
|
|
185
|
+
:pswitch_0
|
|
186
|
+
:pswitch_1
|
|
187
|
+
.end packed-switch
|
|
188
|
+
```
|
|
189
|
+
```kotlin
|
|
190
|
+
when (value) {
|
|
191
|
+
0 -> { /* case 0 */ }
|
|
192
|
+
1 -> { /* case 1 */ }
|
|
193
|
+
else -> { /* default */ }
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 7. Object Creation
|
|
198
|
+
```smali
|
|
199
|
+
new-instance v0, Ljava/util/ArrayList;
|
|
200
|
+
invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V
|
|
201
|
+
```
|
|
202
|
+
```kotlin
|
|
203
|
+
val list = ArrayList<Any>()
|
|
204
|
+
// or better: val list = mutableListOf<Any>()
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 8. Casting & instanceof
|
|
208
|
+
```smali
|
|
209
|
+
# instanceof
|
|
210
|
+
instance-of v1, v0, Ljava/lang/String;
|
|
211
|
+
|
|
212
|
+
# cast
|
|
213
|
+
check-cast v0, Ljava/lang/String;
|
|
214
|
+
```
|
|
215
|
+
```kotlin
|
|
216
|
+
if (obj is String) { ... } // instanceof
|
|
217
|
+
val str = obj as String // cast
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 🎯 High-Value Patterns to Look For
|
|
223
|
+
|
|
224
|
+
### API Endpoints
|
|
225
|
+
```smali
|
|
226
|
+
# Look for URL string concatenation
|
|
227
|
+
const-string v0, "/api/v1/users"
|
|
228
|
+
invoke-virtual {v1, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### SharedPreferences Keys
|
|
232
|
+
```smali
|
|
233
|
+
const-string v0, "user_token"
|
|
234
|
+
invoke-interface {v1, v0}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Intent Actions & Extras
|
|
238
|
+
```smali
|
|
239
|
+
const-string v0, "com.example.ACTION_REFRESH"
|
|
240
|
+
const-string v1, "extra_user_id"
|
|
241
|
+
invoke-virtual {v2, v1, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Database Queries
|
|
245
|
+
```smali
|
|
246
|
+
const-string v0, "SELECT * FROM users WHERE id = ?"
|
|
247
|
+
invoke-virtual {v1, v0, v2}, Landroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;)Landroid/database/Cursor;
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Encryption Patterns
|
|
251
|
+
```smali
|
|
252
|
+
const-string v0, "AES/CBC/PKCS5Padding"
|
|
253
|
+
invoke-static {v0}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
|
|
254
|
+
|
|
255
|
+
const-string v0, "SHA-256"
|
|
256
|
+
invoke-static {v0}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 🔍 Obfuscation Patterns (ProGuard/R8)
|
|
262
|
+
|
|
263
|
+
### Renamed Classes
|
|
264
|
+
```
|
|
265
|
+
Original: Lcom/example/UserRepository;
|
|
266
|
+
Obfuscated: La/b/c;
|
|
267
|
+
```
|
|
268
|
+
**Strategy:** Follow method calls and string constants to understand purpose.
|
|
269
|
+
|
|
270
|
+
### Renamed Methods
|
|
271
|
+
```
|
|
272
|
+
Original: ->getUserProfile
|
|
273
|
+
Obfuscated: ->a(Ljava/lang/String;)V
|
|
274
|
+
```
|
|
275
|
+
**Strategy:** Look at parameters, return types, and what the method does internally.
|
|
276
|
+
|
|
277
|
+
### String Encryption
|
|
278
|
+
```smali
|
|
279
|
+
# Common pattern: encrypted strings decoded at runtime
|
|
280
|
+
invoke-static {v0}, Lcom/example/StringDecryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
|
|
281
|
+
```
|
|
282
|
+
**Strategy:** Find the decryptor class, understand the algorithm, then decrypt all strings.
|
|
283
|
+
|
|
284
|
+
### Tips for Obfuscated Code
|
|
285
|
+
1. **Start from entry points** (Activities in Manifest) — these are rarely obfuscated
|
|
286
|
+
2. **Follow string constants** — strings reveal purpose
|
|
287
|
+
3. **Check annotation classes** — Retrofit/Room annotations may survive obfuscation
|
|
288
|
+
4. **mapping.txt** — if available in APK, use it to deobfuscate
|
|
289
|
+
5. **Look for SDK packages** — third-party SDKs are usually not obfuscated
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 📊 Register Width Rules
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
Single-width (1 register): boolean, byte, char, short, int, float, Object reference
|
|
297
|
+
Double-width (2 registers): long, double
|
|
298
|
+
|
|
299
|
+
Example:
|
|
300
|
+
.method public calc(IJLjava/lang/String;)V
|
|
301
|
+
.registers 6
|
|
302
|
+
# p0 = this
|
|
303
|
+
# p1 = int param (I)
|
|
304
|
+
# p2-p3 = long param (J) — takes 2 registers!
|
|
305
|
+
# p4 = String param
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
*smali-reading-guide v1.0.0 — AI reference for Smali bytecode interpretation*
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# 🗺️ App Map: [App Name]
|
|
2
|
+
|
|
3
|
+
**Generated:** [Date]
|
|
4
|
+
**Source:** [Apktool dir path]
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📱 Identity
|
|
9
|
+
|
|
10
|
+
| Property | Value |
|
|
11
|
+
|----------|-------|
|
|
12
|
+
| Package | [com.example.app] |
|
|
13
|
+
| App Name | [Display Name] |
|
|
14
|
+
| Min SDK | [value] |
|
|
15
|
+
| Target SDK | [value] |
|
|
16
|
+
| Screens | [count] Activities |
|
|
17
|
+
| Services | [count] |
|
|
18
|
+
| Receivers | [count] |
|
|
19
|
+
| Providers | [count] |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🧭 Screen Flow
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌──────────┐ ┌──────────┐ ┌──────────────┐
|
|
27
|
+
│ Splash │───→│ Login │───→│ Main Tab │
|
|
28
|
+
└──────────┘ └──────────┘ ├──────────────┤
|
|
29
|
+
│ Tab 1: Home │
|
|
30
|
+
│ Tab 2: ... │
|
|
31
|
+
│ Tab 3: ... │
|
|
32
|
+
└──────────────┘
|
|
33
|
+
│
|
|
34
|
+
┌─────┴─────┐
|
|
35
|
+
│ Detail │
|
|
36
|
+
│ ... │
|
|
37
|
+
└───────────┘
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
*Or use Mermaid:*
|
|
41
|
+
```mermaid
|
|
42
|
+
graph LR
|
|
43
|
+
Splash --> Login
|
|
44
|
+
Login --> MainTab
|
|
45
|
+
MainTab --> Home
|
|
46
|
+
MainTab --> Tab2
|
|
47
|
+
MainTab --> Tab3
|
|
48
|
+
Home --> Detail
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 📦 Library Landscape
|
|
54
|
+
|
|
55
|
+
### ✅ Reuse (add to build.gradle)
|
|
56
|
+
| Library | Detected Package | Latest Version | Action |
|
|
57
|
+
|---------|-----------------|----------------|--------|
|
|
58
|
+
|
|
59
|
+
### 🔄 Replace (legacy → modern)
|
|
60
|
+
| Old Library | Detected Package | Modern Replacement |
|
|
61
|
+
|-------------|-----------------|-------------------|
|
|
62
|
+
|
|
63
|
+
### 🔵 Firebase / Google SDKs
|
|
64
|
+
| SDK | Detected | Action |
|
|
65
|
+
|-----|----------|--------|
|
|
66
|
+
|
|
67
|
+
### 📱 Native (.so) — Keep
|
|
68
|
+
| File | Architecture | Notes |
|
|
69
|
+
|------|-------------|-------|
|
|
70
|
+
|
|
71
|
+
### 🏷️ App Code (rebuild in Kotlin)
|
|
72
|
+
| Package | Estimated Module |
|
|
73
|
+
|---------|-----------------|
|
|
74
|
+
|
|
75
|
+
### ❓ Unknown (needs investigation)
|
|
76
|
+
| Package | Path | Possible Library |
|
|
77
|
+
|---------|------|-----------------|
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 📊 Complexity Estimate
|
|
82
|
+
|
|
83
|
+
| Area | Rating | Notes |
|
|
84
|
+
|------|--------|-------|
|
|
85
|
+
| Data Layer | ●●●○○ | [N] APIs, [N] local DB, [N] DataStores |
|
|
86
|
+
| Core Logic | ●●○○○ | [N] crypto utils, [N] formatters |
|
|
87
|
+
| UI Screens | ●●●●○ | [N] screens, [N] complex layouts |
|
|
88
|
+
| SDK Integration | ●●○○○ | [N] third-party, [N] native libs |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 🔍 Key Observations
|
|
93
|
+
|
|
94
|
+
- [Notable patterns: obfuscation level, unusual architecture, etc.]
|
|
95
|
+
- [Security observations: certificate pinning, root detection, etc.]
|
|
96
|
+
- [Risks: native libs without source, proprietary SDKs, etc.]
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
> **Next:** Anh review map này, có gì cần điều chỉnh không?
|
|
101
|
+
> → OK → Proceed to Phase 1 (Architecture Design)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# 🏗️ Architecture Blueprint: [App Name]
|
|
2
|
+
|
|
3
|
+
**Generated:** [Date]
|
|
4
|
+
**Based on:** App Map v[date]
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📐 Layer Map
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────┐
|
|
12
|
+
│ Presentation │
|
|
13
|
+
│ ├── screens/ ([N] screens) │
|
|
14
|
+
│ ├── navigation/ (NavGraph + Routes) │
|
|
15
|
+
│ ├── theme/ (Material 3 Theme) │
|
|
16
|
+
│ └── components/ (Shared UI) │
|
|
17
|
+
├─────────────────────────────────────┤
|
|
18
|
+
│ Domain │
|
|
19
|
+
│ ├── model/ ([N] business models) │
|
|
20
|
+
│ ├── repository/ ([N] interfaces) │
|
|
21
|
+
│ └── usecase/ ([N] use cases) │
|
|
22
|
+
├─────────────────────────────────────┤
|
|
23
|
+
│ Data │
|
|
24
|
+
│ ├── remote/ ([N] API services) │
|
|
25
|
+
│ ├── local/ (Room DB, DataStore) │
|
|
26
|
+
│ └── repository/ ([N] impls) │
|
|
27
|
+
├─────────────────────────────────────┤
|
|
28
|
+
│ DI (Hilt) │
|
|
29
|
+
│ └── modules/ (Network, DB, Repo) │
|
|
30
|
+
└─────────────────────────────────────┘
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🗂️ Feature → File Mapping
|
|
36
|
+
|
|
37
|
+
| Feature | Domain Model | Repository | UseCase | Screen(s) | ViewModel |
|
|
38
|
+
|---------|-------------|-----------|---------|-----------|-----------|
|
|
39
|
+
| Auth | User, Token | AuthRepo | LoginUC, RegisterUC | Login, Register | AuthVM |
|
|
40
|
+
| Home | [Model] | [Repo] | [UC] | Home | HomeVM |
|
|
41
|
+
| Profile | [Model] | [Repo] | [UC] | Profile, Edit | ProfileVM |
|
|
42
|
+
| Settings | [Model] | [Repo] | [UC] | Settings | SettingsVM |
|
|
43
|
+
| ... | ... | ... | ... | ... | ... |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🌐 API Endpoints
|
|
48
|
+
|
|
49
|
+
| # | Method | Endpoint | Auth | Notes |
|
|
50
|
+
|---|--------|----------|------|-------|
|
|
51
|
+
| 1 | POST | /auth/login | No | JWT response |
|
|
52
|
+
| 2 | GET | /users/me | Bearer | User profile |
|
|
53
|
+
| ... | ... | ... | ... | ... |
|
|
54
|
+
|
|
55
|
+
**Base URL:** `[extracted from Smali]`
|
|
56
|
+
**Auth Type:** [Bearer token / API key / Custom]
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 💾 Data Schema
|
|
61
|
+
|
|
62
|
+
| Model | Key Fields | Source | Storage |
|
|
63
|
+
|-------|-----------|--------|---------|
|
|
64
|
+
| User | id, name, email, avatar | API + Local | Room |
|
|
65
|
+
| Settings | theme, lang, notif | Local only | DataStore |
|
|
66
|
+
| ... | ... | ... | ... |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 📁 Project Structure
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
app/src/main/java/[package]/
|
|
74
|
+
├── App.kt
|
|
75
|
+
├── di/
|
|
76
|
+
│ ├── AppModule.kt
|
|
77
|
+
│ ├── NetworkModule.kt
|
|
78
|
+
│ └── DatabaseModule.kt
|
|
79
|
+
├── data/
|
|
80
|
+
│ ├── remote/
|
|
81
|
+
│ │ ├── api/
|
|
82
|
+
│ │ ├── dto/
|
|
83
|
+
│ │ └── interceptor/
|
|
84
|
+
│ ├── local/
|
|
85
|
+
│ │ ├── db/
|
|
86
|
+
│ │ ├── dao/
|
|
87
|
+
│ │ ├── entity/
|
|
88
|
+
│ │ └── datastore/
|
|
89
|
+
│ └── repository/
|
|
90
|
+
├── domain/
|
|
91
|
+
│ ├── model/
|
|
92
|
+
│ ├── repository/
|
|
93
|
+
│ └── usecase/
|
|
94
|
+
├── presentation/
|
|
95
|
+
│ ├── navigation/
|
|
96
|
+
│ ├── theme/
|
|
97
|
+
│ ├── components/
|
|
98
|
+
│ └── screens/
|
|
99
|
+
│ ├── splash/
|
|
100
|
+
│ ├── auth/
|
|
101
|
+
│ ├── home/
|
|
102
|
+
│ └── .../
|
|
103
|
+
└── util/
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 🔢 Build Order
|
|
109
|
+
|
|
110
|
+
| # | Phase | Scope | Complexity |
|
|
111
|
+
|---|-------|-------|-----------|
|
|
112
|
+
| 1 | 🟢 Setup | Project + DI skeleton + Theme | Low |
|
|
113
|
+
| 2 | 🟢 Models | Domain data classes | Low |
|
|
114
|
+
| 3 | 🟡 Data | API + Room + DataStore | Medium |
|
|
115
|
+
| 4 | 🟡 Utils | Crypto, formatters (parity test!) | Medium |
|
|
116
|
+
| 5 | 🔴 Feature: [First] | Blueprint → Build | High |
|
|
117
|
+
| 6 | 🔴 Feature: [Second] | Blueprint → Build | High |
|
|
118
|
+
| ... | ... | ... | ... |
|
|
119
|
+
| N | 🔴 Final | Parity check + QA | High |
|
|
120
|
+
|
|
121
|
+
**Suggested first feature:** [Name] — because [reason]
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🔧 Tech Stack Decisions
|
|
126
|
+
|
|
127
|
+
| Decision | Choice | Rationale |
|
|
128
|
+
|----------|--------|-----------|
|
|
129
|
+
| UI Framework | Jetpack Compose + Material 3 | Modern, declarative |
|
|
130
|
+
| DI | Hilt | Standard Android DI |
|
|
131
|
+
| Network | Retrofit + OkHttp | [Keep/Replace based on scan] |
|
|
132
|
+
| JSON | Kotlin Serialization | Type-safe, KMP ready |
|
|
133
|
+
| Image Loading | [Coil / Keep Glide] | [reason] |
|
|
134
|
+
| Local DB | Room | [reason] |
|
|
135
|
+
| Preferences | DataStore | Replaces SharedPreferences |
|
|
136
|
+
| Async | Coroutines + Flow | Modern concurrency |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
> **Next:** Anh muốn bắt đầu từ feature nào?
|
|
141
|
+
> Em suggest: **[Feature]** vì [reason].
|
|
142
|
+
> → Pick feature → Phase 2 (Blueprint)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# 📐 Feature Blueprint: [Feature Name]
|
|
2
|
+
|
|
3
|
+
**Generated:** [Date]
|
|
4
|
+
**Architecture:** [App Name] v[date]
|
|
5
|
+
**Feature:** [Feature Name]
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🔍 Smali Analysis Summary
|
|
10
|
+
|
|
11
|
+
| Item | Value |
|
|
12
|
+
|------|-------|
|
|
13
|
+
| Files analyzed | [list of Smali files] |
|
|
14
|
+
| Classes found | [count] |
|
|
15
|
+
| API calls detected | [count] |
|
|
16
|
+
| Local storage | [types: SharedPrefs, SQLite, etc.] |
|
|
17
|
+
|
|
18
|
+
### Key Observations
|
|
19
|
+
- [Pattern 1: e.g., "Uses MD5 + Base64 for password hashing"]
|
|
20
|
+
- [Pattern 2: e.g., "Token stored in SharedPreferences key 'auth_token'"]
|
|
21
|
+
- [Pattern 3: e.g., "Custom header 'X-App-Key' in all requests"]
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📦 Domain Models
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
data class [Model](
|
|
29
|
+
val field1: Type,
|
|
30
|
+
val field2: Type,
|
|
31
|
+
// ...
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📡 API Contract
|
|
38
|
+
|
|
39
|
+
```kotlin
|
|
40
|
+
interface [Feature]Api {
|
|
41
|
+
@[METHOD]("[endpoint]")
|
|
42
|
+
suspend fun [method](@Body request: [Request]): [Response]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Request/Response DTOs:**
|
|
47
|
+
```kotlin
|
|
48
|
+
@Serializable
|
|
49
|
+
data class [Request](/* fields */)
|
|
50
|
+
|
|
51
|
+
@Serializable
|
|
52
|
+
data class [Response](/* fields */)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🗄️ Repository Contract
|
|
58
|
+
|
|
59
|
+
```kotlin
|
|
60
|
+
interface [Feature]Repository {
|
|
61
|
+
suspend fun [method1](...): Result<[Type]>
|
|
62
|
+
fun [method2](): Flow<[Type]>
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 🧩 UseCase Signatures
|
|
69
|
+
|
|
70
|
+
```kotlin
|
|
71
|
+
class [Action]UseCase(private val repo: [Feature]Repository) {
|
|
72
|
+
suspend operator fun invoke(...): Result<[Type]>
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🎨 UI State Design
|
|
79
|
+
|
|
80
|
+
```kotlin
|
|
81
|
+
// State
|
|
82
|
+
data class [Screen]UiState(
|
|
83
|
+
val field1: Type = default,
|
|
84
|
+
val isLoading: Boolean = false,
|
|
85
|
+
val error: String? = null
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
// One-time events
|
|
89
|
+
sealed interface [Screen]Event {
|
|
90
|
+
data class NavigateTo[Next](/* params */) : [Screen]Event
|
|
91
|
+
data class ShowSnackbar(val message: String) : [Screen]Event
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// User actions
|
|
95
|
+
sealed interface [Screen]Action {
|
|
96
|
+
data class Update[Field](val value: Type) : [Screen]Action
|
|
97
|
+
data object Submit : [Screen]Action
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 🖼️ Screen Wireframe
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
┌────────────────────────┐
|
|
107
|
+
│ │
|
|
108
|
+
│ [Layout sketch] │
|
|
109
|
+
│ │
|
|
110
|
+
└────────────────────────┘
|
|
111
|
+
|
|
112
|
+
Behaviors:
|
|
113
|
+
- [Interaction 1]
|
|
114
|
+
- [Interaction 2]
|
|
115
|
+
- [Error handling]
|
|
116
|
+
- [Navigation on success]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 📁 Files to Create
|
|
122
|
+
|
|
123
|
+
| File | Layer | Type |
|
|
124
|
+
|------|-------|------|
|
|
125
|
+
| [Model].kt | domain/model | Data class |
|
|
126
|
+
| [Feature]Repository.kt | domain/repository | Interface |
|
|
127
|
+
| [Action]UseCase.kt | domain/usecase | Class |
|
|
128
|
+
| [Feature]Api.kt | data/remote/api | Retrofit interface |
|
|
129
|
+
| [DTOs].kt | data/remote/dto | Serializable |
|
|
130
|
+
| [Feature]RepositoryImpl.kt | data/repository | Implementation |
|
|
131
|
+
| [Screen]Screen.kt | presentation/screens | Composable |
|
|
132
|
+
| [Screen]ViewModel.kt | presentation/screens | ViewModel |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🔗 Dependencies
|
|
137
|
+
|
|
138
|
+
- **Depends on:** [other features/modules this needs]
|
|
139
|
+
- **Depended by:** [features that need this]
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
> **Next:** Anh xem contracts ổn không?
|
|
144
|
+
> → OK → Phase 3 (Implementation)
|
|
145
|
+
> → Adjust → Update blueprint
|