DeepSeek Harness 插件

dsh-checkout-guard

Pre-flight guard for git working copies: is the checkout you are about to write to the one you think it is? Branch identity, drift from the remote and how stale that figure is, the identity your next(英文原文)

跳到安装方式

来源信息

GitHub 仓库
LeslieWylie/dsh-checkout-guard
最近更新
2026年8月18日
分类
安全与权限
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/LeslieWylie/dsh-checkout-guard
插件名:dsh-checkout-guard
作者:LeslieWylie

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh.md来源说明 · 只读预览
README 语言

dsh-checkout-guard

你正要写入的这个工作副本,是不是你以为的那个?

一个 DSH 插件,在你编辑、提交、推送之前回答这个问题,而不是之后。它读取一个 git checkout,告诉你:它相对远端处在什么位置、这个答案有多陈旧、你下一个提交会 署谁的名、暂存区里已经躺着什么、以及本机是否还有同一个仓库的另一份 clone 已经 跑到了你前面。

只读。不显式要求就不联网。从不占用 index 锁。

---

为什么

这里每一项检查都对应一次真实发生过的事故,通常发生在同时操作多个仓库的 agent 身上:

出了什么事你事后才看到
在落后 8 个提交的 checkout 里改代码你的"修复"把别人的工作退回去了,或者推送被拒
同一个仓库有两份 clone,你在陈旧的那份里改动凭空消失,forge 上永远看不到
并发进程把 HEAD 切到了别的分支你的提交落在一个你没听说过的分支上
git add 之前暂存区里已经有东西你的提交打包进了别人的半成品
仓库没有本地 user.email一个工作邮箱被永久钉在公开提交上
detached HEAD提交存在过,然后不存在了,全程无提示

这些都不会报错。git 完全照你说的做了;是你在误读的状态下说的。这就是本插件覆盖的 全部问题域。

安装

npm install dsh-checkout-guard

然后在 profile 的 cordis.yml 追加:

- id: checkout-guard
  name: 'dsh-checkout-guard'

需要 Node 22.19+ 或 24+。运行期唯一依赖是 PATH 上有 git

工具

checkout_guard —— 单个工作副本,深度检查

{ "path": "/abs/path/to/repo", "expectBranch": "main" }
{
  "branch":  { "current": "main", "detached": false, "upstream": "origin/main", "linkedWorktree": false },
  "sync":    { "ahead": 1, "behind": 1, "fetchAgeSeconds": 255600, "fetchedNow": false },
  "remote":  { "normalized": "github.com/acme/widget", "host": "github.com", "publicForge": true },
  "identity":{ "email": "you@example.com", "source": "global", "repositoryOverride": false },
  "workingTree": { "staged": [], "unstaged": ["package.json"], "untracked": [], "clean": false },
  "duplicateCheckouts": [ { "path": "/elsewhere/widget", "branch": "main", "ahead": 3, "aheadOfThisOne": true } ],
  "blockers": [ "diverged from origin/main by 1 commit(s) (and 1 ahead) ...",
                "another checkout of the same remote is ahead of this one: /elsewhere/widget ..." ],
  "warnings": [ "remote refs were last updated 71h ago ..." ],
  "verdict": "blocked",
  "safeToWrite": false
}

调用方只需要看 safeToWrite 一个字段。blockers 是继续下去会丢失或错置工作的 状态;warnings 是值得知道、但不必然是错的情况。

参数作用
path(必填)工作副本的绝对路径,或它内部任意子目录
fetch先联系远端,让 ahead/behind 是当下的。唯一联网的选项,默认 false
expectBranch你认为自己在哪个分支。不符即 blocker
expectIdentity你期望的提交署名邮箱。不符即 blocker
remote对比哪个远端(默认 origin)
staleAfterHours远端 ref 多久算陈旧(默认 24)
findDuplicates / duplicateRoots / maxDepth / maxRepos控制重复 clone 的搜索范围

expectBranchexpectIdentity 是把"报告"变成"断言"的开关。不传,插件只描述; 传了,插件会拒绝。

checkout_guard_scan —— 某个根目录下的所有工作副本

{ "roots": ["/abs/path/to/projects"], "maxDepth": 3 }

每个 checkout 返回一行——分支、upstream、ahead/behind、未提交数量、上次 fetch 距今多久——外加:

  • needsAttention:落后、分叉、detached、或没有 upstream 的那些
  • duplicateRemotes:按远端分组的路径,一眼看出同一个仓库有几份 clone

先跑这个找出值得细看的 checkout,再把路径逐个交给 checkout_guard

刻意不做的事

  • 不告诉你远端是否已归档。 那需要调 forge 的 API,本插件不发带认证的 HTTP

请求。remote.normalized 会给你 host/owner/repo,你可以自己去查。

  • 不修任何东西。 不 pull、不 rebase、不 stash、不 checkout。"落后"和"分叉"

的正确恢复方式不一样,在两者之间做选择不该由一个 guard 替你决定。

  • 不评判你的身份。 它只报告署名来自哪份配置,并且仅在涉及公开 forge 且仓库

没有本地覆盖时才警告。你传 expectIdentity,它就严格按你给的值比对——它从不 猜测你的邮箱"应该"是什么。

安全性质

  • 不对任何仓库写入。 唯一可能修改东西的命令是 git fetch --dry-run,仅在

fetch: true 时执行,且只动 FETCH_HEAD

  • 每次调用都带 GIT_OPTIONAL_LOCKS=0 普通的 git status 会刷新并重写

index,从而占用 .git/index.lock。一个立足于"此刻可能有另一个 agent 在这个 checkout 里"的 guard,绝不能反过来卡住那个 agent。

  • GIT_TERMINAL_PROMPT=0、空 GIT_ASKPASS 对私有远端 fetch 会快速失败,

而不是停在一个没人看得见的凭据提示上。

  • URL 归一化时先剥掉内嵌凭据,凭据不可能进入结果对象或日志。
  • 路径白名单。 两侧都做 realpath,所以放在允许目录里的软链接无法读到外面。

配置

- id: checkout-guard
  name: 'dsh-checkout-guard'
  config:
    roots:
      - /Users/you/projects

roots 限定插件能看的一切范围。不设时默认为你的 home 目录。

开发

npm install
npm test          # 在临时目录里对真实 git 仓库跑的单元测试
npm run test:boot # 把插件装载进真实 cordis Context

没有构建步骤。 src/index.js 逐字节就是发布出去的入口。编译到 lib/ 再把 产物提交上去的插件,得永远维持两者同步,而所有 import src/ 的测试都会通过—— 与此同时,安装者真正运行的那份产物是过期的。去掉构建,就去掉了这整类问题。

单元测试创建真实仓库——真实远端、真实推送、真实分叉——而不是给 git 打桩。手写的 测试替身会按作者的预期作答,而作者对仓库状态的预期,恰恰就是被测对象本身。

tests/boot.test.mjs 在裸 clone 下打印 SKIP 并退出 0,不挡贡献者;在 CI 设置的 DSH_BOOT_STRICT=1 下退出 1。一个被跳过却报告为绿的集成测试,比没有测试更糟。

English · MIT