README.id.md
September 13, 2026 · View on GitHub
DSH Android
Perangkat Android langsung di dalam percakapan DeepSeek Harness — emulator atau ponsel USB, digerakkan sepenuhnya melalui adb.
20 alat agen • aliran langsung dalam proses, tanpa helper eksternal • panel navigasi tiga tombol • build & jalankan Gradle • Vision OCR
npm: @zseven-w/dsh-android · Rilis plugin saat ini: 0.1.0-rc.4 · Diuji dengan DSH 0.1.1-rc.1
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Deutsch · Português · Русский · हिन्दी · Türkçe · ไทย · Tiếng Việt · Bahasa Indonesia
Perangkat Android yang dialirkan dan dikendalikan dari dalam percakapan DSH — panggilan alat agen di tengah, panel perangkat langsung di kanan
Mengapa DSH Android
DSH Android memberi agen perangkat Android sungguhan di dalam percakapan — dan memberi Anda pikselnya. Agen dapat memulai aliran pada emulator atau ponsel yang terhubung USB, membangun dan memasang proyek Gradle, menggerakkan UI lewat resource-id/teks atau lewat OCR, membaca logcat, serta memeriksa proses dan memori, sementara aliran langsung perangkat dirender di panel samping persisten tempat Anda bisa mengetuk, menyeret, memutar, dan menekan Back / Home / Recents langsung pada video. Tanpa blok gambar dan tanpa file rekaman layar: byte visual hanya mencapai UI melalui URL bertanda tangan dan kedaluwarsa yang disajikan server web DSH.
Hanya ada satu jalur kode. adb devices -l melaporkan sebuah serial, dan serial itulah satu-satunya identitas sebuah perangkat — emulator-5554, serial USB, atau target ip:port semuanya berperilaku identik. Plugin ini tidak terikat pada produk emulator mana pun (AVD, Genymotion, WSA, ladang perangkat awan), dan tidak ada pemisahan simulator/perangkat asli yang perlu dipikirkan.
| 📱 Perangkat langsung dalam percakapan | Aliran PNG multipart/x-mixed-replace yang diproduksi dalam proses dan disajikan langsung dari buffer bingkai terbaru melalui rute /_dsh/dsh-android/* bertanda tangan. |
| 🔌 Tanpa helper aliran eksternal, tanpa port internal | Satu proses anak adb exec-out persisten menjalankan while :; do screencap -p; done; host sendiri yang memecah PNG bersambung menjadi bingkai. Tidak ada server aliran loopback untuk diproksikan, tidak ada rentang port untuk dikelola, dan tidak ada apa pun untuk diadopsi setelah keluar secara kasar. |
| 🧩 Satu jalur kode adb | Emulator dan ponsel adalah hal yang sama bagi adb maupun bagi plugin ini. Tanpa tumpukan ganda simctl/WebDriverAgent, tanpa ritual build-dan-percayai sebelum perangkat fisik bisa dipakai. |
| 🛠️ 20 alat agen | Perangkat, nyalakan/matikan, tangkapan layar, interaksi, build & jalankan Gradle, pencantuman/peluncuran aplikasi, pohon UI uiautomator + ketuk per elemen, aksi baris daftar/umpan, temukan/ketuk/tunggu teks dengan Vision OCR, logcat, proses, backtrace ANR/crash, meminfo, info aplikasi. |
| 👆 Panel navigasi tiga tombol | Ketuk dan seret pada video langsung; bilah alat dengan ◁ Back · ○ Home · □ Recents plus putar, tangkapan layar, dan segarkan; menu perangkat untuk panel notifikasi, pengaturan cepat, kunci, bangunkan, dan asisten. |
| 🖼️ Multimodal bawaan | Pada model yang mampu memproses gambar, setiap alat penangkap (screenshot, interact, tap_element, tap_text, tap_row) mengembalikan tangkapan layar ITU SENDIRI sebagai image block — model melihat layar secara langsung. OCR tetap ada untuk ketukan teks berpresisi piksel dan rute khusus teks; model khusus teks tetap menerima ringkasan JSON biasa. |
| 🔐 Rute bertanda tangan khusus loopback | Setiap rute mewajibkan peer loopback, Host loopback (DNS rebinding ditolak), dan pemeriksaan Fetch-Metadata/Origin — sebelum kapabilitas apa pun diperiksa. Kapabilitas HMAC-SHA256 kedaluwarsa dalam 10 menit. |
| 🔍 Otomasi semantik + visual | android_ui_tree membuang hierarki uiautomator dan android_tap_element mengetuk berdasarkan resource-id, teks, atau content-description; saat pohon kosong atau teksnya tercetak di dalam gambar, android_find_text / android_tap_text meng-OCR layar alih-alih menebak koordinat. |
Alat
Ke-20 alat terdaftar di setiap host dan hanya mengembalikan JSON polos — byte visual hanya mencapai UI melalui presentationMeta + rute bertanda tangan, tidak pernah sebagai blok gambar. Saat adb tidak dapat diselesaikan, alat tetap terdaftar dan setiap panggilan gagal dengan error penjelas yang menyebutkan cara memperbaikinya.
Koordinat selalu ternormalisasi 0..1 terhadap bingkai yang dialirkan. Bingkai mengikuti rotasi layar (aplikasi lanskap dialirkan 2400×1080 pada perangkat 1080×2400) dan input tap berbagi ruang yang sama, sehingga tidak ada perhitungan rotasi di sisi klien di mana pun dalam plugin ini.
Alat inti
| Alat | Fungsinya | Parameter utama |
|---|---|---|
android_devices | Mencantumkan setiap perangkat yang dilaporkan adb devices -l (serial, status, emulator/fisik, model, versi Android, level API, nama AVD) plus nama AVD di mesin ini di bawah avds. Gunakan untuk menemukan serial yang diterima alat lain. Enumerasi yang gagal melempar error alih-alih mengembalikan daftar kosong. | — |
android_boot | Memulai aliran langsung. Teruskan serial yang ONLINE untuk langsung mengalirkannya, atau nama AVD untuk meluncurkan emulator itu lebih dulu lalu mengalirkannya setelah selesai boot (bisa beberapa menit saat mulai dingin). Aliran tetap hidup selama percakapan sehingga panel dapat menampilkan perangkat secara langsung. | device (wajib — sebuah serial atau nama AVD) |
android_shutdown | Mematikan emulator (adb emu kill) dan menghentikan aliran bila aliran menarget perangkat tersebut. Perangkat fisik ditolak beserta alasannya: adb tidak dapat mematikan daya sebuah ponsel. | device |
android_screenshot | Menangkap PNG dan mengembalikan ringkasan JSON singkat (path, byte, dimensi, perangkat); gambar dirender di kartu dan panel, tidak pernah sebagai blok gambar. | device (opsional — perangkat yang dialirkan, jika tidak maka satu-satunya yang daring) |
android_interact | Berinteraksi dengan perangkat yang dialirkan: ketuk pada koordinat ternormalisasi 0..1, ketik teks, tekan tombol navigasi atau perangkat keras (back, home, recents, power, volume_up, volume_down, menu, enter, delete), kirim gestur usap, atau gulir. Setelah aksi tenang (~300 ms) tangkapan layar baru memperlihatkan efeknya. | action (wajib — tap/type/button/gesture/scroll), x/y, text, name, json, device |
android_list_apps | Mencantumkan paket yang terpasang pada perangkat (pm list packages), lengkap dengan nama versi dari dumpsys package dan label manusiawi bila dapat diselesaikan — nama paket pihak ketiga tidak dapat ditebak, jadi cantumkan dulu atau teruskan name ke android_launch_app. | device, query (substring tanpa membedakan huruf besar/kecil, termasuk CJK), include_system (default false) |
android_launch_app | Meluncurkan aplikasi terpasang lewat packageName, atau lewat name (substring label tanpa membedakan huruf besar/kecil, diselesaikan lewat pencantuman yang sama). Tepat salah satu dari keduanya. relaunch menghentikan paksa aplikasi lebih dulu. | packageName atau name (tepat satu), device, relaunch |
android_build_run | Membangun proyek Gradle (./gradlew assembleDebug), memasang APK debug hasilnya (adb install -r), dan meluncurkannya. Build penuh memakan waktu beberapa menit; saat gagal, hasilnya memuat ekor keluaran error Gradle. | projectPath (wajib), device |
Alat pohon UI dan baris (uiautomator)
| Alat | Fungsinya | Parameter utama |
|---|---|---|
android_ui_tree | Membuang hierarki uiautomator dari aplikasi terdepan sebagai node — type (ekor nama kelas), text, contentDesc, resourceId, bounds dalam piksel, enabled, focused — dibatasi ~40 KB (level terdalam dipangkas dan truncated disetel). | device, max_depth, filter (substring tanpa membedakan huruf besar/kecil pada teks/content-description/resource-id) |
android_tap_element | Mengetuk elemen berdasarkan identitas — resource_id cocok dengan resource-id node; text cocok dengan teks atau content-description-nya. Cocok persis dulu, lalu substring tanpa membedakan huruf besar/kecil; duplikat bersarang diciutkan menjadi satu target dan kecocokan ambigu mencantumkan hingga 8 kandidat alih-alih memilih salah satu. Elemen yang nonaktif ditolak. Ketukan mendarat di tengah elemen, lalu tangkapan layar ~300 ms memperlihatkan efeknya; teruskan expect_text / expect_gone dan ketukan beserta verifikasinya menjadi satu perjalanan pulang-pergi. | device, resource_id, text, expect_text, expect_gone |
android_ui_rows | Membaca layar daftar/umpan (RecyclerView dan kerabatnya) sebagai BARIS, bukan pohon mentah: anak-anak berbentuk sama yang berulang menjadi baris yang membawa indeks, frame dalam piksel, label gabungan, dan penghitung yang diurai dari label itu (angka + token pengklasifikasi, bahasa Tionghoa atau Inggris — tanpa kosakata aplikasi yang dikodekan). Kunci penghitung dapat bolak-balik: teruskan sebuah kunci persis seperti yang tercantum ke android_tap_row.expect_count. | device, max_depth |
android_tap_row | Mengetuk pada posisi relatif di dalam satu baris yang terlihat (index dari android_ui_rows; x/y sebagai pecahan frame baris itu, default 0.5 = tengah). Frame berasal dari pembacaan pohon yang SEGAR, jadi tidak ada koordinat absolut yang ditebak, dan indeks di luar rentang GAGAL alih-alih dijepit. Dengan expect_count={key, delta} alat membaca ulang baris setelah ~800 ms dan memverifikasi penghitung bergeser tepat ±1; kunci yang tidak dikenal MENOLAK ketukan sebelum terjadi. | device, index (wajib), x, y, expect_count ({key, delta}) |
Alat OCR, log, dan debug
| Alat | Fungsinya | Parameter utama |
|---|---|---|
android_find_text | Meng-OCR layar SAAT INI dengan helper Vision yang dikompilasi plugin (pengenalan akurat, zh-Hans + en-US). Gunakan saat pohon UI kosong atau menurun, untuk teks yang dirender sebagai grafis (angka badge, harga yang tercetak dalam gambar), atau untuk memverifikasi secara independen apa yang ada di layar. Mengembalikan {device, size, items:[{text, confidence, rect}]} dengan rect berupa kotak piksel berasal kiri-atas, terurut berdasarkan keyakinan dan dibatasi ~40 KB. Khusus host macOS. | device, query (substring tanpa membedakan huruf besar/kecil), min_confidence (default 0.3) |
android_tap_text | Meng-OCR layar SAAT INI dan mengetuk pusat kecocokan teks terbaik — aturan persis → mengandung → daftar kandidat yang sama seperti android_tap_element, untuk teks yang tidak terlihat pohon UI. Pusat piksel yang cocok dinormalisasi terhadap ukuran bingkai lalu dikirim sebagai ketukan; setelah ~300 ms tangkapan layar baru memperlihatkan efeknya. Khusus host macOS. | device, query (wajib), min_confidence, expect_text, expect_gone |
android_wait_for | Menunggu sampai sebuah teks muncul atau hilang, mem-polling pipeline tangkap + OCR yang sama setiap 600 ms hingga kondisinya terpenuhi atau waktu habis (bawaan 8 dtk, maks. 60 dtk). Timeout adalah jawaban normal matched:false, tidak pernah error. Khusus host macOS. | device, text (wajib), mode (appear/disappear), timeout_ms, min_confidence |
android_logs | Membaca apa yang dicatat perangkat: snapshot (logcat -d -v time pada jendela waktu terakhir, default 2m) atau follow (tangkapan langsung terbatas selama duration_seconds, default 10, maksimal 60 — tidak pernah aliran yang menggantung). Saring ke satu aplikasi dengan bundle_id (nama paket Android, diselesaikan menjadi pid-nya). Output dibatasi ~300 baris / 30 KB dengan petunjuk penyempitan. | device, mode (snapshot/follow), duration, duration_seconds, bundle_id, grep |
android_processes | Mencantumkan proses yang berjalan pada perangkat (ps -A) sebagai {pid, name} — sumber pid untuk android_backtrace. | device, filter (substring tanpa membedakan huruf besar/kecil pada nama proses) |
android_backtrace | Meminta proses membuang tumpukannya (kill -3) dan membaca jejak ANR hasilnya dari /data/anr/. Sebagian besar perangkat non-root menolak direktori itu, sehingga alat menurun ke buffer crash (logcat -b crash -d) dan melaporkan secara jujur mesin mana yang menjawab serta apa yang tidak dapat dilihatnya. | device, pid atau bundle_id |
android_meminfo | Mengurai dumpsys meminfo <package>: total PSS, pembagian Java/native/grafis, dan kategori teratas — jawaban Android untuk ringkasan kebocoran. | device, bundle_id (wajib) |
android_app_info | Fakta aplikasi terpasang dari dumpsys package <package>: nama dan kode versi, direktori data, path kode, waktu pemasangan pertama, dan tanda sistem. Aplikasi yang tidak ada mengembalikan installed: false plus catatan yang menyebut android_list_apps — bukan melempar error. | device, bundle_id (wajib) |
Permukaan tampilan
- Panel samping. Tampilan langsung berada di panel kanan persisten (dok tetap yang menyingkirkan percakapan, atau hamparan terpusat pada viewport sempit). Panel merender aliran PNG langsung dan menerima klik-untuk-mengetuk serta seret-untuk-gestur langsung pada video, dengan bilah alat yang memuat ◁ Back, ○ Home, □ Recents, putar, tangkapan layar, dan segarkan. Menu perangkat menjalankan lima aksi tingkat perangkat (panel notifikasi, pengaturan cepat, kunci, bangunkan, asisten). Pemilih perangkat mencantumkan setiap perangkat adb dalam SATU daftar, dikelompokkan menurut jenis, dengan AVD yang luring ditampilkan sebagai petunjuk yang mengarah ke
android_bootalih-alih boot-saat-diklik. Mode ukuran dan gaya bingkai (tanpa bingkai / bezel / cangkang ponsel) bekerja seperti pada kembaran iOS-nya; panel menyesuaikan rasio aspeknya dari ukuran alami bingkai itu sendiri, sehingga rotasi tidak butuh konfigurasi apa pun. - Kartu percakapan ringkas. Hasil alat dirender sebagai kartu satu baris tanpa citra sebaris: nama perangkat, sublabel aksi, lencana status, dan isyarat “buka di panel samping”. Mengeklik baris membuka panel.
- Kapsul status di atas input. Saat panel tertutup dan sebuah aliran daring, pil kecil muncul di atas kolom input dan membuka panel saat diklik.
- Mode standar dan Mode Code. Sesi standar memakai
presentationMetayang diproyeksikan host; dispatch Mode Code bersarang tidak membawa meta, jadi klien merekonstruksi meta yang identik dari JSON hasil yang tahan lama — panel, kartu, dan kapsul bekerja di kedua mode.
Keamanan
- Peramban tidak pernah berbicara dengan adb, dan tidak ada port internal untuk diajak bicara. Aliran diproduksi di dalam proses ini dan disajikan dari memori; setiap byte melintasi origin server web DSH melalui rute
/_dsh/dsh-android/*milik plugin:/stream/<token>(PNG multipart langsung),/screenshot/<token>(PNG ter-cache), plus/grant,/switch-device,/devices,/capture,/status,/control, dan/device-action. Ini adalah permukaan serangan yang jelas lebih kecil daripada server aliran loopback yang diproksikan. - Pagar loopback rangkap tiga, diterapkan sebelum kapabilitas apa pun dibaca. Peer transport harus berupa alamat loopback, header
Hostharus menyebut otoritas loopback (sehinggaHostDNS-rebinding ditolak), dan Fetch-Metadata/Originharus same-origin. Host dan Origin adalah data yang dikendalikan pemanggil dan tidak pernah dipercaya begitu saja. - Kapabilitas HMAC-SHA256 yang kedaluwarsa dalam 10 menit, berformat
base64url(payload).base64url(mac)dan ditandatangani dengan kunci 32 byte per-rumah-DSH (<DSH_HOME>/cache/dsh-android/stream-access.key, mode 0600, dibuat secara atomik). Kapabilitas yang dicetak untuk satu perangkat berhenti bekerja begitu perangkat lain mengambil slot aliran, dan kapabilitas tangkapan layar tidak dapat diputar ulang terhadap rute aliran. - Rute tangkapan layar hanya menyajikan tepat satu direktori. Path ditelusuri dengan
lstat(tautan simbolis apa pun ditolak), diakhiri pemeriksaan pembendunganrealpath, dibuka denganO_NOFOLLOW, dibatasi ukurannya, dan divalidasi ulang setelah pembacaan — sehingga file yang ditukar menjadi symlink antara pencetakan dan pengambilan tidak pernah disajikan. /granttidak pernah mem-boot apa pun. Ia hanya memulai loop bingkai untuk perangkat yang sudah daring, dan menolak (409device_busy) merebut aliran dari perangkat lain. Berpindah perangkat menuntut gestur/switch-deviceyang eksplisit; mem-boot AVD tetap menjadi urusan alatandroid_boot.- Keep-alive dan berhenti saat idle. Loop bingkai yang crash dimulai ulang di latar belakang (~5 dtk jeda); tanpa konsumen, aliran berhenti sendiri setelah 5 menit. Penghentian yang disengaja tidak pernah dilawan.
Persyaratan
- Node ≥ 24.11.0.
- adb, dari platform-tools Android SDK, diselesaikan dalam urutan ini: variabel lingkungan
ADB→adbdiPATH→<ANDROID_HOME>/<ANDROID_SDK_ROOT>/akar SDK bawaan per OS +/platform-tools/adb. Pasang dengansdkmanager "platform-tools", dengan Android Studio, atau denganbrew install --cask android-platform-tools. Tanpa adb, plugin tetap dimuat dan ke-20 alat terdaftar; setiap panggilan lalu menjelaskan apa yang kurang. - Sebuah perangkat: emulator produk apa pun, atau ponsel dengan USB debugging aktif. Peluncur
emulatorbersifat opsional dan hanyaandroid_boot-lewat-nama-AVD yang membutuhkannya — selebihnya bekerja dengan apa pun yang bisa dilihat adb. - DSH ≥ 0.1.0-rc.6 dengan bundel web untuk panel. Profil headless juga bekerja: ke-20 alat berfungsi normal, hanya tanpa tampilan langsung.
- Host macOS untuk OCR (hanya
android_find_text/android_tap_text/android_wait_foryang membutuhkannya): plugin mengompilasiassets/ocr.swiftbawaannya denganswiftcpada pemakaian pertama ke~/Library/Caches/dsh-android/bin/ocr. Pada host Linux dan Windows, ketiga alat itu melaporkan bahwa OCR membutuhkan framework Vision macOS; 17 alat lainnya tidak terpengaruh. Penimpaan:DSHPLUGIN_ANDROID_OCR_DIR,DSHPLUGIN_ANDROID_OCR_SWIFT,DSHPLUGIN_ANDROID_SWIFTC. - ADBKeyboard (opsional, untuk masukan CJK dan emoji):
adb shell input texthanya mendukung ASCII. Pasang ADBKeyboard di perangkat dan pilih sebagai IME aktif, maka teks non-ASCII dikirim melalui antarmuka broadcast-nya. Tanpanya, pengetikan non-ASCII DITOLAK beserta petunjuk pemasangan — tidak pernah salah ketik secara diam-diam.
Perangkat fisik
Tidak ada padanan WebDriverAgent yang harus dibangun, ditandatangani, dipercaya, atau ditandatangani ulang setiap tujuh hari. Aktifkan USB debugging, colokkan ponselnya, terima permintaan otorisasi di perangkat, dan ia muncul di android_devices dengan setiap alat bekerja terhadapnya. Perangkat yang tidak terotorisasi dilaporkan apa adanya beserta petunjuk permintaannya, bukan sebagai kegagalan misterius.
Tiga catatan jujur:
- Laju bingkai lebih rendah lewat USB — kira-kira 2–5 fps pada ponsel dibanding 5–10 fps pada emulator, karena setiap bingkai melintasi tautan USB sebagai PNG utuh.
- Pengetikan CJK butuh ADBKeyboard (lihat di atas); ini berlaku sama untuk emulator maupun ponsel.
android_shutdowntidak dapat mematikan daya ponsel. adb tidak punya kata kerja semacam itu; alat mengatakannya terus terang alih-alih berpura-pura.
Performa
Diukur pada emulator (Android 14, 1080×2400):
| Loop screencap persisten | ≈ 8 fps |
Bingkai pertama ensureStreaming | ~200 ms |
Perjalanan pulang-pergi input tap | ~130 ms |
Satu proses anak persisten itulah yang membelinya: memunculkan satu adb per bingkai memakan ~50–100 ms sebelum ada piksel yang bergerak. Harapkan ~5–10 fps pada emulator dan ~2–5 fps pada ponsel USB, tergantung mesin dan kerapatan layarnya.
Pasang di DSH
dsh plugin --profile web add @zseven-w/dsh-android@latest
dsh web
Atau tambahkan sebagai dependensi paket profil yang sudah ada:
pnpm add @zseven-w/dsh-android
Mulai cepat
- Temukan perangkat — “Cantumkan perangkat Android.” →
android_devices. - Mulai aliran — “Alirkan emulator-5554.” →
android_boot. Panel terbuka dengan perangkat tampil langsung. (Nama AVD akan mem-boot emulator itu lebih dulu.) - Ketuk pada video — ketuk atau seret langsung pada panel, atau biarkan agen yang menggerakkan: “Buka Pengaturan, lalu ketuk Display.” →
android_interact, atauandroid_ui_tree+android_tap_elementuntuk ketukan berbasis identitas, atauandroid_find_text+android_tap_textsaat pohonnya buta. - Build dan jalankan aplikasi Anda — “Build dan jalankan /path/to/MyApp.” →
android_build_run. Build Gradle penuh memakan waktu beberapa menit; saat selesai, aplikasi diluncurkan dan Anda menontonnya langsung di panel. - Baca log — “Tampilkan dua menit terakhir logcat untuk com.example.app.” →
android_logs.
Pemecahan masalah
- Semua alat mengatakan adb tidak tersedia — pesan errornya menyebutkan ketiga tingkat resolusi. Setel
ADB=/path/to/adb, taruhadbdiPATH, atau pasang platform-tools SDK (sdkmanager "platform-tools"). - Perangkat berstatus
unauthorized— terima permintaan USB debugging di layar perangkat.android_devicesmelaporkan statusnya secara jujur alih-alih menyembunyikan perangkatnya. android_boottidak menemukan AVD — peluncuremulatortidak dapat ditemukan. Jalankan emulator dengan cara apa pun; ia muncul diandroid_devicesbegitu adb melihatnya, danandroid_bootlalu memakai serialnya.- Teks non-ASCII ditolak — pasang ADBKeyboard dan pilih sebagai metode masukan (lihat Persyaratan). Penolakan itu disengaja:
input textakan membuang atau merusak karakternya secara diam-diam. android_find_textmengatakan OCR tidak tersedia — OCR butuh host macOS (framework Vision milik Apple). Ke-17 alat non-OCR bekerja di mana saja.- Aliran berhenti sendiri — itu kebijakan idle, bukan crash: tanpa konsumen (panel tertutup, tidak ada kartu terpasang, tidak ada rute aktif) aliran berhenti setelah 5 menit dan dimulai ulang pada panggilan alat berikutnya atau saat panel dibuka. Loop yang crash dimulai ulang sendiri dalam ~5 detik.
- Rotasi tampak salah di launcher — launcher dan Pengaturan mengunci dirinya ke potret dan mengabaikan
user_rotation. Itu perilaku normal Android, bukan bug plugin; putarlah di dalam aplikasi yang mengizinkannya.
Pengembangan
pnpm install
pnpm run build # host tsc + client bundle → lib/
pnpm run typecheck
pnpm test # every static suite; no device required
Pengujian asap di scripts/ melatih lib/ yang telah dibangun. Semuanya statis kecuali dev-emulator-smoke.mjs, yang butuh perangkat dan melaporkan SKIP (exit 0) saat tidak ada.
| Skrip | Cakupannya |
|---|---|
node scripts/dev-adb-smoke.mjs | Resolusi adb (env / PATH / SDK) terhadap biner shim, penguraian devices -l, exec-out yang aman untuk biner, pemecah bingkai PNG beserta resinkronisasinya, escaping input-text, dan siklus hidup host (aliran, kontrol, berhenti saat idle, dispose) terhadap toolchain palsu. |
node scripts/dev-routes-static-smoke.mjs | Rute bertanda tangan terhadap host palsu: grant relatif, token kedaluwarsa/palsu/lintas-jenis, pagar loopback, amplop 405/415/400, penolakan perangkat berkode, validasi /control, bentuk rotasi, pembendungan tangkapan layar, dan aliran multipart langsung. |
node scripts/dev-tools-smoke.mjs | Alat inti terhadap host palsu melalui seam createAndroidTools. |
node scripts/dev-uitree-smoke.mjs | Alat pohon UI dan baris: penguraian XML uiautomator, selektor, pembatasan kedalaman, heuristik baris dan penghitung. |
node scripts/dev-logs-smoke.mjs | snapshot/follow android_logs, filter, batas, dan pemungutan proses. |
node scripts/dev-panel-smoke.mjs | Komponen panel, mode ukuran, gaya bingkai, logika dok/pemicu/kapsul (SSR saja). |
node scripts/dev-emulator-smoke.mjs [serial] | Perangkat langsung: bingkai pertama, laju bingkai berkelanjutan, perjalanan pulang-pergi ketukan, dispose. |
Pemecahan masalah
Aliran kosong / putih pada emulator
Jika panel mengalirkan gambar putih (atau hitam) polos sementara android_ui_tree
masih melihat elemen UI sungguhan, pembacaan balik framebuffer GPU-host milik emulator
rusak di mesin Anda (masalah gfxstream yang dikenal pada sebagian host macOS —
screencap sendiri mengembalikan bingkai kosong, sehingga setiap alat layar terpengaruh).
Luncurkan ulang emulator dengan perenderan perangkat lunak:
emulator -avd <name> -gpu swiftshader_indirect
atau setel hw.gpu.mode=swiftshader_indirect di config.ini milik AVD tersebut. Perangkat
fisik tidak pernah terpengaruh.
Peta jalan
- Sumber dengan laju bingkai lebih tinggi. Seam
StreamSourcesengaja dibuat dapat dicolok: jalurscrcpy-server+ WebCodecs H.264 dapat menggantikan aliran PNG per bingkai tanpa menyentuh rute, alat, maupun panel. - Muat ulang panas pratinjau Compose. Kembaran iOS-nya menukar-panas pratinjau SwiftUI sebagai dylib; Compose hari ini tidak punya primitif hot-swap yang setara, jadi ini tetap menjadi rencana masa depan alih-alih fitur yang dikirim tapi rapuh.
Ekosistem
- DSH iOS Simulator — arsitektur yang sama untuk Simulator iOS dan iPhone yang terhubung USB
- DSH Crew — delegasikan pekerjaan ke agen DSH dari Claude Code / Codex
- DSH Noema — memori jangka panjang untuk DSH
- DSH OpenPencil — periksa dan edit dokumen desain
.opdi dalam percakapan
Kredit & lisensi
- Android SDK platform-tools (
adb) — diselesaikan saat runtime, tidak pernah didistribusikan ulang: lisensi SDK Google tidak mengizinkan pemaketannya. - ADBKeyboard — Senzhk — IME opsional di perangkat yang menopang pengetikan non-ASCII (Apache-2.0; tidak dipaketkan).
- Arsitektur dan postur rute dibagi dengan dsh-ios, yang menjadi asal porting plugin ini.
- Lihat THIRD_PARTY_NOTICES.md untuk pemberitahuan lengkap.
Lisensi: MIT