前言¶
DSH 的會話散落在 $DSH_HOME/sessions/<工作區編碼>/<會話 id>/ 下,官方只提供了歸檔能力,沒有真正刪除。想清理掉某個舊會話,只能手動上去刪目錄;更麻煩的是,只要這個會話還被宿主加載在內存裏,刪了文件它也會被寫回來,重啓後照樣出現。
full626/dsh-session-trash-90d 就是來填這個缺口的:一個 DSH 客戶端組合包,在 Web GUI 裏給出會話列表、回收站、恢復、徹底清除,以及官方缺失的「取消歸檔」。下文按「它解決什麼 → 怎麼用 → 哪裏要注意」來講。
這是什麼¶
一句話定位:DSH Web GUI 的會話管理插件,提供列表、歸檔 / 取消歸檔,以及真正刪除(可恢復的回收站先接住,再做不可恢復的徹底清除)。
- 維護者:Full626
- 分類:客戶端(DSH 組合包 bundle,不是獨立應用)
- 星標:0
- 許可證:MIT
- 適用宿主:DSH
>=0.2.0 <0.3.0,Node>=22
它的入口是「設置 → 會話管理」,不新增獨立界面。
爲什麼不能直接刪文件¶
DSH 0.2.x 的 sessionPersistence 只有 create/open/stat/list/flush,sessions 只有 create/prepare/enter/announce/flush/get/list/fork,沒有刪除會話的 API。所以「真刪」只能直接刪磁盤上的工件。
而以前的「真刪」插件在這裏踩坑:它們只跳過 agent.status === 'running'(正在生成回覆),但 running 和 live(已加載進內存)是兩回事。於是「idle 但 live」的會話被刪掉文件後,宿主會把它寫回來,重啓後等於沒刪。
這個插件的做法是墓碑 + 啓動重放:
刪除請求
├─ 非 live → 直接刪文件(乾淨)
└─ live → 記一條墓碑 + 嘗試釋放 + 刪文件,並如實標記 pending
宿主每次啓動(+5 秒後補一次)→ 重放墓碑:此時沒人打開它們,刪了就真沒了
確認消失且不再 live 後,墓碑才被清掉
每次刪除會同時清理:會話目錄、投影緩存、歸檔集合、workspace 記賬。
設計上有一個取捨值得記一筆:host 半側只依賴文件系統,加上兩個可選服務——workspaceRegistry 管歸檔集合,sessions 做 liveness 探測——不碰任何私有 API。將來 DSH 重構時,這個插件的表現是降級(列表變空)而不是崩掉。
核心功能¶
| 功能 | 說明 |
|---|---|
| 會話列表 | 標題、工作區、最近修改、大小,以及 內存中 / 已歸檔 標記 |
| 移入回收站 | 不直接抹掉:會話目錄帶投影緩存一起搬進 sessions-trash,保留 90 天 |
| 恢復 | 放回原來的工作區,緩存一併還原 |
| 徹底清除 / 清理過期 | 手動清單個,或清掉超過 90 天的;列回收站時也會自動清 |
| 空會話摺疊 | 只開過沒用過、只有頭部記錄的會話默認隱藏,可展開 |
| 歸檔 / 取消歸檔 | 官方只有歸檔沒有取消,這裏補上 |
| 墓碑狀態 | 界面提示還有幾個待下次啓動處理 |
導出沒有做,官方 /export 已經夠用,不重複造。
回收站的目錄結構¶
$DSH_HOME/sessions-trash/<刪除時間戳>-<會話 id>/
├─ meta.json 原工作區、標題、大小、刪除時間
├─ session/ 會話目錄(原樣搬過來)
└─ cache.json 投影緩存(原樣搬過來)
每個條目自帶元數據,沒有全局清單,所以不會出現清單和實際文件對不上的情況。目錄名以時間戳開頭,天然按時間排序;恢復就是原路搬回去。過期清理在兩個時機觸發:宿主啓動時,以及每次打開回收站時。
安裝與啓用¶
本包是 DSH 組合包(bundle):profile 只要把包名選進 dsh.profile.bundles,加載器就會應用自帶的 cordis.patch.yml。
倉庫裏的 install.ps1 腳本支持三種幹跑方式:
cd dsh-session-trash-90d
.\install.ps1 -Profile desktop # 默認就是 desktop
.\install.ps1 -Profile desktop -DryRun # 只看將要做的改動
.\install.ps1 -Profile desktop -Uninstall
第一步,先 DryRun。 它會打印將要改哪些 profile 文件,確認無誤再真正執行。
也可以走 profile 自己的插件管理器(設置裏的「插件」頁),填倉庫地址:
https://github.com/Full626/dsh-session-trash-90d
或命令行:
dsh plugin --profile desktop add 'github:Full626/dsh-session-trash-90d'
第二步,重啓應用。 新組合層要下次組合才生效,裝完不重啓看不到變化。
第三步,打開設置 → 會話管理。
典型用法¶
裝完重啓後,日常操作都在「設置 → 會話管理」裏完成:
1、會話列表裏看到所有已存儲會話及其元信息,區分 內存中 和 已歸檔。
2、要清理某個會話,點「移入回收站」——它連目錄帶緩存一起搬走,不是直接抹掉。
3、需要找回時,在回收站裏點「恢復」,它會回到原來那個工作區。
4、確認不要了,才用「徹底清除」,或把超過 90 天的交給「清理過期」。
宿主內存里正活着、又沒能釋放的會話,刪除後不會立即消失。界面上會提示「還有 N 個待下次啓動處理」,這是刻意的誠實:下次宿主啓動時重放墓碑,確認消失且不再 live,墓碑纔會被清掉。
命令行側也有一組接口可用於自動化:
| 方法 | 路徑 | 說明 |
|---|---|---|
| GET | /list |
會話列表 + 待處理墓碑 + 保留天數 |
| GET | /trash |
回收站條目(順帶清理過期項) |
| GET | /state |
墓碑、home、兩個根目錄、保留天數 |
| POST | /delete |
body {"ids":[...]} —— 移入回收站 |
| POST | /restore |
/purge |
| POST | /archive |
/unarchive |
驗證時怎麼跑¶
主機半側有一套不碰真實數據的測試:在臨時 $DSH_HOME 裏造假會話,用最小 fake ctx 驅動真實插件代碼,專門覆蓋那個迴歸——假造「內存回寫」,再驗證啓動重放把它清掉。
node scripts/test-host.mjs # 27 項:列表/刪除/墓碑/重放/歸檔/錯誤處理
跑在真實桌面端上的檢查,默認只讀:
# 只讀:列出會話、墓碑狀態
node scripts/check-api.mjs --url http://127.0.0.1:19387
# 真要刪幾個(謹慎)
node scripts/check-api.mjs --url http://127.0.0.1:19387 --delete session-xxxx
適用場景與注意¶
適合這些人:
- 在 DSH 0.2.x 上做開發,受夠了「會話刪不掉 / 刪了又回來」。
- 需要批量清理舊會話,又不希望誤刪後無法找回。
- 需要取消歸檔這項官方沒提供的能力。
需要留意的幾點:
1、刪除默認保留 90 天;「徹底清除」和過期清理纔是不可恢復的。所以別把回收站當成無限期保險箱,也別把徹底清除當常規操作。
2、回收站佔用磁盤,刪得多了記得清,或讓它自己過期。
3、宿主正在運行某個會話時不會刪它(會跳過並告知),這是刻意設計,不是 bug。
4、插件以當前 DSH 進程權限運行,裝的是就直接改 profile 文件——安裝前先讀源碼和 MIT 許可證,install.ps1 先加 -DryRun 看一遍。
5、會話正文是 JSONL + 多幀 zstd,本插件只做管理,不解析正文內容,拿不到「這會話講了什麼」的語義。
6、路徑佈局按 DSH 0.2.x 的 $DSH_HOME/sessions/<工作區編碼>/<會話 id>/ 解析;將來若改佈局,表現是列表變空而不是誤刪。
7、本插件是社區第三方包,目錄頁與倉庫都是獨立站點項目,與 DeepSeek / 幻方沒有官方從屬關係。
小結¶
dsh-session-trash-90d 的價值在於它承認了「會話刪了會復活」這個真實約束,並給出一個可驗證的解法:墓碑 + 啓動重放,加上 90 天回收站、原工作區恢復、取消歸檔。如果你正在 DSH 0.2.x 上做會話治理,值得先 node scripts/test-host.mjs 看那 27 項測試跑通,再裝到 profile 上。
目錄頁:https://www.skillhub.cn/plugins/Full626/dsh-session-trash-90d
倉庫:https://github.com/Full626/dsh-session-trash-90d