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 缓存来实现迁移。
核心功能¶
-
跨工作区拖拽逻辑
- 拖到目标工作区头行:会话归入该工作区,并追加到列表末尾。
- 拖到目标工作区会话行上半部分:插到该会话前面。
- 拖到目标工作区会话行下半部分:插到该会话后面。
- 同工作区内拖拽:不拦截,仍由官方处理排序。
-
迁移与安全
- 后台作业执行:长迁移在后台作业中执行,避免界面无响应。
- 帧操作:只重写第一帧(header),尾部原样复制,写完自检。
- 旧目录处理:旧目录移出 sessions 根,停在备份区(
<root>/../session-drag-move-backup)。 - 运行检查:迁移前检查会话是否在运行,运行中或当前会话会被拒绝。
- 目标冲突:目标文件已存在则整体拒绝,不做半截写入。
-
侧栏适配
插件按运行时 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。