前言¶
DSH 的「歸檔」只是一個標籤。它會話寫進取 storages/workspace.json 的 archivedSessionIds 之後,官方的 archived-session-gate 保證的是這個會話「在還原前不再跑模型步驟」,但它不保證這個會話不再佔磁盤:會話日誌仍留在 .dsh/sessions/<工作區>/<會話id>/,投影記錄仍留在 .dsh/storages/session_projcache/sessions/<id>.json。
問題在於投影記錄用的是 JSON 後端,官方註釋寫明讀寫共享統一的內存狀態,也就是說全部記錄常駐內存。按 README 裏的實測:2395 條記錄 / 169.5 MB JSON,其中 126 條已歸檔的記錄佔 40.8 MB(24.1%),條目數只佔 5%。歸檔的大多是長篇會話,恰好是最佔地方的那批。
下面介紹的沉眠閣(slumberpavilion)就是處理這件事的:把已歸檔會話的日誌目錄和投影記錄真正移出 .dsh,落到 ~/DSH-Archive,並提供讀取、還原、刪除工具。維護者是 AngleNaris,分類爲記憶。
這是什麼¶
沉眠閣是一個 DSH 插件,做的事是三件事:每隔一段時間檢查 archivedSessionIds,發現新歸檔的會話;把它的日誌目錄與投影記錄移動到 ~/DSH-Archive(不是刪除);在 manifest.json 裏記下來源與去向,隨時可以還原。
它保持免配置:安裝並加載後即可使用,沒有獨立的用戶配置界面,也不需要用戶設置參數。搬移是插件的設計行爲,不是可選動作。
核心功能¶
加載約 15 秒後首次掃描,之後後臺按 20 秒間隔檢查歸檔列表。插件只搬移已被 DSH 標記爲歸檔的會話,不會主動把普通會話寫成歸檔。使用 DSH_HOME 的宿主從該目錄讀取歸檔區。
搬移保留原文文件與還原清單。archive_delete 是單獨的永久刪除操作,不可恢復,且工具調用沒有二次確認。
讀取歸檔內容¶
這是插件區別於「直接把文件挪走」的部分:它把歸檔會話的多幀 zstd 日誌按幀魔數 28 B5 2F FD 切開逐個解壓,因爲 DSH 的 session.v4.jsonl.zstd 是邊寫邊追加的多幀格式,Node 的 zstdDecompressSync 只解第一幀就收工。README 裏的實測結果:60.6 MB 的會話共 31,528 幀、56,701 行、零失敗,壓縮比約 ×3.8。
Agent 工具¶
插件註冊五個工具,可直接在對話裏調用:
| 工具 | 作用 |
|---|---|
archive_list |
列出歸檔會話,按體積降序 |
archive_read |
讀一個歸檔會話,支持 keyword 過濾、compact 只留對話輪次、maxChars 逐條截斷 |
archive_session |
執行歸檔:標記 + 立刻搬走,不用等後臺掃描 |
archive_restore |
還原歸檔:搬回 .dsh、撤銷歸檔標記、清清單 |
archive_delete |
永久刪除一個歸檔會話(日誌 + 投影文件 + 清單條目) |
單次命中是硬約束:ID 或片段模糊命中多條時拒絕執行並列出候選,避免搬錯會話。歸檔正在跑的會話默認拒絕(WorkspaceActiveSessionError),加 stopActivity=true 則先請求停掉它的工作再歸檔。拒絕歸檔正在執行這條工具的那個會話。
archive_session 走宿主的 ctx.workspaceRegistry.archiveSession(),所以歸檔狀態由 DSH 自己寫進 workspace.json,不靠改文件;標記落盤後插件立刻執行一輪 sweep(),返回裏報出最終目錄。
archive_restore 的順序是「搬文件 → unarchiveSession() → 清清單」。目標位置已有同名目錄時拒絕;清單裏記着原始 from,優先搬回原位,沒有記錄時退回 .dsh/sessions/<工作區>/<會話 ID>;投影記錄跟着搬回,目標已存在的不覆蓋。撤銷標記失敗時仍然搬文件,並在返回裏明確警告「它仍算已歸檔,請在界面取消歸檔」。
安裝與啓用¶
在 DSH 插件商店安裝沉眠閣並由宿主加載即可,無需填寫配置或修改插件參數。
手動集成到 profile 時,在該 profile 目錄安裝 npm 包:
npm install slumberpavilion
然後在 profile 的 package.json 裏把包裝進 bundles:
"dependencies": {
"slumberpavilion": "^0.1.1"
},
"dsh": {
"profile": {
"bundles": [
"...",
"slumberpavilion"
]
}
}
重啓 DSH。本地開發時可以用 file: 依賴加一條符號鏈接代替 npm 安裝:
ln -s ../plugins/slumberpavilion ~/.dsh/profiles/desktop/node_modules/slumberpavilion
典型用法¶
歸檔搬移默認自動進行,無需額外啓用。裝好之後通常的路徑有兩種,效果一樣。
方式一是命令行,不依賴 DSH,隨時可用:
node lib/cli.js list 20
node lib/cli.js read f8ab825e 上下文壓縮 50
node lib/cli.js info f8ab825e
方式二是對話裏直接調工具。要歸檔某個會話,先跑一次帶 dryRun=true 的 archive_session 看清目標,確認無誤後去掉 dryRun 執行;要還原同理先 dryRun 再看目標目錄。archive_delete 不可恢復且沒有二次確認,調用前同樣務必先跑 dryRun=true。
手動還原的話,manifest.json 裏每個條目都記着 from(原路徑)與 to(歸檔路徑),把 to 移回 from,再去界面裏取消歸檔並從清單刪掉那一條。
兼容性¶
- README 聲明的 DSH 宿主範圍爲
>=0.2.1-rc.2 <0.4.0-0;已記錄的桌面實測版本僅爲 DSH 0.2.1-rc.3。範圍聲明不代表其他版本均已完成實測。 - Node.js 要求
>=22.15.0,用於讀取 zstd 會話日誌;桌面版以其內置 Node.js 爲準。 - 插件依賴宿主的
tools、workspaceRegistry服務,以及sessions、storages/workspace.json和storages/session_projcache/sessions的內部佈局。宿主改變這些接口或文件佈局時需要重新驗證兼容性。 package.json在dsh.engines.dsh聲明宿主範圍,並在頂層engines.dsh保留同值供兼容讀取。這兩處都是發佈元數據,無需用戶配置。- 源碼裏的
Configschema 與cordis.patch.yml參數用於 Cordis 宿主裝配、內部實現和測試,不代表本插件提供了用戶設置界面。
已知邊界¶
掃描只處理「已歸檔」的會話,歸檔標記由 DSH 寫。移動後 workspace.json 裏的 archivedSessionIds 不會清理,會指向一個不存在的會話;README 說明實測這不影響啓動,列表按投影記錄渲染,記錄沒了就不顯示。
若會話日誌已被 DSH 重新摺疊出新的投影記錄,下次掃描會再搬一次。判據覆蓋頂層與各批次目錄的 manifest.json,早先只讀頂層那份,老批次條目會被當成沒搬過、每輪空轉一次。
archive_session 只認磁盤上還在 .dsh/sessions 裏的會話;只剩歸檔副本的請用 archive_list / archive_read。
適用場景與注意¶
適合那些會話數量多、長篇歸檔會話佔比高、因此 session_projcache 常駐內存明顯喫緊的 DSH profile。這類會話繼續留在 .dsh 裏不會帶來任何價值,搬走之後既省內存也能在需要時讀回來。
使用前需要注意幾點。插件以當前 DSH 進程的權限運行,裝的是它會自己搬文件、改清單,archive_delete 不可恢復且沒有二次確認,因此安裝前應先檢查源碼與許可證(本項目爲 MIT)。執行歸檔、還原、刪除操作前先用 dryRun=true 看目標路徑。
另外排障信息寫在 %TEMP%\slumber-pavilion-diag.log,裏面記一行 apply、一行 defineTool 是否取到、每個工具是否註冊成功,改了代碼重載插件後先看這個文件。
結尾¶
沉眠閣把「歸檔」從一個只改標籤的動作,變成一個真正把日誌與投影記錄移出加載路徑的動作;需要時能再讀回來、搬回去或徹底刪掉。項目地址:插件目錄頁 https://www.skillhub.cn/plugins/AngleNaris/slumberpavilion ,源碼 https://github.com/AngleNaris/slumberpavilion 。