READMESource: main@26a60618
dsh-tool-git
Git tools for DeepSeek Harness agents — nine structured, model-facing tools that replace "shelling out to git and parsing text":
| Tool | Purpose | Key parameters | Canonical value highlights |
|---|---|---|---|
git_status |
Working-tree status | workdir? |
Structured branch/head/clean/staged/unstaged/untracked/conflicts |
git_diff |
Diff (unstaged by default) | staged? stat? paths? |
diff text or stat numeric summary; UI diff card |
git_log |
Commit history | count? paths? |
commits[] (hash/shortHash/author/date/subject) |
git_add |
Stage files | paths? or all? |
stagedFiles[] read back from the index |
git_commit |
Create a commit | message (required) body? amend? stageAll? |
New hash/shortHash/branch; empty index returns reason: 'nothing-to-commit' |
git_branch |
List/create/checkout/delete branches | action? name? startPoint? force? |
branches[] (name/current/upstream) or action result |
git_show |
Show a commit or a file at a revision | rev path? stat? |
Commit metadata + patch (UI diff card) or file content (UI read card) |
git_restore |
Discard working-tree changes / unstage | paths staged? source? |
restored[] — the files actually changed |
git_merge |
Merge a branch/commit | rev noFF? abort? message? |
New HEAD, or conflicts[] on a merge conflict |
All tools accept workdir (defaults to the session workspace; relative paths resolve against it).
Compatibility
- Tested against DeepSeek Harness 0.1.0-rc.6 — the peer/dev dependency pins in
package.jsonmatch the packages shipped with that version. - Harness plugin interfaces are still evolving during the preview. If you upgrade
dsh, re-runpnpm testagainst the new version and report any breakage. - Requires
git≥ 2.23 (--porcelain=v2andgit restore).
Install
# From GitHub (pnpm runs the prepare build automatically)
dsh plugin --profile web add github:Huasfan/dsh-tool-git
# First git install: pnpm refuses to run build scripts until explicitly allowed —
# dsh prints the exact key to add to the profile's pnpm-workspace.yaml:
# allowBuilds:
# dsh-tool-git: true
# Consider pinning a commit: github:Huasfan/dsh-tool-git#<commit-sha>
Local / development:
# Patch overlay using the bundle layer
dsh --profile web --patch /abs/path/to/dsh-tool-git/cordis.patch.yml
# Or load the TypeScript source directly (the loader supports .ts, including
# relative imports):
# name: '/abs/path/to/dsh-tool-git/src/index.ts'
Configuration (cordis.yml)
- id: git-tool
name: dsh-tool-git
config:
gitPath: git # git executable, default "git"
timeoutMs: 30000 # per-invocation timeout in ms, default 30000
Config is a Schemastery schema: invalid configuration fails loudly at load time with an actionable error.
Design principles
- One canonical JSON value.
executereturns only the structured value declared byoutput.schema;output.renderturns it into model-facing prose. The model never parses prose for fields (per the official tool authoring reference). - Non-zero exits are domain outcomes, not exceptions. A failing
gitcall (not a repository, unmatched pathspec, rejected hook, …) returns{ ok: false, error }; only infrastructure failures (missing executable, timeout, cancellation) throw. Timeouts land inerror; cancellation re-throws as anAbortErrorusing the registry-recognizedTOOL_ABORTED. - Cooperative cancellation.
exec.signalis forwarded tochild_process.execFileon every call. - No shell injection.
execFilewith an argument array; command strings are never interpolated. Environment is pinned (LC_ALL=C,GIT_TERMINAL_PROMPT=0,GIT_PAGER=cat) and read-only commands use--no-optional-locks. - Registration is an effect.
ctx.tools.register(...)unregisters automatically when the plugin unloads. - Machine-readable parsing.
git status --porcelain=v2 -z --branchwith positional slicing (paths may contain spaces); a rename's original path is the bare record that immediately follows. - Tool-owned UI cards. Pure
presentCall/presentResultpresenters, withoutput.presentationMetaprojecting replayable diff-card and read-card data (git_diff,git_show) that survives session-log replay.
Reference implementation: @deepseek-ai/dsh-tool-bash.
Development
pnpm install # all dev dependencies come from npm; no local dsh install needed
pnpm typecheck # tsc --noEmit (TS 5.8 strict + erasableSyntaxOnly)
pnpm test # vitest: 28 tests (parser unit tests + real scratch-repo integration)
pnpm build # esbuild bundle → lib/index.js (same as the prepare script)
Peer packages (@deepseek-ai/dsh-tools etc.) are pinned to the exact versions shipped
with dsh 0.1.0-rc.6; at runtime they resolve from the profile's in-box dependencies.
Documentation
- CONTRIBUTING.md — how to build, test, and submit changes.
- RELEASE-NOTES.md — per-version release notes.
No comments yet. Be the first to write one.