dsh-in-hand

remotetested: passnpmApache-2.0

Phone client for DeepSeek Harness — no app to install (PWA). Read sessions, background jobs, subagents, goal rounds, workflows and pending approvals, and talk to any session from it: streamed replies, tool-call progress, stop at any time, switch sessions and models. Also ships a GUI sidebar panel. F

下载量 / Downloads
6,966
依赖体积 / node_modules
1.13 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-in-hand

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

掌上 DSH(dsh-in-hand)

[English](README.en.md) · 简体中文

<p align="center">

<picture>

<source media="(prefers-color-scheme: dark)" srcset="docs/assets/hero-zh-dark.webp">

<img src="docs/assets/hero-zh-light.webp" width="100%" alt="掌上 DSH:左边是手机上的待批准卡片,右边是「不用装 App」的三行说明">

</picture>

</p>

<p align="center">不用装 App。手机上把 DSH 的待批准一次点掉。</p>

<p align="center">

<a href="https://github.com/dingchenhui0618-arch/dsh-in-hand/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/dingchenhui0618-arch/dsh-in-hand/actions/workflows/ci.yml/badge.svg?branch=main&amp;style=flat-square"></a>

<a href="https://www.npmjs.com/package/dsh-in-hand"><img alt="npm" src="https://img.shields.io/npm/v/dsh-in-hand?style=flat-square"></a>

<a href="LICENSE"><img alt="许可证 Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square"></a>

</p>

<p align="center">

<img src="docs/assets/flow-approve.gif" width="240" alt="首页的「待批准」卡片:点「批准一次」,在二次确认里点「允许一次」,卡片变成「已提交 · 允许一次」">

<img src="docs/assets/flow-sessions.gif" width="240" alt="点左上角 ☰ 打开抽屉:工作台与操作在前,往下滑到会话列表,点一条进对话">

<img src="docs/assets/flow-theme.gif" width="240" alt="在抽屉里把字号调到「大」,再点「切换到暗色」,回到暗色首页">

</p>

<p align="center">左:待批准一次点掉 · 中:抽屉里挑会话 · 右:字号与明暗</p>

形态就是一个网页:手机浏览器打开即可。同一个 Wi-Fi 下走局域网直连,人在外面走经中继的公网入口,两条路在页面右上角随时切。

30 秒上手

1. 装插件(在跑 DSH 的那台电脑上):dsh plugin --profile web add dsh-in-hand

2. 重启 DSH:桌面客户端关掉再打开(命令行装的用 dsh web)—— 插件行来自 profile 的 bundle 图,不重启不生效。

3. 手机打开:同一 Wi-Fi 用中继的局域网地址 http://<电脑的内网 IP>:3099/taskwatch,人在外面用中继的 HTTPS 域名;首次进配对页输一次 6 位码。

为什么用它

  • 不用公网 IP:电脑在 NAT 后面也能连上,路由器不用做端口映射。
  • 能接着聊:还是桌面上那批会话,手机上回一句就继续,逐字看着它跑。
  • 能批一次:手机在线时,待批准卡片直接给「批准一次 / 拒绝」;超时或手机切走就自动退回桌面(v1.8.0)。
  • 拍一张直接发:输入框旁的相机键唤起系统相机,拍完就在输入区看到缩略图、大小和取消;发送前在手机上压到长边 1600、保留拍摄方向,原图不出手机(仍走本机收件箱,不进云端,v1.8.9)。
  • 等待和交付物都在这一页:哪件事在等你、进度到哪,展开就能看;生成好的图和 PDF 直接打开。

从只读监控长成手机客户端

它起初只是一份只读的任务监控页——让你在手机上瞄一眼 DSH 有几个任务在跑、有没有事在等你;后来接上了 DSH 自己的会话运行时,长成了手机浏览器里的 DSH 客户端:左上角会话列表、右上角新建对话、输入框上方是当前会话的实时指标(轮次 / 步数 / token/s / Token 消耗 / 缓存命中率 / 上下文占用),可以直接对话、逐字跟随输出、随时打断;再往后,手机上还能一次性批准 / 拒绝一次工具调用、回答选项式提问。

没有 App 可装:不需要原生代码、不需要打包、不需要上架。手机上进一次「添加到主屏幕」,之后它就是一个图标;页面按请求读盘、壳由 Service Worker 换版,所以代码更新后下一次打开就会跟上。

打开就是概览(v1.8.2)

