DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-checkout-guard

L

dsh-checkout-guard

Manifest valid

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

hasBundlePatch

dsh-checkout-guard

Is the working copy you are about to write to the one you think it is?

A DSH plugin that answers that before you edit, commit, or push — not after. It reads a git checkout and tells you where it sits relative to its remote, how stale that answer is, who your next commit will be attributed to, what work is already sitting in the index, and whether another clone of the same repository on this machine has moved ahead of the one you are in.

Read-only. Offline unless you ask for a fetch. Never takes the index lock.


Why

Every check here exists because a specific mistake actually happened, usually to an agent working across many repositories at once:

What goes wrongWhat you see afterwards
You edit a checkout that is 8 commits behindYour "fix" reverts work, or your push is rejected after the fact
Two clones of one repository, you are in the stale oneChanges vanish; the repo on the forge never shows them
A concurrent process moved HEAD to another branchYour commit lands on a branch you have never heard of
Something was already staged before you ran git addYour commit packages somebody else's work in progress
No repository-local user.emailA work address is permanently attached to a public commit
Detached HEADThe commits exist, then don't, and nothing warned you

None of these throw. Git does exactly what you asked; you asked in a state you had misread. That is the entire problem space this plugin covers.

Install

npm install dsh-checkout-guard

Then append to your profile's cordis.yml:

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

Node 22.19+ or 24+. The only runtime requirement is git on PATH.

Tools

checkout_guard — one working copy, in depth

{ "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); you are reading code the remote has already moved past, and a push will be rejected",
    "another checkout of the same remote is ahead of this one: /elsewhere/widget (main, 3 ahead vs 1); you may be editing the stale copy"
  ],
  "warnings": [
    "remote refs were last updated 71h ago; ahead/behind is computed from that snapshot, not from the remote as it is now (re-run with fetch: true)"
  ],
  "verdict": "blocked",
  "safeToWrite": false
}

safeToWrite is the one field a caller needs. blockers are states where proceeding loses or misplaces work; warnings are things worth knowing that are not automatically wrong.

ParameterEffect
path (required)Absolute path to the working copy, or any directory inside it
fetchContact the remote first so ahead/behind is current. The only networked option, default false
expectBranchThe branch you believe you are on. A mismatch is a blocker
expectIdentityThe email you expect to author with. A mismatch is a blocker
remoteRemote to compare against (default origin)
staleAfterHoursWhen remote refs count as stale (default 24)
findDuplicates / duplicateRoots / maxDepth / maxReposControl the search for other clones

expectBranch and expectIdentity are how you turn a report into an assertion. Without them the plugin describes; with them it refuses.

checkout_guard_scan — every working copy under a root

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

Returns one row per checkout — branch, upstream, ahead/behind, uncommitted counts, fetch age — plus:

  • needsAttention: the ones that are behind, diverged, detached, or have no upstream
  • duplicateRemotes: paths grouped by remote, so two clones of one repository are visible at a glance

Run this first to find out which checkouts deserve a closer look, then hand those paths to checkout_guard.

What it deliberately does not do

  • It does not tell you a remote is archived. That needs the forge's API, and this plugin does not make authenticated HTTP calls. remote.normalized gives you host/owner/repo to check yourself.
  • It does not fix anything. No pull, no rebase, no stash, no checkout. The recovery for "behind" and the recovery for "diverged" are different, and picking between them is not a decision a guard should make for you.
  • It does not judge your identity. It reports which config your author line comes from, and warns only when a public forge is involved and the repository has no local override. If you pass expectIdentity, it compares against exactly what you named — it never guesses what your address should be.

Safety properties

  • No writes to any repository. The only command that can modify anything is git fetch --dry-run, which runs only when fetch: true and touches nothing but FETCH_HEAD.
  • GIT_OPTIONAL_LOCKS=0 on every call. Ordinary git status refreshes and rewrites the index, taking .git/index.lock. A guard whose whole premise is "another agent may be in this checkout right now" must not be able to block that agent.
  • GIT_TERMINAL_PROMPT=0, empty GIT_ASKPASS. A fetch against a private remote fails fast instead of parking on a credential prompt nobody can see.
  • Credentials are stripped during URL normalization, before a remote can reach a result object or a log line.
  • Path allowlist. Both sides are realpath'd, so a symlink planted inside an allowed root cannot read outside it.

Configuration

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

roots bounds everything the plugin will look at. Unset, it defaults to your home directory.

Development

npm install
npm test          # unit tests against real git repos in a temp dir
npm run test:boot # loads the plugin into a real cordis Context

There is no build step. src/index.js is the published entry point, byte for byte. Plugins that compile to lib/ and commit the output have to keep the two in sync forever, and every test that imports src/ passes while the artifact an installer runs is stale. Removing the build removes the whole class.

The unit tests create real repositories — real remotes, real pushes, real divergence — rather than stubbing git. A hand-written double answers the way its author expects, and the author's expectation about repository state is precisely what is under test.

tests/boot.test.mjs exits 0 with a SKIP from a bare clone so contributors are not blocked, and exits 1 under DSH_BOOT_STRICT=1, which CI sets. A skipped integration test reported as green is worse than no test at all.

中文 · MIT

Comments

Loading…

Similar plugins

dsh-depguard

by DeLightor

Dependency-topology guard: pre-install conflict prediction and post-install detection of duplicate @deepseek-ai/dsh-* copies, version drift, and vendored core services that cause Symbol-key crashes li

Development & InfrastructureTools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Aug 16, 2026

dsh plugin --profile web add dsh-depguard

by WhitePlusMS

Read-only Git Graph view for the DeepSeek Harness web interface. Inspect commit topology, branches, tags, remotes, HEAD, and working-tree status in a dedicated view beside Chat and Trajectory.

Development & InfrastructureManifest valid

★ 2

↓ 668/wk

MIT

JavaScript

Aug 18, 2026

dsh plugin --profile web add dsh-git-graph

by BOWLUNA

Structured git tools for DeepSeek Harness agents: status, diff, log, branch, commit and stash - pinned output, no shell involved, approval-gated writes.

Development & InfrastructureTools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Sep 24, 2026

dsh plugin --profile web add dsh-zcode-git

by jkrandom-sudo

Security audit for DeepSeek Harness plugins: static permission profile with file/line evidence + a runtime sentinel gating credential access and unknown-host egress · DSH 插件安全审计:静态权限画像(附文件/行号证据)+ 运行时哨

Manifest valid

★ 4

↓ 154/wk

MIT

TypeScript

Sep 11, 2026

dsh plugin --profile web add dsh-plugin-audit

by Oliver0804

Map dsh (DeepSeek Harness) workspaces onto a Discord category — query session trajectories and live subagents, and drive an agent, from anywhere with no inbound port.

Development & InfrastructureManifest valid

★ 2

↓ 52/wk

MIT

JavaScript

Sep 10, 2026

dsh plugin --profile web add dsh-discord-bot

by GooDAnDReaDY

GitHub operations for DeepSeek Harness: releases, tags, a guarded API pass-through, sanitized mirror publication, workflow runs and repository settings.

Terminal & ClientsDevelopment & InfrastructureSecurity & AuditManifest valid

★ 0

MIT

JavaScript

Sep 27, 2026

dsh plugin --profile web add @goodandready/dsh-github-ops