DeepSeek Harness 會話清理插件:dsh-session-purge

前言

在本地調試或長時間運行 DSH(DeepSeek Harness)時,側邊欄的會話列表會逐漸積累大量廢棄會話。只刪磁盤上的 session*.jsonl 文件,內存裏還保留着進程內的會話條目和 Agent 引用,導致列表裏仍然出現這條記錄,點進去還能讀到內存內容。此外,投影緩存、工作區記賬與全文索引裏的殘留也會一直存在。dsh-session-purge 插件通過右鍵菜單提供了一套完整的清理流程,刪除時會話目錄、投影緩存、工作區記賬、進程內會話條目與 Agent 引用,以及全文索引,確保隻影響目標會話。

插件定位

devve-1/dsh-session-purge 是 DeepSeek Harness 的客戶端插件,由維護者 DEVVE-1 開發。它通過側邊欄右鍵菜單提供“刪除會話”入口,二次確認後清理該會話的所有持久化痕跡,同時保證其他會話不受影響。

核心功能

刪除範圍

刪除操作覆蓋以下位置:

  • 會話目錄:$DSH_HOME/sessions/<project>/<sessionId>/,包括所有代際的 session*.jsonl[.zstd],目錄刪空後順帶回收空掉的 project 目錄。
  • 投影緩存:$DSH_HOME/storages/session_projcache/sessions/<sessionId>.json,先走 storageDomain 的內存表寫鏈,再兜底刪除文件。
  • 工作區記賬:$DSH_HOME/storages/workspace.json 中該會話在 sessionIds、pinnedSessionIds、archivedSessionIds 裏的全部引用。
  • 進程內狀態:ctx.sessions 與 ctx.agents 中的活條目,觸發 session/disposed 事件,客戶端會話列表同步移除該行。
  • 全文索引:主動觸發一次索引對賬,讓該會話的 FTS 記錄立刻消失。

附件($DSH_HOME/attachments)與派生圖片緩存($DSH_HOME/cache)是多會話共享的,不會清理。

安全邊界

  • 會話 id 先過正則 ^[A-Za-z0-9][A-Za-z0-9._-]*$(長度 ≤ 200),再映射成單個路徑段;刪除前斷言目標確實是會話根目錄下以該 id 命名的一級目錄,杜絕路徑穿越。
  • 不以“運行時還持有這個 Agent”爲拒絕條件。DSH 的 Agent 註冊表會把進程內打開過的會話一直持有着,真正該攔的是“有東西在跑”,由 workspace/session-activity 報出。
  • 會話有在跑的工作(turn / job / subagent / schedule):確認後走和歸檔同一條 workspace/session-stop 通道,然後輪詢等待清空(默認最多 4s,可用 settleMs 調),停不乾淨就報 session-active 且不動任何文件。
  • 刪除前先把活會話摘掉。會話列表是把進程內還活着的會話無條件並進來的,只刪磁盤的話列表裏會一直留着這一行、點開還能看到內存裏的內容。摘掉之後 session/disposed 會發出去,客戶端自行去掉那一行,jsonl 後端關掉寫句柄。
  • 摘活會話會讓寫句柄異步收尾(writer.close() 把緩衝落一次盤),所以刪完文件後進行自適應複查:默認每 40ms 探一次會話目錄,連續兩輪乾淨才收工(從沒摘過活會話的只要一輪),總預算 residualBudgetMs(默認 1.5s)兜底,清掉的都記進 residualPaths。
  • 搜索索引對賬給 searchBudgetMs(默認 800ms)的同步預算:冷索引第一次對賬可能要讀一遍全部會話日誌,超預算就中止並把對賬丟到後臺繼續,響應不等它。索引本來就在每次查詢前自行對齊,所以延遲清掉不會讓被刪內容被搜出來。
  • 被刪的 id 進一個進程內墓碑集合,並掛一條 agent/pre-step 攔門(形狀同歸檔會話的 gate),遲到的投遞只會以 blocked 收場。
  • HTTP 接口只在 webServer 上註冊一條 exact 路由 /session-purge,並要求:POST + application/json + Host 必須是迴環地址(localhost / 127.x / ::1)+ Origin 與 Host 同源 + Sec-Fetch-Site 不能是 cross-site。不設置任何 CORS 頭。

接口

POST /session-purge
content-type: application/json
{ "sessionId": "session-...", "stop": true }

200 { "ok": true, "result": { sessionId, removedPaths, residualPaths, projectionCache,
                             detachedWorkspaces, detachedLive, searchReconciled,
                             activityStopped, liveAgent, elapsedMs } }
409 { "ok": false, "code": "session-active", "message": "...", "activity": [...] }
400 / 403 / 405 / 413 / 415 / 500  其餘校驗失敗

searchReconciled 取 done(索引已對完賬)/ background(超預算轉後臺)/ unavailable(索引不可用或被關閉)。elapsedMs 是這次刪除在 Host 側的實際耗時。

安裝與啓用

插件包已經是一個可直接加載的 bundle(package.json 的 dsh.bundle.patch + dsh.client),Host 半邊 lib/index.js、瀏覽器半邊 lib/client.js 都是最終產物,無需構建。

通過 plugin_manager 安裝

從 GitHub 倉庫裝(plugin_manager 的 install_bundle 支持 git 地址):

install_bundle  target = https://github.com/DEVVE-1/dsh-session-purge

本地目錄裝(target 填本目錄的絕對路徑):

install_bundle  target = <本目錄絕對路徑>

通過本地腳本安裝

進入插件目錄,用運行時自帶的 pnpm 把本目錄作爲 file: 依賴裝進 profile:

cd <本目錄>
$node = "$env:DSH_HOME\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe"
& $node .\install.mjs --dry-run
& $node .\install.mjs                 # 默認 desktop profile,可加 --profile <name>

腳本會:用 pnpm 把包名追加到 dsh.profile.bundles → 按哈希把包內容同步進安裝目錄 → 複查。它要寫 profile 目錄(在 DSH 工作區之外),所以只能由你自己執行。

手動安裝

cd $env:DSH_HOME\profiles\desktop
pnpm add file:<本目錄絕對路徑>

然後把包名加進 profile package.json 的 dsh.profile.bundles:

"dsh": {
  "profile": {
    "bundles": [
      "@deepseek-ai/dsh-base",
      "@deepseek-ai/dsh-web-app",
      "session-purge"
    ]
  }
}

Live profile 會即時 recompose;否則重啓應用。裝好後刷新一次頁面,瀏覽器半邊纔會進入模塊表。

典型用法

安裝完成後,在左側邊欄右鍵點擊某個會話,菜單裏會出現「刪除會話」選項。點擊後彈出二次確認框,確認後執行刪除。該會話及其所有痕跡會被清理,其他會話保持不變。

適用場景與注意

  • 適合需要頻繁清理廢棄會話的 DSH 本地開發場景。
  • 插件以當前 DSH 進程權限運行,安裝前建議檢查源碼與許可證。
  • 插件依賴內部形狀(store + detachEntered),上游改結構時會靜默降級而不是報錯。
  • 刪除時如果會話有在跑的工作,會先嚐試停止,停不乾淨則拒刪並返回 session-active。

結尾

dsh-session-purge 通過側邊欄右鍵菜單提供了一套完整的會話清理流程,確保刪除會話時所有持久化痕跡都被清乾淨,不影響其他會話。如需查看源碼或更新版本,可訪問插件目錄或 GitHub 倉庫。

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

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

小夜