dsh-session-drag-move: Drag-and-Drop Migration of DSH Left Sidebar Sessions Across Workspaces

DeepSeek Harness (DSH) 的左侧栏工作区面板中,官方只支持同工作区内的会话拖拽排序。跨工作区拖拽时,onDrop 不会触发,insertSessionBefore 也会拒绝不属于本工作区的会话。dsh-session-drag-move 插件接管了这段原本空白的交互,实现了真正的会话迁移。

安装与启用

插件通过 CLI 安装:

dsh plugin --profile desktop add dsh-session-drag-move

若需手动安装,需将插件目录放入 profile 的 node_modules 中,并在 cordis.patch.yml 中注册。

工作原理

DSH 中会话的归属是派生的:工作区包含所有 header 的 cwd 等于本工作区路径的会话。workspace.json 里的 sessionIds 只是顺序账本。要换工作区,必须改 header。

会话日志是 Zstandard 帧的拼接,第一帧即为 header。插件通过重写第一帧的 cwd,原样复制尾部帧,再同步 registry 缓存来实现迁移。

核心功能

  1. 跨工作区拖拽逻辑

    • 拖到目标工作区头行:会话归入该工作区,并追加到列表末尾。
    • 拖到目标工作区会话行上半部分:插到该会话前面。
    • 拖到目标工作区会话行下半部分:插到该会话后面。
    • 同工作区内拖拽:不拦截,仍由官方处理排序。
  2. 迁移与安全

    • 后台作业执行:长迁移在后台作业中执行,避免界面无响应。
    • 帧操作:只重写第一帧(header),尾部原样复制,写完自检。
    • 旧目录处理:旧目录移出 sessions 根,停在备份区(<root>/../session-drag-move-backup)。
    • 运行检查:迁移前检查会话是否在运行,运行中或当前会话会被拒绝。
    • 目标冲突:目标文件已存在则整体拒绝,不做半截写入。
  3. 侧栏适配
    插件按运行时 DOM 契约识别行,而非源码类名:

    • 主契约:[data-row-key="session:<id>"] 和 [data-row-key="workspace:<id>"]
    • 兜底:*_sessionRow 类名后缀,[draggable="true"] 和 [role="treeitem"] 属性
    • 适配第三方侧栏(如 dsh-better-workspace)时,按源码类名匹配一定失败,插件通过匹配后缀与属性保持兼容。

已知限制与依赖

  • 版本敏感:插件依赖 workspaceRegistry 的内部字段(headers / sessionPaths / host.rememberSessionPath)。这些字段版本敏感,插件会进行 feature-probe,探测不到会返回结构化错误。
  • 缓存同步:投影缓存 ~/.dsh/stores/session_projcache/sessions/<id>.json 里的 record.identity.cwd 目前未改写(不影响归属)。
  • 静默失败:若某个侧栏把 data-row-key 等信号全部换掉,插件会静默不接管(不影响原生拖拽),可通过控制台日志 [sm] 定位。

API 接口

长迁移在后台执行,可通过以下接口查询进度:

POST /session-drag-move/api/move       # 开始迁移,传 wait: true 可同步等待结果
POST /session-drag-move/api/progress   # 查询进度,返回 state, phase, detail, result, error

phase 取值包括 resolve, scan, index, read, rewrite, write-main, move-extras, backup, ledger, branches, done。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye