dsh-mobile
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 8 GitHub stars
Code Uyari
- network request — Outbound network request in deploy/relay/compose.yaml
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
DeepSeek Harness Android app: control your DeepSeek Harness agents from your phone. The agent runs on your PC; a host plugin inside DSH pairs the phone by QR code over Wi-Fi or Tailscale, no cloud. Chats of all projects, live replies, photos and files, steer, agent questions, notifications. Unofficial, MIT.

DSH Mobile
Case study on the website: https://logachev.net/#case-dsh-mobile · Technical write-up (in Russian) on Habr
English | Русский
Your DeepSeek Harness agent runs on your computer. From your Android phone you assign tasks with photos and files, read replies in real time, answer the agent's questions and get an “Answer ready” notification.
Published releases · 0.9.0 candidate · Installation · Architecture · Security
An unofficial project by Pavel Logachev. Developed independently of DeepSeek.
Android 8.0+ · QR code pairing · Wi‑Fi or Tailscale
Models, tools and subscriptions stay on the computer. DSH Mobile has no cloud server.
What's new in 0.9.0
Current source candidate: app 0.9.0 / versionCode 17 and host 0.9.0, with additive API /v1 extensions. This is not a publication announcement: final artifact and physical acceptance results belong in the release checklist.
- Notifications now follow phone-started tasks: completion, failure and needs-answer through
GET /v1/sessions/{id}/prompt-outcomesand capabilitypromptOutcomes. No permanent idle connection notification or coverage banner. The old feed is retired: older apps report notifications unavailable on the new host, so upgrade both components together. - Turn errors are shown in chat. Recovery hold/witness and
recovery-status,recovery-hold,recovery-release --new-epochsupport operator reconciliation, not exactly-once execution. - At most 32 unsettled host dispatches; overflow is refused before admission. A ten-minute post-admission deadline settles as
uncertain, without automatic replay. - Network return wakes reconnect; online status follows the first authorized index page. Chat opens stream-first without an initial full GET; the first nonempty text is published immediately, with subsequent updates still throttled. Real-phone speed numbers still require measurements.
- DSH
0.2.1-rc.5passed the full isolated canary: 25 checks. This is not physical-phone or external-model acceptance. Evidence matrix.
What you can do from your phone
- Open chats from all projects. Search chats and filter them by project. The project list follows the DSH sidebar and updates without re-pairing.
- Assign tasks. Pick a project and a preset and write the task right away: the app creates a chat and sends the text once.
- Send photos and files. A shot from the camera, photos through the system photo picker (Photo Picker), files through the system file picker. Uploading starts as soon as you pick them. One message can carry up to 20 attachments with a total size of up to 200 MiB, each file up to 20 MiB. The agent receives PNG, JPEG, WebP and GIF images as images; files are handed to the DSH attachment store at the moment of sending. Unsent uploads expire on the computer after 10 minutes and never reach DSH.
- Read the reply in real time. Markdown, tables, code blocks with a copy button. Images from messages appear right in the conversation; tap one to open a full-screen viewer where you can zoom in, send it via Share or save it. Files from messages can be downloaded — up to 20 MiB. Service events are collapsed into an “Agent activity” line — the full text opens on tap. A long compacted chat whose older history cannot be restored within the limits opens with the latest messages and a note that the history is truncated.
- Add messages and steer while the agent works. By default a message joins the DSH queue and reaches the agent on its next turn. “Steer” delivers it at the agent's next step without stopping the current turn: hold the send button or tap ↳ on a queued message. You can also remove a message from the queue.
- Answer the agent's questions. Pick one or more options, write your own answer or skip the question. The option the agent recommends is marked but not preselected. Approvals of agent actions stay on the computer.
- Rename a chat and change its model. Both actions are in the ⋯ menu. The new model applies from the next model request, possibly as early as the next step of the running turn; a request that is already in progress is not switched.
- Stop a run. A separate Stop button asks for confirmation.
- Get notifications for your tasks. One local switch enables watches for phone-started tasks when the host publishes
promptOutcomes. Completion, failure and needs-answer alerts open the corresponding chat; a final outcome replaces its waiting alert. Android channels control sound. Desktop-started tasks are not automatically watched. Contract and limits. - Come back to the conversation. Message search, a draft for each chat and copying with a long press.
Features are available only when the host reports their capability. Use the 0.9.0/0.9.0 pair for the new notifications; the old notification feed is not a fallback. Attachments, queue/steer, question answers, rename, model choice and file downloads remain available.
The theme follows the system one; you can also choose light or dark manually. The interface is in Russian and English: the language follows the system or is chosen in the app settings. Large font sizes are supported.

