dsh-git-guard
DeepSeek Harness 的 Git 感知写入守卫:阻止整文件写入覆盖用户未提交的更改,回合结束时报告受保护文件的情况
bibibala
@bibibala
⬇ 1
★ 1
main
安装
dsh plugin --profile web add github:bibibala/dsh-git-guard
需要可复现安装时,可在仓库后追加 #commit 固定提交。
DeepSeek Harness 的 Git 感知写入守卫:阻止整文件写入覆盖用户未提交的更改,回合结束时报告受保护文件的情况
该插件未提供要点说明,请参考仓库 README。
deepseek-harnessdsh-plugingitguard
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/bibibala/dsh-git-guard |
| 许可证 | MIT |
| 主要语言 | main |
| 下载量 | 1 |
| GitHub 星标 | 1 |
| 最近推送 | 2026-08-14 |
| 收录日期 | 2026-09-19 |
| 分类 | 安全与权限 |
事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
# dsh-git-guard
A git-aware write guard plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness). It stops the agent from silently destroying the user's uncommitted work: at each turn start it snapshots every file with uncommitted changes (staged, unstaged, or untracked) in the session workspace's repository and backs them up; a whole-file replacement tool call (the `write` tool by default) targeting such a file is denied at `tools/pre-execute` with corrective feedback; at turn end the protected files are re-verified and the outcome is reported as a plugin-source notice in the session log. The guard runs its own credential-scrubbed `git` subprocess — never the model's shell.
## Install
The plugin is distributed as a [bundle](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish): an npm package with a `dsh.bundle` manifest that contributes one configuration layer.
```sh
dsh plugin --profile web add dsh-git-guard
```
For a git install (no npm package): `dsh plugin --profile web add github:you/dsh-git-guard` — the first `add` fails until you allow the package's build script in the profile's `pnpm-workspace.yaml` (`allowBuilds: dsh-git-guard: true`), because pnpm refuses to run `prepare` on git dependencies by default. Lock the commit (`#`) and only authorize source you trust.
Verify the layer before starting:
```sh
dsh --profile web --dump-config # shows a "# == dsh-git-guard" layer
```
Remove with `dsh plugin --profile web remove dsh-git-guard`.
## Config
```yaml
- id: git-guard
name: dsh-git-guard
config:
mode: block # block | warn | off; default block
includeUntracked: true # protect untracked files and directories
maxBackupBytes: 1048576 # hash/backup cap per protected file
backupRoot: ~/.dsh/git-guard/backups # default: harness home
```
- `mode: block` denies a whole-file write to a protected file with a reason naming the path and the fix (targeted edit, or commit/stash first). `warn` lets the write proceed and attaches a notice to its result. `off` disables interception while keeping the turn-end report.
- Config fails loud at load: a non-integer or non-positive `maxBackupBytes`, a relative `backupRoot`, or a duplicate/empty `blockTools` entry throws.
## How it works
- **Protected set** — On `turn/start`, parses `git status --porcelain=v1 -z` in the repository containing the session cwd and protects every dirty path, minus files the agent whole-file-wrote earlier in this process. Protected files are hashed and copied to `backupRoot///` when they fit `maxBackupBytes`; untracked directories protect their subtree by prefix.
- **Interception** — `tools/pre-execute` awaits the turn's snapshot (the first tool call of a turn can never race the hashing), resolves the target path against the session cwd with symlinks canonicalized, and denies or warns when the target is protected. A guarded write to an unclaimed file claims it as agent-owned for later turns.
- **Turn-end report** — re-hashes each protected file and checks `git diff --quiet HEAD` for tracked files: `modified` (uncommitted changes remain), `lost` (worktree equals HEAD or file gone, with the backup path), or `blocked`. The report is appended as a plugin-source `user/message` notice, so it is logged and model-visible with no new session event type. Sessions outside a git repository stay inactive.
## Model experience
The denial is a tool error naming the protected path and the fix; the turn-end report is a `notice`-form context whose one-line summary is bounded to 120 characters. Both are retained history for the agent and follow the reusable request prefix (append-only; they do not invalidate existing KV-cache entries).
## Development
```sh
pnpm install
pnpm run build # types into lib/types, bundle into lib/index.mjs
pnpm test # unit + real-composition suite against throwaway git repos
```
The bundle's `prepare` script runs the same self-contained tsdown build, so a git install produces `lib/` without a monorepo checkout.
## Release
The release flow follows the [antfu/starter-ts](https://github.com/antfu/starter-ts) convention: bump, tag, and push locally; CI publishes to npm and creates the GitHub release.
```sh
pnpm run release # bumpp: bump patch, commit, tag v*, push
pnpm run release -- minor # or major, or an explicit version
```
Pushing a `v*` tag triggers [.github/workflows/release.yml](.github/workflows/release.yml), which publishes the package to npm and generates the GitHub release from commits. The publish step needs a `NODE_AUTH_TOKEN` repository secret — an npm token with publish permission (Settings → Secrets and variables → Actions).
## License
MIT
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。