dsh-session-move:側欄工作區文件夾與會話移動

前言

DeepSeek Harness(DSH)側欄默認只有一層「工作區(目錄)」:多個本地項目並列展示,會話歸屬完全由工作目錄(cwd)決定。官方沒有把工作區再分組的虛擬層級,也沒有把一條會話遷到另一個工作區並同步改 cwd 的接口。項目一多、會話一多,側欄會顯得扁平,跨目錄整理會話只能手工改底層數據。

dsh-session-move(維護者 ayachinene285,版本 0.2.1,MIT)在客戶端側補上「文件夾分組 + 拖動排序 + 真會話搬家」三塊能力:分組只在側欄生效,磁盤上不建虛擬目錄;真正換工作區時會改會話文件裏的 cwd 並搬遷會話目錄,與 DSH 的掛載規則對齊。

這是什麼

一句話:DSH 客戶端插件,在工作區之上增加可嵌套的虛擬文件夾,並支持把工作區/文件夾/會話拖動排序,以及把會話移動到另一個工作區(或僅歸入文件夾)。

代碼分兩部分:lib/index.js 跑在 DSH 本地服務進程,負責讀會話文件、改 cwd、提供本地 API;lib/client.js 負責側欄 UI、菜單和彈窗。通過 cordis.patch.yml 以 insert 方式掛載,不禁用官方入口。

核心功能

虛擬文件夾分組

  • 側欄右上角「+」可新建文件夾,不選本地目錄;文件夾可嵌套,可包含多個工作區;工作區不能作爲父級。
  • 工作區「…」:移入文件夾 / 不放入文件夾(頂層)。
  • 文件夾「…」:新建子文件夾、重命名、移入其它文件夾、刪除(解散後內容上移一層)。
  • 「+」→「新增工作區(選擇本地目錄)」仍走官方選目錄流程;文件夾內也可「新建工作區(選目錄後放進這裏)」。
  • 展開狀態記在瀏覽器 localStorage,默認展開。
  • 會話可見性與官方一致:已歸檔默認隱藏、子代理不顯示、非當前空會話不顯示;未歸屬任何工作區的會話在「未分組」。

會話:搬家與僅分組

會話行「…」→「移動到工作區 / 文件夾…」:

操作 效果
選工作區 真正移動:會話 cwd 改爲該目錄,會話目錄搬到新項目下
文件夾行「把會話放這裏」 僅側欄歸組,工作目錄不變
「移出文件夾」 回到工作區列表下,不改 cwd
填寫新目錄 登記爲新工作區並移動

同一條會話可反覆移動。已在目標工作區、會話正在跑、子代理會話等情況會提示且不動數據。目標目錄不存在時,默認先建同名空目錄再搬;彈窗可關閉該行爲。

僅分組時,會話在文件夾下只出現一次,不會在工作區裏重複;移出用「移出文件夾」。

拖動排序

工作區、文件夾、會話均可拖(行首淺灰手柄 ⠿,指針事件實現,不依賴瀏覽器原生拖放):

  • 落在目標行上 30%:插到前面;下 30%:插到後面。
  • 落在文件夾行中間 40%:放進該文件夾(自動展開)。
  • 列表底部空白:放到最外層末尾。

拖動不會改會話的工作目錄;換工作區仍用菜單「移動到工作區 / 文件夾…」。工作區內會話順序在 localStorage;文件夾內順序與層級在 storages/session-move-folders.json,重啓後保持。

會話移動的實現要點

DSH 用會話文件中的 cwd 判定歸屬;官方無移動 API。插件兩步完成:

  1. 改數據:重寫會話文件第一個 zstd 幀裏的 cwd,把會話目錄搬到新 cwd 對應項目目錄下,正文逐字節不動;失敗回滾。
  2. 重新掛載:讓 DSH 按磁盤現狀重讀會話,掛到目標工作區並從舊工作區摘掉。

移動後不需重啓 DSH,也無需手工改 workspace.json。

冷會話與打開中的會話

  • 從未打開:可直接移動。
  • 已打開但空閒:進程佔用寫入權,移動記入待辦 <DSH 數據目錄>/storages/session-move-pending.json,下次啓動自動執行;失敗保留記錄並寫入 lastError。
  • 有回合在跑:拒絕,需等跑完。

工作區目錄不存在

彈窗標「目錄不存在」;默認可先建同名空目錄再搬。取消「目錄不存在時自動新建同名目錄」則直接報錯。目錄僅改名時,可用「移動到新目錄」填真實路徑並登記新工作區。

本地 API

方法 路徑 說明
GET /api/dsh-session-move?sessionId=<id> 工作區列表、會話歸屬、待辦移動
POST /api/dsh-session-move { action: "move", sessionId, workspaceId 或 targetPath, title?, createMissingDir? }

寫請求僅接受本機同源,校驗 Origin、Host、Sec-Fetch-Site。

安裝與啓用

插件以當前 DSH 進程權限運行,安裝前建議瀏覽 GitHub 倉庫 源碼並確認 MIT 許可證。

  1. 將插件包放到本機任意目錄(README 支持 clone 或下載倉庫;亦可從 SkillHub 目錄頁 獲取分發方式)。
  2. 裝入 profile:
dsh plugin --profile <profile 名> add <插件目錄>

桌面版若命令被拒,可在應用內「插件」頁安裝,或手動把 dsh-session-move 加入 profile 的 package.json 中 dsh.profile.bundles。

  1. 完全退出 DSH 再打開。改插件不能靠刷新頁面;界面與後臺都需重載。

卸載:從 dsh.profile.bundles 刪除條目,執行 dsh plugin --profile <name> remove dsh-session-move,再完整重啓。

典型用法

  1. 側欄「+」新建文件夾,用「…」把工作區移入,或拖進文件夾中間區域。
  2. 多項目並行時,用拖動調整工作區/文件夾順序;會話在同一工作區內拖只改顯示順序。
  3. 要把 Agent 會話換到另一個倉庫:會話「…」→「移動到工作區 / 文件夾…」→ 選目標工作區(或填新路徑);僅想側欄歸類則點文件夾行的「把會話放這裏」。
  4. 目標目錄被刪:在彈窗確認路徑,保留默認「自動新建同名目錄」後點移動,或填新路徑登記工作區。

適用場景與注意

適合誰:本地多倉庫、側欄需要層級整理;需要把會話 cwd 遷到另一項目且不想手改 JSONL/zstd 的用戶。

已知邊界(來自 README):

  • 移動後工具調用在新目錄下執行;歷史裏舊路徑不會改寫。
  • 有回合在跑的會話不能移動。
  • 僅支持官方 JSONL 存儲(session-persistence-jsonl,日誌 v4)。
  • 已歸檔會話可移動,側欄仍顯示爲歸檔。
  • 界面模塊有 immutable 緩存,改 client 後必須完整重啓 DSH。

社區插件生態遵循 DSH「一切皆插件」思路;SkillHub 爲獨立目錄站,與 DeepSeek / 幻方無官方從屬關係。

結尾

dsh-session-move 用虛擬文件夾和拖動排序減輕側欄扁平化的負擔,並在官方未提供移動 API 的前提下,按 DSH 的 cwd 規則安全改寫會話數據並完成重新掛載。需要分組展示與真實換庫開發時,可對照 README 安裝並在完全重啓後使用。

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

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

小夜