Skip to content

Releases: 201222-L/dsh-mobile-remote

DSH Remote v3.2.0

Choose a tag to compare

@201222-L 201222-L released this 07 Oct 15:43

插件 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 点选后提示正确、发送后走命令通路且无用户气泡;宽表格横滑与操作栏位置逐项核对。

升级

  1. 电脑端:安装 dsh-mobile-remote-v3.2.0.tgz 后重启 DSH(插件持有 LAN 监听,不建议热重载;本次含命令通路的休眠唤醒修复,不重启不生效)。
  2. 手机端:安装 DSH-Remote-v3.2.0.apk(同签名覆盖安装,登录态与数据保留)。
  3. 自检:手机输入框发 /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

Choose a tag to compare

@201222-L 201222-L released this 22 Sep 15:01

插件 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 黑名单 + hasMore durable 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 test 127 项)。
  • 子代理面板行可点(#11 复核补正):会话工具 →「子代理」原本只是纯展示(行上无 onTap),看得到列表却进不去;现在整行可点跳进该子代理会话,右侧补箭头提示,返回时恢复原会话(与「分支」同款语义:顺路看一眼,不改主会话)。showSessionToolsSheet / openChat 增加仅测试用的 apiClient 注入位(与 ChatScreen.apiClient 同款),补 1 例回归(面板不切会话 → 点行切换并推入会话页 → 返回恢复原会话),flutter test 133 项。
  • 工具卡片标题显示裸 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:io HttpResponse.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

Choose a tag to compare

@201222-L 201222-L released this 16 Sep 14:25

v3.1.4(2026-09-16)— issue #14 / #12 / #13:离线待答不再丢 + ntfy 标题修复 + 注入折叠 + 任务面板 + 压缩后重同步

插件 3.1.4 + App 3.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 已完成),展开态完整清单(状态图标 + 完成项置灰);实时靠 SSE todo/write/turn/start 折叠,打开会话/断线重连后用 /api/todos 对齐一次(历史只有 50 条窗口,投影读法保证长时间工具链之后仍然准确)。面板为垂直布局的普通子项,与活动条 / 审批卡 / 队列停靠条顺排,不会重叠。

修复(issue #13:/compact 之后首条回复"消失")

  • 复现结论:当前版本未能复现(真机实时 + 历史两条路径,各两个会话)。逐条对账两端都正常:
    • 插件侧:压缩后的 assistant/message 确实广播了(seq=44/64/83,textLen 63/37/501…),/api/history 里也在;
    • App 侧:事件被正常处理并渲染(Chat: build itemCount 16→19→21 递增),截图里压缩后的长回复(含表格、代码块、链接)完整显示。
    • 另核实两条推测不成立:① 压缩用 shadowedSeqs + summarySeq 的遮蔽模型(surfaceOp: {op:"replace"}),seq 只增不减;② assistant/chunk 在 0.1.5 内核里不是会话事件(不在 known-event-types),"流式草稿被 turn/end 清空"这条路在当前内核下无法发生。
  • 但排查中发现两处真实隐患,按报告人给的排查建议 2/3 落地兜底:
    1. 压缩后按新表面重载:/compact 会重写会话表面(旧节点被 shadow),App 此前不重载 → 手机继续显示已被 shadow 的旧消息,与桌面端视图分叉。现在收到 compaction/end 立即按当前表面重建(_load(reset: true))。
    2. 轮次兜底补拉: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 test 28/28(含 needsTurnEndResync 4 项)。

升级

  1. 电脑端:安装 dsh-mobile-remote-v3.1.4.tgz 后重启 DSH(插件持有 LAN 监听,不建议热重载)。
  2. 手机端:安装 DSH-Remote-v3.1.4.apk(同签名覆盖安装,登录态与数据保留)。
  3. 自检:设置 → 通知 → 发送测试通知 → 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

Choose a tag to compare

@201222-L 201222-L released this 08 Sep 17:06

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): 推送通道自检 + 企业微信机器人通道 + 文档同步

Choose a tag to compare

@201222-L 201222-L released this 08 Sep 03:44

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 + App 3.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

Choose a tag to compare

@201222-L 201222-L released this 26 Aug 06:41

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系统,反斜杠路径属于非法路径。

修复方案

  1. 电脑‑服务端改动
    路径分隔符会根据当前运行平台自动适配归一化:WSL/Linux使用/、Windows使用\;目录浏览、新建文件夹、会话工作目录全部生效。
    在 /m/api/directories 根目录接口,新增增量字段 sep,旧版手机客户端会自动忽略此字段,向下兼容。
  2. 手机‑App端改动
    目录选择器不再硬编码反斜杠\,改为读取服务端下发的分隔符拼接路径;工作区列表展示服务端原始路径,路径规范化仅用于内部匹配校验。

升级生效方法

  1. 电脑端:将插件升级至3.1.1,重启DSH程序。仅更新服务端插件,旧版手机App就已经能够恢复目录浏览。
  2. 手机端:安装v3.1.1安装包(覆盖安装,原有数据保留),即可获得完整修复,实现路径正确显示与拼接。

验证情况

  • 单元测试:dirpicker_logic_test.dart 6项测试(正反斜杠拼接、根视图、旧插件回退兼容);wsl‑path‑check.mjs 8项服务端路径归一化用例。
  • 代码检查:flutter analyze无报错;flutter test 24项全部通过;node --check校验成功。
  • Windows平台运行效果与v3.1.0版本完全一致,无回归问题。

注意:本次开发者无真实WSL硬件环境,没有做真机实测;WSL使用者升级后遇到异常,欢迎继续提交反馈。

更新包附件

  1. DSH‑Remote‑v3.1.1.apk — 手机客户端安装包(版本3.1.1+16)
  2. dsh‑mobile‑remote‑v3.1.1.tgz — 电脑端插件包(3.1.1版本,包含修复代码与配套文档)

补充备注

  1. 纯Windows无WSL用户:该版本与3.1.0功能完全一致,非必要可不升级;如需升级则插件与手机App版本同步更新。
  2. 版本兼容性:sep属于纯新增字段,插件与App任意新旧版本交叉组合都可以正常运行,低版本一方不会获得新特性。完整兼容规则可查阅README文档「版本与兼容」章节。dsh-web 移动端远程同装时请配 path: /mr 共存。

DSH Remote v3.1.0

Choose a tag to compare

@201222-L 201222-L released this 24 Aug 21:08

新增(感谢社区 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

Choose a tag to compare

@201222-L 201222-L released this 22 Aug 22:02

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

Choose a tag to compare

@201222-L 201222-L released this 21 Aug 19:38

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 版本逐版更新适配。等待以下任一信号出现后再恢复跟进:

  1. DSH 发布 1.0 正式版 或官方宣布 API/插件接口冻结;
  2. 官方明确停止破坏性变更(存储格式、插件契约稳定)。

届时可能对项目进行重构:重新梳理依赖策略(当前核心依赖精确锁定 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

Choose a tag to compare

@201222-L 201222-L released this 21 Aug 14:50

一、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 版本逐版更新适配。等待以下任一信号出现后再恢复跟进:

  1. DSH 发布 1.0 正式版 或官方宣布 API/插件接口冻结;
  2. 官方明确停止破坏性变更(存储格式、插件契约稳定)。

届时可能对项目进行重构:重新梳理依赖策略(当前核心依赖精确锁定 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,反馈与测试支持。