@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,172 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-resolution="cinematic">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width={{WIDTH}}, height={{HEIGHT}}" />
|
|
6
|
+
<script src="./gsap.min.js"></script>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
html,
|
|
15
|
+
body {
|
|
16
|
+
width: {{WIDTH}}px;
|
|
17
|
+
height: {{HEIGHT}}px;
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
background: #050606;
|
|
20
|
+
font-family: Arial, sans-serif;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#root {
|
|
24
|
+
position: relative;
|
|
25
|
+
width: {{WIDTH}}px;
|
|
26
|
+
height: {{HEIGHT}}px;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
background: #050606;
|
|
29
|
+
color: #f4f0e8;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.video-shot {
|
|
33
|
+
position: absolute;
|
|
34
|
+
inset: 0;
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
object-fit: cover;
|
|
38
|
+
background: #050606;
|
|
39
|
+
opacity: 0;
|
|
40
|
+
will-change: opacity, transform;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.grade,
|
|
44
|
+
.vignette,
|
|
45
|
+
.grain,
|
|
46
|
+
.title,
|
|
47
|
+
.subtitle-cue {
|
|
48
|
+
position: absolute;
|
|
49
|
+
pointer-events: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.grade {
|
|
53
|
+
inset: 0;
|
|
54
|
+
z-index: 20;
|
|
55
|
+
background:
|
|
56
|
+
radial-gradient(circle at 50% 28%, rgba(226, 235, 220, 0.12), transparent 34%),
|
|
57
|
+
linear-gradient(90deg, rgba(8, 27, 33, 0.36), transparent 45%, rgba(56, 34, 20, 0.18)),
|
|
58
|
+
linear-gradient(0deg, rgba(4, 5, 5, 0.2), rgba(4, 5, 5, 0.2));
|
|
59
|
+
mix-blend-mode: soft-light;
|
|
60
|
+
opacity: 0.76;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.vignette {
|
|
64
|
+
inset: -2px;
|
|
65
|
+
z-index: 30;
|
|
66
|
+
box-shadow: inset 0 0 180px 58px rgba(0, 0, 0, 0.84);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.grain {
|
|
70
|
+
inset: 0;
|
|
71
|
+
z-index: 35;
|
|
72
|
+
opacity: 0.12;
|
|
73
|
+
background-image:
|
|
74
|
+
repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.045) 0, rgba(255, 255, 255, 0.045) 1px, transparent 1px, transparent 3px),
|
|
75
|
+
repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0, rgba(0, 0, 0, 0.05) 1px, transparent 1px, transparent 5px);
|
|
76
|
+
mix-blend-mode: overlay;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.title {
|
|
80
|
+
left: 8%;
|
|
81
|
+
bottom: 13%;
|
|
82
|
+
z-index: 60;
|
|
83
|
+
display: grid;
|
|
84
|
+
gap: 14px;
|
|
85
|
+
padding: 18px 34px 20px 24px;
|
|
86
|
+
background: linear-gradient(90deg, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0.38), transparent);
|
|
87
|
+
text-transform: uppercase;
|
|
88
|
+
filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.82));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.kicker {
|
|
92
|
+
font-size: {{KICKER_SIZE}}px;
|
|
93
|
+
line-height: 1;
|
|
94
|
+
color: #f4f0e8;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.headline {
|
|
98
|
+
font-size: {{TITLE_SIZE}}px;
|
|
99
|
+
line-height: 0.95;
|
|
100
|
+
letter-spacing: 0;
|
|
101
|
+
font-weight: 700;
|
|
102
|
+
color: #f4f0e8;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.subtitle-cue {
|
|
106
|
+
left: 50%;
|
|
107
|
+
bottom: 7.5%;
|
|
108
|
+
z-index: 70;
|
|
109
|
+
width: 74%;
|
|
110
|
+
transform: translateX(-50%);
|
|
111
|
+
color: #f7f2e8;
|
|
112
|
+
font-size: {{SUBTITLE_SIZE}}px;
|
|
113
|
+
line-height: 1.22;
|
|
114
|
+
text-align: center;
|
|
115
|
+
text-shadow:
|
|
116
|
+
0 2px 4px rgba(0, 0, 0, 0.96),
|
|
117
|
+
0 0 18px rgba(0, 0, 0, 0.72);
|
|
118
|
+
}
|
|
119
|
+
</style>
|
|
120
|
+
</head>
|
|
121
|
+
<body>
|
|
122
|
+
<div id="root" data-composition-id="main" data-start="0" data-duration="{{DURATION}}" data-width="{{WIDTH}}" data-height="{{HEIGHT}}">
|
|
123
|
+
{{VIDEO_CLIPS}}
|
|
124
|
+
<audio id="music-bed" class="clip" data-start="0" data-duration="{{DURATION}}" data-track-index="5" data-volume="{{MUSIC_VOLUME}}" src="./media/music.m4a" preload="auto"></audio>
|
|
125
|
+
{{DIALOGUE_AUDIO}}
|
|
126
|
+
{{CAPTIONS}}
|
|
127
|
+
|
|
128
|
+
<div class="grade"></div>
|
|
129
|
+
<div class="vignette"></div>
|
|
130
|
+
<div class="grain"></div>
|
|
131
|
+
<div class="title">
|
|
132
|
+
<div class="kicker">{{KICKER}}</div>
|
|
133
|
+
<div class="headline">{{TITLE}}</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<script>
|
|
138
|
+
window.__timelines = window.__timelines || {};
|
|
139
|
+
|
|
140
|
+
const tl = gsap.timeline({ paused: true });
|
|
141
|
+
const duration = {{DURATION}};
|
|
142
|
+
|
|
143
|
+
gsap.set(".title", { autoAlpha: 0, y: 18 });
|
|
144
|
+
gsap.set(".subtitle-cue", { autoAlpha: 0, y: 10 });
|
|
145
|
+
|
|
146
|
+
tl.fromTo(".title", { autoAlpha: 0, y: 18 }, { autoAlpha: 1, y: 0, duration: 1.2, ease: "power2.out" }, 0.25);
|
|
147
|
+
tl.to(".title", { autoAlpha: 0, y: -10, duration: 0.9, ease: "power2.in" }, {{TITLE_OUT}});
|
|
148
|
+
tl.fromTo(".grade", { opacity: 0.62 }, { opacity: 0.82, duration, ease: "sine.inOut" }, 0);
|
|
149
|
+
|
|
150
|
+
document.querySelectorAll(".subtitle-cue").forEach((el) => {
|
|
151
|
+
const start = Number(el.dataset.start || 0);
|
|
152
|
+
const cueDuration = Number(el.dataset.duration || 1);
|
|
153
|
+
tl.fromTo(el, { autoAlpha: 0, y: 10 }, { autoAlpha: 1, y: 0, duration: 0.18, ease: "power2.out" }, start);
|
|
154
|
+
tl.to(el, { autoAlpha: 0, y: -6, duration: 0.22, ease: "power2.in" }, Math.max(start, start + cueDuration - 0.22));
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const videoShots = Array.from(document.querySelectorAll(".video-shot"));
|
|
158
|
+
videoShots.forEach((el, index) => {
|
|
159
|
+
const start = Number(el.dataset.start || 0);
|
|
160
|
+
const clipDuration = Number(el.dataset.duration || 0);
|
|
161
|
+
const fadeIn = index === 0 ? 0.35 : Math.min(0.7, Math.max(0.35, clipDuration * 0.12));
|
|
162
|
+
const fadeOut = Math.min(0.7, Math.max(0.35, clipDuration * 0.12));
|
|
163
|
+
tl.fromTo(el, { opacity: 0, scale: 1.012 }, { opacity: 1, scale: 1, duration: fadeIn, ease: "sine.out" }, start);
|
|
164
|
+
if (index < videoShots.length - 1) {
|
|
165
|
+
tl.to(el, { opacity: 0, duration: fadeOut, ease: "sine.inOut" }, Math.max(start, start + clipDuration - fadeOut));
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
window.__timelines["main"] = tl;
|
|
170
|
+
</script>
|
|
171
|
+
</body>
|
|
172
|
+
</html>
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-resolution="landscape">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width={{WIDTH}}, height={{HEIGHT}}" />
|
|
6
|
+
<script src="./gsap.min.js"></script>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
html,
|
|
15
|
+
body {
|
|
16
|
+
width: {{WIDTH}}px;
|
|
17
|
+
height: {{HEIGHT}}px;
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
background: #020202;
|
|
20
|
+
font-family: Arial, sans-serif;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#root {
|
|
24
|
+
position: relative;
|
|
25
|
+
width: {{WIDTH}}px;
|
|
26
|
+
height: {{HEIGHT}}px;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
background: #020202;
|
|
29
|
+
color: #f3f1ea;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.video-shot {
|
|
33
|
+
position: absolute;
|
|
34
|
+
inset: 0;
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
object-fit: cover;
|
|
38
|
+
background: #020202;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.grade,
|
|
42
|
+
.vignette,
|
|
43
|
+
.pulse,
|
|
44
|
+
.flash,
|
|
45
|
+
.scanline,
|
|
46
|
+
.title,
|
|
47
|
+
.meter {
|
|
48
|
+
position: absolute;
|
|
49
|
+
pointer-events: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.grade {
|
|
53
|
+
inset: 0;
|
|
54
|
+
z-index: 20;
|
|
55
|
+
background:
|
|
56
|
+
radial-gradient(circle at 52% 34%, rgba(244, 232, 184, 0.14), transparent 34%),
|
|
57
|
+
linear-gradient(110deg, rgba(13, 58, 50, 0.3), transparent 38%, rgba(122, 32, 18, 0.24)),
|
|
58
|
+
linear-gradient(0deg, rgba(4, 4, 4, 0.16), rgba(4, 4, 4, 0.16));
|
|
59
|
+
mix-blend-mode: color-dodge;
|
|
60
|
+
opacity: 0.34;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.vignette {
|
|
64
|
+
inset: -2px;
|
|
65
|
+
z-index: 30;
|
|
66
|
+
box-shadow: inset 0 0 220px 76px rgba(0, 0, 0, 0.82);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.pulse {
|
|
70
|
+
inset: -10%;
|
|
71
|
+
z-index: 40;
|
|
72
|
+
background:
|
|
73
|
+
radial-gradient(circle at 50% 50%, rgba(255, 222, 138, 0.26), transparent 20%),
|
|
74
|
+
radial-gradient(circle at 50% 50%, rgba(42, 211, 158, 0.12), transparent 42%);
|
|
75
|
+
mix-blend-mode: screen;
|
|
76
|
+
opacity: 0;
|
|
77
|
+
transform: scale(0.92);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.flash {
|
|
81
|
+
inset: 0;
|
|
82
|
+
z-index: 45;
|
|
83
|
+
background: #f7f0cf;
|
|
84
|
+
mix-blend-mode: screen;
|
|
85
|
+
opacity: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.scanline {
|
|
89
|
+
inset: 0;
|
|
90
|
+
z-index: 50;
|
|
91
|
+
background: repeating-linear-gradient(
|
|
92
|
+
0deg,
|
|
93
|
+
rgba(255, 255, 255, 0.05) 0,
|
|
94
|
+
rgba(255, 255, 255, 0.05) 1px,
|
|
95
|
+
transparent 1px,
|
|
96
|
+
transparent 4px
|
|
97
|
+
);
|
|
98
|
+
opacity: 0.13;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.title {
|
|
102
|
+
left: 74px;
|
|
103
|
+
bottom: 82px;
|
|
104
|
+
z-index: 60;
|
|
105
|
+
display: grid;
|
|
106
|
+
gap: 12px;
|
|
107
|
+
text-transform: uppercase;
|
|
108
|
+
filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.8));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.kicker {
|
|
112
|
+
font-size: 18px;
|
|
113
|
+
line-height: 1;
|
|
114
|
+
letter-spacing: 0;
|
|
115
|
+
color: #d8c27c;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.headline {
|
|
119
|
+
font-size: 58px;
|
|
120
|
+
line-height: 0.94;
|
|
121
|
+
font-weight: 800;
|
|
122
|
+
letter-spacing: 0;
|
|
123
|
+
color: #f6f1df;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.meter {
|
|
127
|
+
left: 74px;
|
|
128
|
+
right: 74px;
|
|
129
|
+
bottom: 44px;
|
|
130
|
+
z-index: 60;
|
|
131
|
+
height: 2px;
|
|
132
|
+
background: rgba(246, 241, 223, 0.16);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.meter span {
|
|
136
|
+
display: block;
|
|
137
|
+
width: 100%;
|
|
138
|
+
height: 100%;
|
|
139
|
+
background: linear-gradient(90deg, #c7a33a, #f4ead0, #38c69d);
|
|
140
|
+
transform: scaleX(0);
|
|
141
|
+
transform-origin: left;
|
|
142
|
+
}
|
|
143
|
+
</style>
|
|
144
|
+
</head>
|
|
145
|
+
<body>
|
|
146
|
+
<div id="root" data-composition-id="main" data-start="0" data-duration="{{DURATION}}" data-width="{{WIDTH}}" data-height="{{HEIGHT}}">
|
|
147
|
+
{{VIDEO_CLIPS}}
|
|
148
|
+
<audio id="music" class="clip" data-start="0" data-duration="{{DURATION}}" data-track-index="5" src="./media/music.mp3" preload="auto"></audio>
|
|
149
|
+
|
|
150
|
+
<div class="grade"></div>
|
|
151
|
+
<div class="vignette"></div>
|
|
152
|
+
<div class="pulse"></div>
|
|
153
|
+
<div class="flash"></div>
|
|
154
|
+
<div class="scanline"></div>
|
|
155
|
+
|
|
156
|
+
<div class="title">
|
|
157
|
+
<div class="kicker">{{KICKER}}</div>
|
|
158
|
+
<div class="headline">{{TITLE}}</div>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="meter"><span></span></div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<script>
|
|
164
|
+
window.__timelines = window.__timelines || {};
|
|
165
|
+
|
|
166
|
+
const tl = gsap.timeline({ paused: true });
|
|
167
|
+
const cutTimes = {{CUT_TIMES}};
|
|
168
|
+
const flashColors = {{FLASH_COLORS}};
|
|
169
|
+
|
|
170
|
+
gsap.set(".title", { autoAlpha: 0, y: 26 });
|
|
171
|
+
gsap.set(".meter span", { scaleX: 0 });
|
|
172
|
+
gsap.set(".flash", { opacity: 0 });
|
|
173
|
+
gsap.set(".pulse", { opacity: 0, scale: 0.94 });
|
|
174
|
+
|
|
175
|
+
tl.fromTo(".title", { autoAlpha: 0, y: 26 }, { autoAlpha: 1, y: 0, duration: 0.42, ease: "power3.out" }, 0.18);
|
|
176
|
+
tl.to(".title", { autoAlpha: 0, y: -14, duration: 0.34, ease: "power2.in" }, 2.36);
|
|
177
|
+
tl.to(".meter span", { scaleX: 1, duration: {{DURATION}}, ease: "none" }, 0);
|
|
178
|
+
tl.fromTo(".grade", { opacity: 0.26 }, { opacity: 0.42, duration: {{DURATION}}, ease: "sine.inOut" }, 0);
|
|
179
|
+
|
|
180
|
+
cutTimes.forEach((time, index) => {
|
|
181
|
+
tl.set(".flash", { backgroundColor: flashColors[index % flashColors.length] }, time - 0.02);
|
|
182
|
+
tl.fromTo(".flash", { opacity: 0 }, { opacity: 0.34, duration: 0.045, ease: "none", overwrite: "auto" }, time - 0.015);
|
|
183
|
+
tl.to(".flash", { opacity: 0, duration: 0.18, ease: "power2.out", overwrite: "auto" }, time + 0.035);
|
|
184
|
+
tl.fromTo(".pulse", { opacity: 0.34, scale: 0.93 }, { opacity: 0, scale: 1.08, duration: 0.42, ease: "power2.out" }, time);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
tl.to(".vignette", { boxShadow: "inset 0 0 260px 90px rgba(0, 0, 0, 0.88)", duration: 3.3, ease: "power2.in" }, {{FINAL_VIGNETTE_START}});
|
|
188
|
+
tl.fromTo(".title", { autoAlpha: 0, y: 18 }, { autoAlpha: 1, y: 0, duration: 0.48, ease: "power3.out" }, {{FINAL_TITLE_START}});
|
|
189
|
+
tl.to(".title", { autoAlpha: 0, y: -10, duration: 0.46, ease: "power2.in" }, {{FINAL_TITLE_END}});
|
|
190
|
+
|
|
191
|
+
window.__timelines["main"] = tl;
|
|
192
|
+
</script>
|
|
193
|
+
</body>
|
|
194
|
+
</html>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: smali-to-kotlin
|
|
3
|
+
description: >-
|
|
4
|
+
Android Reverse Engineering specialist. Reads Apktool output (Smali, resources, manifest)
|
|
5
|
+
and rebuilds the app from scratch using modern Kotlin + Jetpack Compose + Clean Architecture.
|
|
6
|
+
Includes library detection to reuse existing dependencies.
|
|
7
|
+
author: Antigravity Team
|
|
8
|
+
version: 2.0.0
|
|
9
|
+
trigger: conditional
|
|
10
|
+
activation_keywords:
|
|
11
|
+
- "/reverse-android"
|
|
12
|
+
- "smali"
|
|
13
|
+
- "apktool"
|
|
14
|
+
- "reverse engineer"
|
|
15
|
+
- "dịch ngược"
|
|
16
|
+
- "tái tạo apk"
|
|
17
|
+
- "rebuild apk"
|
|
18
|
+
- "smali to kotlin"
|
|
19
|
+
priority: high
|
|
20
|
+
platform: android
|
|
21
|
+
sibling_skill: smali-to-swift (iOS counterpart)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# 🔧 Smali-to-Kotlin Skill
|
|
25
|
+
|
|
26
|
+
> **Purpose:** Transform decompiled Android APK into a modern Kotlin app with Jetpack Compose + Clean Architecture (MVVM).
|
|
27
|
+
> **Philosophy:** "Read Smali to understand WHAT and WHY → Write Kotlin for HOW."
|
|
28
|
+
|
|
29
|
+
## ⚠️ SCOPE CLARITY
|
|
30
|
+
|
|
31
|
+
| This skill DOES | This skill DOES NOT |
|
|
32
|
+
|-----------------|---------------------|
|
|
33
|
+
| Read & analyze Smali/Java decompiled code | Write Smali code |
|
|
34
|
+
| Rebuild logic in modern Kotlin | Modify original APK |
|
|
35
|
+
| Detect & reuse third-party libraries | Crack/bypass security |
|
|
36
|
+
| Extract only needed resources (on-demand) | Mass-copy resources blindly |
|
|
37
|
+
|
|
38
|
+
→ iOS reverse engineering → sibling skill: `smali-to-swift`
|
|
39
|
+
|
|
40
|
+
## 🎯 ROLE DEFINITION
|
|
41
|
+
|
|
42
|
+
When this skill is active, the agent becomes:
|
|
43
|
+
|
|
44
|
+
> **Expert Android Reverse Engineer & Kotlin Architect**
|
|
45
|
+
> - Master at reading Smali bytecode and obfuscated Java
|
|
46
|
+
> - Fluent in Clean Architecture + MVVM + Jetpack Compose
|
|
47
|
+
> - Knows when to reuse vs rewrite third-party dependencies
|
|
48
|
+
> - Enforces resource-on-demand principle (zero bloat)
|
|
49
|
+
|
|
50
|
+
## 📋 EXECUTION PIPELINE (6 Steps)
|
|
51
|
+
|
|
52
|
+
> **Rule:** Always complete one step fully before moving to the next.
|
|
53
|
+
> **Rule:** After each step, create a checkpoint summary for the user.
|
|
54
|
+
|
|
55
|
+
**Identify the topic** from the user's request and load the corresponding file:
|
|
56
|
+
|
|
57
|
+
### Getting Started
|
|
58
|
+
- Modern tech stack & legacy replacements → `examples/getting-started/tech-stack.md`
|
|
59
|
+
|
|
60
|
+
### Pipeline Steps
|
|
61
|
+
- **Step 0** Library Scanner + **Step 1** Manifest & Bootstrap → `examples/pipeline/scanner-and-bootstrap.md`
|
|
62
|
+
- **Step 2-6** Data Layer, Logic, UI, SDK, Parity Check → `examples/pipeline/data-ui-parity.md`
|
|
63
|
+
|
|
64
|
+
## 🔄 WORKFLOW INTEGRATION
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
triggers_from:
|
|
68
|
+
- "/reverse-android" workflow command
|
|
69
|
+
- Keywords: "smali", "apktool", "dịch ngược", "rebuild"
|
|
70
|
+
|
|
71
|
+
delegates_to:
|
|
72
|
+
- "/test" — after parity check
|
|
73
|
+
- "/deploy" — when rebuild is complete
|
|
74
|
+
- symphony-orchestrator — auto-track progress per step
|
|
75
|
+
|
|
76
|
+
works_with:
|
|
77
|
+
- memory-sync — saves decisions, patterns, solutions
|
|
78
|
+
- orchestrator — routes to this skill based on intent
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 🚫 ANTI-PATTERNS
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
never_do:
|
|
85
|
+
- Copy all resources blindly from APK → only on-demand
|
|
86
|
+
- Use deprecated libraries (AsyncTask, Volley) → always use modern replacements
|
|
87
|
+
- Skip library scanning step → always detect reusable packages first
|
|
88
|
+
- Modify encryption output → must match original exactly
|
|
89
|
+
- Create massive God Activity → split into Compose screens + ViewModels
|
|
90
|
+
- Hardcode API keys/secrets → use BuildConfig or encrypted storage
|
|
91
|
+
|
|
92
|
+
always_do:
|
|
93
|
+
- Run Library Scanner (Step 0) before any coding
|
|
94
|
+
- Present library report to user for approval
|
|
95
|
+
- Unit test all encryption/hashing utils
|
|
96
|
+
- Use sealed classes for UI state
|
|
97
|
+
- Follow Clean Architecture layer separation strictly
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 📊 CHECKPOINT TEMPLATE
|
|
101
|
+
|
|
102
|
+
After each step, output:
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
## ✅ Step [N] Complete: [Step Name]
|
|
106
|
+
### What was done:
|
|
107
|
+
- [Summary]
|
|
108
|
+
### Files created:
|
|
109
|
+
- [List]
|
|
110
|
+
### ⏭️ Next: Step [N+1] — [Step Name]
|
|
111
|
+
- [What user needs to provide]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 🧩 PLATFORM RE TEMPLATE PATTERN
|
|
115
|
+
|
|
116
|
+
| Step | Android (this skill) | iOS (smali-to-swift) |
|
|
117
|
+
|------|---------------------|---------------------|
|
|
118
|
+
| 0 | Library Scanner (Smali packages) | Framework Scanner (Frameworks/ + headers) |
|
|
119
|
+
| 1 | AndroidManifest.xml | Info.plist + Entitlements |
|
|
120
|
+
| 2 | Retrofit + Room | URLSession + SwiftData |
|
|
121
|
+
| 3 | Kotlin crypto utils | Swift CryptoKit/CommonCrypto |
|
|
122
|
+
| 4 | Jetpack Compose + StateFlow | SwiftUI + @Observable |
|
|
123
|
+
| 5 | Hilt + JNI | SPM + Bridging Header |
|
|
124
|
+
| 6 | Parity Check | Parity Check |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
*smali-to-kotlin v2.0.0 — Modular Router Architecture*
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Modern Tech Stack (Mandatory)
|
|
2
|
+
|
|
3
|
+
## Core
|
|
4
|
+
|
|
5
|
+
| Layer | Technology | Replaces |
|
|
6
|
+
|-------|-----------|----------|
|
|
7
|
+
| **UI** | Jetpack Compose + Material 3 | XML Layouts + findViewById |
|
|
8
|
+
| **State** | StateFlow + ViewModel | LiveData / AsyncTask |
|
|
9
|
+
| **Navigation** | Navigation Compose | Intent-based navigation |
|
|
10
|
+
| **DI** | Hilt (Dagger) | Manual DI / ServiceLocator |
|
|
11
|
+
|
|
12
|
+
## Data Layer
|
|
13
|
+
|
|
14
|
+
| Purpose | Technology | Replaces |
|
|
15
|
+
|---------|-----------|----------|
|
|
16
|
+
| **Network** | Retrofit + OkHttp + Kotlin Serialization | Volley / HttpURLConnection |
|
|
17
|
+
| **Local DB** | Room Database | Raw SQLite / SQLiteOpenHelper |
|
|
18
|
+
| **Preferences** | DataStore (Proto/Preferences) | SharedPreferences |
|
|
19
|
+
| **Image Loading** | Coil | Picasso / Glide (evaluate) |
|
|
20
|
+
| **Async** | Kotlin Coroutines + Flow | AsyncTask / Handler / Thread |
|
|
21
|
+
|
|
22
|
+
## Observability
|
|
23
|
+
|
|
24
|
+
| Purpose | Technology |
|
|
25
|
+
|---------|-----------|
|
|
26
|
+
| **Crash** | Firebase Crashlytics |
|
|
27
|
+
| **Analytics** | Firebase Analytics |
|
|
28
|
+
| **Logging** | Timber |
|
|
29
|
+
|
|
30
|
+
## Replacements Table (Legacy → Modern)
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
always_replace:
|
|
34
|
+
AsyncTask: "Coroutines (suspend fun / Flow)"
|
|
35
|
+
Volley: "Retrofit + OkHttp"
|
|
36
|
+
HttpURLConnection: "Retrofit + OkHttp"
|
|
37
|
+
Handler/Looper: "Coroutines (Dispatchers.Main)"
|
|
38
|
+
BroadcastReceiver (local): "Flow / EventBus → SharedFlow"
|
|
39
|
+
SharedPreferences: "DataStore"
|
|
40
|
+
SQLiteOpenHelper: "Room"
|
|
41
|
+
ListView/GridView: "LazyColumn/LazyGrid (Compose)"
|
|
42
|
+
findViewById: "Compose state"
|
|
43
|
+
Gson: "Kotlin Serialization (kotlinx.serialization)"
|
|
44
|
+
|
|
45
|
+
evaluate_before_replacing:
|
|
46
|
+
Glide: "Keep if deeply integrated, otherwise → Coil"
|
|
47
|
+
RxJava: "Migrate to Coroutines + Flow (gradual)"
|
|
48
|
+
EventBus: "Replace with SharedFlow"
|
|
49
|
+
Butter Knife: "Not needed in Compose"
|
|
50
|
+
Dagger 2: "Upgrade to Hilt"
|
|
51
|
+
|
|
52
|
+
keep_as_is:
|
|
53
|
+
- "OkHttp (still current)"
|
|
54
|
+
- "Retrofit (still current)"
|
|
55
|
+
- "Firebase SDKs (use latest version)"
|
|
56
|
+
- "Google Play Services"
|
|
57
|
+
- "Native .so libraries (JNI)"
|
|
58
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Step 2: Data Layer Reconstruction 💾
|
|
2
|
+
|
|
3
|
+
**Input:** Smali/Java code for API endpoints, JSON models, database queries.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
### 1. Models: POJO/Smali → Kotlin data class
|
|
8
|
+
- Use `@Serializable` (kotlinx.serialization) or `@JsonClass` (Moshi)
|
|
9
|
+
- Preserve JSON field names with `@SerialName`
|
|
10
|
+
|
|
11
|
+
### 2. API Layer
|
|
12
|
+
- Extract base URL, endpoints, headers from Smali
|
|
13
|
+
- Create Retrofit `@GET/@POST` interfaces
|
|
14
|
+
- Identify auth patterns (token, API key, custom headers)
|
|
15
|
+
|
|
16
|
+
### 3. Local Storage
|
|
17
|
+
- SQLite queries → Room entities + DAOs
|
|
18
|
+
- SharedPreferences keys → DataStore schema
|
|
19
|
+
|
|
20
|
+
### 4. Repository
|
|
21
|
+
- Create interface in `domain/repository/`
|
|
22
|
+
- Implement in `data/repository/`
|
|
23
|
+
- Use Flow for reactive data streams
|
|
24
|
+
|
|
25
|
+
## Smali Reading Tips
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Finding API base URL:
|
|
29
|
+
const-string → "https://" or "http://"
|
|
30
|
+
.field → BASE_URL or API_URL
|
|
31
|
+
|
|
32
|
+
Finding endpoints:
|
|
33
|
+
StringBuilder + append patterns
|
|
34
|
+
Annotation patterns (@GET, @POST in obfuscated form)
|
|
35
|
+
|
|
36
|
+
Finding JSON parsing:
|
|
37
|
+
JSONObject, JSONArray usage
|
|
38
|
+
Gson.fromJson / TypeToken patterns
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
# Step 3: Core Logic & Utils Reconstruction 🧮
|
|
44
|
+
|
|
45
|
+
**Input:** Smali for encryption, hashing, time formatting, custom utils.
|
|
46
|
+
|
|
47
|
+
## Tasks
|
|
48
|
+
|
|
49
|
+
1. Translate mathematical/encryption logic from Smali → Kotlin
|
|
50
|
+
- Preserve exact input/output signatures (server compatibility)
|
|
51
|
+
- Use `object` for stateless utils, extension functions for type-specific
|
|
52
|
+
2. Map encoding patterns:
|
|
53
|
+
- MD5/SHA hashing → `MessageDigest`
|
|
54
|
+
- AES/DES encryption → `javax.crypto.Cipher`
|
|
55
|
+
- Base64 → `android.util.Base64` or `java.util.Base64`
|
|
56
|
+
- Custom obfuscation → reverse step-by-step
|
|
57
|
+
3. **Verification:** Unit tests comparing output with original app
|
|
58
|
+
|
|
59
|
+
> ⚠️ Encryption/hashing MUST produce identical output. Any mismatch breaks server communication.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
# Step 4: UI & ViewModel Reconstruction (Per Screen) 🎨
|
|
64
|
+
|
|
65
|
+
**Input:** `layout_xxx.xml` + Smali for Activity/Fragment.
|
|
66
|
+
|
|
67
|
+
## XML → Compose Migration
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
LinearLayout (vertical) → Column
|
|
71
|
+
LinearLayout (horizontal) → Row
|
|
72
|
+
FrameLayout → Box
|
|
73
|
+
RelativeLayout → Box with alignment
|
|
74
|
+
RecyclerView → LazyColumn / LazyGrid
|
|
75
|
+
ScrollView → verticalScroll modifier
|
|
76
|
+
ImageView → Image / AsyncImage (Coil)
|
|
77
|
+
TextView → Text
|
|
78
|
+
EditText → TextField / OutlinedTextField
|
|
79
|
+
Button → Button / TextButton
|
|
80
|
+
ProgressBar → CircularProgressIndicator
|
|
81
|
+
CardView → Card (Material 3)
|
|
82
|
+
Toolbar/ActionBar → TopAppBar (Material 3)
|
|
83
|
+
BottomNavigationView → NavigationBar (Material 3)
|
|
84
|
+
TabLayout + ViewPager → TabRow + HorizontalPager
|
|
85
|
+
SwipeRefreshLayout → pullRefresh modifier
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## ViewModel Pattern
|
|
89
|
+
|
|
90
|
+
```kotlin
|
|
91
|
+
sealed interface ScreenUiState {
|
|
92
|
+
data object Loading : ScreenUiState
|
|
93
|
+
data class Success(val data: ScreenData) : ScreenUiState
|
|
94
|
+
data class Error(val message: String) : ScreenUiState
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- Expose via `StateFlow` from ViewModel
|
|
99
|
+
- Handle one-time events via `SharedFlow` (navigation, snackbar)
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# Step 5-6: SDK Integration + Parity Check
|
|
104
|
+
|
|
105
|
+
## SDK Integration
|
|
106
|
+
|
|
107
|
+
1. Keep `.so` files in `jniLibs/`, declare `external fun` matching C/C++ signatures
|
|
108
|
+
2. Add latest stable versions to `build.gradle.kts`
|
|
109
|
+
3. Use Version Catalogs (`libs.versions.toml`)
|
|
110
|
+
4. Initialize in `@HiltAndroidApp Application` class
|
|
111
|
+
|
|
112
|
+
## Parity Check (Per-Module)
|
|
113
|
+
|
|
114
|
+
1. **Branch Coverage:** All `if-else`, `when`, `try-catch` paths from Smali
|
|
115
|
+
2. **API Parity:** Same request/response formats
|
|
116
|
+
3. **Data Parity:** Local storage read/write matches
|
|
117
|
+
4. **UI Parity:** Screen-by-screen comparison
|
|
118
|
+
5. **Performance:** R8 rules, Compose stability, coroutine scope management
|