DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

File Claim — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-file-claim

File Claim

并行写入,绝不覆盖——为在同一工作区中协作的并发 DeepSeek Harness (DSH) 会话提供文件声明/保护:声明/释放、通过心跳接管失效声明,以及异步待处理合并区(git 三方合并)

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-file-claim@0.2.0
README兼容性版本

兼容性与来源证明

File Claim 以 dsh-file-claim 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
npm
Registry 更新时间
2026/9/20

版本

0.2.0stable
2026/9/2
0.1.7stable
2026/8/16
0.1.6stable
2026/8/14
查看其余 6 个版本收起版本
0.1.5stable
2026/8/14
0.1.4stable
2026/8/14
0.1.3stable
2026/8/14
0.1.2stable
2026/8/14
0.1.1stable
2026/8/14
0.1.0stable
2026/8/14

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
108 kB
文件数
7
Surface
any
许可证
MIT
发布源
npm
GitHub
★ 6
周下载
115
安全扫描
✓ v0.2.0 扫描通过
最近提交
2026/9/2
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

dsh-file-claim

Write in parallel. Never overwrite. File claim / protection for concurrent DeepSeek Harness (DSH) sessions working the same workspace.

When several DSH sessions run in parallel against one workspace, they have no awareness of each other: two sessions can overwrite the same file, a crashed session leaves stale state behind, and a session that wants to edit a file another session owns can only wait or guess. dsh-file-claim turns a proven coordination protocol into native DSH tools, lifecycle events, and a write guard — so parallel agents cooperate instead of clobbering each other.

claim_files({ paths: ["README.md"] })   # "I'm editing this"
write / edit ...                          # writes to files claimed by others are denied
release_files({ paths: ["README.md"] })  # "done — pending edits auto-merge now"

Table of Contents

  • Features
  • Why
  • Install
  • Quick Start
  • Usage Examples
  • Tools
  • Commands
  • Write Guard
  • Configuration
  • Audit Log
  • Pending Merge Area
  • Enforcement Boundary
  • FAQ
  • Development
  • Related Projects
  • License

Features

  • 🔒 claim / release — a session declares exclusive ownership of file paths before editing them; duplicates merge idempotently, directory claims cover descendants, and '.' claims the whole workspace.
  • ❤️ heartbeat + stale takeover + orphan self-heal — heartbeats refresh automatically via agent lifecycle events; a crashed / hard-killed session's claims are cleared immediately on the next activity (per-process pid check) and swept by the heartbeat interval; staleMs expiry (2h, for records without a pid) and --force takeover remain as the slow fallback.
  • 🧩 async pending merge area — instead of blocking, a session writes its edited content plus the git HEAD base into a pending area; when the owner releases, the entry is auto-merged via a git 3-way merge (current × base × pending) when conflict-free, or applied manually with pending apply when it conflicts.
  • 🛡️ write guard — a tools/pre-execute guard refuses writes to files actively claimed by another session, with a hint (wait / takeover when stale / pend) and an opt-in commit guard.
  • ⚡ zero automation burden — agent/created / agent/status refresh the heartbeat, and agent/disposed auto-releases every claim of a departed session.
  • 📦 pure Host plugin, zero dependencies — no Browser side, no build step, node: builtins only; Windows-friendly.
  • 🧾 audit trail — every claim / release / takeover / pending mutation is appended as one JSON line, for traceability and post-crash reconciliation.

Why

The DSH host has no built-in cross-session file protection, and a full scan of 505 dsh-plugin topic repositories found zero file-claim/coordination plugins. The pending merge area — write your edit now, merge it cleanly once the owner releases — is unique in the agent file-lock category. This is a gap-filler, not a duplicate.

Compared with the category

Checked against 11 Claude Code / Codex file-lock and coordination tools (claude-code-file-locks, parallel-sessions, guardex, agent-orchestrator, blackboard-mcp, mclaude, ruah-orch, knot, …):

