📱 Dispatch tasks to DeepSeek Harness (dsh) from your phone — approvals on your lock screen, isolated git worktrees, E2E encrypted, self-hostable. Like Claude Code Dispatch, for dsh.
2
stars
34
commits
TypeScript
primary language
Aug 25, 2026
updated
Dispatch tasks to DeepSeek Harness from your phone. Approve tool calls with one tap. Command every machine you own.
从手机给 DeepSeek Harness (dsh) 派任务、审批一键批、一部手机指挥所有机器。中文说明 →
Like Claude Code's Dispatch + Remote Control, but for dsh — open source, end-to-end encrypted, self-hostable.
dsh web binds to 127.0.0.1 with no auth — by design. Every existing remote tool wraps that web page in a WebView. dsh-dispatch is not a mirror. It is a command center:
| WebView mirrors | dsh-dispatch | |
|---|---|---|
| See sessions from the couch | ✅ | ✅ |
| Dispatch a new task from your phone | ❌ | ✅ into an isolated git worktree |
| Approval push notifications, tap to allow/deny | ❌ | ✅ for every session, even desk-started ones |
| Many machines on one screen | ❌ one tunnel each | ✅ one board |
| Relay can read your traffic | usually | never — zero-knowledge, E2E encrypted |
git worktree, spins up a fresh dsh session, and reports the final answer back with a push notification.approval/request waterfall. Phone and desktop race; first decision wins; nothing is ever auto-approved.ask_user_question choices show up on your phone; answer from anywhere and the session continues (also rescues the upstream no-answerer hang).danger-full-access to skip approvals for fully-trusted tasks; off by default, machine-gated, permanent red badge on every such session.┌────────────┐ E2E encrypted ┌───────┐ E2E encrypted ┌──────────┐
│ dsh plugin │ ───── wss ─────► │ relay │ ◄──── wss ────── │ PWA │
│ (machine) │ │ (dumb │ │ (phone) │
│ │ │ pipe) │ │ │
└────────────┘ └───────┘ └──────────┘
approval/request waterfall sees only approve / dispatch
ctx.agents.create + worktree ciphertext web push alerts
| package | npm | what it is |
|---|---|---|
dsh-dispatch | the dsh plugin — event-bus listener, approval race, worktree dispatch | |
dsh-dispatch-relay | stateless ciphertext router + Web Push, Docker/npx one-liner | |
@dsh-dispatch/pwa | — | installable phone app (PWA) — no app store needed |
On the machine that runs dsh:
# 1. Run a relay — yours, or any you trust (it can't read your traffic)
npx dsh-dispatch-relay # listens on :8787
# 2. Install the plugin into your dsh profile
dsh plugin --profile web add dsh-dispatch
# 3. Configure it — ~/.dsh/profiles/web/cordis.patch.yml
- id: dsh-dispatch
config:
relay: 'ws://localhost:8787/ws' # wss:// for anything non-local
allowedRoots: ['/path/you/allow'] # dispatch stays OFF until you set this
pwaUrl: 'https://alextangson.github.io/dsh-dispatch' # where the pairing link points
# 4. Boot dsh, then run /dispatch-pair and open the printed link on your phone
dsh web
The phone app is hosted at https://alextangson.github.io/dsh-dispatch — no install, no app store; add it to your Home Screen so Web Push can reach the lock screen. It is a static page that talks only to the relay you configured, so self-host it from packages/pwa if you would rather not load it from GitHub Pages.
Your phone reaches the relay directly, so a relay on localhost only works from the same machine. For a real phone, put the relay somewhere reachable over wss:// — a $5 VPS, or a tunnel in front of it.
Approval forwarding works immediately after pairing; dispatch activates once allowedRoots is set. Relay self-hosting (Docker, VAPID push keys) and every config key: see packages/relay and packages/plugin.
allowedRoots. Treat it like an SSH key. Rotate anytime with /dispatch-repair.nacl.secretbox, per-message nonce). The relay stores room presence and push endpoints — never plaintext, never keys.allowedRoots are rejected visibly. Worktrees are never auto-deleted.v0.4.0 on npm — developer preview tracking dsh 0.1.x (upstream warns of breaking changes; every harness API touchpoint is isolated in one adapter layer). Everything below is verified end-to-end against dsh 0.1.1-rc.2 with the real DeepSeek API, not in mocks: phone dispatch → worktree session → real tool execution → sandbox-escalation approval pushed to the phone → allow → command runs; a question answered from the phone flows back into the running session; a follow-up typed on the phone reopens a finished session, the card names the tool it runs and keeps the turn's trail, and the session's transcript reads back on the phone; a full-access dispatch runs under danger-full-access and writes outside the workspace with no approval prompts.
The hosted PWA tracks main and the plugin is released from it, so the two line up at 0.4.0. An older machine degrades visibly rather than silently: the directory step says the plugin is too old and falls back to a text field, no reply box appears, and a transcript that the machine cannot serve says so instead of spinning.
dsh-dispatch-relay stays at 0.2.0 — it has not changed since, and a version bump with no diff behind it is a lie about what you are installing.
Known limitations:
danger-full-access preset, which sets approval: 'never' — so it raises no approval cards at all. Full access and phone approvals are mutually exclusive per session, by dsh's own preset semantics. That's the trade: speed for no review surface.questions.get in the protocol yet); the machine re-reminds until answered.next: () => Promise<ApprovalOutcome> with no argument, and the only withdrawal path is ApprovalRequest.signal, which belongs to the asker. dsh does log approval/decided with the outcome when the phone claims a request, so the web app has what it needs to dismiss its own card.Roadmap: real-device push polish → fleet views → session history beyond the live board.
这是什么:dsh 官方没有手机端、没有远程方案。现有第三方全是"把 localhost:3080 套壳进 WebView"。dsh-dispatch 走的是 Claude Code Dispatch 那条路——一个指挥中心:
ask_user_question 时,选项直接出现在手机上,答完会话继续跑。快速开始:npx dsh-dispatch-relay → dsh plugin --profile web add dsh-dispatch → 在 profile 的 cordis.patch.yml 里配 relay 和 allowedRoots → dsh 里执行 /dispatch-pair,手机打开 https://alextangson.github.io/dsh-dispatch 扫码即配对。手机是直连 relay 的,所以 localhost 上的 relay 只有本机能用;真要用手机,relay 得放在 wss:// 能访问到的地方。
版本:插件与托管 PWA 都在 0.4.0。机器上如果还是 0.2.0,降级是看得见的——目录选择器会提示"这台机器的插件较旧"并退回手填,追问输入框不出现;升级插件即可。
已知限制:手机先答审批后,dsh 网页版那张卡片会残留——决定已生效、卡片是死的(点了会被丢弃,不会重复执行),但插件没有 API 能撤下它。另外两边看到的会话不是同一批:手机只列活着的会话(包括你在电脑上开的),不含历史;而手机派的任务跑在新建 worktree 里,没被注册成工作区,所以在 dsh 网页版侧栏里看不到。
安全:配对码即信任边界(当 SSH 私钥对待,可随时 /dispatch-repair 轮换);派任务只进你白名单的目录;审批永不自动通过(唯一例外是你主动开启的完全访问模式,那类会话在看板上永久标红)。
Issues and PRs welcome. The wire protocol is frozen in docs/PROTOCOL.md; product boundaries in docs/PRODUCT.md; every dsh API claim is sourced in docs/dsh-plugin-groundtruth.md.
Keywords: DeepSeek Harness plugin, dsh-plugin, dsh remote control, mobile approvals, phone dispatch, agent remote control, E2E encrypted relay, Claude Code Dispatch alternative, DeepSeek 手机远程控制, 手机审批, 远程派任务.
MIT
34 commits
TypeScript
96.6%
CSS
2.4%
📱 Dispatch tasks to DeepSeek Harness (dsh) from your phone — approvals on your lock screen, isolated git worktrees, E2E encrypted, self-hostable. Like Claude Code Dispatch, for dsh.
2
stars
34
commits
TypeScript
primary language
Aug 25, 2026
updated
Dispatch tasks to DeepSeek Harness from your phone. Approve tool calls with one tap. Command every machine you own.
从手机给 DeepSeek Harness (dsh) 派任务、审批一键批、一部手机指挥所有机器。中文说明 →
Like Claude Code's Dispatch + Remote Control, but for dsh — open source, end-to-end encrypted, self-hostable.
dsh web binds to 127.0.0.1 with no auth — by design. Every existing remote tool wraps that web page in a WebView. dsh-dispatch is not a mirror. It is a command center:
| WebView mirrors | dsh-dispatch | |
|---|---|---|
| See sessions from the couch | ✅ | ✅ |
| Dispatch a new task from your phone | ❌ | ✅ into an isolated git worktree |
| Approval push notifications, tap to allow/deny | ❌ | ✅ for every session, even desk-started ones |
| Many machines on one screen | ❌ one tunnel each | ✅ one board |
| Relay can read your traffic | usually | never — zero-knowledge, E2E encrypted |
git worktree, spins up a fresh dsh session, and reports the final answer back with a push notification.approval/request waterfall. Phone and desktop race; first decision wins; nothing is ever auto-approved.ask_user_question choices show up on your phone; answer from anywhere and the session continues (also rescues the upstream no-answerer hang).danger-full-access to skip approvals for fully-trusted tasks; off by default, machine-gated, permanent red badge on every such session.┌────────────┐ E2E encrypted ┌───────┐ E2E encrypted ┌──────────┐
│ dsh plugin │ ───── wss ─────► │ relay │ ◄──── wss ────── │ PWA │
│ (machine) │ │ (dumb │ │ (phone) │
│ │ │ pipe) │ │ │
└────────────┘ └───────┘ └──────────┘
approval/request waterfall sees only approve / dispatch
ctx.agents.create + worktree ciphertext web push alerts
| package | npm | what it is |
|---|---|---|
dsh-dispatch | the dsh plugin — event-bus listener, approval race, worktree dispatch | |
dsh-dispatch-relay | stateless ciphertext router + Web Push, Docker/npx one-liner | |
@dsh-dispatch/pwa | — | installable phone app (PWA) — no app store needed |
On the machine that runs dsh:
# 1. Run a relay — yours, or any you trust (it can't read your traffic)
npx dsh-dispatch-relay # listens on :8787
# 2. Install the plugin into your dsh profile
dsh plugin --profile web add dsh-dispatch
# 3. Configure it — ~/.dsh/profiles/web/cordis.patch.yml
- id: dsh-dispatch
config:
relay: 'ws://localhost:8787/ws' # wss:// for anything non-local
allowedRoots: ['/path/you/allow'] # dispatch stays OFF until you set this
pwaUrl: 'https://alextangson.github.io/dsh-dispatch' # where the pairing link points
# 4. Boot dsh, then run /dispatch-pair and open the printed link on your phone
dsh web
The phone app is hosted at https://alextangson.github.io/dsh-dispatch — no install, no app store; add it to your Home Screen so Web Push can reach the lock screen. It is a static page that talks only to the relay you configured, so self-host it from packages/pwa if you would rather not load it from GitHub Pages.
Your phone reaches the relay directly, so a relay on localhost only works from the same machine. For a real phone, put the relay somewhere reachable over wss:// — a $5 VPS, or a tunnel in front of it.
Approval forwarding works immediately after pairing; dispatch activates once allowedRoots is set. Relay self-hosting (Docker, VAPID push keys) and every config key: see packages/relay and packages/plugin.
allowedRoots. Treat it like an SSH key. Rotate anytime with /dispatch-repair.nacl.secretbox, per-message nonce). The relay stores room presence and push endpoints — never plaintext, never keys.allowedRoots are rejected visibly. Worktrees are never auto-deleted.v0.4.0 on npm — developer preview tracking dsh 0.1.x (upstream warns of breaking changes; every harness API touchpoint is isolated in one adapter layer). Everything below is verified end-to-end against dsh 0.1.1-rc.2 with the real DeepSeek API, not in mocks: phone dispatch → worktree session → real tool execution → sandbox-escalation approval pushed to the phone → allow → command runs; a question answered from the phone flows back into the running session; a follow-up typed on the phone reopens a finished session, the card names the tool it runs and keeps the turn's trail, and the session's transcript reads back on the phone; a full-access dispatch runs under danger-full-access and writes outside the workspace with no approval prompts.
The hosted PWA tracks main and the plugin is released from it, so the two line up at 0.4.0. An older machine degrades visibly rather than silently: the directory step says the plugin is too old and falls back to a text field, no reply box appears, and a transcript that the machine cannot serve says so instead of spinning.
dsh-dispatch-relay stays at 0.2.0 — it has not changed since, and a version bump with no diff behind it is a lie about what you are installing.
Known limitations:
danger-full-access preset, which sets approval: 'never' — so it raises no approval cards at all. Full access and phone approvals are mutually exclusive per session, by dsh's own preset semantics. That's the trade: speed for no review surface.questions.get in the protocol yet); the machine re-reminds until answered.next: () => Promise<ApprovalOutcome> with no argument, and the only withdrawal path is ApprovalRequest.signal, which belongs to the asker. dsh does log approval/decided with the outcome when the phone claims a request, so the web app has what it needs to dismiss its own card.Roadmap: real-device push polish → fleet views → session history beyond the live board.
这是什么:dsh 官方没有手机端、没有远程方案。现有第三方全是"把 localhost:3080 套壳进 WebView"。dsh-dispatch 走的是 Claude Code Dispatch 那条路——一个指挥中心:
ask_user_question 时,选项直接出现在手机上,答完会话继续跑。快速开始:npx dsh-dispatch-relay → dsh plugin --profile web add dsh-dispatch → 在 profile 的 cordis.patch.yml 里配 relay 和 allowedRoots → dsh 里执行 /dispatch-pair,手机打开 https://alextangson.github.io/dsh-dispatch 扫码即配对。手机是直连 relay 的,所以 localhost 上的 relay 只有本机能用;真要用手机,relay 得放在 wss:// 能访问到的地方。
版本:插件与托管 PWA 都在 0.4.0。机器上如果还是 0.2.0,降级是看得见的——目录选择器会提示"这台机器的插件较旧"并退回手填,追问输入框不出现;升级插件即可。
已知限制:手机先答审批后,dsh 网页版那张卡片会残留——决定已生效、卡片是死的(点了会被丢弃,不会重复执行),但插件没有 API 能撤下它。另外两边看到的会话不是同一批:手机只列活着的会话(包括你在电脑上开的),不含历史;而手机派的任务跑在新建 worktree 里,没被注册成工作区,所以在 dsh 网页版侧栏里看不到。
安全:配对码即信任边界(当 SSH 私钥对待,可随时 /dispatch-repair 轮换);派任务只进你白名单的目录;审批永不自动通过(唯一例外是你主动开启的完全访问模式,那类会话在看板上永久标红)。
Issues and PRs welcome. The wire protocol is frozen in docs/PROTOCOL.md; product boundaries in docs/PRODUCT.md; every dsh API claim is sourced in docs/dsh-plugin-groundtruth.md.
Keywords: DeepSeek Harness plugin, dsh-plugin, dsh remote control, mobile approvals, phone dispatch, agent remote control, E2E encrypted relay, Claude Code Dispatch alternative, DeepSeek 手机远程控制, 手机审批, 远程派任务.
MIT
34 commits
TypeScript
96.6%
CSS
2.4%