The screenshots were taken in the real app with synthetic demo data. They contain no real chats or connected models.
Screenshots
Historical 0.8 screenshots; the notification screen does not describe the 0.9.0 design.

DSH Mobile 0.8: the agent works on your computer, and your chat with it is on your phone.

Chats from all DSH projects in one list.

The agent is working and you add a message: to the queue, or “Steer” at the next step.

Camera photos, gallery pictures and files — in one message to the agent.

An agent question: pick an option, write your own answer or skip it.

The ⋯ menu: renaming the chat and changing the model.

An image from the chat in full screen: zoom in, share, save.

Notifications: the answer is ready, the agent has asked a question.
How it works
A companion plugin is installed on the computer. It opens a narrow API to the paired phone over a secure connection but does not expose the DSH web interface to the outside.
Android app
│ HTTPS over Wi‑Fi or Tailscale
│ or through your own relay
▼
Companion plugin inside DSH
│
▼
Your projects and agents on the computer
The phone is only a client: the agent keeps working after you close the app. The main conversation history is stored in DSH on the computer.
The Android client is written in Kotlin and Jetpack Compose; the plugin runs on Node.js. Your own relay is an optional way to connect; the project does not provide a shared public relay.
Installation
You can hand the detailed setup guide to your DSH agent. It contains environment checks, commands and separate approval of the installation, access rights and activation.
Check the requirements.
Computer: Windows, DeepSeek Harness
0.2.0-rc.2,0.2.1-alpha.1or0.2.1-rc.5, Node.js 24.x, OpenSSL 3. The 0.9.0 target is rc.5 (25 canary checks); the first two are retained on historical full/registry canaries, while rc.4 is unsupported. Evidence limits. Phone: Android 8.0+. DSH itself must run on Node 24, not just a suitable executable on PATH.Download and verify the release files.
Open Releases. For the selected published release, obtain its signed APK, host ZIP and both SHA-256 sidecars from the same release. Candidate 0.9.0 still requires final acceptance; do not invent its asset URLs or substitute an older pair.
UNSIGNED-verification.apkis verification evidence, not an installable download.Specify the absolute paths to the downloaded files and compare the hashes with the
.sha256files. If they do not match, stop.$zip = '<ABSOLUTE_DOWNLOADED_HOST_ZIP>' $apk = '<ABSOLUTE_DOWNLOADED_SIGNED_APK>' (Get-FileHash -LiteralPath $zip -Algorithm SHA256).Hash.ToLowerInvariant() (Get-FileHash -LiteralPath $apk -Algorithm SHA256).Hash.ToLowerInvariant() # Compare exactly with the release's .sha256 files. A mismatch means STOP.Prepare the plugin on the computer.
Extract the installer from the archive and read it. In the commands below, replace the placeholders: the path to the script and the computer's address on your home network or in Tailscale. If you do not need an additional address, remove the second element of the array.
$installer = '<ABSOLUTE_REVIEWED_INSTALL_HOST_PS1>' $hosts = @('<ACTUAL_PRIMARY_LAN_OR_TAILSCALE_HOST>', '<OPTIONAL_ADDITIONAL_SAN>') # Remove the second element if not needed. Substitute approved real values locally. & $installer -ZipPath $zip -Hosts $hosts -WhatIf & $installer -ZipPath $zip -Hosts $hostsThis step prepares the files and configuration but does not yet connect the plugin to DSH.
Activate the plugin.
After reviewing the proposed changes:
& $installer -ZipPath $zip -Hosts $hosts -ActivateThe installer does not restart DSH. If the plugin has not started, follow the troubleshooting steps in the guide: a restart may be needed, but it is approved separately.
If home Wi‑Fi needs a Windows Firewall rule, add it only with the owner's consent and only for the private network. The installer does not change the firewall automatically.
Install the APK on the phone.
Allow Android to install apps from the chosen source. Turn this permission off after installation.
Pair the phone with a QR code.
On the computer, specify the directory of the installed plugin version and check the configuration:
$plugin = '<EXACT_LOCALAPPDATA_DSHMOBILE_PLUGIN_VERSION_DIRECTORY>' $cli = Join-Path $plugin 'dist/cli.js' $config = Join-Path $env:LOCALAPPDATA 'DSHMobile/host/host.json' node $cli verify-config --config $configThen choose one pairing command. Read-only access to all current and future projects:
node $cli pair --config $config --read all --ttl 300 --qrOr read access and running tasks in all of these projects — only if you agree to give the phone these rights:
node $cli pair --config $config --read all --execute all --ttl 300 --qrIn the app, tap “Scan QR code”, check the computer's address and the certificate fingerprint, then confirm pairing. The camera is used only for scanning; the code is recognized without a network and without Google services.
To use it away from home, install Tailscale on the computer and the phone, connect both to your Tailscale network and specify the computer's name when preparing the plugin. You do not need to open a port on your router. The alternative is your own relay on a VPS.
Upgrading to 0.9.0: upgrade app and host together after verifying signatures and hashes. An APK update must retain the signing certificate; do not uninstall to bypass a signature mismatch. Use the reviewed host installer with -Upgrade -Activate: it unmounts the old plugin, waits for listener closure and mounts the whole immutable build. A DSH restart needs separate approval because it ends running turns. Keep a private state backup and follow upgrade/rollback instructions and release notes. Previous physical results do not establish the new candidate’s behavior.
The current source pair is 0.9.0/0.9.0. The historical published pair is app 0.8.2 and host 0.7.2 (historical release); its checks below are not 0.9.0 acceptance.
Security
- Agent permissions stay the same. The plugin runs inside DSH with its permissions. Project filtering is not a sandbox: an agent can do the same from the phone as from the computer. Give the right to run tasks only to trusted devices.
- The invitation is a secret. The QR code is single-use and valid for no more than 15 minutes. Do not publish it, send it to a chat or save it in shared logs. Pairing checks the computer's certificate, its validity period, the address and the pinned fingerprint.
- Provider keys are not sent to the phone. Pairing data is protected by Android Keystore and excluded from backups. The plugin's private files on Windows are accessible only to the owner of the user account.
- Revoke a lost phone on the computer. Signing out of the app locally deletes the pairing data from the phone but does not revoke access on the DSH side.
- Notifications do not contain the completed answer. Failure alerts may include a short summary; lock-screen content is private. Chat names use a localized fallback without fetching a transcript. Details.
- The relay does not see chat contents. It forwards encrypted traffic but sees IP addresses, timing and the amount of data transferred.
Do not expose the DSH web port to the outside and do not disable TLS verification. Details are in the security overview.
Building from source
From the repository root, in PowerShell:
cd host; npm ci; npm ci --prefix ../relay; npm run check # companion plugin, Node 24; the tests need the neighboring relay
cd ..\android
powershell -NoProfile -ExecutionPolicy Bypass -Command "& ../tools/android-build.ps1 -Tasks ':app:assembleDebug', ':app:testDebugUnitTest', ':app:lintDebug'"
JDK 21 is recommended; the Windows helper also supports JDK 17. You need Android SDK platform 36 and build-tools 36.0.0.
A regular release build of the APK is unsigned and cannot be installed as is. Building, packaging the plugin and signing with your own key are described in the build guide and the APK release guide.
Historical release 0.8.2 checks
Historical release: app 0.8.2 (versionCode 15) and host 0.7.2; release notes. This table describes only that build, not the currently installed pair or 0.9.0.
| Component | What was checked |
|---|---|
| Android 0.8.2 | On Android code 3dc0126: two full JVM runs, 357/357 each; lintDebug — 0 errors (46 warnings, 1 hint). The release helper runs assembleRelease, testDebugUnitTest and lintRelease |
| APK signature | The same certificate, SHA-256: F9080C63B49A0BDE6B74AA2ADF7E9531D6C4F305978A24D3F5D271A39F1B7B95; v2/v3 schemes, 16 KB alignment; non-debuggable, HTTPS-only |
| Plugin 0.7.2 | 282/282 with the Cordis module env; without it, 275 pass and 5 skipped (280 total). Independent re-review of the host code: GO after three blockers were fixed |
| Installer | 28/28 synthetic scenarios; not a check of installation on a phone |
| Physical phone | OnePlus, Android 16, APK 3dc0126: the sending status after 0.3–0.7 s; sends in a new and an existing chat and after more than 110 s idle; send → Home ×2 — one delivered prompt each time; the upgrade over 0.8.1 kept pairing |
| Not verified with instruments on a phone | Notification latency and tap routing with host 0.7.2; auto-retry and the “not sent” banner on a real network switch (the send button was disabled during reconnect); delivery under real Doze |
| APK permissions | INTERNET, CAMERA, POST_NOTIFICATIONS, FOREGROUND_SERVICE, FOREGROUND_SERVICE_SPECIAL_USE, ACCESS_NETWORK_STATE and the app's own signature-level receiver permission. No telemetry and no Google services |
Limitations
- The computer and DSH must stay on. The phone does not run an agent. One pairing targets one computer; the project list considers the first 100 registered projects.
- This is intentionally a native subset, not desktop parity. Plugin/skill management is not exposed. Action approvals stay on the desktop because there is no verified plugin API for them; they are distinct from answerable agent questions.
- Notifications are best effort, without FCM/UnifiedPush. There is no idle service/permanent connection notification or coverage banner. A pending phone task still uses an FGS: its notification cannot be guaranteed invisible on all OEMs. Valid watches/outbox restore after process death and unlocked reboot subject to pairing, permission and OS guards. After force-stop, launch the app manually. Doze, battery saving, offline devices, 24-hour expiry or eviction from the 32-watch bound can prevent delivery. Exact limits.
- Offline content is a bounded stale/read-only cache. At most 8 snapshots, 3500 KiB of serialized snapshot UTF-8, 24-hour age, each snapshot at most 2 MiB; the index is bounded separately. Cache is not authorization, command reconciliation or a full archive. Fresh snapshots contain at most 100 messages/2 MiB; older-history recovery is bounded to 16 pages/16 MiB. Upstream JSONL currently reads the whole log before those limits apply.
- Updating DSH requires compatibility verification. Setup may fill the version from
dsh --version; the runtime plugin checks the configured declaration, not the installed version. Only the exact matrix entries are supported. - A dropped connection does not prove non-delivery. Automatic retry requires transport proof that request headers were not sent: at most three attempts with the same requestId. Never automatically resend after admission; a lost response or receipt404 never proves non-execution. A proven not-sent failure keeps the draft and offers manual Retry; for
uncertain, inspect DSH first. - Recovery is not exactly-once. A witness detects only provable local rollback. Missing/rolled-back DB and witness require a manual hold before reopening admission. Epoch is an operator decision record, not client-visible fencing: after release a lost requestId can be admitted as new. Procedure.
Does the name require a DeepSeek model or subscription?
No. DSH Mobile is a companion to the DeepSeek Harness host, not a purchase of a particular DeepSeek model or plan. Models, providers and billing stay on the computer. This project establishes no cost/task-count comparison with other subscriptions.
Documentation
- Installation, upgrade and removal
- Architecture
- Mobile client protocol
- Security
- DSH integration
- Deploying your own relay and its protocol
- Building from source
- Signing and releasing the Android APK
- Contributing
Need something similar?
This project was built by Pavel Logachev. I build websites, web services, Telegram bots, apps and automation for your task: I work out the task, build the solution and launch it myself. 20 years in IT: first as an engineer, then as a project manager. Tell me about your task by email or on Telegram — a 20–30 minute review is free, and you do not need a ready-made specification. Prices and other projects are on logachev.net and in my profile.
License
MIT © 2026 Pavel Logachev. Third-party dependencies are distributed under their own licenses.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi