A DeepSeek Harness (dsh) plugin that visualizes Git status in the Web UI: current branch, HEAD, dirty-state counts (staged / modified / untracked), ahead/behind, recent commits, and changed files — right in the session header, no terminal needed.
Read this in 简体中文.
- 📦 npm: https://www.npmjs.com/package/dsh-git-ui
- 🐙 GitHub: https://github.com/Julyves/dsh-git-ui
- 🐛 Issues: https://github.com/Julyves/dsh-git-ui/issues
-
Branch pill in the session header (right-aligned, per-session): shows the current branch at a glance, with dirty-state and ahead/behind indicators:
State Pill Clean ⎇ mainDirty ⎇ main · +2 −1 ?3(staged / modified / untracked)Ahead / behind ⎇ main ↑1 ↓2Detached HEAD ⎇ (detached) · a1b2c3dUnborn (no commits) ⎇ main · 无提交Not a git repo Dimmed 无 Git 仓库Git unavailable / error Dimmed Git 不可用(reason in tooltip) -
Detail popover (click the pill): repository root, count grid (staged / modified / untracked / ahead / behind), recent commits (hash · subject · author · relative time), changed-file list with status chips, manual refresh button, and last-checked time:
-
Always-fresh data, zero interaction: automatic fetch on session open, silent polling (host-configured interval, default 30s, no overlapping requests), immediate refresh when an agent turn completes (best-effort — the working tree most likely changed right then), resync after reconnect, and a manual refresh button.
-
Deterministic degradation: non-git directories, missing cwd, missing git, timeouts, and oversized repositories show stable fallback states — never crashes, never spams:
-
Pure read-only UI: no new model tools, no session events, no impact on agent behavior.
Requires a running DeepSeek Harness (dsh) with the web profile.
# Install from the npm registry.
dsh plugin --profile web add dsh-git-uiRestart dsh web. Open a session in a git repository and the branch pill appears in the session header.
To verify the install:
cat ~/.dsh/profiles/web/package.json # dsh.profile.bundles should list dsh-git-uiTo remove:
dsh plugin --profile web remove dsh-git-uiLocal development install (links this repo into the profile instead):
dsh plugin --profile web add ./. Local tarball / link installs (file:...tgz,github:...) symlink the package outside the profile tree, so its@deepseek-ai/*peer dependencies (provided by the host installation) are not reachable by Node's resolution. Keep the dev peer symlinks in this repo'snode_modules/@deepseek-ai/*(see Development) whenever installing locally.
- Open a session whose working directory is inside a git repository.
- Read the branch pill in the header at any time — no action needed.
- Click the pill to inspect repository root, counts, recent commits, and changed files; use
刷新(refresh) for an immediate re-check.
Each session shows the Git status of its own working directory. Non-repository sessions show a dimmed placeholder instead of the pill.
All defaults work out of the box. Advanced users may override the plugin config in the profile's cordis.patch.yml (a later layer wins; the row replaces the whole config):
- id: git-ui
config:
defaultRefreshIntervalMs: 60000 # polling interval (ms); 0 disables polling
maxChanges: 200 # max changed-file entries in a snapshot
timeoutMs: 3000 # per git-command timeout (ms)
maxStatusBytes: 8388608 # status-output cap before truncation- Node.js
^22.19.0 || >=24.0.0 - dsh
>= 0.1.0-rc(developer preview) giton the host machine (the plugin shells out togit)
- Shows the Git state of the session's working directory only (no remote URL / push-branch names yet).
- Polling-based refresh (default 30s); file-watcher event push is a planned extension.
- Changed-file list is capped (
maxChanges); when status output overflows the in-memory cap (default 4 MiB) it is recovered from a private spill file so counts stay exact — only if the spill cap (64 MiB) also overflows does the snapshot fall back to approximate (truncated: true). - Browser never sends paths — only a
sessionId; the host resolves the authoritative cwd and runs read-only git commands.
pnpm install
# Link the host-provided peers into the repo so a local profile install
# (`dsh plugin --profile web add ./`) resolves them: pnpm symlinks the
# package into the profile, and Node follows the realpath back into this
# repo, so `node_modules/@deepseek-ai/*` must point at the host fallback.
mkdir -p node_modules/@deepseek-ai
for p in "$HOME"/.dsh/profiles/node_modules/@deepseek-ai/*; do
ln -sfn "$p" "node_modules/@deepseek-ai/$(basename "$p")"
done
pnpm run typecheck
pnpm test
pnpm run build # host (esbuild ESM, never minified) + client (ModuleLoader factory closure)
dsh plugin --profile web add ./ # local install; restart dsh web to verify