前言¶
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/created、agent/status 自动刷新;会话正常离开时,agent/disposed 会释放它的全部认领。崩溃或被强杀时,下一次任意会话活动会按进程 pid 清掉已死记录,心跳间隔再兜底扫一遍。staleMs 默认 2 小时,主要针对没有 pid 的旧记录;这类记录可以用 force 接管。
3、异步 pending 合并区。 文件被别人占着时,不必干等。pending_write 把「改好的新内容 + 当时的 git HEAD base」写入待合并区。持有者 release_files 后,插件会用 git merge-file 做 current × base × pending 三路合并:无冲突就落盘并清条目,有冲突则带标记落盘并保留条目,缺 base 则拒绝,不会盲合。
4、写入守卫。 插件在 tools/pre-execute 拦截 write / edit / bash / pwsh。目标路径被其他活跃会话认领时,调用会被拒绝,并提示三种出路:等对方释放、对方 stale 后 force 接管、或改走 pending_write。read 不拦截。默认不拦 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_apply 或 pending_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