使用 dsh-file-claim 爲並行 DSH 會話提供文件認領與保護

前言

DeepSeek Harness(簡稱 dsh)是 DeepSeek 開源的智能體運行時,核心理念是「一切皆插件」:模型、工具、技能、會話、沙箱、存儲和 UI,都可以在配置層替換或擴展,不必改宿主源碼。官方倉庫在 deepseek-ai/deepseek-harness,目前仍是面向 Harness 開發者的預覽階段。

實際用起來,同一個工作區裏同時開幾個 DSH 會話很常見:一個改文檔,一個改源碼,一個跑測試。宿主本身並不協調這些會話對同一文件的寫入。兩個會話可能先後覆蓋同一份文件;某個會話崩潰或被強殺後,過期佔用也沒有內建清理。想改別人正在編輯的文件時,只能乾等,或者賭一把直接寫。

社區目錄 DeepSeek Harness 插件庫 收錄了由 Nwflower 維護的會話與消息插件 dsh-file-claim。它把認領 / 釋放、心跳接管,以及基於 git 三方合併的異步待合併區,做成 DSH 原生工具和寫入守衛。需要先說清楚:這個目錄是獨立站點,與 DeepSeek / 幻方沒有官方從屬關係,不是官方應用商店;插件是否安裝、是否信任,仍然要看倉庫源碼和許可證。

截至 2026 年 8 月 18 日,目錄頁與 GitHub 倉庫均顯示 6 星,許可證爲 MIT,主要語言是 JavaScript。本文安裝命令以目錄頁原文爲準,功能與用法交叉對照倉庫 README 與 package.json

dsh-file-claim 是什麼

dsh-file-claim 是一款面向 DeepSeek Harness 的 Host 插件,用來給「共用同一工作區的併發會話」提供文件認領和保護。倉庫地址是 Nwflower/dsh-file-claim,當前 npm 版本爲 0.1.7,要求 node >= 18。它沒有 Browser 側、沒有構建步驟,只使用 Node 內置模塊,文檔寫明對 Windows 友好。

它解決的問題可以收成一句話:先聲明「我在改這些路徑」,別人的直接寫入會被拒絕;急着落筆也不用阻塞,可以把改動放進待合併區,等持有者釋放後再做 git 三方合併。項目 README 的概括是 Write in parallel. Never overwrite.

項目文檔還寫到:DSH 宿主沒有內建跨會話文件保護;作者調研時掃描了 505 個帶 dsh-plugin topic 的倉庫,未找到同類文件認領 / 協調插件。這是項目自己的調研結論,目錄頁也轉述了同一段話,本文不當作獨立第三方統計。

核心功能

倉庫 README 列出的能力可以分成下面幾塊。這些都來自中英文 README 的交叉對照,不是額外推斷。

1、認領與釋放。 會話在編輯前調用 claim_files,對文件或目錄聲明獨佔認領。重複認領會冪等合併;認領目錄會覆蓋其下所有路徑;認領 '.' 等於認領整個工作區。改完後用 release_files 釋放指定路徑,也可以一次釋放全部。

2、心跳、stale 接管與孤兒自愈。 心跳由 agent/createdagent/status 自動刷新;會話正常離開時,agent/disposed 會釋放它的全部認領。崩潰或被強殺時,下一次任意會話活動會按進程 pid 清掉已死記錄,心跳間隔再兜底掃一遍。staleMs 默認 2 小時,主要針對沒有 pid 的舊記錄;這類記錄可以用 force 接管。

3、異步 pending 合併區。 文件被別人佔着時,不必乾等。pending_write 把「改好的新內容 + 當時的 git HEAD base」寫入待合併區。持有者 release_files 後,插件會用 git merge-filecurrent × base × pending 三路合併:無衝突就落盤並清條目,有衝突則帶標記落盤並保留條目,缺 base 則拒絕,不會盲合。