Differentiatordsh-file-claimTypical alternatives
Conflict handlingasync pending area + git 3-way merge — write now, merge cleanly once the owner releaseswait / deny only ("lock → write → release")
Target platformDSH-native — identity, tools, events, guard and slash commands all integratedClaude Code / Codex hooks; none target DSH
Platform supportzero-dependency Node, Windows-friendlyBash/jq/flock solutions lean macOS/Linux; guardex has no native Windows
Storageworkspace sidecars — <file>.dshclaim next to each protected file (the .agentlock idiom)central state dir (.coord/, ~/.claude/…) or worktree isolation
Enforcementcooperative tool-layer guardrail (fail-open, matching the category's de-facto standard)hook interception / declarative locks; top tools fall back to worktree isolation

Install

dsh plugin add dsh-file-claim

For development / manual verification against a local checkout:

dsh plugin --profile web add -w link:<repo-path>

Requires DSH with node >= 18 and git on PATH (used only by the 3-way merge).

Quick Start

  1. Claim before you write. Editing files? Call claim_files first — it declares exclusive ownership so other sessions leave them alone.
  2. Write freely. Your own claims never block you; writes to files actively claimed by another session are denied with a hint (wait / takeover when stale / pend).
  3. Busy file? Don't wait — pend. Use pending_write to drop your edited content into the pending area (with the git HEAD base). Once the owner calls release_files, the entry is auto-merged when conflict-free — or run pending_apply manually for a clean 3-way merge.
  4. Release when done. release_files clears your claims, auto-merges waiting pending entries, and surfaces the ones that need manual attention.
claim_files({ paths: ["README.md", "src/"] })
write / edit ...
release_files({ paths: ["README.md"] })

Usage Examples

Two sessions, one workspace. Session A owns README.md; session B wants to edit it too:

// Session A
claim_files({ paths: ["README.md"], note: "rewriting the docs" })
write  ...  README.md          // allowed: own claim
release_files({ paths: ["README.md"] })

// Session B — meanwhile
who_claims({ paths: ["README.md"] })          // → claimed by A
write ... README.md                           // → DENIED with a hint
pending_write({ path: "README.md", content: "..." })  // async, no blocking
// When A releases, the entry is auto 3-way merged (or surfaced for manual pending_apply)

Recover from a crashed session. Session A dies mid-work; its claims expire after staleMs (2h default), then:

claim_status()                      # → A shows [stale]
claim_files({ paths: ["README.md"], force: true })   # take over

Tools

Eight model-facing tools (identity is the calling session — no --as needed):

ToolPurpose
claim_filesClaim file/dir paths exclusively before editing (paths, optional note, force for stale takeover)
release_filesRelease paths (paths) or everything (all)
who_claimsRead-only: who claims given paths
claim_statusRead-only: session registry, claims, pending area overview, recent audit
pending_writeAsync write: put edited content (+ git HEAD base) into the pending area for a file actively claimed by another session
pending_apply3-way merge current × base × pending onto disk; conflict-free auto-clears, conflicts leave markers
pending_showRead-only: view one pending entry's meta and content
pending_dropDiscard one pending entry (no merge)

Commands

Human-usable slash commands (same semantics as the tools above — useful when the model is unavailable, or for shell-bound users). The line after the command name is split quote-aware, so paths and notes containing spaces work (--note "multi word note"). Command runs are recorded in the session log only, never fed to the model.

CommandPurpose
/claim <path>... [--note <text>] [--force]Claim file/dir paths exclusively; --force takes over a stale holder
/release [<path>... | --all]Release paths or everything
/claim-statusRead-only: session registry, claims, pending area overview

The standalone core also ships a CLI: node claim.mjs status | audit [n] | claim ... — same semantics, no DSH required.

Write Guard

tools/pre-execute denies write / edit / bash / pwsh calls whose target path is actively claimed by another session. The denial message names the holder and suggests: wait for release_files, take over with claim_files(force: true) once stale, or use pending_write. read is not intercepted — reading is observation, not modification, and the claim contract only protects the write surface. Shell-path parsing (bash/pwsh) is best-effort: only redirection targets and the target arguments of explicit write commands are extracted (pwsh Set-Content / Add-Content / Out-File / New-Item / Copy-Item / Move-Item / Remove-Item / Rename-Item; bash tee / dd of= / cp / mv / rm). Quoted literals are never treated as write targets — they are data, URLs or patterns, not files being written — and commands that yield no parseable target pass through (fail-open).

With guardCommit: true, a git commit that explicitly stages paths actively claimed by another session (git commit -- <path> or legacy git commit <path>) is also denied; commit messages are never inspected, and a bare git commit (no paths) passes through — its scope cannot be known.

Configuration

Passed as plugin config in the bundle (cordis.patch.yml):

KeyDefaultMeaning
staleMs7200000 (2h)Heartbeat expiry before a session is considered stale
guardtrueSet false to disable the pre-execute write guard
guardCommitfalseOpt-in: also deny git commit that explicitly stages paths actively claimed by another session
heartbeatMs600000 (10min)Fallback heartbeat interval
- insert:
    - id: dsh-file-claim
      name: dsh-file-claim
      config:
        staleMs: 3600000        # 1h
        guardCommit: true       # also guard explicit git commits

Since 0.2.0, state is stored as workspace sidecar files — the lock travels with the protected file (the claude-code-file-locks .agentlock idiom, adopted because DSH reserves no in-workspace directory convention):

README.md.dshclaim                 claim sidecar (JSON: version, path, tag, note, startedAt, lastSeenAt, pid)
README.md.dshpending/              pending-merge sidecar (content / base / meta.json), next to the target
.dsh-file-claim.audit.jsonl        workspace-global audit log (append-only, at the root)
.dsh-file-claim.lock               transient cross-process mutex (exists only during a mutation)

Recommend adding these to .gitignore:

*.dshclaim
*.dshpending/
.dsh-file-claim.audit.jsonl
.dsh-file-claim.lock

When a workspace still carries the ≤0.1.7 flat .dsh-file-claim/ directory (or an unpublished 0.2.0 .dsh/dsh-file-claim/), the first tool/command call migrates it to sidecars (the old directory is kept — delete it manually once verified; its registry.json is renamed registry.json.migrated as the idempotency marker). The write guard also reads the old registry until that first call, so protection is seamless across the upgrade. State survives restarts; nothing ever touches .git/.

Audit Log

Every business mutation — claim, takeover, release, pending write / apply / drop, prune, drop — is appended as one JSON line to .dsh-file-claim.audit.jsonl ({ at, tag, type, paths/path, detail }), for traceability and post-crash reconciliation. Heartbeats are intentionally not logged (noise). node claim.mjs audit [n] prints the latest n entries (default 10); claim_status always shows the three most recent. Audit writes are append-only and never block or alter claim semantics; a failed audit append surfaces a warning line without failing the operation. The file self-rotates at 1 MB (keeping the most recent half plus the new entry), so it never grows without bound.

Pending Merge Area

Storage layout (a sidecar directory next to the protected file):

<relpath>.dshpending/content     new file content to merge
<relpath>.dshpending/base        git HEAD version at write time (merge base)
<relpath>.dshpending/meta.json   { pender, claimedBy, at, baseSha }

Write conditions: pending_write requires the target to be actively claimed by another session — otherwise write the file directly after claim_files. base is only recorded when git HEAD contains the path; a missing base is a deliberate non-mergeable entry.

Apply semantics (pending_apply): runs git merge-file over current × base × pending (three real file snapshots staged in a temp dir). No conflicts → merged content lands on disk and the entry is cleared. Conflicts → the merged output (with conflict markers) lands on disk and the entry is kept for manual resolution. Missing base → refused, never a blind merge. Active claim by any session → refused until released.

release_files runs an unlock check: pending entries aimed at the released paths (or at the releasing session) are auto-merged when the 3-way merge is conflict-free (content lands on disk, entry cleared); entries that cannot merge — still occupied, missing base, conflicts, or missing file — stay pending and are surfaced with manual pending_apply / pending_show / pending_drop hints.

Enforcement Boundary

The guard is advisory / cooperative, not a mandatory lock: arbitrary shell commands (echo > file, git checkout, scripts), external editors, and IDE/git operations bypass the tool stack entirely. It upgrades "self-discipline via AGENTS.md" to "tool-layer guardrail + model-visible state", matching the fail-open posture of the whole category.

FAQ

Can bash/pwsh writes be fully intercepted? No. Only redirection targets and the target arguments of explicit write commands are parsed; arbitrary shell, scripts, external editors and IDE/git operations bypass the tool stack. That is the documented cooperative boundary, not a bug — see Enforcement Boundary.

How long until a crashed session's claims are cleared? Normally immediately: every session record carries its process pid, and any session activity (claim / release / sync / prune) sweeps records whose pid is dead — a crash or hard kill is cleaned up on the very next activity, no waiting. agent/disposed releases normally-departed sessions at once, and staleMs (default 2h) is only the slow fallback for records without a pid (e.g. written by older versions).

Does this work across multiple repos? Yes. The claim root is the workspace resolved from the session's cwd (workspaceRegistry), falling back to cwd — parallel repos are isolated by design.

Where is state stored? As workspace sidecar files: <target>.dshclaim next to each claimed file, <target>.dshpending/ next to each pending-merge target, and .dsh-file-claim.audit.jsonl at the workspace root. Add the gitignore patterns above; state survives restarts and never touches .git/. Workspaces upgraded from ≤0.1.7 have their old .dsh-file-claim/ state migrated to sidecars on the first tool/command call (the old directory is kept; delete it manually once verified).

Why can't the model see the claim tools? Model-visible tools depend on the deployment's tool presentation/restrictions (like every plugin tool). The plugin registers globally via ctx.tools.register, the same path as official tool packages.

What if a pending entry can't merge? It stays pending with the reason surfaced (still occupied, missing base, conflicts, missing file). Use pending_show to inspect and pending_apply / pending_drop to resolve — nothing is ever blindly merged.

Do claim sidecars and the audit file grow forever? No. Stale sessions' sidecars are pruned automatically on the heartbeat interval (so departed sessions' records don't accumulate), and .dsh-file-claim.audit.jsonl self-rotates at 1 MB. Both stay bounded in normal use.

Development

npm test        # node --test: claim.mjs unit tests (20) + index.mjs mock-ctx integration (13)
npm pack --dry-run

Layout: claim.mjs is the zero-dependency pure-logic core (portable, CLI entry retained); index.mjs is the only host-facing file; test/ covers both. CI runs tests, a bilingual-README structure sync check, and a pack dry-run.

Related Projects

  • dsh-chat-import — the sibling DSH plugin whose session.mjs coordination protocol this plugin was ported and enhanced from.
  • awesome-dsh-plugin — the DSH plugin ecosystem index (505 repos scanned during this project's research).
  • @deepseek-ai/dsh — the DeepSeek Harness host.

License

MIT — see LICENSE.