@leejungkiin/awkit 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +3 -3
  2. package/VERSION +1 -1
  3. package/bin/awf.js +1 -1
  4. package/bin/awk.js +237 -26
  5. package/core/AGENTS.md +8 -9
  6. package/core/GEMINI.md +74 -199
  7. package/package.json +3 -2
  8. package/skill-packs/neural-memory/skills/nm-memory-sync/SKILL.md +2 -2
  9. package/skills/CATALOG.md +3 -2
  10. package/skills/README.md +109 -0
  11. package/skills/android-re-analyzer/SKILL.md +238 -0
  12. package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
  13. package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
  14. package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
  15. package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
  16. package/skills/android-re-analyzer/references/setup-guide.md +221 -0
  17. package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
  18. package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
  19. package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
  20. package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
  21. package/skills/awf-session-restore/SKILL.md +108 -184
  22. package/skills/beads-manager/SKILL.md +2 -2
  23. package/skills/brainstorm-agent/SKILL.md +47 -2
  24. package/skills/gemini-conductor/SKILL.md +234 -0
  25. package/skills/memory-sync/SKILL.md +29 -1
  26. package/skills/nm-memory-sync/SKILL.md +2 -2
  27. package/skills/orchestrator/SKILL.md +29 -155
  28. package/skills/skills/nm-memory-sync/SKILL.md +2 -2
  29. package/skills/smali-to-kotlin/SKILL.md +1 -1
  30. package/skills/smali-to-swift/SKILL.md +1 -1
  31. package/skills/swiftui-pro/SKILL.md +108 -0
  32. package/skills/swiftui-pro/agents/openai.yaml +10 -0
  33. package/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  34. package/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  35. package/skills/swiftui-pro/references/accessibility.md +13 -0
  36. package/skills/swiftui-pro/references/api.md +39 -0
  37. package/skills/swiftui-pro/references/data.md +43 -0
  38. package/skills/swiftui-pro/references/design.md +31 -0
  39. package/skills/swiftui-pro/references/hygiene.md +9 -0
  40. package/skills/swiftui-pro/references/navigation.md +14 -0
  41. package/skills/swiftui-pro/references/performance.md +46 -0
  42. package/skills/swiftui-pro/references/swift.md +56 -0
  43. package/skills/swiftui-pro/references/views.md +35 -0
  44. package/skills/symphony-enforcer/SKILL.md +362 -0
  45. package/skills/symphony-orchestrator/SKILL.md +301 -0
  46. package/skills/telegram-notify/SKILL.md +57 -0
  47. package/symphony/LICENSE +21 -0
  48. package/symphony/README.md +178 -0
  49. package/symphony/app/api/agents/route.js +152 -0
  50. package/symphony/app/api/events/route.js +22 -0
  51. package/symphony/app/api/knowledge/route.js +253 -0
  52. package/symphony/app/api/locks/route.js +29 -0
  53. package/symphony/app/api/notes/route.js +125 -0
  54. package/symphony/app/api/preflight/route.js +23 -0
  55. package/symphony/app/api/projects/route.js +116 -0
  56. package/symphony/app/api/roles/route.js +134 -0
  57. package/symphony/app/api/skills/route.js +82 -0
  58. package/symphony/app/api/status/route.js +18 -0
  59. package/symphony/app/api/tasks/route.js +157 -0
  60. package/symphony/app/api/workflows/route.js +61 -0
  61. package/symphony/app/api/workspaces/route.js +15 -0
  62. package/symphony/app/globals.css +2605 -0
  63. package/symphony/app/layout.js +20 -0
  64. package/symphony/app/page.js +2122 -0
  65. package/symphony/cli/index.js +1060 -0
  66. package/symphony/core/agent-manager.js +357 -0
  67. package/symphony/core/context-bus.js +100 -0
  68. package/symphony/core/db.js +223 -0
  69. package/symphony/core/file-lock-manager.js +154 -0
  70. package/symphony/core/merge-pipeline.js +234 -0
  71. package/symphony/core/orchestrator.js +236 -0
  72. package/symphony/core/task-manager.js +335 -0
  73. package/symphony/core/workspace-manager.js +168 -0
  74. package/symphony/jsconfig.json +7 -0
  75. package/symphony/lib/core.mjs +1034 -0
  76. package/symphony/mcp/index.js +29 -0
  77. package/symphony/mcp/server.js +110 -0
  78. package/symphony/mcp/tools/context.js +80 -0
  79. package/symphony/mcp/tools/locks.js +99 -0
  80. package/symphony/mcp/tools/status.js +82 -0
  81. package/symphony/mcp/tools/tasks.js +216 -0
  82. package/symphony/mcp/tools/workspace.js +143 -0
  83. package/symphony/next.config.mjs +7 -0
  84. package/symphony/package.json +53 -0
  85. package/symphony/scripts/postinstall.js +49 -0
  86. package/symphony/symphony.config.js +41 -0
  87. package/templates/conductor-tracks.md +38 -0
  88. package/templates/specs/PROJECT.md +50 -0
  89. package/templates/specs/ROADMAP.md +79 -0
  90. package/templates/specs/TECH-SPEC.md +81 -0
  91. package/templates/specs/task-spec-template.xml +65 -0
  92. package/templates/workflow_dual_mode_template.md +5 -5
  93. package/workflows/_uncategorized/AGENTS.md +38 -0
  94. package/workflows/_uncategorized/decompile.md +67 -0
  95. package/workflows/_uncategorized/skill-health.md +7 -7
  96. package/workflows/ads/ads-audit.md +5 -5
  97. package/workflows/ads/ads-optimize.md +10 -10
  98. package/workflows/ads/adsExpert.md +7 -7
  99. package/workflows/conductor.md +97 -0
  100. package/workflows/context/auto-implement.md +4 -4
  101. package/workflows/context/codebase-sync.md +19 -8
  102. package/workflows/context/next.md +27 -27
  103. package/workflows/context/user-intent-analysis-workflow.md +4 -4
  104. package/workflows/expert/codeExpert.md +28 -31
  105. package/workflows/expert/debugExpert.md +11 -11
  106. package/workflows/expert/planExpert.md +21 -36
  107. package/workflows/git/smart-git-ops.md +49 -6
  108. package/workflows/lifecycle/debug.md +7 -7
  109. package/workflows/lifecycle/deploy.md +10 -10
  110. package/workflows/lifecycle/init.md +103 -91
  111. package/workflows/lifecycle/master-code-workflow.md +3 -3
  112. package/workflows/lifecycle/plan.md +19 -21
  113. package/workflows/quality/audit.md +1 -1
  114. package/workflows/quality/project-audit.md +1 -1
  115. package/workflows/roles/vibe-coding-master-workflow.md +2 -2
  116. package/workflows/smart-git-ops.md +146 -0
  117. package/workflows/ui/app-screen-analyzer.md +4 -4
  118. package/workflows/ui/create-feature.md +8 -8
  119. package/workflows/ui/create-spec-architect.md +11 -11
