dsh-session-delete:在 DSH 裏真正刪除會話

前言

在 DeepSeek Harness(DSH)裏結束一段對話後,側欄裏「刪掉」會話,往往只是把 id 寫進 workspace.json 的 archivedSessionIds,界面不再顯示,磁盤上的日誌、緩存和索引並不會少一個字節。官方文檔對這一點寫得很清楚:dsh-session-persistence 沒有刪除或保留 API;dsh-session-persistence-jsonl 不會刪除會話文件;dsh-client-ui-workspace 也沒有 Session 刪除能力。

對自託管、在意本地數據殘留或合規留痕的開發者來說,歸檔不等於清除。社區插件 dsh-session-delete(維護者 wangyueyueye,分類 admin-security)補的是「按落點枚舉、確認後再刪」這一條鏈路,並把刪乾淨當成一等目標,而不是再包一層隱藏。

這是什麼

dsh-session-delete 給 DSH 增加可審計的「刪除會話」能力:先掃描會話在磁盤上的所有相關落點,在彈窗裏列出大小與原因,用戶選定刪除範圍、擦除方式並勾選確認後,才由宿主側 API 執行刪除。

README 特別提醒:npm 上的 dsh-session-delete 包可能是另一位作者的另一插件;若要本文描述的「投影緩存、工作區索引、插件數據、孤兒附件、覆蓋擦除」能力,請只從上述 GitHub 倉庫安裝。

核心功能:它刪什麼、不刪什麼

一個 DSH 會話不是單個文件,而是散在多個目錄裏的一組數據。插件按落點逐層清理,並在掃描結果裏說明「刪什麼、多大、哪些不刪、爲什麼」。

落點 位置(相對 <DSH_HOME>) 爲何必須處理
會話記錄 sessions/<工作區>/<id>/session.vN.jsonl.zstd 每一代都要刪;只刪最新代時舊代可能在讀取時頂上來
投影緩存 storages/session_projcache/sessions/<id>.json[.bak.*] 含標題與逐輪 prompt/response 原文
工作區索引 storages/workspace.json 會話順序、置頂、歸檔中的 id;不清會留空行
插件數據 storages/<任意插件域>/.../<id>.json 有限深度掃描,不硬編碼插件名
附件對象 attachments/v1/... 內容尋址、去重、默認不自動刪;僅「徹底」檔且確認無其他會話引用時處理

明確不刪的包括:工作區裏由命令產生的文件(無法可靠歸屬到單會話)、運行日誌與會話日誌導出(無到會話的映射)、spill 溢出文件(系統臨時目錄按時間自清)。

三檔刪除範圍

  1. 僅對話記錄:會話記錄 + 投影緩存 + 工作區索引
  2. 記錄 + 插件數據:在上述基礎上再加各插件按會話存的數據
  3. 徹底(含附件):再刪僅被本會話引用的附件對象

任意檔位都會清理工作區索引,否則側欄仍會留下指向已刪數據的行。

兩種擦除方式

  • 普通刪除:直接解除鏈接,較快;數據塊可能仍被恢復工具讀到。
  • 覆蓋擦除:先寫零並 fsync 再刪,抬高恢復門檻;對 SSD 磨損均衡、CoW 文件系統等不是物理級保證。

本地刪除不能撤回已經發給模型提供商的內容。例如 dsh-session-log-deepseek 默認會把會話日誌增量作爲請求字段上傳;開關在 設置 → 通用 →「在使用官方模型 API 時上傳 Session Log」。

安裝與啓用

裝完後需要重開 DSH(客戶端 boot 圖譜在啓動時組裝)。任選一種方式:

A. 從本地目錄安裝(README 推薦,便於審計)

在 Web 端 設置 → 插件 選本地目錄,或手動改 profile 三處:

1. profile/node_modules/ 裏放入本包(或建指向源碼目錄的聯接)
2. profile/package.json:
   "dependencies": { "dsh-session-delete": "file:<絕對路徑>/dsh-session-delete" }
   "dsh.profile.bundles": [ ..., "dsh-session-delete" ]

B. 從 Git 安裝並鎖 commit

"dsh-session-delete": "github:<user>/dsh-session-delete#<commit-sha>"

C. npm

pnpm add dsh-session-delete

然後把 dsh-session-delete 追加進 dsh.profile.bundles。

不要改 profile 的 cordis.patch.yml 去插 session-delete——bundle 自帶 patch,重複會插入同一個 id。

卸載可用 plugin_manager 的 remove_bundle,或手動清理 dependencies、bundles 與 node_modules 中的包。掛載成功會在 <DSH_HOME>/logs/session-delete.log 寫 mounted …;每次刪除追加 <DSH_HOME>/logs/session-delete-audit.jsonl 一行。

典型用法

  1. 在會話列表某一行打開 ... 菜單,選擇 刪除會話。
  2. 彈窗先只讀掃描,展示各層待刪項與不刪項及原因。
  3. 必須無默認值地選定三項:刪除範圍、擦除方式、我已知曉:刪除後無法恢復;三項齊全後刪除按鈕纔可點,缺項時按鈕旁會提示。
  4. 正在運行的會話會被拒絕刪除(插件無法安全 teardown 他人的 AgentHandle)。
  5. 若刪的是當前打開的會話,完成後會重載頁面;否則側欄對應行當場消失,無需整頁刷新。

刪當前打開會話時,數據清完後還會調用 archiveSession 讓 live 行從列表消失;插件下次掛載時會清理「已歸檔但既不在內存也不在磁盤」的 id,避免 workspace.json 里長期留墓碑。

適用場景與安全邊界

適合誰:需要在自託管 DSH 上主動清除本地會話正文、緩存、索引與部分插件側車數據的 admin 或注重隱私的用戶;需要刪除前看清清單、留審計 jsonl 的場景。

安裝前務必知曉:DSH 的 Host 插件在宿主進程內、工作區沙箱之外運行(與官方描述一致)。安裝即信任作者與約 650 行、零第三方依賴的 lib/index.js。誤刪無回收站;覆蓋擦除在 SSD 上也不是物理不可逆。

插件自述的安全設計包括:宿主僅用 node:fs/promises、node:path、node:os;package.json 無 scripts;唯一 API 路由 /api/session-delete 且由 DSH 連接層校驗 owner;待刪路徑需落在 sessions/、storages/、attachments/ 根內並經過 realpath 閘門;會話 id 白名單 ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$;不跟隨符號鏈接/目錄聯接做遞歸刪除。

兼容性:針對 DSH 0.2.1-rc.x 存儲佈局;會話格式升到 v5 時會話日誌文件名規則需複覈。運行期依賴 ctx.sessionPersistence、ctx.workspaceRegistry、ctx.sessions、ctx.connection.fetch 及客戶端 slots/locale/sessions。

自測(零依賴):

node test/selftest.mjs
node test/client-test.mjs

結尾

DSH 生態強調「一切皆插件」;社區目錄 skillhub.cn 與 DeepSeek / 幻方無官方從屬關係。若你的需求是「歸檔隱藏」以外的本地徹底清理,dsh-session-delete 把官方未提供的刪除面補全到日誌各代、投影緩存、索引、插件域與可選孤兒附件,並在 UI 上用掃描清單與三項門控把誤操作空間壓小。

羽毛球分组比赛记分
小程序二维码

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

小夜