Repository navigation
Releases: haotian-lu-prog/dsh-archived
Releases · haotian-lu-prog/dsh-archived
Release list
dsh-archived 0.4.1 — 彻底删除后的幽灵行
修的是什么
彻底删除一个已归档会话后,它会重新出现在工作区列表里(文件其实已经删了),
只有重启 DSH 才消失。
根因
- 归档只是把 id 放进 workspace registry 的
archivedSessionIds——那是唯一让会话从所有列表里消失的东西; - 归档不释放宿主持有的活会话,而浏览器的行来自
session.list= 持久化 header ∪ 活会话,
所以宿主仍能为一个文件已删的会话产出摘要; - 工作区的
sessionIds记账位从未被碰过——解除隐藏后行立刻回到原工作区分组。
「删文件 + 立刻清索引」= 让宿主内存里的幽灵立刻可见。
修法
- 宿主还记着这个会话时,索引条目先留着(唯一挡住幽灵行的那一处),记进
$DSH_HOME/dsh-archived/deferred.json,面板不画它,宿主放手(重启必然放手)后自动清; - 永久删除额外走官方
Workspace.detachSession摘掉工作区记账位,并广播
api-session/removed,让已打开的客户端当场收行; - 回收站路径不摘记账位、不广播——恢复要回到原位。
升级
dsh plugin --profile <profile> remove dsh-archived
dsh plugin --profile <profile> add dsh-archived@0.4.1同路径的版本升级不会让宿主重新 import,必须 remove + add 或重启。
验证
npm test:host-smoke 102 / client-smoke 31 / compat-check 12 全绿;- 真宿主
tools/e2e.py连跑三遍:61 PASS / 3 SKIP / 0 FAIL; - 隔离宿主上复现幽灵行场景:修复后删除当时幽灵被挡住、重启后索引条目自动清;
- 消费者冒烟:
npm pack产物装进全新 profile 再跑 e2e,同样全绿。
dsh-archived 0.4.0 — 清理陈旧会话
新增:「清理陈旧会话」
「设置 → 已归档」页顶部新增一节,专门处理没归档过、但早就不用了的会话:
- 扫描(只读):默认 14 天没写过的,或从没有过用户消息的空会话;下拉可切 7 / 14 / 30 天
- 删除:勾选后二次确认 → 进同一个回收站(30 天内可恢复),并通过官方
Workspace.detachSession从工作区列表摘除 - 每周半自动(默认关):开启后每周最多跑一次,只入回收站,永远不做永久删除
安全边界
- 24 小时硬保护:日志在 24 小时内写过的一律不列、不删(与天数设置无关)
- 正在运行、或有运行中子代理后代的会话 → 直接拒绝
- 已归档会话不由这一节经手(仍归归档流程),扫描阶段就过滤掉
- 宿主缺
Workspace.detachSession→ 返回no-detach拒绝删除,不会出现「删了文件却留下悬挂行」 - 「陈旧」以日志文件的最后写入时间为准,不看
session.lock(宿主每次打开会话都会重建它,算作活跃会让死会话永远年轻)
新增路由
POST /api/dsh-archived/sweep/scan · /sweep/delete · /sweep/settings · /sweep/run
验证
| 套件 | 结果 |
|---|---|
npm test |
131 项全绿(host-smoke 88 · client-smoke 31 · compat-check 12,其中新增 detachSession 契约断言) |
真宿主 tools/e2e.py(隔离宿主) |
55 PASS / 3 SKIP / 0 FAIL,新增场景:候选识别 → 24h 保护拒绝 → 入回收站 → 设置落盘 → 每周只跑一次 |
| 打包 | npm pack 11 个文件,含 lib/host/sweep.js 与 cordis.patch.yml,无 .ts 残留;装进隔离 profile 可被 --dump-config 识别 |
顺带修正两处既有断言(main 上同样失败,非本次引入):e2e 的「无 marker 即拒绝」对齐 0.3.1 放宽后的信任模型;GET /state 的尺寸断言改为等日志落盘再断言。
升级
dsh plugin --profile <profile> add dsh-archived@0.4.0不需要迁移:自动清理默认关闭,开启时才创建 $DSH_HOME/dsh-archived/sweep.json。
dsh-archived 0.3.2 — 导入会话删不掉
修了什么
「设置 → 已归档」里删不掉:面板画得出那 40 条导入会话,但逐条删除、批量删除、恢复、打开文件夹全部被回绝,而且一个字节都没动(回收站 mtime 还停在 10-02,投影缓存文档 mtime 还是导入那一刻)。
两个缺陷,各自都能造成静默失败:
- id 白名单写死。
SESSION_ID只认session-<uuid>,而归档索引里的行是导入插件命名的import-<uuid>/import-session-<uuid>,deleteOne()第一行就回绝。 - 目录名 ≠ 注册表 id。 归档索引存带命名空间的 id,磁盘上的会话目录是
session-<uuid>或裸 uuid(DSH 按日志头里的id命名)。老locateArtifacts拿注册表 id 拼路径,真机 40 条命中 0 条——只修正则的话会「报告成功、日志全留在盘上」,正是本插件存在的意义所要防的那种假成功。
改动
SESSION_ID收三种形态;新增canonicalSessionId()(注册表 id → 存储 id,供宿主 API 与磁盘用)与artifactIdCandidates()locateArtifacts按decodeSegment解出的目录名与候选比对,只认候选内的名字,命名空间撞车也不会误删别的会话日志- 导入行可能别名到一个正在跑的会话(
import-<uuid>的裸 uuid 撞上session-<uuid>),新增runningAlias拒绝 - 回收站与缓存文档一律用存储 id;
restoreSession把目录放回存储 id 名下 - 客户端
request()现在会因非 2xx 抛错(以前 403/500 照样 resolve,再在payload.results.filter上抛TypeError,把真实原因换成一句通用文案)
验证
| 套件 | 结果 |
|---|---|
tools/host-smoke.mjs |
68/68(新增 import id 回归,含别名拒绝与 5 条畸形 id) |
tools/client-smoke.mjs |
31/31 |
tools/compat-check.mjs |
11/11 |
tools/e2e.py |
40/40(隔离 DSH_HOME + dsh --profile web,插件指向本仓库) |
无破坏性变更:没有新增能力,也没有需要使用者改配置的地方。