@leejungkiin/awkit 1.4.2 → 1.5.0
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/README.md +32 -9
- package/bin/awk.js +464 -87
- package/bin/claude-generators.js +3 -1
- package/bin/cline-generators.js +3 -1
- package/bin/codex-generators.js +7 -2
- package/core/orchestrator.md +17 -3
- package/core/skill-runtime-manifest.json +37 -0
- package/package.json +2 -2
- package/skill-packs/creator-studio/README.md +19 -0
- package/skill-packs/creator-studio/pack.json +10 -0
- package/skill-packs/marketing/README.md +64 -0
- package/skill-packs/marketing/pack.json +37 -0
- package/skill-packs/mobile-android/README.md +16 -0
- package/skill-packs/mobile-android/pack.json +10 -0
- package/skill-packs/mobile-ios/README.md +22 -0
- package/skill-packs/mobile-ios/pack.json +16 -0
- package/skill-packs/neural-memory/pack.json +8 -2
- package/skill-packs/superpowers/pack.json +1 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/SKILL.md +59 -358
- package/skill-packs/superpowers/skills/writing-skills/SKILL.md +60 -654
- package/skill-packs/superpowers/skills/writing-skills/examples/anti-rationalization.md +75 -0
- package/skill-packs/superpowers/skills/writing-skills/examples/cso-optimization.md +67 -0
- package/skill-packs/superpowers/skills/writing-skills/examples/tdd-for-skills.md +63 -0
- package/skills/CATALOG.md +49 -44
- package/skills/brainstorm-agent/SKILL.md +55 -315
- package/skills/brainstorm-agent/templates/brief-template.md +76 -0
- package/skills/codex-conductor/SKILL.md +55 -259
- package/skills/codex-conductor/examples/prompt-templates.md +72 -0
- package/skills/module-spec-writer/SKILL.md +38 -365
- package/skills/module-spec-writer/examples/port-migration-mode.md +40 -0
- package/skills/module-spec-writer/templates/module-spec-template.md +118 -0
- package/skills/orchestrator/SKILL.md +17 -8
- package/skills/single-flow-task-execution/SKILL.md +56 -363
- package/skills/single-flow-task-execution/examples/workflow-example.md +91 -0
- package/skills/smali-to-kotlin/SKILL.md +23 -416
- 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-swift/SKILL.md +18 -621
- package/skills/smali-to-swift/examples/getting-started/tech-stack.md +72 -0
- package/skills/smali-to-swift/examples/getting-started/toolchain.md +32 -0
- package/skills/smali-to-swift/examples/pipeline/core-logic.md +45 -0
- package/skills/smali-to-swift/examples/pipeline/data-layer.md +76 -0
- package/skills/smali-to-swift/examples/pipeline/framework-scanner.md +73 -0
- package/skills/smali-to-swift/examples/pipeline/project-bootstrap.md +76 -0
- package/skills/smali-to-swift/examples/pipeline/sdk-integration.md +66 -0
- package/skills/smali-to-swift/examples/pipeline/ui-viewmodel.md +96 -0
- package/skills/smali-to-swift/references/objc-to-swift-mapping.md +57 -0
- package/skills/spec-gate/SKILL.md +51 -265
- package/skills/spec-gate/templates/design-templates.md +93 -0
- package/skills/symphony-enforcer/SKILL.md +24 -555
- package/skills/symphony-enforcer/examples/startup-protocol.md +92 -0
- package/skills/symphony-enforcer/examples/task-completion.md +100 -0
- package/skills/symphony-enforcer/examples/three-phase.md +107 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +99 -0
- package/skills/symphony-orchestrator/SKILL.md +1 -1
- package/skills/writing-skills/SKILL.md +82 -70
- package/skills/writing-skills/examples/anti-rationalization.md +53 -0
- package/skills/writing-skills/examples/cso-optimization.md +52 -0
- package/skills/writing-skills/examples/tdd-for-skills.md +48 -0
- package/templates/help.html +447 -0
- package/skills/memory-sync/SKILL.md +0 -424
- package/skills/memory-sync/memory-router.md +0 -185
- package/skills/memory-sync/memory-templates.md +0 -201
|
@@ -6,7 +6,7 @@ description: >-
|
|
|
6
6
|
modern Swift + SwiftUI + Clean Architecture (MVVM).
|
|
7
7
|
Includes framework detection to reuse existing dependencies.
|
|
8
8
|
author: Antigravity Team
|
|
9
|
-
version:
|
|
9
|
+
version: 2.0.0
|
|
10
10
|
trigger: conditional
|
|
11
11
|
activation_keywords:
|
|
12
12
|
- "/reverse-ios"
|
|
@@ -26,11 +26,9 @@ sibling_skill: smali-to-kotlin (Android counterpart)
|
|
|
26
26
|
|
|
27
27
|
# 🍎 Smali-to-Swift Skill
|
|
28
28
|
|
|
29
|
-
> **Purpose:** Transform decrypted iOS IPA
|
|
29
|
+
> **Purpose:** Transform decrypted iOS IPA into a modern Swift app with SwiftUI + Clean Architecture (MVVM).
|
|
30
30
|
> **Philosophy:** "Read ObjC headers to understand WHAT and WHY → Write Swift for HOW."
|
|
31
31
|
|
|
32
|
-
---
|
|
33
|
-
|
|
34
32
|
## ⚠️ SCOPE CLARITY
|
|
35
33
|
|
|
36
34
|
| This skill DOES | This skill DOES NOT |
|
|
@@ -39,13 +37,8 @@ sibling_skill: smali-to-kotlin (Android counterpart)
|
|
|
39
37
|
| Rebuild logic in modern Swift + SwiftUI | Modify original IPA |
|
|
40
38
|
| Detect & reuse third-party frameworks | Crack/bypass DRM or jailbreak |
|
|
41
39
|
| Extract only needed resources (on-demand) | Mass-copy assets blindly |
|
|
42
|
-
| Set up Clean Architecture project structure | Handle Android reverse engineering |
|
|
43
|
-
| Scan IPA frameworks for dependency reuse | Submit to App Store |
|
|
44
40
|
|
|
45
|
-
→
|
|
46
|
-
→ After rebuild complete → use `/test` or `/deploy` workflows
|
|
47
|
-
|
|
48
|
-
---
|
|
41
|
+
→ Android reverse engineering → sibling skill: `smali-to-kotlin`
|
|
49
42
|
|
|
50
43
|
## 🎯 ROLE DEFINITION
|
|
51
44
|
|
|
@@ -57,601 +50,27 @@ When this skill is active, the agent becomes:
|
|
|
57
50
|
> - Knows when to reuse vs rewrite third-party frameworks
|
|
58
51
|
> - Enforces resource-on-demand principle (zero bloat)
|
|
59
52
|
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## 🧰 iOS RE TOOLCHAIN
|
|
63
|
-
|
|
64
|
-
### Decryption & Extraction
|
|
65
|
-
| Tool | Purpose | Output |
|
|
66
|
-
|------|---------|--------|
|
|
67
|
-
| **frida-ios-dump** / **bagbak** | Decrypt IPA from jailbroken device | Decrypted .app bundle |
|
|
68
|
-
| **class-dump** / **class-dump-swift** | Extract ObjC/Swift headers | `.h` header files |
|
|
69
|
-
| **Hopper Disassembler** | ARM disassembly + pseudo-code | Pseudo-C / ARM ASM |
|
|
70
|
-
| **IDA Pro** | Advanced disassembly | Pseudo-C / ARM ASM |
|
|
71
|
-
| **jtool2** | Mach-O analysis, entitlements | Entitlements plist, segments |
|
|
72
|
-
| **plutil / plistutil** | Read binary plists | Readable plist XML |
|
|
73
|
-
|
|
74
|
-
### What we get from an IPA:
|
|
75
|
-
```
|
|
76
|
-
Payload/App.app/
|
|
77
|
-
├── App # Mach-O binary (encrypted → need decrypt first)
|
|
78
|
-
├── Info.plist # App metadata (bundle ID, permissions, URL schemes)
|
|
79
|
-
├── Frameworks/ # Embedded frameworks (.framework / .dylib)
|
|
80
|
-
│ ├── SomeSDK.framework/
|
|
81
|
-
│ └── libswiftCore.dylib
|
|
82
|
-
├── Assets.car # Compiled asset catalog
|
|
83
|
-
├── Base.lproj/ # Storyboards / XIBs (compiled)
|
|
84
|
-
│ ├── Main.storyboardc/
|
|
85
|
-
│ └── LaunchScreen.storyboardc/
|
|
86
|
-
├── *.nib # Compiled XIB files
|
|
87
|
-
├── *.momd # Core Data models (compiled)
|
|
88
|
-
├── embedded.mobileprovision # Provisioning profile
|
|
89
|
-
├── _CodeSignature/ # Code signing
|
|
90
|
-
└── [other resources: json, png, html, js, fonts...]
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## 🏗️ MODERN TECH STACK (Mandatory)
|
|
96
|
-
|
|
97
|
-
### Core
|
|
98
|
-
| Layer | Technology | Replaces |
|
|
99
|
-
|-------|-----------|----------|
|
|
100
|
-
| **UI** | SwiftUI + iOS 17+ | UIKit Storyboards / XIBs |
|
|
101
|
-
| **State** | `@Observable` (Observation framework) | `@ObservableObject` / KVO |
|
|
102
|
-
| **Navigation** | NavigationStack + NavigationPath | UINavigationController / segues |
|
|
103
|
-
| **DI** | Swift DI (protocol + init injection) | Singletons / Service Locators |
|
|
104
|
-
|
|
105
|
-
### Data Layer
|
|
106
|
-
| Purpose | Technology | Replaces |
|
|
107
|
-
|---------|-----------|----------|
|
|
108
|
-
| **Network** | URLSession + async/await | AFNetworking / Alamofire (evaluate) |
|
|
109
|
-
| **JSON** | Codable (Swift built-in) | NSJSONSerialization / Mantle / ObjectMapper |
|
|
110
|
-
| **Local DB** | SwiftData (iOS 17+) or Core Data | Raw SQLite / FMDB / Realm |
|
|
111
|
-
| **Preferences** | UserDefaults / @AppStorage | NSUserDefaults direct |
|
|
112
|
-
| **Keychain** | KeychainAccess (or custom wrapper) | Raw Security.framework |
|
|
113
|
-
| **Image Loading** | AsyncImage / Kingfisher / Nuke | SDWebImage (evaluate) |
|
|
114
|
-
| **Async** | Swift Concurrency (async/await, actors) | GCD / NSOperation / PromiseKit |
|
|
115
|
-
|
|
116
|
-
### Observability
|
|
117
|
-
| Purpose | Technology |
|
|
118
|
-
|---------|-----------|
|
|
119
|
-
| **Crash** | Firebase Crashlytics |
|
|
120
|
-
| **Analytics** | Firebase Analytics |
|
|
121
|
-
| **Logging** | OSLog / swift-log |
|
|
122
|
-
|
|
123
|
-
### Replacements Table (Legacy → Modern)
|
|
124
|
-
|
|
125
|
-
```yaml
|
|
126
|
-
always_replace:
|
|
127
|
-
NSURLConnection: "URLSession async/await"
|
|
128
|
-
AFNetworking: "URLSession async/await"
|
|
129
|
-
NSJSONSerialization: "Codable / JSONDecoder"
|
|
130
|
-
Mantle/ObjectMapper: "Codable"
|
|
131
|
-
GCD_dispatch_async: "Task { } / async-await"
|
|
132
|
-
NSOperation: "TaskGroup / async let"
|
|
133
|
-
NSTimer: "Timer.publish (Combine) or Task.sleep"
|
|
134
|
-
UIAlertView: "SwiftUI .alert modifier"
|
|
135
|
-
UIActionSheet: "SwiftUI .confirmationDialog"
|
|
136
|
-
UITableView: "List / LazyVStack"
|
|
137
|
-
UICollectionView: "LazyVGrid / LazyHGrid"
|
|
138
|
-
UIPageViewController: "TabView with .page style"
|
|
139
|
-
Storyboard_segues: "NavigationStack + NavigationLink"
|
|
140
|
-
NSNotificationCenter_addObserver: "NotificationCenter.notifications (AsyncSequence)"
|
|
141
|
-
KVO: "@Observable macro"
|
|
142
|
-
Delegate_patterns: "AsyncStream or closures"
|
|
143
|
-
Target_Action: "SwiftUI action closures"
|
|
144
|
-
|
|
145
|
-
evaluate_before_replacing:
|
|
146
|
-
Alamofire: "Keep if deeply used for interceptors/retry, otherwise → URLSession"
|
|
147
|
-
SDWebImage: "Replace with AsyncImage + Kingfisher"
|
|
148
|
-
Realm: "Migrate to SwiftData (if iOS 17+)"
|
|
149
|
-
RxSwift: "Migrate to async/await + AsyncSequence (gradual)"
|
|
150
|
-
SnapKit: "Replace with SwiftUI layout"
|
|
151
|
-
Masonry: "Replace with SwiftUI layout"
|
|
152
|
-
MBProgressHUD: "SwiftUI .overlay + ProgressView"
|
|
153
|
-
SVProgressHUD: "SwiftUI .overlay + ProgressView"
|
|
154
|
-
IQKeyboardManager: "SwiftUI handles keyboard automatically"
|
|
155
|
-
|
|
156
|
-
keep_as_is:
|
|
157
|
-
- "Firebase SDKs (use latest via SPM)"
|
|
158
|
-
- "Google Sign-In"
|
|
159
|
-
- "Facebook SDK (latest)"
|
|
160
|
-
- "Apple frameworks (MapKit, CoreLocation, AVFoundation, etc.)"
|
|
161
|
-
- "Native C/C++ libraries (.dylib)"
|
|
162
|
-
- "CryptoKit (Apple native)"
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
53
|
## 📋 EXECUTION PIPELINE (6 Steps)
|
|
168
54
|
|
|
169
55
|
> **Rule:** Always complete one step fully before moving to the next.
|
|
170
56
|
> **Rule:** After each step, create a checkpoint summary for the user.
|
|
171
57
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
**Purpose:** Scan the IPA structure to identify all third-party frameworks before any coding.
|
|
175
|
-
|
|
176
|
-
**Process:**
|
|
177
|
-
1. **Scan `Frameworks/` directory:**
|
|
178
|
-
```
|
|
179
|
-
Frameworks/Alamofire.framework → Alamofire (network)
|
|
180
|
-
Frameworks/SDWebImage.framework → SDWebImage (image loading)
|
|
181
|
-
Frameworks/Realm.framework → Realm (database)
|
|
182
|
-
Frameworks/FBSDKCoreKit.framework → Facebook SDK
|
|
183
|
-
Frameworks/GoogleSignIn.framework → Google Sign-In
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
2. **Scan class-dump headers for imports:**
|
|
187
|
-
```
|
|
188
|
-
#import <AFNetworking/...> → AFNetworking
|
|
189
|
-
#import <Masonry/...> → Masonry (auto-layout)
|
|
190
|
-
#import <MBProgressHUD/...> → MBProgressHUD
|
|
191
|
-
@import Firebase; → Firebase SDK
|
|
192
|
-
@import GoogleMobileAds; → AdMob
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
3. **Check Mach-O linked frameworks:**
|
|
196
|
-
```bash
|
|
197
|
-
otool -L Payload/App.app/App | grep -v /System | grep -v /usr/lib
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
4. **Check embedded dylibs:**
|
|
201
|
-
```bash
|
|
202
|
-
find Payload/App.app -name "*.dylib" -o -name "*.framework" | sort
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
5. **Check for CocoaPods / SPM markers:**
|
|
206
|
-
```
|
|
207
|
-
Pods/ directory presence → was using CocoaPods
|
|
208
|
-
.package.resolved → was using SPM
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
6. **Output: Framework Detection Report**
|
|
212
|
-
```markdown
|
|
213
|
-
## 📦 Framework Detection Report
|
|
214
|
-
|
|
215
|
-
### ✅ Can Reuse (add to Package.swift / Podfile)
|
|
216
|
-
| Framework | Detected | Latest Version | Action |
|
|
217
|
-
|-----------|----------|----------------|--------|
|
|
218
|
-
| Alamofire | Frameworks/Alamofire.framework | 5.9.0 | Evaluate |
|
|
219
|
-
| Kingfisher | (header import) | 7.12.0 | Add via SPM |
|
|
220
|
-
|
|
221
|
-
### 🔄 Must Replace (legacy)
|
|
222
|
-
| Old Framework | Detected | Modern Replacement |
|
|
223
|
-
|---------------|----------|-------------------|
|
|
224
|
-
| AFNetworking | Frameworks/AFNetworking.framework | URLSession async/await |
|
|
225
|
-
| Masonry | header imports | SwiftUI layout |
|
|
226
|
-
|
|
227
|
-
### 🍏 Apple Frameworks Used
|
|
228
|
-
| Framework | Purpose |
|
|
229
|
-
|-----------|---------|
|
|
230
|
-
| MapKit | Maps |
|
|
231
|
-
| CoreLocation | GPS |
|
|
232
|
-
| AVFoundation | Camera/Audio |
|
|
233
|
-
|
|
234
|
-
### 📱 Native (.dylib) — Investigate
|
|
235
|
-
| File | Notes |
|
|
236
|
-
|------|-------|
|
|
237
|
-
| libcrypto.dylib | Custom crypto? |
|
|
238
|
-
|
|
239
|
-
### ❓ Unknown (investigate)
|
|
240
|
-
| Framework/Import | Notes |
|
|
241
|
-
|------------------|-------|
|
|
242
|
-
| CustomSDK.framework | Proprietary? |
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
### Step 1: Info.plist & Entitlements Analysis + Project Bootstrap 📄
|
|
248
|
-
|
|
249
|
-
**Input:** User provides `Info.plist` + entitlements from IPA.
|
|
250
|
-
|
|
251
|
-
**Tasks:**
|
|
252
|
-
1. Extract Bundle ID and display name
|
|
253
|
-
2. List required permissions (Privacy keys):
|
|
254
|
-
```
|
|
255
|
-
NSCameraUsageDescription → Camera
|
|
256
|
-
NSPhotoLibraryUsageDescription → Photo Library
|
|
257
|
-
NSLocationWhenInUseUsageDescription → Location
|
|
258
|
-
NSMicrophoneUsageDescription → Microphone
|
|
259
|
-
```
|
|
260
|
-
3. Identify URL Schemes (deep links)
|
|
261
|
-
4. Check app capabilities from entitlements:
|
|
262
|
-
```
|
|
263
|
-
com.apple.developer.associated-domains → Universal Links
|
|
264
|
-
aps-environment → Push Notifications
|
|
265
|
-
com.apple.developer.in-app-payments → Apple Pay
|
|
266
|
-
```
|
|
267
|
-
5. Analyze class-dump headers for entry points:
|
|
268
|
-
- `AppDelegate` → lifecycle logic
|
|
269
|
-
- Root ViewController → initial screen
|
|
270
|
-
- Tab bar / Navigation structure
|
|
271
|
-
6. **Output:** Propose Clean Architecture project structure
|
|
272
|
-
|
|
273
|
-
**Project Structure Template:**
|
|
274
|
-
```
|
|
275
|
-
App/
|
|
276
|
-
├── App.swift # @main entry point
|
|
277
|
-
├── AppDelegate.swift # UIKit lifecycle (if needed for SDKs)
|
|
278
|
-
├── Info.plist
|
|
279
|
-
├── Assets.xcassets/
|
|
280
|
-
├── DI/ # Dependency Injection
|
|
281
|
-
│ └── AppContainer.swift
|
|
282
|
-
├── Data/ # Data Layer
|
|
283
|
-
│ ├── Network/
|
|
284
|
-
│ │ ├── APIClient.swift # URLSession wrapper
|
|
285
|
-
│ │ ├── Endpoints/ # API endpoint definitions
|
|
286
|
-
│ │ └── DTOs/ # Codable response models
|
|
287
|
-
│ ├── Local/
|
|
288
|
-
│ │ ├── SwiftDataModels/ # @Model classes
|
|
289
|
-
│ │ ├── KeychainService.swift
|
|
290
|
-
│ │ └── UserDefaultsKeys.swift
|
|
291
|
-
│ └── Repositories/ # Repository implementations
|
|
292
|
-
├── Domain/ # Domain Layer
|
|
293
|
-
│ ├── Models/ # Business models
|
|
294
|
-
│ ├── Repositories/ # Repository protocols
|
|
295
|
-
│ └── UseCases/
|
|
296
|
-
├── Presentation/ # Presentation Layer
|
|
297
|
-
│ ├── Navigation/
|
|
298
|
-
│ │ ├── AppNavigation.swift # NavigationStack + routes
|
|
299
|
-
│ │ └── Route.swift # Deep link routes
|
|
300
|
-
│ ├── Theme/
|
|
301
|
-
│ │ ├── AppTheme.swift # Colors, fonts, spacing
|
|
302
|
-
│ │ └── Components/ # Reusable SwiftUI components
|
|
303
|
-
│ └── Screens/
|
|
304
|
-
│ ├── Launch/
|
|
305
|
-
│ │ └── LaunchScreen.swift
|
|
306
|
-
│ ├── Auth/
|
|
307
|
-
│ │ ├── LoginScreen.swift
|
|
308
|
-
│ │ └── LoginViewModel.swift
|
|
309
|
-
│ ├── Home/
|
|
310
|
-
│ │ ├── HomeScreen.swift
|
|
311
|
-
│ │ └── HomeViewModel.swift
|
|
312
|
-
│ └── ...
|
|
313
|
-
├── Utilities/
|
|
314
|
-
│ ├── Extensions/
|
|
315
|
-
│ ├── Crypto/ # Encryption/hashing utils
|
|
316
|
-
│ └── Helpers/
|
|
317
|
-
└── Resources/
|
|
318
|
-
├── Localizable.xcstrings
|
|
319
|
-
└── Fonts/
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
### Step 2: Data Layer Reconstruction 💾
|
|
325
|
-
|
|
326
|
-
**Input:** User provides class-dump headers + Hopper pseudo-code for network/data classes.
|
|
327
|
-
|
|
328
|
-
**Tasks:**
|
|
329
|
-
1. **Models:** Convert ObjC interfaces → Swift structs
|
|
330
|
-
```objc
|
|
331
|
-
// ObjC header (class-dump)
|
|
332
|
-
@interface UserModel : NSObject
|
|
333
|
-
@property (nonatomic, copy) NSString *userId;
|
|
334
|
-
@property (nonatomic, copy) NSString *fullName;
|
|
335
|
-
@property (nonatomic, assign) NSInteger age;
|
|
336
|
-
@end
|
|
337
|
-
```
|
|
338
|
-
```swift
|
|
339
|
-
// Swift
|
|
340
|
-
struct User: Codable, Identifiable {
|
|
341
|
-
let id: String
|
|
342
|
-
let fullName: String
|
|
343
|
-
let age: Int
|
|
344
|
-
|
|
345
|
-
enum CodingKeys: String, CodingKey {
|
|
346
|
-
case id = "user_id"
|
|
347
|
-
case fullName = "full_name"
|
|
348
|
-
case age
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
2. **API Layer:**
|
|
354
|
-
- Extract base URL, endpoints, headers from disassembly
|
|
355
|
-
- Create async URLSession-based API client:
|
|
356
|
-
```swift
|
|
357
|
-
actor APIClient {
|
|
358
|
-
private let session: URLSession
|
|
359
|
-
private let baseURL: URL
|
|
360
|
-
|
|
361
|
-
func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T {
|
|
362
|
-
let (data, response) = try await session.data(for: endpoint.urlRequest(baseURL: baseURL))
|
|
363
|
-
guard let httpResponse = response as? HTTPURLResponse,
|
|
364
|
-
(200...299).contains(httpResponse.statusCode) else {
|
|
365
|
-
throw APIError.invalidResponse
|
|
366
|
-
}
|
|
367
|
-
return try JSONDecoder().decode(T.self, from: data)
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
3. **Local Storage:**
|
|
373
|
-
- CoreData models → SwiftData `@Model` classes
|
|
374
|
-
- NSUserDefaults keys → `@AppStorage` or typed UserDefaults wrapper
|
|
375
|
-
- Keychain items → KeychainAccess wrapper
|
|
376
|
-
|
|
377
|
-
4. **Repository:**
|
|
378
|
-
```swift
|
|
379
|
-
// Domain layer - protocol
|
|
380
|
-
protocol UserRepository: Sendable {
|
|
381
|
-
func getUser(id: String) async throws -> User
|
|
382
|
-
func login(email: String, password: String) async throws -> AuthToken
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Data layer - implementation
|
|
386
|
-
final class UserRepositoryImpl: UserRepository {
|
|
387
|
-
private let apiClient: APIClient
|
|
388
|
-
private let modelContext: ModelContext
|
|
389
|
-
|
|
390
|
-
func getUser(id: String) async throws -> User {
|
|
391
|
-
// offline-first: check local → fetch remote → cache
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
### Step 3: Core Logic & Utils Reconstruction 🧮
|
|
58
|
+
**Identify the topic** from the user's request and load the corresponding file:
|
|
399
59
|
|
|
400
|
-
|
|
60
|
+
### Getting Started
|
|
61
|
+
- RE Toolchain & IPA structure → `examples/getting-started/toolchain.md`
|
|
62
|
+
- Modern tech stack & legacy replacements → `examples/getting-started/tech-stack.md`
|
|
401
63
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
64
|
+
### Pipeline Steps
|
|
65
|
+
- **Step 0** Framework Scanner (ALWAYS FIRST) → `examples/pipeline/framework-scanner.md`
|
|
66
|
+
- **Step 1** Info.plist + Project Bootstrap → `examples/pipeline/project-bootstrap.md`
|
|
67
|
+
- **Step 2** Data Layer Reconstruction → `examples/pipeline/data-layer.md`
|
|
68
|
+
- **Step 3** Core Logic & Crypto → `examples/pipeline/core-logic.md`
|
|
69
|
+
- **Step 4** UI & ViewModel (Per Screen) → `examples/pipeline/ui-viewmodel.md`
|
|
70
|
+
- **Step 5-6** SDK Integration + Parity Check → `examples/pipeline/sdk-integration.md`
|
|
407
71
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
// ObjC (class-dump + disassembly)
|
|
411
|
-
+ (NSString *)md5Hash:(NSString *)input;
|
|
412
|
-
+ (NSData *)aesEncrypt:(NSData *)data withKey:(NSString *)key;
|
|
413
|
-
```
|
|
414
|
-
```swift
|
|
415
|
-
// Swift
|
|
416
|
-
import CryptoKit
|
|
417
|
-
import CommonCrypto
|
|
418
|
-
|
|
419
|
-
enum CryptoUtils {
|
|
420
|
-
static func md5Hash(_ input: String) -> String {
|
|
421
|
-
let data = Data(input.utf8)
|
|
422
|
-
var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
|
|
423
|
-
data.withUnsafeBytes { CC_MD5($0.baseAddress, CC_LONG(data.count), &digest) }
|
|
424
|
-
return digest.map { String(format: "%02x", $0) }.joined()
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
static func aesEncrypt(data: Data, key: String) throws -> Data {
|
|
428
|
-
// Implement matching original algorithm exactly
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
3. **Verification:** XCTest unit tests with known input/output pairs
|
|
434
|
-
|
|
435
|
-
**Critical Rule:**
|
|
436
|
-
> ⚠️ Crypto/hash functions MUST produce identical output to the original app.
|
|
437
|
-
> Test with known pairs captured from the running original app.
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
### Step 4: UI & ViewModel Reconstruction (Per Screen) 🎨
|
|
442
|
-
|
|
443
|
-
**Input:** Storyboard analysis + class-dump headers for ViewControllers.
|
|
444
|
-
|
|
445
|
-
**Tasks:**
|
|
446
|
-
1. **Resource Extraction (On-Demand):**
|
|
447
|
-
- Extract only images, colors, strings for current screen
|
|
448
|
-
- Use Asset Catalog for organized resources
|
|
449
|
-
- Map ObjC string tables to `Localizable.xcstrings`
|
|
450
|
-
|
|
451
|
-
2. **UIKit → SwiftUI Migration:**
|
|
452
|
-
```
|
|
453
|
-
UIViewController → SwiftUI View struct
|
|
454
|
-
UINavigationController → NavigationStack
|
|
455
|
-
UITabBarController → TabView
|
|
456
|
-
UITableView → List / LazyVStack
|
|
457
|
-
UICollectionView → LazyVGrid / LazyHGrid
|
|
458
|
-
UIScrollView → ScrollView
|
|
459
|
-
UIImageView → AsyncImage / Image
|
|
460
|
-
UILabel → Text
|
|
461
|
-
UITextField → TextField
|
|
462
|
-
UIButton → Button
|
|
463
|
-
UIActivityIndicatorView → ProgressView
|
|
464
|
-
UIAlertController → .alert / .confirmationDialog modifier
|
|
465
|
-
UIPageViewController → TabView(.page)
|
|
466
|
-
UIStackView → VStack / HStack
|
|
467
|
-
MKMapView → Map (MapKit SwiftUI)
|
|
468
|
-
WKWebView → WebView (custom wrapper)
|
|
469
|
-
UIRefreshControl → .refreshable modifier
|
|
470
|
-
UISearchController → .searchable modifier
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
3. **ViewModel Creation:**
|
|
474
|
-
```swift
|
|
475
|
-
@Observable
|
|
476
|
-
final class LoginViewModel {
|
|
477
|
-
var email = ""
|
|
478
|
-
var password = ""
|
|
479
|
-
var isLoading = false
|
|
480
|
-
var error: String?
|
|
481
|
-
|
|
482
|
-
private let loginUseCase: LoginUseCase
|
|
483
|
-
|
|
484
|
-
init(loginUseCase: LoginUseCase) {
|
|
485
|
-
self.loginUseCase = loginUseCase
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
func login() async {
|
|
489
|
-
isLoading = true
|
|
490
|
-
defer { isLoading = false }
|
|
491
|
-
do {
|
|
492
|
-
try await loginUseCase.execute(email: email, password: password)
|
|
493
|
-
} catch {
|
|
494
|
-
self.error = error.localizedDescription
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
4. **Screen Composable:**
|
|
501
|
-
```swift
|
|
502
|
-
struct LoginScreen: View {
|
|
503
|
-
@State private var viewModel: LoginViewModel
|
|
504
|
-
|
|
505
|
-
init(loginUseCase: LoginUseCase) {
|
|
506
|
-
_viewModel = State(initialValue: LoginViewModel(loginUseCase: loginUseCase))
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
var body: some View {
|
|
510
|
-
Form {
|
|
511
|
-
TextField("Email", text: $viewModel.email)
|
|
512
|
-
.textContentType(.emailAddress)
|
|
513
|
-
.keyboardType(.emailAddress)
|
|
514
|
-
|
|
515
|
-
SecureField("Password", text: $viewModel.password)
|
|
516
|
-
.textContentType(.password)
|
|
517
|
-
|
|
518
|
-
Button("Login") {
|
|
519
|
-
Task { await viewModel.login() }
|
|
520
|
-
}
|
|
521
|
-
.disabled(viewModel.isLoading)
|
|
522
|
-
}
|
|
523
|
-
.overlay { if viewModel.isLoading { ProgressView() } }
|
|
524
|
-
.alert("Error", isPresented: .constant(viewModel.error != nil)) {
|
|
525
|
-
Button("OK") { viewModel.error = nil }
|
|
526
|
-
} message: {
|
|
527
|
-
Text(viewModel.error ?? "")
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
---
|
|
534
|
-
|
|
535
|
-
### Step 5: Third-party SDK & Native Library Integration 📦
|
|
536
|
-
|
|
537
|
-
**Input:** Framework Report from Step 0.
|
|
538
|
-
|
|
539
|
-
**Tasks:**
|
|
540
|
-
1. **Swift Package Manager setup:**
|
|
541
|
-
```swift
|
|
542
|
-
// Package.swift dependencies (or Xcode SPM UI)
|
|
543
|
-
dependencies: [
|
|
544
|
-
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "11.0.0"),
|
|
545
|
-
.package(url: "https://github.com/onevcat/Kingfisher", from: "7.12.0"),
|
|
546
|
-
.package(url: "https://github.com/kishikawakatsumi/KeychainAccess", from: "4.2.2"),
|
|
547
|
-
]
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
2. **Native C/C++ libraries:**
|
|
551
|
-
```swift
|
|
552
|
-
// Bridging header for C libraries
|
|
553
|
-
// App-Bridging-Header.h
|
|
554
|
-
#include "native_crypto.h"
|
|
555
|
-
|
|
556
|
-
// Swift usage
|
|
557
|
-
func callNativeFunction() -> String {
|
|
558
|
-
let result = native_function_name(param)
|
|
559
|
-
return String(cString: result)
|
|
560
|
-
}
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
3. **App lifecycle for SDK init:**
|
|
564
|
-
```swift
|
|
565
|
-
@main
|
|
566
|
-
struct MyApp: App {
|
|
567
|
-
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
|
568
|
-
|
|
569
|
-
var body: some Scene {
|
|
570
|
-
WindowGroup {
|
|
571
|
-
ContentView()
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
class AppDelegate: NSObject, UIApplicationDelegate {
|
|
577
|
-
func application(_ application: UIApplication,
|
|
578
|
-
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
579
|
-
FirebaseApp.configure()
|
|
580
|
-
// Other SDK initialization
|
|
581
|
-
return true
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
---
|
|
587
|
-
|
|
588
|
-
### Step 6: Parity Check & Quality Gate ✅
|
|
589
|
-
|
|
590
|
-
**Per-module checklist:**
|
|
591
|
-
1. **Branch Coverage:** Review all conditional paths from disassembly
|
|
592
|
-
2. **API Parity:** Same requests/responses as original
|
|
593
|
-
3. **Data Parity:** Crypto output matches, local storage compatible
|
|
594
|
-
4. **UI Parity:** Screen-by-screen comparison
|
|
595
|
-
5. **Performance:**
|
|
596
|
-
- Instruments profiling
|
|
597
|
-
- No unnecessary @State re-renders
|
|
598
|
-
- Proper actor isolation (no data races)
|
|
599
|
-
|
|
600
|
-
---
|
|
601
|
-
|
|
602
|
-
## 🔍 ObjC HEADER READING GUIDE
|
|
603
|
-
|
|
604
|
-
### Property Types → Swift
|
|
605
|
-
```objc
|
|
606
|
-
@property (nonatomic, copy) NSString *name; // → let name: String
|
|
607
|
-
@property (nonatomic, strong) NSArray *items; // → let items: [Any] (refine type)
|
|
608
|
-
@property (nonatomic, assign) BOOL isActive; // → let isActive: Bool
|
|
609
|
-
@property (nonatomic, assign) NSInteger count; // → let count: Int
|
|
610
|
-
@property (nonatomic, assign) CGFloat height; // → let height: CGFloat
|
|
611
|
-
@property (nonatomic, strong) NSDictionary *meta; // → let meta: [String: Any]
|
|
612
|
-
@property (nonatomic, strong) NSDate *createdAt; // → let createdAt: Date
|
|
613
|
-
@property (nonatomic, strong) NSURL *imageURL; // → let imageURL: URL?
|
|
614
|
-
@property (nonatomic, strong) NSData *data; // → let data: Data
|
|
615
|
-
@property (nullable, nonatomic, copy) NSString *bio; // → let bio: String?
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
### Method Signatures → Swift
|
|
619
|
-
```objc
|
|
620
|
-
- (void)fetchUserWithId:(NSString *)userId completion:(void (^)(UserModel *, NSError *))completion;
|
|
621
|
-
// → func fetchUser(id: String) async throws -> User
|
|
622
|
-
|
|
623
|
-
+ (instancetype)sharedInstance;
|
|
624
|
-
// → static let shared = ClassName()
|
|
625
|
-
|
|
626
|
-
- (BOOL)validateEmail:(NSString *)email;
|
|
627
|
-
// → func validateEmail(_ email: String) -> Bool
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
### Delegate Patterns → Swift
|
|
631
|
-
```objc
|
|
632
|
-
@protocol UserServiceDelegate <NSObject>
|
|
633
|
-
- (void)userServiceDidFetchUser:(UserModel *)user;
|
|
634
|
-
- (void)userServiceDidFailWithError:(NSError *)error;
|
|
635
|
-
@end
|
|
636
|
-
```
|
|
637
|
-
```swift
|
|
638
|
-
// Replace with async/await:
|
|
639
|
-
func fetchUser() async throws -> User
|
|
640
|
-
// Or AsyncStream for multiple values:
|
|
641
|
-
func userUpdates() -> AsyncStream<User>
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### Blocks → Closures / async
|
|
645
|
-
```objc
|
|
646
|
-
typedef void (^CompletionHandler)(NSData * _Nullable data, NSError * _Nullable error);
|
|
647
|
-
- (void)requestWithCompletion:(CompletionHandler)completion;
|
|
648
|
-
```
|
|
649
|
-
```swift
|
|
650
|
-
// Modern Swift: drop the callback, use async
|
|
651
|
-
func request() async throws -> Data
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
---
|
|
72
|
+
### Reference
|
|
73
|
+
- ObjC → Swift type mapping → `references/objc-to-swift-mapping.md`
|
|
655
74
|
|
|
656
75
|
## 🔄 WORKFLOW INTEGRATION
|
|
657
76
|
|
|
@@ -669,14 +88,8 @@ works_with:
|
|
|
669
88
|
- memory-sync — saves decisions, patterns, solutions
|
|
670
89
|
- orchestrator — routes to this skill based on intent
|
|
671
90
|
- ios-engineer — shares iOS knowledge base
|
|
672
|
-
|
|
673
|
-
independent_from:
|
|
674
|
-
- brainstorm-agent
|
|
675
|
-
- smali-to-kotlin (sibling, same pattern, different platform)
|
|
676
91
|
```
|
|
677
92
|
|
|
678
|
-
---
|
|
679
|
-
|
|
680
93
|
## 🚫 ANTI-PATTERNS
|
|
681
94
|
|
|
682
95
|
```yaml
|
|
@@ -686,7 +99,7 @@ never_do:
|
|
|
686
99
|
- Use GCD dispatch_async for new code → use async/await
|
|
687
100
|
- Use NSJSONSerialization → use Codable
|
|
688
101
|
- Modify encryption output → must match original exactly
|
|
689
|
-
- Create massive ViewController God objects → split into
|
|
102
|
+
- Create massive ViewController God objects → split into Views + ViewModels
|
|
690
103
|
- Skip framework scanner step → always detect reusable dependencies first
|
|
691
104
|
- Use ObjC in new code → Swift only (except bridging headers for C libs)
|
|
692
105
|
- Force unwrap optionals → use guard let / if let / nil coalescing
|
|
@@ -702,37 +115,22 @@ always_do:
|
|
|
702
115
|
- Use SPM for dependency management (not CocoaPods)
|
|
703
116
|
```
|
|
704
117
|
|
|
705
|
-
---
|
|
706
|
-
|
|
707
118
|
## 📊 CHECKPOINT TEMPLATE
|
|
708
119
|
|
|
709
120
|
After each step, output:
|
|
710
121
|
|
|
711
122
|
```markdown
|
|
712
123
|
## ✅ Step [N] Complete: [Step Name]
|
|
713
|
-
|
|
714
124
|
### What was done:
|
|
715
125
|
- [Summary]
|
|
716
|
-
|
|
717
126
|
### Files created:
|
|
718
127
|
- [List]
|
|
719
|
-
|
|
720
|
-
### Resources extracted:
|
|
721
|
-
- [Only what was needed]
|
|
722
|
-
|
|
723
|
-
### Decisions made:
|
|
724
|
-
- [Key decisions]
|
|
725
|
-
|
|
726
128
|
### ⏭️ Next: Step [N+1] — [Step Name]
|
|
727
129
|
- [What user needs to provide]
|
|
728
130
|
```
|
|
729
131
|
|
|
730
|
-
---
|
|
731
|
-
|
|
732
132
|
## 🧩 PLATFORM RE TEMPLATE PATTERN
|
|
733
133
|
|
|
734
|
-
This skill follows the same **6-step pipeline** as `smali-to-kotlin`:
|
|
735
|
-
|
|
736
134
|
| Step | Android (smali-to-kotlin) | iOS (smali-to-swift) |
|
|
737
135
|
|------|--------------------------|---------------------|
|
|
738
136
|
| 0 | Library Scanner (Smali packages) | Framework Scanner (Frameworks/ + headers) |
|
|
@@ -745,5 +143,4 @@ This skill follows the same **6-step pipeline** as `smali-to-kotlin`:
|
|
|
745
143
|
|
|
746
144
|
---
|
|
747
145
|
|
|
748
|
-
*smali-to-swift
|
|
749
|
-
*Created by Antigravity Team*
|
|
146
|
+
*smali-to-swift v2.0.0 — Modular Router Architecture*
|