@@ -0,0 +1,448 @@
1
+ #!/usr/bin/env bash
2
+ # install-dep.sh — Install a single dependency for Android reverse engineering
3
+ # Usage: install-dep.sh <dependency>
4
+ # Dependencies: java, jadx, vineflower, dex2jar, apktool, adb
5
+ #
6
+ # Exit codes:
7
+ # 0 — installed successfully
8
+ # 1 — installation failed
9
+ # 2 — requires manual action (e.g. sudo needed but not available)
10
+ set -euo pipefail
11
+
12
+ usage() {
13
+ cat <<EOF
14
+ Usage: install-dep.sh <dependency>
15
+
16
+ Install a dependency required for Android reverse engineering.
17
+
18
+ Available dependencies:
19
+ java Java JDK 17+
20
+ jadx jadx decompiler
21
+ vineflower Vineflower (Fernflower fork) decompiler
22
+ dex2jar DEX to JAR converter
23
+ apktool Android resource decoder
24
+ adb Android Debug Bridge
25
+
26
+ The script detects your OS and package manager, then:
27
+ - Installs directly if possible (brew, or user-local install)
28
+ - Uses sudo if available and needed
29
+ - Prints manual instructions if neither option works
30
+ EOF
31
+ exit 0
32
+ }
33
+
34
+ if [[ $# -lt 1 || "$1" == "-h" || "$1" == "--help" ]]; then
35
+ usage
36
+ fi
37
+
38
+ DEP="$1"
39
+
40
+ # --- Detect environment ---
41
+ OS="unknown"
42
+ PKG_MANAGER="none"
43
+ HAS_SUDO=false
44
+ ARCH=$(uname -m)
45
+
46
+ case "$(uname -s)" in
47
+ Linux) OS="linux" ;;
48
+ Darwin) OS="macos" ;;
49
+ esac
50
+
51
+ # Detect package manager
52
+ if command -v brew &>/dev/null; then
53
+ PKG_MANAGER="brew"
54
+ elif command -v apt-get &>/dev/null; then
55
+ PKG_MANAGER="apt"
56
+ elif command -v dnf &>/dev/null; then
57
+ PKG_MANAGER="dnf"
58
+ elif command -v pacman &>/dev/null; then
59
+ PKG_MANAGER="pacman"
60
+ fi
61
+
62
+ # Check sudo availability
63
+ if command -v sudo &>/dev/null; then
64
+ if sudo -n true 2>/dev/null; then
65
+ HAS_SUDO=true
66
+ else
67
+ # sudo exists but may need password — we'll try it and let it prompt
68
+ HAS_SUDO=true
69
+ fi
70
+ fi
71
+
72
+ info() { echo "[INFO] $*"; }
73
+ ok() { echo "[OK] $*"; }
74
+ fail() { echo "[FAIL] $*" >&2; }
75
+ manual() {
76
+ echo "[MANUAL] $*" >&2
77
+ echo " Cannot install automatically. Please install manually and retry." >&2
78
+ exit 2
79
+ }
80
+
81
+ # --- Helper: install via system package manager (needs sudo on Linux) ---
82
+ pkg_install() {
83
+ local pkg="$1"
84
+ case "$PKG_MANAGER" in
85
+ brew)
86
+ info "Installing $pkg via Homebrew..."
87
+ brew install "$pkg"
88
+ ;;
89
+ apt)
90
+ if [[ "$HAS_SUDO" == true ]]; then
91
+ info "Installing $pkg via apt..."
92
+ sudo apt-get update -qq && sudo apt-get install -y -qq "$pkg"
93
+ else
94
+ manual "Run: sudo apt-get install $pkg"
95
+ fi
96
+ ;;
97
+ dnf)
98
+ if [[ "$HAS_SUDO" == true ]]; then
99
+ info "Installing $pkg via dnf..."
100
+ sudo dnf install -y "$pkg"
101
+ else
102
+ manual "Run: sudo dnf install $pkg"
103
+ fi
104
+ ;;
105
+ pacman)
106
+ if [[ "$HAS_SUDO" == true ]]; then
107
+ info "Installing $pkg via pacman..."
108
+ sudo pacman -S --noconfirm "$pkg"
109
+ else
110
+ manual "Run: sudo pacman -S $pkg"
111
+ fi
112
+ ;;
113
+ *)
114
+ manual "No supported package manager found. Install $pkg manually."
115
+ ;;
116
+ esac
117
+ }
118
+
119
+ # --- Helper: download a file ---
120
+ download() {
121
+ local url="$1" dest="$2"
122
+ if command -v curl &>/dev/null; then
123
+ curl -fsSL -o "$dest" "$url"
124
+ elif command -v wget &>/dev/null; then
125
+ wget -q -O "$dest" "$url"
126
+ else
127
+ fail "Neither curl nor wget available."
128
+ return 1
129
+ fi
130
+ }
131
+
132
+ # --- Helper: get latest GitHub release tag ---
133
+ gh_latest_tag() {
134
+ local repo="$1"
135
+ local url="https://api.github.com/repos/$repo/releases/latest"
136
+ if command -v curl &>/dev/null; then
137
+ curl -fsSL "$url" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/'
138
+ elif command -v wget &>/dev/null; then
139
+ wget -q -O - "$url" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/'
140
+ fi
141
+ }
142
+
143
+ # --- Helper: add a line to shell profile if not already present ---
144
+ add_to_profile() {
145
+ local line="$1"
146
+ local profile=""
147
+ if [[ -f "$HOME/.zshrc" ]]; then
148
+ profile="$HOME/.zshrc"
149
+ elif [[ -f "$HOME/.bashrc" ]]; then
150
+ profile="$HOME/.bashrc"
151
+ elif [[ -f "$HOME/.profile" ]]; then
152
+ profile="$HOME/.profile"
153
+ fi
154
+
155
+ if [[ -n "$profile" ]]; then
156
+ if ! grep -qF "$line" "$profile" 2>/dev/null; then
157
+ echo "$line" >> "$profile"
158
+ info "Added to $profile: $line"
159
+ info "Run 'source $profile' or start a new shell to apply."
160
+ fi
161
+ else
162
+ info "Add this to your shell profile: $line"
163
+ fi
164
+ }
165
+
166
+ # =====================================================================
167
+ # Dependency installers
168
+ # =====================================================================
169
+
170
+ install_java() {
171
+ if command -v java &>/dev/null; then
172
+ local ver
173
+ ver=$(java -version 2>&1 | head -1 | sed -n 's/.*"\([0-9]*\)\..*/\1/p')
174
+ if [[ -n "$ver" ]] && (( ver >= 17 )); then
175
+ ok "Java $ver already installed"
176
+ return 0
177
+ fi
178
+ fi
179
+
180
+ info "Installing Java JDK 17+..."
181
+ case "$PKG_MANAGER" in
182
+ brew) brew install openjdk@17 ;;
183
+ apt) pkg_install "openjdk-17-jdk" ;;
184
+ dnf) pkg_install "java-17-openjdk-devel" ;;
185
+ pacman) pkg_install "jdk17-openjdk" ;;
186
+ *) manual "Install Java JDK 17+ from https://adoptium.net/" ;;
187
+ esac
188
+
189
+ # Verify
190
+ if command -v java &>/dev/null; then
191
+ ok "Java installed: $(java -version 2>&1 | head -1)"
192
+ else
193
+ fail "Java installation may require PATH update."
194
+ if [[ "$PKG_MANAGER" == "brew" ]]; then
195
+ add_to_profile 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"'
196
+ fi
197
+ exit 1
198
+ fi
199
+ }
200
+
201
+ install_jadx() {
202
+ if command -v jadx &>/dev/null; then
203
+ ok "jadx already installed: $(jadx --version 2>/dev/null || echo 'unknown')"
204
+ return 0
205
+ fi
206
+
207
+ # Try brew first (cleanest)
208
+ if [[ "$PKG_MANAGER" == "brew" ]]; then
209
+ info "Installing jadx via Homebrew..."
210
+ brew install jadx
211
+ ok "jadx installed via Homebrew"
212
+ return 0
213
+ fi
214
+
215
+ # User-local install from GitHub releases (no sudo needed)
216
+ info "Installing jadx from GitHub releases..."
217
+ local tag
218
+ tag=$(gh_latest_tag "skylot/jadx")
219
+ if [[ -z "$tag" ]]; then
220
+ fail "Could not determine latest jadx version."
221
+ manual "Download from https://github.com/skylot/jadx/releases/latest"
222
+ fi
223
+
224
+ local version="${tag#v}"
225
+ local url="https://github.com/skylot/jadx/releases/download/${tag}/jadx-${version}.zip"
226
+ local tmp_zip
227
+ tmp_zip=$(mktemp /tmp/jadx-XXXXXX.zip)
228
+
229
+ info "Downloading jadx $version..."
230
+ download "$url" "$tmp_zip"
231
+
232
+ local install_dir="$HOME/.local/share/jadx"
233
+ rm -rf "$install_dir"
234
+ mkdir -p "$install_dir"
235
+ unzip -qo "$tmp_zip" -d "$install_dir"
236
+ rm -f "$tmp_zip"
237
+ chmod +x "$install_dir/bin/jadx" "$install_dir/bin/jadx-gui" 2>/dev/null || true
238
+
239
+ # Add to PATH
240
+ mkdir -p "$HOME/.local/bin"
241
+ ln -sf "$install_dir/bin/jadx" "$HOME/.local/bin/jadx"
242
+ ln -sf "$install_dir/bin/jadx-gui" "$HOME/.local/bin/jadx-gui"
243
+ export PATH="$HOME/.local/bin:$PATH"
244
+ add_to_profile 'export PATH="$HOME/.local/bin:$PATH"'
245
+
246
+ if command -v jadx &>/dev/null; then
247
+ ok "jadx $version installed to $install_dir"
248
+ else
249
+ ok "jadx $version installed to $install_dir"
250
+ info "Run: export PATH=\"\$HOME/.local/bin:\$PATH\" to use it now"
251
+ fi
252
+ }
253
+
254
+ install_vineflower() {
255
+ # Check if already available
256
+ if command -v vineflower &>/dev/null || command -v fernflower &>/dev/null; then
257
+ ok "Vineflower/Fernflower CLI already installed"
258
+ return 0
259
+ fi
260
+ for candidate in \
261
+ "${FERNFLOWER_JAR_PATH:-}" \
262
+ "$HOME/vineflower/vineflower.jar" \
263
+ "$HOME/fernflower/fernflower.jar" \
264
+ "$HOME/fernflower/build/libs/fernflower.jar" \
265
+ "$HOME/vineflower/build/libs/vineflower.jar"; do
266
+ if [[ -n "$candidate" ]] && [[ -f "$candidate" ]]; then
267
+ ok "Vineflower/Fernflower JAR already exists: $candidate"
268
+ return 0
269
+ fi
270
+ done
271
+
272
+ # Try brew
273
+ if [[ "$PKG_MANAGER" == "brew" ]]; then
274
+ info "Installing vineflower via Homebrew..."
275
+ if brew install vineflower 2>/dev/null; then
276
+ ok "Vineflower installed via Homebrew"
277
+ return 0
278
+ fi
279
+ info "Homebrew formula not available, falling back to direct download."
280
+ fi
281
+
282
+ # Download JAR from GitHub releases (no sudo needed)
283
+ info "Installing Vineflower from GitHub releases..."
284
+ local tag
285
+ tag=$(gh_latest_tag "Vineflower/vineflower")
286
+ if [[ -z "$tag" ]]; then
287
+ fail "Could not determine latest Vineflower version."
288
+ manual "Download from https://github.com/Vineflower/vineflower/releases/latest"
289
+ fi
290
+
291
+ local version="${tag#v}"
292
+ local url="https://github.com/Vineflower/vineflower/releases/download/${tag}/vineflower-${version}.jar"
293
+ local install_dir="$HOME/.local/share/vineflower"
294
+ mkdir -p "$install_dir"
295
+
296
+ info "Downloading Vineflower $version..."
297
+ download "$url" "$install_dir/vineflower.jar"
298
+
299
+ # Create wrapper script
300
+ mkdir -p "$HOME/.local/bin"
301
+ cat > "$HOME/.local/bin/vineflower" <<'WRAPPER'
302
+ #!/usr/bin/env bash
303
+ exec java -jar "$HOME/.local/share/vineflower/vineflower.jar" "$@"
304
+ WRAPPER
305
+ chmod +x "$HOME/.local/bin/vineflower"
306
+
307
+ export PATH="$HOME/.local/bin:$PATH"
308
+ export FERNFLOWER_JAR_PATH="$install_dir/vineflower.jar"
309
+ add_to_profile 'export PATH="$HOME/.local/bin:$PATH"'
310
+ add_to_profile "export FERNFLOWER_JAR_PATH=\"$install_dir/vineflower.jar\""
311
+
312
+ ok "Vineflower $version installed to $install_dir/vineflower.jar"
313
+ info "FERNFLOWER_JAR_PATH set to $install_dir/vineflower.jar"
314
+ }
315
+
316
+ install_dex2jar() {
317
+ if command -v d2j-dex2jar &>/dev/null || command -v d2j-dex2jar.sh &>/dev/null; then
318
+ ok "dex2jar already installed"
319
+ return 0
320
+ fi
321
+
322
+ # Try brew
323
+ if [[ "$PKG_MANAGER" == "brew" ]]; then
324
+ info "Installing dex2jar via Homebrew..."
325
+ if brew install dex2jar 2>/dev/null; then
326
+ ok "dex2jar installed via Homebrew"
327
+ return 0
328
+ fi
329
+ info "Homebrew formula not available, falling back to direct download."
330
+ fi
331
+
332
+ # Download from GitHub (no sudo needed)
333
+ info "Installing dex2jar from GitHub releases..."
334
+ local tag
335
+ tag=$(gh_latest_tag "pxb1988/dex2jar")
336
+ if [[ -z "$tag" ]]; then
337
+ # Fallback: pxb1988 hasn't released in a while, try known version
338
+ tag="v2.4"
339
+ fi
340
+
341
+ local version="${tag#v}"
342
+ local url="https://github.com/pxb1988/dex2jar/releases/download/${tag}/dex-tools-${version}.zip"
343
+ local tmp_zip
344
+ tmp_zip=$(mktemp /tmp/dex2jar-XXXXXX.zip)
345
+
346
+ info "Downloading dex2jar $version..."
347
+ if ! download "$url" "$tmp_zip"; then
348
+ # Try alternate naming
349
+ url="https://github.com/pxb1988/dex2jar/releases/download/${tag}/dex-tools-v${version}.zip"
350
+ download "$url" "$tmp_zip" || {
351
+ fail "Download failed."
352
+ manual "Download from https://github.com/pxb1988/dex2jar/releases/latest"
353
+ }
354
+ fi
355
+
356
+ local install_dir="$HOME/.local/share/dex2jar"
357
+ rm -rf "$install_dir"
358
+ mkdir -p "$install_dir"
359
+ unzip -qo "$tmp_zip" -d "$install_dir"
360
+ rm -f "$tmp_zip"
361
+
362
+ # The zip may contain a top-level directory — find the actual bin location
363
+ local bin_dir=""
364
+ if [[ -f "$install_dir/d2j-dex2jar.sh" ]]; then
365
+ bin_dir="$install_dir"
366
+ else
367
+ bin_dir=$(find "$install_dir" -name "d2j-dex2jar.sh" -exec dirname {} \; | head -1)
368
+ fi
369
+
370
+ if [[ -z "$bin_dir" ]]; then
371
+ fail "Could not find d2j-dex2jar.sh in extracted archive."
372
+ manual "Download and extract manually from https://github.com/pxb1988/dex2jar/releases"
373
+ fi
374
+
375
+ chmod +x "$bin_dir"/*.sh 2>/dev/null || true
376
+
377
+ mkdir -p "$HOME/.local/bin"
378
+ for script in "$bin_dir"/d2j-*.sh; do
379
+ local name
380
+ name=$(basename "$script" .sh)
381
+ ln -sf "$script" "$HOME/.local/bin/$name"
382
+ done
383
+
384
+ export PATH="$HOME/.local/bin:$PATH"
385
+ add_to_profile 'export PATH="$HOME/.local/bin:$PATH"'
386
+
387
+ ok "dex2jar $version installed to $install_dir"
388
+ }
389
+
390
+ install_apktool() {
391
+ if command -v apktool &>/dev/null; then
392
+ ok "apktool already installed"
393
+ return 0
394
+ fi
395
+
396
+ case "$PKG_MANAGER" in
397
+ brew) info "Installing apktool via Homebrew..."; brew install apktool ;;
398
+ apt) pkg_install "apktool" ;;
399
+ *) manual "Install apktool from https://apktool.org/docs/install" ;;
400
+ esac
401
+
402
+ if command -v apktool &>/dev/null; then
403
+ ok "apktool installed"
404
+ else
405
+ fail "apktool installation may have failed."
406
+ exit 1
407
+ fi
408
+ }
409
+
410
+ install_adb() {
411
+ if command -v adb &>/dev/null; then
412
+ ok "adb already installed"
413
+ return 0
414
+ fi
415
+
416
+ case "$PKG_MANAGER" in
417
+ brew) info "Installing adb via Homebrew..."; brew install android-platform-tools ;;
418
+ apt) pkg_install "adb" ;;
419
+ dnf) pkg_install "android-tools" ;;
420
+ pacman) pkg_install "android-tools" ;;
421
+ *) manual "Install Android SDK Platform Tools from https://developer.android.com/tools/releases/platform-tools" ;;
422
+ esac
423
+
424
+ if command -v adb &>/dev/null; then
425
+ ok "adb installed"
426
+ else
427
+ fail "adb installation may have failed."
428
+ exit 1
429
+ fi
430
+ }
431
+
432
+ # =====================================================================
433
+ # Dispatch
434
+ # =====================================================================
435
+
436
+ case "$DEP" in
437
+ java) install_java ;;
438
+ jadx) install_jadx ;;
439
+ vineflower|fernflower) install_vineflower ;;
440
+ dex2jar) install_dex2jar ;;
441
+ apktool) install_apktool ;;
442
+ adb) install_adb ;;
443
+ *)
444
+ echo "Error: Unknown dependency '$DEP'" >&2
445
+ echo "Available: java, jadx, vineflower, dex2jar, apktool, adb" >&2
446
+ exit 1
447
+ ;;
448
+ esac