- Inicio
- Plugins
- Sesiones y mensajes
- dsh-plugin-workspace-archive
dsh-plugin-workspace-archive
windfromkadath/dsh-plugin-workspace-archive
Archives the sessions of a workspace when its folder is deleted or moved away, or when its registration is removed, and restores them when it returns: unarchives only the sessions it archived itself, re-attaches every member its ledger recorded (including sessions you archived manually, whose archived state is left unchanged), and adopts ungrouped sessions whose working directory is that workspace path.
Instalar
dsh plugin --profile web add github:windfromkadath/dsh-plugin-workspace-archiveREADME
dsh-plugin-workspace-archive
DSH(DeepSeek Harness)插件:工作区文件夹被删除或移走时,把它名下的会话归档;同一个文件夹放回来时,把这些会话带回该工作区 —— 只走官方 API。
English: README.en.md
它补的是哪条缝
DSH 有意把"目录缺失"和"归档"分开:
- 目录无法校验的工作区(被移动、被删除、从未记录)无法加入新会话,其中的会话会散成「无项目」;
- 「移除项目」保留文件夹与会话历史,但重新添加同一目录会从空项目开始:旧会话不会自动回来。
本插件补上这条缺失的联动。它不改 app.asar、不写官方 storages/ 与 sessions/ 文件,自己的记账放在 DSH 主目录下的 sidecar 里。
它做什么
| 触发 | 结果 |
|---|---|
| 已登记的工作区目录被删除或移走 | 把该路径下由本插件登记过的会话归档(侧栏默认视图不再显示,在"全部对话"里仍可见) |
| 工作区登记被移除(菜单里的「删除工作区」,文件夹还在) | 同样视为消失并归档 —— 否则那些对话会散成「无项目」。这一条不等确认窗口:官方删除登记是即时的,等窗口就是让你盯着那批对话散在侧栏里看几秒 |
| 目录或登记回来 | 本插件归档过的那批会话取消归档;并且台账里记过的全部成员都会被挂回该路径的工作区 —— 包括在消失之前就已经归档的会话(典型是你自己手动归档的) |
| 一条会话待在「无项目」里,但它的工作目录就是某个已登记工作区的路径 | 启动后自动挂回该工作区(判据:不在任何工作区的成员表 + 目录精确相等;可用 adoptUngrouped: false 关闭) |
你说「归档这个工作区」(模型调用 workspace_archive 工具) | 该工作区里官方尚未归档的会话被收进归档;action='unarchive' 恢复 —— 只放回本工具归档的那批,你自己在官方界面里归档的原样不动。(注意:归档不等于隐藏工作区行 —— 官方默认每个分组都显示,行还在,只是下面空了) |
你在输入框打 /archive-workspace <路径或标题>(或 /restore-workspace <…>) | 和上一行同一个动作,但由你自己触发、不经过大模型。命令注册在宿主侧(官方 dsh-commands),输入框的命令弹窗里能选;恢复用的还是那批独立清单 —— 所以它不会放回你自己在官方界面里归档的会话 |
三条永不违反的规则:
- 你自己归档的会话永远不会被取消归档:它们只是回到自己的分组里,仍然隐藏,直到你手动取消归档;
- 归档 / 恢复只处理它记过账的会话:台账是插件运行期间、工作区健康时写下的;这条路径绝不按工作目录反查。唯一的例外是启动后那一次归位:只把工作目录精确等于某已登记工作区路径、且不属于任何工作区的会话挂回去,可用
adoptUngrouped: false关闭。 - 手动归档与自动归档是两份清单,互不撤销:你让它归档的工作区,不会因为那个目录"消失又回来"被自动流程放出来;反过来,自动归档的那批手动恢复也碰不到。
它为什么做得成(关键机制)
因为这条能力不需要改任何文件:DSH 里"会话属于哪个组"存在工作区记录的一份成员表里,而官方恰好提供了往这份表里补一笔的 API(Workspace.attachSession)。
- 分组是"名册",不是"档案"里的字段。 会话日志里写的是它自己的工作目录;"它显示在哪个工作区下"是工作区记录里的成员表 —— 改分组 = 改名册,官方允许。
- 官方挂载只校验一个条件,而这个条件天然成立。
attachSession会读会话 header 的cwd,要求它规范化后精确等于该工作区路径,否则拒绝;而"无项目"里的孤会话,cwd 本来就等于那个路径 —— 官方自己会放行(它也顺手代我们复核了一遍,塞错组在机制上不可能)。 - "没在名册上"是官方自己留下的空洞。 官方只在第一次启动时按 cwd 把已有会话归组一次(bootstrap 一次性,写完 initialized 标记就不再跑),此后新增的工作区不会再回头认领旧会话 —— 这正是本插件补的那一步。
而"把会话从一个工作区迁到另一个工作区"做不到(在只走官方 API 的前提下):那要求改 cwd 本身,可它是写死在会话日志里的,官方没有任何改 cwd 的 API。详见 docs/recon/05-migration-and-multi-folder.md 与 docs/plan-session-migration.md。
环境要求
- DSH(DeepSeek Harness)桌面版或 CLI;开发与验证基线是
0.2.0-rc.2。 - Node.js 22.5+(由宿主提供)。
- 零运行时依赖:插件不 import 标准库以外的任何东西 —— 这是刻意的:通过目录联接装载的插件按真实路径解析嵌套 import,够不到宿主自带的包。
安装
三种方式,推荐第一种:
-
从 npm 安装(推荐,2026-10-08 已发布
0.1.0)dsh plugin add dsh-plugin-workspace-archive插件管理器走 npm registry(官方源,回退
registry.npmmirror.com;两侧实测都已同步)。想钉版本就写dsh-plugin-workspace-archive@<version>。 -
从本地检出安装(本仓库真机验证用的就是这条):把目录联接进 profile 的
node_modules,并把包名写进 profile 清单。本机用.verify/install-desktop.mjs一次完成这四步,--uninstall可回滚。 -
从本仓库按提交安装:官方插件管理器也接受 GitHub 规格,例如
dsh plugin add github:WindFromKadath/dsh-plugin-workspace-archive#<commit>。
必须重启宿主/应用:插件行与 bundle 在启动时固定,HMR 从不热装载。配置默认值在 src/index.js 的 resolveConfig;profile 的 patch 行可以覆盖 dryRun、confirmDelayMs、pollIntervalMs、watch、adoptUngrouped、adoptDelayMs。
验证
npm test—— 157 项离线断言(工具行为、决策层、台账、真 Cordis 装载、"无项目归位"的选择逻辑、消失判据的分档确认、目录 watcher 对「改名」事件的唤醒与不放大无关 churn、手动归档工作区的决策与工具定义契约、斜杠命令的注册与 handler 行为、tasks.csv自身的结构守卫,以及"插件源码不得 import 宿主包"的回归)。npm run rm-test—— 69 项针对真 DSH 运行时(一次性DSH_HOME)的断言:建工作区 → 建两个真会话 → 删目录 → 断言只归档该归档的那个 → 放回目录 → 断言它被恢复并挂回工作区,而"用户手动归档"的那个保持归档 → 删除登记再重新添加 → 断言都回到分组 → 未分组的孤会话被自动归位 → 命令阶段:真dsh-commands里/archive-workspace、/restore-workspace确实注册成功且真能归档/恢复(含 3 条对照,证明"查询路径 / 定义形状 / inject 接线"各自可用)→ 改名阶段:改文件夹名后插件被叫醒并在同一窗口内归档。npm run check—— 语法。
上面两套数字是本仓库整套测试套件的总数。仓库里另有一条探索分支(不随本包发布),它的测试也计入其中;见 docs/plan-session-migration.md。
两套都可在本仓库一键重跑,且不碰真实 profile、不碰真实工作区目录。设计约束、已采纳决策与证据线索见 MAINTAINER.md。
已知限制
- 「删除工作区」立即归档,「目录缺失」要等几秒,这不是不一致:目录缺失是一次
stat的观测,可能抖(网络盘、改名中途),所以要等确认窗口(默认 3 秒);而「删除工作区」是官方注册表的权威变更,且本次运行中见过这条登记,所以立即动手。插件刚启动、注册表还没铺完时不会走这条快路(那时"不在清单里"和"被删了"分不清),会退回确认窗口。 - 归档 / 恢复只认它记过账的会话:若"删除 → 重新添加"发生在插件没运行的时候,它只认得台账里最后一次快照 —— 快照里有的成员会被挂回,更早散掉的不会(这类可以由启动时的归位补上,前提是 cwd 仍等于该工作区路径)。
- 挂回分组 ≠ 取消归档:
attach只动工作区成员表,从不碰归档集合。 - 归位只跑一次(启动后延迟 5 秒):之后新出现的孤会话要等下次重启。
- 跨工作区迁移做不到:需要在离线改写会话日志的 header,官方没有这个通道;而且即使改写成功,官方也没有公开入口去重建它在内存里缓存的会话 header ⇒ 必须重启 DSH 才生效。⇒ 这是一条上游能力缺口,本插件不提供该功能。完整的探索记录(机制、实测证据、为什么做不到)见 docs/plan-session-migration.md —— 该目录不随 npm 包发布。
- 不做会话删除、不删文件夹、不做跨机器同步。
- 目录被改名等于换了一个路径:挂回时官方会校验 cwd,对不上时插件只记日志、不改数据。
更新记录
每个已发布版本的内容见 CHANGELOG.md。当前版本 0.2.0。
许可证
MIT —— 见 LICENSE。
Plugins relacionados
dsh-web-ui (dsh-chat-recovery)
zhu1090093659/dsh-web-ui
billion-context
ranxianglei/billion-context
dsh-synapse
liangmianya/dsh-synapse
dsh-chat-import
nwflower/dsh-chat-import