dsh-session-deleter:在 Web UI 中刪除 Session 與單條消息

前言

在 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 原文歸納):

  1. Delete a whole Session — 將整個 Session 目錄(含各代日誌)移動到回收站,可恢復。
  2. Restore — 把回收站中的目錄移回原路徑;若目標路徑已被佔用則拒絕覆蓋。
  3. Delete permanently — 唯一不可撤銷的步驟,也是唯一真正釋放磁盤空間的步驟;需要第二次明確點擊(或 API 傳 confirm: true)。

設計原則:默認可逆。第一次刪除請求不會直接刪字節,在同一文件系統上通過 rename 進回收站,原子完成「破壞性工作」的實質步驟。

單條消息:Shadow 與 Truncate

除整 Session 外,插件還通過 HTTP 暴露消息級接口(見下文路由表):

  • Shadow(line A):只追加、完全可逆。用 developer/message tombstone 替換模型可見 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>/sessions
  • trashRoot:<home>/session-trash/sessions

卸載時:移除 bundle 行與 npm 包即可;回收站中已持有的目錄仍保留,可手工恢復——manifest.json 記錄每條目的原路徑。

磁盤狀態

  • <home>/session-trash/sessions/ — 每次刪除對應一個 held 目錄,另有 manifest.json。
  • <home>/session-trash/ledger.jsonl — 每個操作階段一行,只追加;讀時若末尾行因崩潰 torn 則丟棄,不當作損壞。

典型用法

從 Web UI 刪除 Session

  1. 在側邊欄底部(Settings 旁)打開 Session 選擇器,或對非當前 Session 使用「…」菜單中的刪除項。
  2. 在確認對話框中查看 dry run 計劃(目錄、大小、代數、影響與殘留)。
  3. 確認後 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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