4、寫入守衛。 插件在 tools/pre-execute 攔截 write / edit / bash / pwsh。目標路徑被其他活躍會話認領時,調用會被拒絕,並提示三種出路:等對方釋放、對方 stale 後 force 接管、或改走 pending_writeread 不攔截。默認不攔 git commit;把 guardCommit 設爲 true 後,纔會拒絕「顯式提交他人活躍認領路徑」的 commit。

5、審計日誌。 每次認領、接管、釋放、pending 寫 / 合併 / 丟棄,都會往工作區狀態目錄追加一行 JSON。心跳故意不記,避免把日誌寫爆。audit.jsonl 超過 1MB 會自動輪轉。

另外還有一組斜槓命令:/claim/release/claim-status,語義和上面的工具一致,給模型不可用、或者習慣自己敲命令的人用。命令執行只記入會話日誌,不會進模型歷史。純邏輯核心 claim.mjs 也可以脫離 DSH,用 node claim.mjs status | audit | claim ... 調用。

安裝與啓用

目錄頁給出的安裝命令如下,在 DeepSeek Harness 終端裏運行即可:

dsh plugin add github:Nwflower/dsh-file-claim

需要可復現安裝時,按目錄頁的寫法固定 commit 哈希:

dsh plugin add github:Nwflower/dsh-file-claim#<commit>

倉庫 README 裏還有一條 dsh plugin add dsh-file-claim,走的是 npm 包名。日常安裝以目錄頁的 github:Nwflower/dsh-file-claim 爲準。針對本地 checkout 做開發或手工驗證時,README 給出的是:

dsh plugin --profile web add -w link:<倉庫路徑>

運行環境需要 DSH,以及 node >= 18。三方合併會調用 git merge-file,所以 git 必須在 PATH 裏。

插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前應檢查 源代碼倉庫 和 MIT 許可證;只安裝自己信任的插件。

快速開始

官方快速開始可以收成四步。

1、先認領,再落筆。要改文件就先調用 claim_files,聲明獨佔認領,其他會話就不會直接寫這些路徑。

2、自己的認領不會擋住自己。寫入被其他活躍會話認領的文件會被拒絕,拒絕信息裏會帶持有者和建議。

3、文件被佔時不要乾等,用 pending_write 把改好的內容(含 git HEAD base)放進待合併區。對方 release_files 後,無衝突會自動三路合併落盤;有衝突再手動 pending_apply

4、寫完釋放。release_files 清空認領,自動合併能合併的 pending 條目,並把需要人工處理的條目浮出來。

最小調用順序如下:

claim_files({ paths: ["README.md", "src/"] })
write / edit ...
release_files({ paths: ["README.md"] })

典型用法

下面兩個例子都來自倉庫 README,不是額外編的場景。

兩個會話共用一個工作區。 會話 A 持有 README.md,會話 B 也想改它:

// 會話 A
claim_files({ paths: ["README.md"], note: "重寫文檔" })
write  ...  README.md          // 允許:自己的認領
release_files({ paths: ["README.md"] })

// 會話 B —— 同時進行
who_claims({ paths: ["README.md"] })          // → 被 A 認領
write ... README.md                           // → 拒絕並附提示
pending_write({ path: "README.md", content: "..." })  // 異步,不阻塞
// A release 後條目自動三路合併(或浮出供手動 pending_apply)

從崩潰會話恢復。 會話 A 中途崩潰後,README 把無 pid 的舊記錄寫成:認領在 staleMs(默認 2 小時)後過期,再接管:

claim_status()
claim_files({ paths: ["README.md"], force: true })

FAQ 裏補充得更細:正常情況下崩潰 / 強殺會在下一次會話活動時立刻按 pid 清掉,不必乾等到 2 小時;staleMs 是慢速兜底。

模型可見的 8 個工具如下,身份就是調用會話,不需要 --as

