前言¶
在 DeepSeek Harness(DSH)裏,Session 持久化插件 @deepseek-ai/dsh-session-persistence-jsonl 只提供 create、open、flush、stat、list,沒有刪除接口。界面可以歸檔 Session,卻無法從側邊欄真正移除一條記錄;Workspace 寫入時纔會順帶 prune id,subagent/catalog 又是隻追加的,客戶端也沒有暴露 delete 的服務。磁盤上的 Session 目錄和日誌會長期堆積,而 Harness 本體並未提供對應的 Web 操作。
社區插件 dsh-session-deleter(維護者 ghgjkbf,分類:記憶)在不改 Harness 核心的前提下,補上「整 Session 刪除」以及「單條消息級」的處理:默認進私有回收站,永久刪除需二次確認;消息側支持 shadow(line A)與 truncate(line B),均可撤銷。下面介紹它的定位、能力與用法。
這是什麼¶
dsh-session-deleter 是一個 DSH bundle 插件(npm 包名 dsh-session-deleter,當前版本 0.2.0,MIT 許可證,要求 Node >= 20)。它在 Harness 自帶的 Web 服務器上掛載 /session-deleter 路由,並在 Web UI 的多個 slot 註冊入口,讓你從瀏覽器完成 Session 與消息的刪除類操作,而不依賴 Harness 尚未提供的刪除 API。
SkillHub 目錄頁:ghgjkbf/dsh-session-deleter。源碼與說明:GitHub 倉庫。SkillHub 是社區插件目錄,與 DeepSeek / 幻方無官方從屬關係;DSH 生態遵循「一切皆插件」,安裝前請自行審閱源碼與許可證。
核心功能¶
整 Session:回收站、恢復、永久刪除¶
插件提供三種可從 UI 觸達的操作(README 原文歸納):
- Delete a whole Session — 將整個 Session 目錄(含各代日誌)移動到回收站,可恢復。
- Restore — 把回收站中的目錄移回原路徑;若目標路徑已被佔用則拒絕覆蓋。
- Delete permanently — 唯一不可撤銷的步驟,也是唯一真正釋放磁盤空間的步驟;需要第二次明確點擊(或 API 傳
confirm: true)。
設計原則:默認可逆。第一次刪除請求不會直接刪字節,在同一文件系統上通過 rename 進回收站,原子完成「破壞性工作」的實質步驟。
單條消息:Shadow 與 Truncate¶
除整 Session 外,插件還通過 HTTP 暴露消息級接口(見下文路由表):
- Shadow(line A):只追加、完全可逆。用
developer/messagetombstone 替換模型可見 fold 中的一個 surface 節點,機制與官方 compaction 類似。轉錄界面仍可能顯示原行(按 surface 約定),但 tombstone 不會對 LLM 派生消息——即從模型上下文裏去掉該條,不從屏幕上去掉。 - Truncate(line B):通過重建「保留的 frame 對齊前綴」從 artifact 中移除事件,轉錄行一併消失;會保留
.bak-備份以便字節級恢復。這是唯一會改寫已有字節的消息操作。
安全與拒絕策略¶
插件會拒絕它無法安全完成的請求,例如:
- 正在運行的 Session 日誌仍被寫入,不在其 writer 下刪除。
- 發起請求的 Session 不能刪除自身。
- Session id 作爲路徑段,形如路徑遍歷的 id 會在觸盤前被拒絕。
- 目錄可同時存在 v3、v4 等多代日誌,實現不硬編碼文件名。
重寫日誌時,每個 durable batch 重發一個帶校驗的 Zstandard frame,.jsonl.zstd 是可獨立解碼 frame 的拼接,而非單一流,以保證後續 append 仍能被後端結構掃描識別。
界面入口¶
| 表面 | Slot | 位置說明 |
|---|---|---|
| 側邊欄底部(Settings 旁) | sidebar.footer.action |
order: 20,始終可見,無需 hover |
| Session 選擇對話框 | shell.overlay |
由底部入口打開 |
| Session「…」菜單 | sidebar.workspaces.session.menu.item |
order: 500,在 pin/rename/fork/archive 之後 |
| 確認對話框 | shell.overlay |
全框浮層 |
| 管理頁 | settings.section |
Settings 內 order: 50 |
| 管理頁(同一內容) | shell.overlay |
order: 5,插件內管理浮層 |
側邊欄底部入口是主入口:DSH 只在指針懸停於非當前 Session 行時才繪製「…」,從不 hover 的用戶可能看不到菜單項裏的插件能力。選擇器會列出所有可刪 Session;運行中或當前 Session 會顯示但不可刪。
刪除與管理相關對話框先做 dry run:展示目錄、大小、日誌代數、影響範圍與殘留,再執行移動。
管理頁同一組件渲染兩處。Shell 的 Settings 面板沒有可從客戶端直接打開的 service;選擇器裏的「管理回收站」與對話框裏的「打開管理頁」會打開管理浮層(與 Settings 段相同內容)。仍會 best-effort 嘗試 selectPanel("settings"),以便在註冊了該 key 的構建上跳轉到 Settings。
Host 路由¶
插件在 Harness Web 服務器路徑前綴 /session-deleter 下提供服務:
| 方法 | 路徑 | 用途 |
|---|---|---|
| GET | /health |
生效中的根路徑與當前 Session id |
| GET | /inventory |
所有已存 Session(字節、代數、標題) |
| GET | /plan?sessionId=… |
預演:後果、殘留、阻塞因素 |
| POST | /delete |
{sessionId, force?} → 移入回收站 |
| GET | /trash |
回收站條目、孤兒檢測、大小 |
| POST | /restore |
{id} → 移回 |
| POST | /purge |
{id, confirm: true} → 刪除字節 |
| GET | /ledger?limit= |
只追加的操作日誌 |
| GET | /messages?sessionId=… |
消息列表及 live/shadowed 狀態 |
| POST | /messages/shadow |
{sessionId, seq} → tombstone 單條(line A) |
| POST | /messages/unshadow |
{sessionId, tombstoneSeq} → 撤銷 shadow |
| POST | /messages/truncate |
{sessionId, throughSeq} → 截斷尾部(line B) |
| POST | /messages/untruncate |
{sessionId, backupPath} → 從備份恢復 |
安裝與啓用¶
已抓取資料中的 README 未給出單獨的 dsh plugin add … 一類 CLI 安裝行;SkillHub 頁面標註「可安裝」,具體安裝方式以你當前 DSH 版本的 bundle / 市場流程爲準,並在安裝前閱讀倉庫源碼。
啓用後,可選配置通過 bundle 行的 config 傳入(摘自 README):
- insert:
- id: session-deleter
name: 'dsh-session-deleter'
config:
sessionRoot: 'D:/somewhere/sessions'
trashRoot: 'D:/somewhere/trash'
protectCurrentSession: true
refuseLiveSessions: true
默認值:
sessionRoot:<DSH_HOME|~/.dsh>/sessionstrashRoot:<home>/session-trash/sessions
卸載時:移除 bundle 行與 npm 包即可;回收站中已持有的目錄仍保留,可手工恢復——manifest.json 記錄每條目的原路徑。
磁盤狀態¶
<home>/session-trash/sessions/— 每次刪除對應一個 held 目錄,另有manifest.json。<home>/session-trash/ledger.jsonl— 每個操作階段一行,只追加;讀時若末尾行因崩潰 torn 則丟棄,不當作損壞。
典型用法¶
從 Web UI 刪除 Session¶
- 在側邊欄底部(Settings 旁)打開 Session 選擇器,或對非當前 Session 使用「…」菜單中的刪除項。
- 在確認對話框中查看 dry run 計劃(目錄、大小、代數、影響與殘留)。
- 確認後 Session 目錄移入回收站;需要時在管理頁或浮層中 Restore,或二次確認 永久刪除 以釋放空間。
運行中或當前 Session 不可刪;若配置 protectCurrentSession / refuseLiveSessions 爲 true(默認語義見上),與 README 中的保護策略一致。
通過 HTTP 預演與刪除(示例)¶
在 Harness Web 服務已掛載插件的前提下,可先查清單再預演(路徑相對於站點根下的 /session-deleter):
GET /session-deleter/inventory
GET /session-deleter/plan?sessionId=<你的 session id>
POST /session-deleter/delete
Content-Type: application/json
{"sessionId": "<你的 session id>"}
永久清除回收站中某條(不可恢復):
POST /session-deleter/purge
Content-Type: application/json
{"id": "<回收站條目 id>", "confirm": true}
消息級操作需先 GET /messages?sessionId=… 取得 seq,再按需調用 /messages/shadow 或 /messages/truncate;撤銷分別用 /messages/unshadow 與 /messages/untruncate(truncate 需 backupPath)。
維護者驗證腳本¶
倉庫提供針對真實 Session 樹副本的驗證命令(非 mock 插件邏輯),例如:
node tools/verify-host.mjs "$DSH_HOME/sessions"
node tools/verify-http.mjs
node tools/verify-client.mjs
完整列表與環境變量說明見 GitHub README 的 Verification 一節。
適用場景與注意¶
適合誰:長期在本地或自託管 DSH 上積累大量 Session、需要像桌面應用一樣「刪掉並偶爾找回」的開發者;需要在不改 Harness 的前提下清理磁盤、或精細裁剪某 Session 內消息(模型上下文 vs 界面展示)的場景。
務必注意:
- 插件以當前 DSH 進程權限讀寫
sessionRoot、trashRoot與回收站;安裝前檢查源碼與 MIT 許可證,確認路徑與備份策略可接受。 - 只有 purge(及 truncate 對 artifact 的改寫)會不可逆地改變或刪除字節;其餘 Session 刪除默認可從回收站恢復。
- Shadow 不刪屏幕上的行,Truncate 會;選型前先理解 README 中 Shadow vs truncate 一節。
- 社區目錄與 GitHub 星標(截至資料抓取爲 0)不代表官方背書;版本與行爲以倉庫 CHANGELOG 與 tag 0.2.0 爲準。
結尾¶
dsh-session-deleter 補上了 DSH Web UI 與 Session 持久化層之間缺失的刪除能力:整 Session 默認進回收站,永久刪除需明確確認;消息支持可逆 shadow 與帶備份的 truncate。若你正在維護本地 Session 目錄或需要可控的消息裁剪,可在審閱源碼後通過 bundle 接入。
- 目錄頁:https://www.skillhub.cn/plugins/ghgjkbf/dsh-session-deleter
- GitHub:https://github.com/ghgjkbf/dsh-session-deleter