以前打开是一段对话——你得先翻一眼才知道自己为什么被叫来。现在打开是概览:最上面一行是虎鲸标 + 「掌上 DSH」(v1.8.20),紧接着就是「在等你 N 件」,下面第一张卡能直接点「批准一次」;再往下是「在跑」的三条(跑到第几步、跑了多久),一行后台任务 / 今日轮次,最后是「继续上次会话」和「全部会话」。对话退到第二层,点进去才看正文,左上角有明确的「返回首页」,系统返回手势也回得去(地址是 #session/<id>,刷新不丢)。

两件事刻意没做:没有新写一套审批逻辑(待办卡复用 v1.8.0 的按钮、二次确认与倒计时,只是多了一个放置位置),断网时不清空首页(继续显示上次读到的状态,底下补一条说明,而不是假装"什么都没有在等你")。

并行视图:一屏看清、失败永远在最上面(v1.8.10)

首页「在跑」只有三条,开四五个会话就得一页页翻,失败的那条尤其容易被埋掉。v1.8.10 加了整屏的并行视图(首页「在跑」右上角「全部」,或抽屉里的「并行视图」),排序写死为一句话:

需要你(待批准 / 待回答) → 失败 → 运行中 → 已完成最近

同组按最后活动时间倒序。这条排序不是"红的最显眼",而是分组本身:即使把颜色全去掉,失败仍然在运行中与空闲之上,滑不到它才奇怪。每行只留四件事——标题(最多两行)、状态徽标、一句最新动作(工具名 · 第几步)、已运行 / 结束时长;失败行多一句 ≤60 字的原因和「查看」。有子代理的会话下面折一行「子代理 N」,展开就能看到它们各自的状态,不另开一层页面。

更新沿用现有的 5 秒轮询与 SSE:只按会话 id 复用行、改变化了的那几个字段,不整屏重建;页面不可见时时长计时与轮询一起暂停。390 宽首屏能看到 5 行,无横向溢出,标题两行截断。

手机端一次性审批(v1.8.0)

以前手机只能看「有 N 件事在等你」,真正批准还得回桌面。现在 approval/request 是 waterfall,插件可以认领它:手机页在线时,待批准卡片会多出「批准一次」和「拒绝」两个按钮。批准会弹一次「确认允许一次?」,拒绝不弹;倒计时结束或页面切走就自动退回桌面。

四条失败语义是这次的核心,功能本身反而简单:

  • 没有手机在线 → 立刻 next()。判据只看手机页最近 15 秒有没有轮询或审批 SSE;桌面 GUI 也打 /taskwatch/data,但不带 view=phone,故意不算在线,免得桌面开着面板却让审批空等。
  • 超时 → next()。approvalTimeoutMs 默认 120000,允许 10000–600000;越界取边界值并在启动时 warn。
  • req.signal abort → 立刻交还,因为桌面端已经先处理了。
  • 只暴露 allowed-once / rejected,不做 always-allow;手机决定只成功一次,重复提交 409,过期或已交还 410。
这张卡只在「手机在线且这次请求可认领」时出现;离线、超时、桌面先处理都会回到原来的「请在桌面端批准」。

手机端回答选项式提问与计划审批(v1.8.3)

P0 的第一类是「放不放行」,第二类是「选哪一个」。v1.8.3 把 user-questions/request

也接上了:它和 approval/request 一样是 waterfall,手机页在线时插件认领它,把题目

变成一张可点的卡。

  • 单题:选项渲染成整行按钮(label 一行、description 第二行小字),点一下即选中,

但仍要再点「提交回答」—— 防的是误触直接交卷。

  • 多选:multiSelect:true 时按钮可以多选,底部同一个「提交回答」。
  • 多题:逐题纵排,答过的题不再显示「待回答」,没答完提交键保持禁用。
  • 计划审批:intent.kind === 'plan-review' 时标题带「计划审批」徽标,intent.approve

对应的那个选项用主色强调(它不是"更推荐",而是这次提问里唯一的放行项)。

  • 自定义回答:每题都有一个默认收起的输入框,展开后可以直接写一句话(≤2000 字)。

提交时作为 custom 字段发给宿主。

  • 一次性与倒计时:与审批卡同一套 mm:ss 倒计时;到 0 显示「已退回桌面」。提交成功后

卡片收起显示「已提交」;宿主回 409 / 410 时显示「已由桌面处理」;网络失败则保留

已选项与自定义草稿、放开按钮让用户重试。

失败语义逐条照抄审批,没有第二套机制:没有手机在线 → 立刻 next();超时(同一个

approvalTimeoutMs,默认 120000)→ next() 并审计 by:'timeout';request.signal

abort → 立刻交还;任何内部异常 → try/catch → next()。审计同样只记

{at, session, kind:'question', title, outcome, by, selectedCount, custom} ——

不记答案原文。

这张卡在三个地方都能答,且是同一份结构:首页待办区、任务详情抽屉、

会话页输入框上方的问答条(只显示当前会话的提问)。

A phone client for DeepSeek Harness with no app to install: it reuses the desktop GUI's design tokens and adds a live metrics row above the composer.

设备列表与撤销(v1.8.7)

抽屉里多了一个「设备」:列出最近用过这个入口的手机与电脑,每行只有摘要名(系统 · 浏览器)、

最近活跃、从局域网还是公网进来,以及一个「撤销」。当前这台带「这台设备」标记;列表里的

id 是 12 位摘要,不是设备 cookie 原值。

撤销当前这台要过一道二次确认,说清后果;确认后本端立即翻到「此设备已被撤销,请重新

配对」,下一次请求由宿主回 401:

  • 宿主给每个浏览器发一个 HttpOnly 的设备 cookie,页面读不到;不记录 IP、不记录完整 UA,

最多 50 台、30 天不活跃自动清。

  • 撤销别的设备不需要确认(一次点击即可),撤销自己才需要 —— 防的是手滑把自己踢下线。
  • 这不是账号体系:本机仍然不鉴权,它解决的是「手机丢了 / 借人了,把这一台踢掉」。

高危动作二次确认(v1.8.8)

手机能批准之后,最危险的那一类不该和下一条普通改文案走同一个动作。v1.8.8 把判定放在

宿主侧:approval/request 到达时,assessRisk({ toolName, reason, detail }) 用

highRiskPatterns 扫一遍宿主手里那几段可见说明,命中返回 'high',页面只收到

pending[].risk。页面里没有任何按工具名或命令猜风险的正则 —— 它只负责画红色

「高危」徽标与第二步。

点「批准一次」不会直接发请求,而是在卡片内部展开确认层:列出工具与原因,写明

「确认执行?此操作不可撤销」,只有「确认执行」(实心危险色)才真的

POST /taskwatch/approve。展开期间卡片其余按钮禁用;「取消

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::41,最后更新 2026-11-03

Links

GitHub · Homepage · npm

Same category