Repository navigation
Releases: 201222-L/dsh-mobile-remote
Release list
DSH Remote v3.2.0
插件 3.2.0 / App 3.2.0+23(版本号三处统一:package.json / pubspec.yaml / tag)
本版把 4 个社区 PR 收进主线(其中 PR #30 覆盖 #29、PR #31 覆盖 #28),并修掉 3 个 App 侧缺陷。
移动端 Git 只读浏览(PR #28)
- 工作区浏览、分支图(父泳道/悬线/拓扑起点修复)、标签配置、只读操作安全防护、工作区过期竞态修复。
会话文件浏览(PR #31)
- 对话操作栏(对话框右上角「三个点」)新增「文件」动作,位于 Git 之后:全屏只读,浏览根 = 当前会话的工作目录,逐级下钻 + 面包屑回跳,不越出会话工作目录。
- 点开文件看等宽 + 行号只读预览;二进制(含 NUL)与超限文件明确说明原因,不伪装成空内容;纯只读,不依赖 Git。
- 操作栏收纳
git/files/session_tools/copy四项并支持长按拖动排序;旧设备上持久化的 3 项顺序会自动回退到含files的新默认(只丢一次自定义排序,不会缺项)。
会话列表状态与子代理排序(PR #29 / #30)
- 会话列表新增运行中标识(运行时品牌色旋转的方形虚线指示器)、隐藏子代理会话、按最新消息时间排序;子代理列表按创建时间倒序并复用同一套状态标识。
- 状态归一收敛为共享
normalizeAgentStatus():内核AgentStatus是idle | running二元,不存在waiting。
斜杠命令:提交时解析并真正执行(issue #25)
- 修复:此前在输入框直接发送
/compact不会执行命令,而是被当成普通用户消息投给模型——会话流出现/compact气泡、模型把它当发言回应、压缩从未发生且没有任何报错。现在提交时在客户端解析:命中内核命令语法且名字在命令目录里 → 走POST /m/api/commands执行,不插入用户气泡,并把命令结果 toast 出来。 - 未知命令不拦截:提示一次后照常按普通消息发送(拦截会让
/tmp这类正常消息永远发不出去;PC 端对无法解析的名字同样是回落发送)。 - ⊕ 命令菜单:裸命令(
/compact、/export)点选即执行;带参数的命令仍填入输入框,并把内核的input.hint作为副标题显示。真机补正:填字后现在会提示「已填入输入框:补参数后点发送才会执行(用法 …)」——此前点选后毫无反馈,用户以为"命令不能用"。 - 命令端点现在会唤醒休眠会话:此前
GET/POST /commands要求会话已挂载,而 App 会列出全部持久化会话(实测本机 171 条、仅 1 条挂载),在旧会话里点命令只看到「命令列表加载失败:session not found」。已抽出resumeDormantAgent与/send共用同一条恢复路径。 - 服务端
commands.execute的整条命令上限 15s → 180s:原值会把/compact掐死(它要等内核完整跑完一次 LLM 摘要);客户端用 200s,504 与客户端超时都按"已提交、结果未知"提示,不断言失败。
模型与推理强度修正(PR #27,修 issue #26)
- 模型身份与强度改为读内核
session/control的modelSelection.next(待生效选择),不再用可能滞后的lastUsed——此前改强度会按上一轮实际使用的模型提交。 - 目录按模型给出可选强度,界面只显示当前模型支持的等级,切换模型不继承旧模型的强度;已持久化但未挂载的会话也能更新模型选择。
- 真机补正:
next为 null 或模型不在目录时,强度区域此前会静默消失,已改为显式说明。
宽表格横滑不再被消息列表抢走(issue #33)
- 根因:表格的横向滚动与外层纵向消息列表在同一手势竞技场竞争,两者阈值相同(Android ≈8px)。首次移动事件纵向分量先越线时,列表赢下整个手势 → 表格完全滑不动,列表跟着手指上翻并触发"加载更早"(每页 30 条、可无限重复),一路被带到任意早的历史。
- 修复:把表格子树的拖拽阈值压到 4px,使"横向分量已明显、纵向先越线"的手势由最内层(表格)胜出。纯纵向手势仍归列表。
- 既有两个表格测试把表格放进裸
Scaffold、外层没有可滚动控件(表格永远赢),这正是缺陷长期被漏掉的原因;新增用例复刻真实层级并断言两个 Scrollable 的偏移。
扫码连接修复(PR #32 的 /m/m 部分)
/m/api/qr-config返回的地址已自带挂载路径,而客户端又拼了一次 → 二维码载荷变成/m/m,App 原样当作请求前缀 → 扫码连接一律 404(v3.0.0 起,LAN 桥与回环两种模式都中招)。已改为"仅当地址自身不含路径时才补挂载路径"。- 该 PR 附带的「二维码首选地址改为优先 Tailscale」未采纳:与本仓库既有的选路设计相反(
lib/index.js明确把 Tailscale 排在最后,避免"扫到组网 IP 而手机组网未开 → 黑洞"),建议单独讨论。
对话操作栏外观(真机反馈)
- 栏体原先用
height: double.infinity撑满整屏,4 个动作只占顶部 224dp,下方一大片空白。已改为按动作数取高,并挂在右上角顶部(与触发它的「对话操作」按钮同侧同高),左侧 14dp 圆角。
验证
node --test 96 通过 / 0 失败 / 1 平台跳过 · timeline-contract-check 77 PASS · account-usage-check 15/15 · account-usage-adversarial-check 19/19 · flutter analyze 0 issue · flutter test 366/366。
关键修复均做了双向验证:/m/m 用变异测试(改回旧实现 7 项变红);#33 用 git checkout 回退修复(用例失败)再恢复;命令端点休眠唤醒的变异验证令 4 条用例失败。
真机验收(Android 17 / LAN 桥):命令在当前会话与旧会话上均可用(对未挂载会话实测 200 + 6 条命令 且会话被唤醒);/goal 点选后提示正确、发送后走命令通路且无用户气泡;宽表格横滑与操作栏位置逐项核对。
升级
- 电脑端:安装
dsh-mobile-remote-v3.2.0.tgz后重启 DSH(插件持有 LAN 监听,不建议热重载;本次含命令通路的休眠唤醒修复,不重启不生效)。 - 手机端:安装
DSH-Remote-v3.2.0.apk(同签名覆盖安装,登录态与数据保留)。 - 自检:手机输入框发
/goal→ 应弹提示「已填入输入框:补参数后点发送才会执行」→ 点发送 → 弹出命令结果且不出现/goal用户气泡;打开一个较旧的会话点命令列表 → 应正常列出 6 条命令(不再报session not found);找一条带宽表格的消息横滑 → 表格能滑动、列表不上翻。
附件
DSH-Remote-v3.2.0.apk(手机安装,同签名覆盖安装)dsh-mobile-remote-v3.2.0.tgz(电脑端插件包)
已知未解决
- issue #20:缺陷本体在 DSH 上游核心(
dsh-session-query.readSession()仍用Session.create而非Session.fromRestore)。上游已加入逃逸口(日志含session/end-seed且data.inherited === true时可跳过等长校验),插件的降级读取仍需保留。
DSH Remote v3.1.5
插件 3.1.5 / App 3.1.5+22(版本号三处统一:package.json / pubspec.yaml / tag)
对话时间线(工具调用与事件详情)
- 工具调用按
callId关联调用与结果,合并为单张 Tool activity 卡片;未知但用户可见的事件进通用事件卡,不再静默丢弃。 - 新增普通 / 调试两种展示模式:普通模式只呈现对话与工具活动(系统注入与协议记录不再占屏),调试模式可审阅原始事件与按需加载的无损详情。
- 新增认证端点
GET /m/api/event-detail;隐私边界 fail-closed:request/header、session/title-llm-request、web/deepseek-search-llm-request(含 system prompt 与 messages)、compaction/*、system/message等内部记录在历史/实时/详情三处都不下发。 /api/history表面过滤改为isTimelineRecord黑名单 +hasMoredurable cursor 分页。
手机用量与额度
- 设置 → 账户新增「用量与额度」页;悬浮球面板新增用量区块(窗口短标签、按需获取、降级为单行余额)。
- 服务端新增只读端点
GET /m/api/account-usage:DeepSeek CNY 余额 / Codex 配额 / OpenCode Go 窗口;凭据只在电脑端使用。
其他修复
- 复制对话(issue #15):正文长按可选中、用户消息复制入口、整段对话导出。
- Markdown 渲染:代码围栏按开启长度配对(#22)、表格共享列宽 + 单元格行内解析 + 含链接单元格崩溃修复(#19)。
- 休眠会话降级读取与配置保持(#21):错误分类 404/500、
degraded/current-surface透传、configDegraded提示。 - 注入消息双模式(#12)、
/compact后轮次兜底补拉(#13)、setState内异步断言缺陷修复。 - SSE 事件流取消窗口的连接泄漏:
eventsRaw()判不出「订阅已取消」(Dart 的isClosed不反映 canceled 位),取消窗口内晚到的响应会挂上一条无人取消的流 → 连接永不释放、线性累积;服务端connections.size是配额依据(默认 16),攒满后手机503 too-many-connections且服务端误判「手机在线」(症状:必须把 App 划掉重开)。已修为显式cancelled标志,并补 5 个 SSE/#13 回归测试(flutter test127 项)。 - 子代理面板行可点(#11 复核补正):会话工具 →「子代理」原本只是纯展示(行上无
onTap),看得到列表却进不去;现在整行可点跳进该子代理会话,右侧补箭头提示,返回时恢复原会话(与「分支」同款语义:顺路看一眼,不改主会话)。showSessionToolsSheet/openChat增加仅测试用的apiClient注入位(与ChatScreen.apiClient同款),补 1 例回归(面板不切会话 → 点行切换并推入会话页 → 返回恢复原会话),flutter test133 项。 - 工具卡片标题显示裸
callId(真机复现):服务端tool/result摘要在结果事件拿不到工具名时,用callId兜底写进了name(关联 id 不是工具名),而 App 的合并规则data['name'] ?? … ?? current?.name让结果事件覆盖了tool/call学到的真名——只有带结果的调用在历史里才有tool/result,所以现象恰好是「历史回放=裸call_00_...、进行中=真名」的分裂。已修为服务端不再下发该兜底 + App 侧把「name==callId」一律视为未知并保留已知工具名(timelineToolNameOf单一实现);结果事件的真实错误名(如UserQuestionError)与显式工具名照常保留。补 5 例 Dart 回归 + 2 条契约断言,真机复验通过。 - #13 排查澄清:
/compact后首条回复丢失的修复本身没有问题——此前端到端用例跑不通是测试载体限制(dart:ioHttpResponse.bufferOutput默认 true 时 <8KB 的 SSE 帧不上线),关掉后三层用例(含「推turn/end→ 兜底补拉」)稳定通过。
安全与健壮性加固(PR #11 存活审计 + 全量复核)
- 修复子代理 / 目标面板必然失败:RPC 端点名与 wire 参数对齐内核注册表(
subagents/list、subagents/interruptByParent、goals/*)。 - 修复问询取消/超时把
null当答案(内核 TypeError)→ 改为{kind:"rejected", error:{...ASK_CANCELLED}};/respond加归属与结构校验。 /m/api/defaults静默提权修复(danger-full-access需显式确认 + preset 白名单)。- LAN 桥未鉴权崩溃修复(absolute-form 请求目标不再导致进程退出);新增非 GET 跨站请求防护。
- 浮动 promise 导致宿主退出、持存队列「插队」静默丢消息、错误文本主机路径外泄、上传静默写错工作区等一并修复。
- App:陈旧 agent 状态(发送键误变「停止」)、详情按钮永久失效、调试预览超长文本、缩略图 OOM、问询卡崩溃、取消静默失败。
验证
node --test 28/28 · timeline-contract-check 77 PASS · account-usage-check 15/15 · account-usage-adversarial-check 19/19 · flutter analyze 0 issue · flutter test 133/133 · debug/release APK 构建成功 · Kotlin 面板单测 27/27。
真机验收(时间线卡片与模式切换、用量页与悬浮球、复制交互、休眠会话降级、子代理/目标面板、问询取消/超时)随本版本装机进行。
v3.1.4
v3.1.4(2026-09-16)— issue #14 / #12 / #13:离线待答不再丢 + ntfy 标题修复 + 注入折叠 + 任务面板 + 压缩后重同步
插件
3.1.4+ App3.1.4+21。App 覆盖安装即可,登录态与数据保留;旧 App 仍可用,只是看不到任务面板、注入折叠与本次的同步兜底。
修复(issue #14 Bug2,同时是 Bug1 的真因:离线审批帧被整个丢弃)
- 现象:必须在审批发生前就停在那个会话里,手机上才会出现审批卡;事后打开 App 什么都没有;App 关闭/被杀时收不到任何「需要你回答」提醒。
- 根因:
onEventsWaterfall第一行if (connections.size === 0) return;—— 手机没连就整段早退,于是 ① 待答条目不建 ② 回放存储pendingFrames不写 ③ 挂在同一函数里的needs-answer推送一起消失。而回放存储唯一的历史写入点在ctx.inject(["apiProxy"], …)的 mux 循环里,0.1.2-rc.1+ 内核已移除 apiProxy(0.1.5-rc.2 全量搜 0 命中)→ 该通道是死代码,/api/events建连时的回放逻辑形同虚设。 - 修复:无论手机是否在线都建条目 + 写回放存储;只在手机在线时 arm 120s fail-close(离线时是桌面端在处理审批,不能被手机侧超时误杀),离线条目走「30 分钟只清理、不结算」的定时器;mobile 接管路径同样写入回放存储。
- 回放写入/清理成对:清理统一收进
finishApproval/finishQuestion,覆盖「手机先答 / 超时 / ✕ 取消 / 桌面端先答(cancel 帧)/ 离线到期」五条路径,不留"幽灵审批卡"。 - 归因更正:报告人推测"
notifyNeedsAnswer的唯一调用点挂在 apiProxy 帧桥上"并不成立——$events瀑布内(审批/问询两个分支)本就有推送调用,真正拦路的就是那行早退;按原建议"把推送搬到 $events 路径"会搬进同一个函数而依然收不到。另核实:内核turn/end {kind:"blocked"}只在preStep返回reject时置位,等待审批期间轮次并未结束,那条兜底路径也救不了"等审批"的推送。
修复(issue #14 Bug3:ntfy 标题丢失、正文变成一坨 JSON)
- 根因:JSON payload 被 POST 到主题地址。ntfy 的 JSON 发布契约是
POST /(或自托管 base path 根)且 body 内带topic;发到主题地址时服务端按纯文本处理整段 JSON。 - 实测证据:
POST https://ntfy.sh/<topic>+{"title":…,"message":…}→ 响应体无title、message为 JSON 原文;POST https://ntfy.sh/+ body 带topic→title正常返回。本机真实通道(微信 + ntfy)修复前的历史消息同样可见该症状。 - 修复:新增导出 helper
ntfyPublish()—— 解析配置里的主题地址,改为 POST 服务器根地址并在 body 内补topic,兼容自托管带 base path 的部署(https://host/ntfy/topic→POST https://host/ntfy/)。配置写法不变;schema 注释与实现口径统一(此前注释写 text/plain + X-Title,与实现不符)。
修复(issue #14:代码块 / 表格横滑误触发「加载更早」,App 侧)
- 根因:
_onLiveScroll不区分滚动来源——代码块/表格内部的横向SingleChildScrollView会把pixels=0的通知冒泡给外层NotificationListener,被误判为"滚到视觉顶部"→ 每次横滑都触发加载更早、列表跳回该轮上方。 - 修复:加
n.depth != 0(忽略嵌套滚动)与n.metrics.axis != Axis.vertical(只认纵向)两道过滤——即报告人给出的两行建议。
新增(issue #12:系统注入消息折叠)
- 结构化判定(报告人建议的
source路线):内核createUserMessage({ source })本就区分来源——真人kind: "user",注入为plugin/agent-instructions/tool/skill-catalog/subagent-settled等;拦路的不是内核,是插件摘要层把来源丢掉了。现在summarizeEvent的user/message分支透出sourceKind(旧内核无source则不下发该字段,App 退回关键词启发式)。 - App 渲染:
sourceKind ≠ "user"的消息渲染成折叠块——一行摘要(类型标签 + 字数)、默认收起、点按展开;展开状态复用「思维链」同一套每消息覆盖存储(键前缀inj:),列表回收重建不丢。原有 3 个关键词黑名单仍直接过滤(PC 端 GUI 也不显示的那三类)。 - 效果:技能目录、
[SCHEDULE REMINDER]、压缩检查点摘要、其它插件注入、子代理结算通知等不再以普通气泡占满屏幕。
新增:会话任务清单面板(对齐 PC 端「任务」面板)
- 数据源与 PC 端同一处:内核
dsh-tool-todo把整份清单以todo/write快照写入会话事件,并注册会话投影todos(投影语义:最新快照生效、turn/start清空)。 - 插件:①
summarizeEvent新增todo/write分支(条数 ≤50、单条 ≤200 字符、status 白名单校验);② 加入SURFACE_TYPES→ 历史补拉/重连回放也能拿到快照;③ 新增GET /m/api/todos?sessionId=—— 直接读内核投影(sessionProjections.stateOf(session, "todos")),休眠/旧内核返回todos: null。 - App:输入框上方新增折叠面板——收起态一行计数(
1 进行中 · 3 待处理 · 4 已完成),展开态完整清单(状态图标 + 完成项置灰);实时靠 SSEtodo/write/turn/start折叠,打开会话/断线重连后用/api/todos对齐一次(历史只有 50 条窗口,投影读法保证长时间工具链之后仍然准确)。面板为垂直布局的普通子项,与活动条 / 审批卡 / 队列停靠条顺排,不会重叠。
修复(issue #13:/compact 之后首条回复"消失")
- 复现结论:当前版本未能复现(真机实时 + 历史两条路径,各两个会话)。逐条对账两端都正常:
- 插件侧:压缩后的
assistant/message确实广播了(seq=44/64/83,textLen 63/37/501…),/api/history里也在; - App 侧:事件被正常处理并渲染(
Chat: build itemCount16→19→21 递增),截图里压缩后的长回复(含表格、代码块、链接)完整显示。 - 另核实两条推测不成立:① 压缩用
shadowedSeqs+summarySeq的遮蔽模型(surfaceOp: {op:"replace"}),seq 只增不减;②assistant/chunk在 0.1.5 内核里不是会话事件(不在known-event-types),"流式草稿被turn/end清空"这条路在当前内核下无法发生。
- 插件侧:压缩后的
- 但排查中发现两处真实隐患,按报告人给的排查建议 2/3 落地兜底:
- 压缩后按新表面重载:
/compact会重写会话表面(旧节点被 shadow),App 此前不重载 → 手机继续显示已被 shadow 的旧消息,与桌面端视图分叉。现在收到compaction/end立即按当前表面重建(_load(reset: true))。 - 轮次兜底补拉:
turn/end时若"本轮出现过真人提问、却没有渲染出更晚的回复条目",判定内容被静默吞掉 → 补拉一次历史(10s 节流防抖);判定抽成纯函数needsTurnEndResync并带单测。
- 压缩后按新表面重载:
- 意义:对方环境里的真因仍待其日志定位;本版两道兜底可让同类"静默丢内容"自愈——最坏是晚一拍显示,不会再只剩一条「轮次结束」分隔条。
诊断增强(issue #14 建议 6)
checks.pendingFrames改为无条件输出,并新增checks.pendingApprovals/checks.pendingQuestions—— 现代内核下也能自查"离线时审批帧有没有被记下来"。- 新增每通道最近一次投递结果
checks.push:<通道名>(ok 21:04:33/fail 21:03:10 · HTTP 401…/idle);事件推送与/api/push-test手动自检两条入口都记录(真机验收时正是它暴露了 Server酱通道当天额度已满)。
验证
- mock 宿主回归
tools/verify-issue14-p0.mjs:37 项断言全绿——push-test 自检记账 / 离线记账 / 离线推送 / ntfy 请求形状(本地假 ntfy 断言 URL 与 body)/ 重连回放 / 手机应答清理 / 对端先答清理 / 离线期间不结算 / 问询同契约 /todo/write摘要与 status 白名单 /sourceKind注入标记 //api/todos端点。 - 真机端到端(LAN 桥 + Android 17,App 3.1.3+20 与 3.1.4+21 各跑一轮):杀掉 App(
mobileOnline=0)→ 触发真实沙箱升级审批 → 诊断pendingApprovals=1 / pendingFrames=1(旧版此处恒 0)→ ntfy 收到带标题的「⚠ 需要你回答」→ 重开 App 出现回放审批卡 → 手机点「允许一次」→ 诊断归零、工具真的执行;审批在手机离线状态下挂起 >120s 未被 fail-close。全自动版回归(离线记账 → 回放帧含 approvalId →/respond→ 成对清空 → 探针文件写入 → 归档)9/9 通过。 - App 3.1.4+21 真机逐项核对:任务面板(计数与清单逐项核对、点开/收起、与其他层不重叠)、注入折叠块(收起/展开)、横滑只滚表格不触发上翻(logcat 判定 + 真·上翻负向对照)、压缩后重同步(日志「压缩完成 → 按新表面重载会话」+ 按新表面重建)、正常轮次无假阳性;
flutter test28/28(含needsTurnEndResync4 项)。
升级
- 电脑端:安装
dsh-mobile-remote-v3.1.4.tgz后重启 DSH(插件持有 LAN 监听,不建议热重载)。 - 手机端:安装
DSH-Remote-v3.1.4.apk(同签名覆盖安装,登录态与数据保留)。 - 自检:设置 → 通知 → 发送测试通知 → ntfy 通知应有标题;随后关闭 App → 在电脑端触发一次需要审批的操作 → ntfy 应收到「⚠ 需要你回答」标题的推送,重开 App 应看到审批卡并可作答;诊断页
pendingFrames / pendingApprovals / pendingQuestions应随状态归零(不留幽灵卡);会话里跑一次长任务(agent 会调todo_write)→ 输入框上方出现「任务」计数条,点开可看清单。
附件
DSH-Remote-v3.1.4.apk(手机安装,同签名覆盖安装)dsh-mobile-remote-v3.1.4.tgz(电脑端插件包)
DSH Remote v3.1.3
v3.1.3(2026-09-08)— issue #9:审批/问询双端呈现,任一端先答即生效
修复(issue #9:手机在线时桌面端不再弹审批/问询框)
- 根因:v3.1.2 answerer 以
{prepend, global}排在内核"转发桌面 GUI"监听之前,手机在线即接管且不next()→ PC 端不弹(瀑布单链,手机独占与桌面呈现互斥)。 - 修复(纯插件侧,无内核改动):瀑布监听者放行
next(),内核dsh-api-remotes把approval/request/user-questions/request转成 typertGateway$events远程事件广播给每个客户端(桌面 GUI 是其一);插件在 both 模式再挂一个进程内$events客户端,任一客户端先回$events/result即结算,其余客户端收 cancel 帧自动收卡。
新增配置 approvalMode(cordis.patch.yml → mobile-remote config,重启生效)
both(默认):桌面 GUI 与手机同时弹卡、先答生效、另一端自动收卡(恢复 v3.1.1 帧桥体验)mobile:v3.1.2 行为——手机在线独占,离线交桌面(外出远程用)desktop:审批/问询只走桌面 GUI(常驻电脑前用)- 旧宿主(0.1.1-rc.2 及更早,无 $events)both 自动按 mobile 处理(诊断 notes 说明)
其它修复
- 手机问询不可用两处根因(v3.1.2 遗留):/respond 按 rpcId 兜底匹配;问询 questions 取值路径(内核瀑布值为顶层 questions)
- ✕ 取消/120s 超时在现代内核下正确结算(cancelled / unavailable),结算广播让所有手机端同步收卡
- 桌面端插件树加载崩溃修复(schemastery 无 z.enum → union/const 写法)
- 环境诊断
runtime.form判定修复:桌面版经 desktopBrowserAccess 探测正确显示 desktop(此前恒显示 cli) - App 3.1.3+18:环境诊断页支持字符串字段与备注行渲染
验证(真机:DSH Desktop 2.0.5 + Android 17 + App 3.1.3+18)
审批/问询 × 双端同弹 × 手机先答/桌面先答(另一端自动收卡)、mobile/desktop 独占、120s 无应答 fail-close、✕ 取消 → cancelled,共 8 场景全部通过。
附件
DSH-Remote-v3.1.3.apk(手机安装,同签名覆盖安装)dsh-mobile-remote-v3.1.3.tgz(电脑端插件包)
feat(v3.1.2): 推送通道自检 + 企业微信机器人通道 + 文档同步
DSH Remote v3.1.2
维护说明(先看):作者此前在生产工厂流水线打工,只能抽空维护,更新慢的原因就在这——现已辞职正式回归开发。后续会持续跟进大家的使用与反馈;因为日常还有其他安排,只要不是严重性问题,基本在周六日集中处理,大家放心使用、随时反馈。
修复(GitHub issues)
- #1 默认权限预设设为「完全访问」后,手机端新建会话必失败(
risk-confirmation-required)——新建会话弹层新增权限预设选择(完全访问先弹风险确认),确认后显式携带confirmDanger,取消则终止 - #2 插件市场「可能遮蔽宿主版本」警告(精确钉版导致 profile 内双实例)——
dsh-llm/dsh-credentials/dsh-sandbox-policy(含schemastery)改为peerDependencies(>=0.1.0-rc.6 <0.2.0),版本随宿主 - #3
session.events依赖(App「该会话暂不可用」等崩溃)——适配 DSH 0.1.2 Session API(snapshotEvents()/eventAt()/seq),全量收敛到eventsOf助手
DSH 0.1.2-rc.1(DSH Desktop v2.0.5)适配(真机验证)
- LAN 桥适配桌面版新浏览器访问门禁(此前手机经桥的所有请求 403);内部 RPC 迁移到进程内 @Remote 网关;休眠会话自动恢复;审批/问询改走内核瀑布对答(手机收审批卡 → 批准 → 内核实测
allowed-once闭环) - 修复通知/悬浮球「任务完成」显示会话短码(异步标题晚到时等待+回写刷新)
新功能(B站反馈落地)
- 🌐 文件传输:手机 ⇄ 电脑 双向——下载(可视化文件选择器:盘符/目录树/文件列表点选,保存到手机「下载/DSH-Remote」)+ 上传(Android 系统文件选择器 → 写入会话工作目录)
- 📋 自由复制:代码块一键复制(含行数提示);消息文本选中/操作栏复制
- 🔔 干活完成提醒(关键升级):
- 新通道企业微信群机器人(推荐:国内稳定、免登录态、约 20 条/分钟,配置见 docs/06 §6);Server酱(微信服务号,免费 5 条/天)/ Bark / ntfy 继续可用;ntfy.sh 公共服务器境内不可直连(已文档标注)
- 「发送测试通知」:App 设置 → 通知 → 一键逐通道验证(网络不通 / 配额超限 / 参数错误一眼区分),配完立刻知道通不通
- 推送超时放宽 + 网络失败自动重试;不依赖手机 App 常驻后台
- 💬 微信入口(可选):想直接在微信里和 agent 说话派活?推荐安装 @xmanrui/dsh-im(DSH 插件,微信/飞书/钉钉等 9 通道)——与本插件互补:它管 IM 对话入口,本插件管手机控制台 + 干活完成提醒
兼容性
- 插件
3.1.2+ App3.1.2+17,适配 DSH 0.1.2-rc.1(DSH Desktop v2.0.5) - 推送通道、公网访问(蒲公英 / Tailscale / FRP 等)均为按需自配置,无统一标准,见 docs/06、docs/04-security 与 README
- 已知待观察:
unknown tool write单次现象(未复现)
打包
- 服务端插件:
dsh-mobile-remote-v3.1.2.tgz - 手机端:
DSH-Remote-v3.1.2.apk(覆盖安装,旧数据保留)
English summary
DSH Remote v3.1.2 — adapted to DSH 0.1.2-rc.1 (Desktop v2.0.5); fixes #6 (new-session deadlock with Full Access default), #7 (dual-instance → peerDependencies), #8 (session.events dependency); new features: PC⇄phone file download/upload, code-block copy, done-notifications via WeChat Work bot (new) with a one-tap channel self-test, more reliable push; approval cards answered from the phone (end-to-end verified). Notes: the maintainer was working on a factory production line — that's why updates were slow — now back full-time and will keep fixing on weekends unless critical.
DSH Remote v3.1.1
DSH Mobile Remote v3.1.1 更新说明 · WSL / 类Unix 路径选择问题修复
插件版本:3.1.1|手机客户端:3.1.1‑16|适配 DSH 0.1.1‑rc2(DSH Desktop v2.0.2)
本次更新解决了 GitHub #5 反馈的缺陷:服务端运行于 WSL 环境时,手机客户端无法正常选择电脑目录路径。
更新简介
此前 WSL、Linux、macOS 这类使用 POSIX 路径规则的设备,用户在手机端浏览并选择电脑目录(例如 /home/...)新建会话时,程序会错误生成 \home 这种带 Windows 反斜杠的非法路径,直接触发「读取失败」,后续文件夹都无法打开。
现在该问题已经修复,类Unix系统下目录浏览选择功能恢复正常。
问题详情
- 故障现象:后端部署在WSL,手机新建会话选择工作目录,从根目录点开home文件夹,路径被拼接成
\home,随即提示读取失败,下级目录全部不可访问。 - 故障根源:移动端目录选择器默认按照Windows规则,使用反斜杠
\拼接路径;但WSL/Linux属于POSIX系统,反斜杠路径属于非法路径。
修复方案
- 电脑‑服务端改动
路径分隔符会根据当前运行平台自动适配归一化:WSL/Linux使用/、Windows使用\;目录浏览、新建文件夹、会话工作目录全部生效。
在/m/api/directories根目录接口,新增增量字段sep,旧版手机客户端会自动忽略此字段,向下兼容。 - 手机‑App端改动
目录选择器不再硬编码反斜杠\,改为读取服务端下发的分隔符拼接路径;工作区列表展示服务端原始路径,路径规范化仅用于内部匹配校验。
升级生效方法
- 电脑端:将插件升级至3.1.1,重启DSH程序。仅更新服务端插件,旧版手机App就已经能够恢复目录浏览。
- 手机端:安装v3.1.1安装包(覆盖安装,原有数据保留),即可获得完整修复,实现路径正确显示与拼接。
验证情况
- 单元测试:
dirpicker_logic_test.dart6项测试(正反斜杠拼接、根视图、旧插件回退兼容);wsl‑path‑check.mjs8项服务端路径归一化用例。 - 代码检查:
flutter analyze无报错;flutter test24项全部通过;node --check校验成功。 - Windows平台运行效果与v3.1.0版本完全一致,无回归问题。
注意:本次开发者无真实WSL硬件环境,没有做真机实测;WSL使用者升级后遇到异常,欢迎继续提交反馈。
更新包附件
DSH‑Remote‑v3.1.1.apk— 手机客户端安装包(版本3.1.1+16)dsh‑mobile‑remote‑v3.1.1.tgz— 电脑端插件包(3.1.1版本,包含修复代码与配套文档)
补充备注
- 纯Windows无WSL用户:该版本与3.1.0功能完全一致,非必要可不升级;如需升级则插件与手机App版本同步更新。
- 版本兼容性:
sep属于纯新增字段,插件与App任意新旧版本交叉组合都可以正常运行,低版本一方不会获得新特性。完整兼容规则可查阅README文档「版本与兼容」章节。dsh-web 移动端远程同装时请配 path: /mr 共存。
DSH Remote v3.1.0
新增(感谢社区 PR #4,作者 marktrue-ahu)
- 对话页可折叠「思维链」块(图标 + 字数 + 箭头,单条消息独立切换;默认状态在 设置→显示 切换,手动状态按消息持久化)
- 修复流式输出不跟随滚动到底:按「停留底部」钉住状态判定,大段 chunk 单帧推高不再掉队
- 悬浮球「运行中的会话」显示会话标题(超宽省略号截断),替代 session id 短码
- 服务端配套字段:assistant/message 新增 reasoning(≤20000 字符,仅非空下发)、bootstrap 的 agents/sessions 新增 title(空则兜底短码)
修复(维护者审核中发现并修复)
- 思维链折叠状态在滚动/重进/重启后丢失 → 状态上移 Store 按会话持久化(每会话 100 条 + 全局 500 条软上限)
- 新建会话缺 model 时首轮崩溃({{model}} 组装无值)→ 统一绑定内核默认模型(含仅传 reasoningEffort 的场景),失败时拆除会话并明确报错
- 移动端新建会话不注入技能目录 → 对齐 PC 端 session.create 契约(setup 挂载预设组装),技能目录恢复注入
- 模型探测报错可操作化(401/403、断连、404 中文引导,覆盖 fetch failed/ENOTFOUND 等);模型提供商页新增已存密钥提示与官方 DeepSeek「内置可用,无需探测」标识
- clampText 截断总长严格 ≤ 上限;诊断接口新增技能目录状态说明
- docs/05 新增 F-20~F-22 用例;docs/09 补充字段级兼容与降级说明
兼容性
- reasoning/title 均为纯增量字段:旧版 App 与新插件、新版 App 与旧插件可混用(新字段自动忽略/回退),无协议破坏
- 同签名覆盖安装,连接配置保留
验证
- 真机(MIUI + LAN 直连)全流程:思维链折叠、滚动跟随、悬浮球标题、探测文案
- flutter analyze 零问题 · App 单测 18/18 · 插件单测 14/14 · node --check
- 运行时验收:无 model / 仅 reasoningEffort 建会话 A/B 通过、技能目录注入断言通过
- Codex 复审通过(P0/P1 清零)
安装
- Android:下载 DSH-Remote-v3.1.0.apk 覆盖安装(同签名,连接配置保留)
- 插件:桌面端更新至 dsh-mobile-remote-v3.1.0.tgz(App 与插件版本三处同步 v3.1.0)
DSH Remote v3.0.0
DSH Mobile Remote v3.0.0 — 适配 DSH 0.1.1‑rc.2 + 局域网连接(双形态)+ 图像链路 + 移动端体验
插件3.0.0 · App 3.0.0+14(热修05‑08全集成)·适配 DSH 0.1.1‑rc.2(DSH Desktop v2.0.2) 四窗口协作
完成:DSH适配 / 局域网连接(双形态)/ 图像链路 / 移动端体验 / 文档全面修正
一句话
适配 DSH 0.1.1‑rc.2 后,把 DeepSeek Harness 装进口袋:手机随时发消息派活、看进度、收通知、审批决策、处理图片——无论你用桌面版还是 web 版,都有对应的局域网连接路径(均实测验证)。
连接方式(先看你是哪种,再动手)
形态一:web版用户(dsh --profile web)——开箱直连,老姿势
- 0.1.1‑rc.2 的 web 版 webserver 默认即
0.0.0.0:3080(--dump‑config确认),手机直接连http://<电脑IP>:3080/m + 口令 - 插件只需在
cordis.patch.yml插入一行(docs/06 §4);不需要 webserver 覆盖行;放行防火墙即可 - 实测:隔离环境 web profile(
0.0.0.0:3081)→局域网IP直连bootstrap HTTP 200(server.urls[0]即局域网地址、auth生效) ⚠️ 更早版本DSH(webserver默认127.0.0.1)才需要覆盖行,且必须写全 host + port
形态二:桌面版用户(DSH Desktop)——用插件LAN桥
- 桌面版webserver强制回环(官方安全决策:桌面应用默认不暴露;DesktopWebServer对非回环host直接throw,patch也覆盖不了)
- 插件内置LAN桥:
lanBridge: { enabled: true, port: 3080, host: 0.0.0.0 }→自建监听0.0.0.0:3080,/m/api*流式转发(SSE透传)→手机连http://<电脑局域网IP>:3080/m + 口令 - 真机验证:本机桥监听 →手机连
192.168.10.8:3080→发消息/发图/SSE全链路走通 - 桥安全边界:只转发移动端面(
/api网关、qr‑config含口令、qr.png一律404);≥16字符强口令才启动;128连接+超时防耗尽;Host头重写
⚠️ webserver覆盖行警示(社区issue教训):cordis patch对已有行是整体替换config——覆盖行必须写全 host + port,缺一即启动报$port missing required value(--dump‑config/smoke测不出,真启动才暴露)。web版默认已正确,无需覆盖。
形态三:跨局域网 / 外出连接 ——能力具备,方案因环境而异,自行选择
- 插件自带能力:虚拟组网地址自动收进地址列表(局域网优先排序)+ App断线多地址自动轮换——电脑上有虚拟网卡/可信中继即可用
- 文档给出样例与要点,不是“包治百病”:因DSH使用者环境差异(组网账号可用性、国内ICP备案、隧道服务可用性、手机保活等),按自己环境选择解决:
- 蒲公英(推荐样例,已实测版):电脑+手机同一账号同一组网 →手机填
http://<电脑虚拟IP>:3080;账号不可用属个体情况 - 其他虚拟组网(ZeroTier/EasyTier/路由器WireGuard等):原理同,节点地址自动收编;其公共节点/控制面可用性以官方为准
- 隧道/中继类(frp/SakuraFrp):需
trustedHosts放行 + 强口令;自有域名须ICP备案;公网必须TLS(明文=口令暴露)
- 蒲公英(推荐样例,已实测版):电脑+手机同一账号同一组网 →手机填
- 通用:
authToken必开;禁止3080映射/穿透公网裸奔;手机组网客户端保活设置(国产ROM免死金牌) - 示例与排查见 docs/06 §5 / FAQ;连不上先用App「环境诊断」页 + 插件
GET /m/api/diagnostics
其他内容(适配/图像/体验/热修/推送/文档/验证)
适配 DSH 0.1.1‑rc.2
commands.execute四参签名、错误对象元组化(11处500修复)、/commands语义拆分——不改内核、真机验证、三轮Code Review。
图像链路(PC端同wire)
/send images base64同形;⊕拍照/相册/命令;原始字节不压缩(内核 ≤2048px/≤4MB规范化);限额与模型能力catalog同源(20MB/张、20张、200MB、64M像素、8192边;deepseek‑v4‑flash‑vision‑exp支持图);排队图片持存;/m/api/attachment渲染+全屏+重试;tool/result嵌套图片(read_image工具结果随助手消息显示);GIF动态链路就绪(Flutter原生),发送后静态=内核规范化(实测与PC端同一sha256,两端口径一致)。
移动端体验
消息操作栏常驻+反馈高亮对齐PC;输入栏两层重构(模型/权限省略+命令⊕+排队胶囊);排队语义方案A(只进dock、任务结束释放);通知/SSE修复(15s误杀、fork误判、唤醒重同步);连接加固(防/m/m404);日志页最新在上、归档上限99放大。
夜间热修①‑⑥
①64KB误限(RST/502根因,readJson透传limit+413预检)②accepted误报③类型误标(魔数嗅探纠正+App双保险)④多图总限20MB→200MB⑤气泡竖图裁切(contain+高度480)⑥发图后输入框残留。
后半程热修 05‑08(发送链路可靠性 + 图片链路完善)
- 热修05:发送结果改为
requestId幂等回执——服务端先行占位、结果快照、同requestId重试绝不二次投递;App草稿绑定requestId、回执查询、未知态明确提示;图片客户端总量上限40MB对齐64MB body预检; - 热修06:用户图文消息改为图卡与文本两个独立气泡(对齐PC端分离式渲染),带图时剥离
[图片]占位行; - 热修07:发送失败不覆盖新输入;回执TTL读取时生效(不再无脑清理);签名纳入会话+最终模式(steer降级提前);桥502
bridge‑unavailable不再误判为失败; - 热修08:认证/限流/Host拒绝5类错误码入明确拒绝白名单(不再走回执对账);回执TTL读取路径全量清理;
单测:发送逻辑 18/18 + 回执/工具 14/14 全PASS。
推送与文档
Server酱³(Turbo已失效,每日5条限);推送失败日志带响应体;文档全面修正(双形态连接、覆盖行警示、外出样例、乱码修复)。
✅验证记录
- 140KB大body:修复前502 →修复后干净JSON;>64MB →413(无RST)
- 手机真机:324KB/256KB/15KB图片零错误;日志实证类型纠正
- 单元:嗅探6例 + 嵌套图12例全PASS;Code Review三轮;全库乱码清零
- 桌面端真机全链路 + web版局域网直连实测(双路径均验证)
📦附件
DSH‑Remote‑v3.0.0.apk(App 3.0.0+14,含热修05‑08)dsh‑mobile‑remote‑v3.0.0.tgz(插件3.0.0,含全部修复与文档)
📌备注 / 已知
- 手机连43120失败=桌面Web界面(仅回环);正确地址:桌面LAN桥3080 / web webserver 3080
- GIF发送后静态=内核规范化(与PC一致);SSE断连=手机息屏Doze(非缺陷)
- 破坏性兼容约束:已发布接口只加字段;版本差矩阵见README
- 作者熬夜适配新DSH,还请多多包涵,可能神志不清,如果发现bug,请务必即使反馈,日志以及是否可以复现,再次谢谢大家。晚安各位!!!
DSH Remote v2.8.0
GitHub Release v2.8.0 描述(直接粘贴)
v2.8.0 — 代码收敛重构 + UI优化
🛠️ 代码收敛重构(行为保持)
服务端(lib/index.js)
- 新增10个公共helper:
readJson/rpcError/requireGet/requirePost/agentSessionId/isLoopback/firstAgent/shortSessionId/notifyTitle/guardRes - 收敛20处JSON解析、9处apiRpc错误映射(502/504/内核code透传)、29处405方法检查
/events保持严格GET‑only(HEAD会悬挂SSE连接)
悬浮球(Kotlin)
- 新增7个helper:
baseUrl/httpGet/postState/openApp/mainIntent/roundedRect/isActive/isBusy - HTTP请求统一(含连接释放)、跳转统一、圆角统一、状态判定统一
- 面板刷新三段独立容错、余额自查兜底
App(Flutter)
- 新建
lib/fmt.dart共享格式化;openChat(7处)/openNotificationsScreen(3处)/openProviders(2处)统一入口 DshSwitch/showToastAt/_persistPrefs收敛;删除死代码
🎨 UI修复
- 消息列表:统一普通列表(内容贴顶、占满可滚动)——修复旧版“下半部分空白、滑动消息消失”;根治50/51条边界滚动跳变
- 输入框胶囊:与输入框左缘对齐;「排队发送」与模型/权限同行,打字区不再被挤窄;长模型名省略号截断
- 插队按钮:图标改为向上小箭头
- 后台任务卡片:移到对话框顶部、可收纳(默认收起一行,点击展开)、整体缩小
- 通知横幅:支持左右滑动关闭;滞留时间 2.5s → 6s
📦 其他
- 版本统一 2.8.0(插件 / App 2.8.0+3)
- 经三轮 Code Review + 真实 DSH 端到端测试(20+ 接口实测、真机验证、双端日志)
维护公告:近期不随 DSH 更新
背景
DeepSeek Harness(DSH)目前仍处于 RC 阶段(最新 v0.1.0‑rc.8),官方已明确声明后续会有破坏性更新(例如 rc.8 起 SQLite 存储格式不兼容、插件/API 接口可能变动)。跟随每个 RC 适配的成本(存储迁移、接口适配、回归测试)会持续累积。
决定
dsh‑mobile‑remote 自 v2.7.2 起,近期不再跟随 DSH 版本逐版更新适配。等待以下任一信号出现后再恢复跟进:
- DSH 发布 1.0 正式版 或官方宣布 API/插件接口冻结;
- 官方明确停止破坏性变更(存储格式、插件契约稳定)。
届时可能对项目进行重构:重新梳理依赖策略(当前核心依赖精确锁定 0.1.0‑rc.6,将评估改为 peerDependencies 跟随宿主)、适配新接口并做完整回归。
兼容性说明
- 插件 v2.7.2 基于 DSH rc.5 环境开发验证(peer 声明 ^0.1.0‑rc.6,范围上覆盖 rc.6/rc.7/rc.8,但未在 rc.7/rc.8 上做过适配测试);
- 与更高版本 DSH 一起使用可能出现接口不兼容(任务/子代理/目标/通知等功能),建议维持当前已验证的组合;
- 本公告不影响日常使用:在当前验证过的 DSH 版本上,v2.7.2 因为之前修复导致出现不少问题,最好是更新到2.8.0版本有更好的体验。
DSH Remote v2.7.2
一、GitHub Release 完整版(直接粘贴)
维护公告(2026‑08‑21):近期不随 DSH 更新
背景
DeepSeek Harness(DSH)目前仍处于 RC 阶段(最新 v0.1.0‑rc.8),官方已明确声明后续会有破坏性更新(例如 rc.8 起 SQLite 存储格式不兼容、插件/API 接口可能变动)。跟随每个 RC 适配的成本(存储迁移、接口适配、回归测试)会持续累积。
决定
dsh‑mobile‑remote 自 v2.7.2 起,近期不再跟随 DSH 版本逐版更新适配。等待以下任一信号出现后再恢复跟进:
- DSH 发布 1.0 正式版 或官方宣布 API/插件接口冻结;
- 官方明确停止破坏性变更(存储格式、插件契约稳定)。
届时可能对项目进行重构:重新梳理依赖策略(当前核心依赖精确锁定 0.1.0‑rc.6,将评估改为 peerDependencies 跟随宿主)、适配新接口并做完整回归。
兼容性说明
- 插件 v2.7.2 基于 DSH rc.5 环境开发验证(peer 声明 ^0.1.0‑rc.6,范围上覆盖 rc.6/rc.7/rc.8,但未在 rc.7/rc.8 上做过适配测试);
- 与更高版本 DSH 一起使用可能出现接口不兼容(任务/子代理/目标/通知等功能),建议维持当前已验证的组合;
- 本公告不影响日常使用:在当前验证过的 DSH 版本上,v2.7.2 功能完整可用。
v2.7.2 更新说明(2026‑08‑21)
🚀 队列停靠区(对齐 PC 端 Queue Dock)
- agent 忙时发送的消息进入队列停靠区,每条排队消息可 ✏️编辑 /
▶️ 插话 / 🗑删除; - 编辑:改内容,agent 按新内容执行;插话:消息插到 agent 下一步执行;删除:撤回,agent 不处理(已被认领时明确提示);
- 运行中输入文字 → 出现「排队发送」胶囊(与模型/权限同款样式),排队入口一目了然;
- 停靠区轻量显示:多条折叠、不挤压输入框、灰色小图标与整体风格统一。
🚀 插队发送
- 长按发送按钮 = 插队(消息插到 agent 下一步,带"已插队"提示);agent 空闲时自动降级普通发送并提示。
🔔 通知:只在"对话真正结束"时推送
- 多轮大任务(goal 驱动/连续队列)不再每完成一个子轮次就推一次 ✅ 任务完成:turn/end 只暂存结果,agent 转为 idle 且稳定 doneGraceMs(默认 15 秒,插件配置可调)、且无 active goal,才判定"对话真正结束"并通知一次;
- 子代理会话不再单独通知完成/失败(它是父任务的一部分,父任务结束才通知);「需要你回答」仍立即通知(交互式提问不能等);
- 审批/提问即时提醒:App 后台/悬浮球未开也能收到"需要你回答"(通知中心 + Server酱/ntfy 推送);
- 审批残留修复:PC 端已回答的审批,手机重连后卡片正确消失;
- 通知帧直推 SSE(mobile/notify):悬浮球/App 与插件通知中心同源渲染;
- max‑tokens 截断的完成通知会标注「max‑tokens 截断」。
💫 悬浮球:横屏修复
- 旋转/翻转 180°/页面跳转后自动贴边:监听配置变更,按新屏幕尺寸恢复贴边(同侧 + 同隐藏状态),不再飘到屏幕中间或消失;
- 挖孔/安全区适配:display cutout 读取,横竖屏切换不再把球推出屏外;
- 拖动钳制:水平限制在 [‑球径+16dp, 屏宽‑16dp]、垂直限制在屏内——永远拖不出屏;
- 自愈兜底:按下时发现越界先钳回允许范围再开始拖;
- 清理后台自动恢复、开关持久化、冷启动面板动作不丢、事件气泡去重。
🛠️ 其他
- 修复 👍/👎 消息反馈 100% 失败(内核版本契约 ifVersion);
- 聊天页:新对话消息贴顶布局(不再上方大片空白)、段落顺序防御修复、叠层会话隔离;
- 四轮全项目 Code Review,50+ 项修复:崩溃防护、泄漏清理、竞态、安全加固;
- 服务端新增配置 doneGraceMs(默认 15000 毫秒);
- SSE agent/status 帧补充 sessionId 与 child 标志;
- 版本号统一 2.7.2(插件 2.7.2 / App 2.7.2+2)。
📦 附件
- DSH‑Remote‑v2.7.2.apk — 手机安装包
- dsh‑mobile‑remote‑v2.7.2.tgz — 插件包(服务端)
🙏 致谢
感谢以下朋友反馈与协助测试:
- @Columbina5201314 — 反馈并协助定位崩溃级 bug(mobile/notify 帧 time 变量引用错误导致 DSH 进程崩溃),本版本已修复;
- LvsH_十三 — B 站 space.bilibili.com/373557735,反馈与测试支持;
- 小圆脸宝宝 — B 站 space.bilibili.com/90303434,反馈与测试支持。