工具 用途
claim_files 編輯前獨佔認領文件或目錄(paths,可選 note,stale 接管用 force
release_files 釋放指定路徑(paths)或全部(all
who_claims 只讀:查詢路徑被誰認領
claim_status 只讀:會話登記、認領、待合併區總覽與最近審計
pending_write 目標被其他活躍會話佔用時,把新內容寫入待合併區
pending_apply 三路合併 current × base × pending 落盤
pending_show 只讀:查看某條 pending 的元信息與內容
pending_drop 丟棄某條 pending,不合並

配置、狀態目錄與合併區

配置通過插件 bundle 的 cordis.patch.yml 傳入。倉庫裏的默認 patch 只插入插件條目,可選項寫在註釋和 README 裏:

默認 含義
staleMs 7200000(2 小時) 心跳過期多久視爲 stale
stateDirName .dsh-file-claim 工作區根下的註冊表和待合併區目錄名
guard true 設爲 false 關閉 pre-execute 寫入守衛
guardCommit false 可選:額外攔截顯式提交他人活躍認領路徑的 git commit
heartbeatMs 600000(10 分鐘) 兜底心跳間隔

README 給出的覆蓋示例:

- insert:
    - id: dsh-file-claim
      name: dsh-file-claim
      config:
        staleMs: 3600000        # 1 小時
        guardCommit: true       # 同時守衛顯式 git commit

認領註冊表、待合併區和審計日誌都在工作區根下的 .dsh-file-claim/。文檔建議把它加入 .gitignore。狀態跨重啓保留,插件不會改 .git/

pending 條目的佈局是:

pending/<relpath>/content     待合併的新文件內容
pending/<relpath>/base        寫入時 git HEAD 版本(合併 base)
pending/<relpath>/meta.json   { pender, claimedBy, at, baseSha }

pending_write 的前提是目標正被其他會話活躍認領;否則應先 claim_files 再直接寫。base 只在 git HEAD 含該路徑時記錄,沒有 base 的條目被刻意標成不可自動合併。pending_apply 時如果任一會話仍佔用該路徑,也會拒絕,直到釋放。

適用場景與注意事項

適合誰,可以從文檔裏的定位直接看:多個 DSH 會話(或多個 Agent)共用一個工作區、需要並行改文件,又不想互相覆蓋。多倉庫並行也支持——認領根按會話 cwd 解析出的工作區劃分,沒有工作區時回退到 cwd,倉庫之間天然隔離。

使用前有幾條邊界必須記住,都來自 README 的「寫入守衛」和「攔截邊界」,不是額外警告。

第一,守衛是協作式護欄,不是強制鎖。任意 shell(例如 echo > file)、腳本、外部編輯器、IDE 和 git 操作都可以繞過工具棧。bash / pwsh 也只盡力解析重定向目標和顯式寫命令的目標參數;解析不出目標就放行(fail-open)。文檔把這一點寫成品類裏的既有姿態,而不是缺陷。

第二,插件以當前 dsh 進程權限運行。安裝前檢查源碼、許可證和近期提交;需要可復現安裝就固定 commit。社區目錄可以當發現入口,但不能替代自己審源碼。

第三,pending 不會盲合。缺 base、仍被佔用、三方合併衝突、目標文件缺失時,條目會留下並附原因,用 pending_show 查看,再用 pending_applypending_drop 處理。

第四,模型側能不能看到這組工具,取決於當前部署的工具展示 / 限制策略。插件本身是通過 ctx.tools.register 全局註冊的,路徑和官方工具包相同;若界面裏看不見,先查部署側的工具過濾,而不是假定插件沒裝上。

小結

dsh-file-claim 做的事情很具體:給共用工作區的並行 DSH 會話補一層文件認領,衝突改動進 git 三方合併的待合併區,而不是讓後寫的會話直接覆蓋。它是社區 MIT 項目,由 Nwflower 維護,不是 DeepSeek 官方插件。

目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-file-claim/

GitHub:https://github.com/Nwflower/dsh-file-claim

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

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

小夜