The repository,
inside the session.
One portable plugin gives a DSH host a real Git surface: status, diffs, history and branch controls in the right sidebar. The same package runs on a web profile and in Rivetdeck, where it is preinstalled.
- Changes, Diff and Graph tabs in the right sidebar
- Git through ctx.subprocess — never a shell
- No model tools, no prompt content

Features
The whole review loop, without leaving the window.
Three tab types join the upstream right sidebar through its standard registration — Changes and Graph as pages, and every file comparison as a dsh-resource diff.
Changes
Status, staging and the commit in one tab
Porcelain v2 status in staged, unstaged and untracked sections, each row badged with its letter. A plus or minus toggles the index; undo discards behind a second confirmation that names the path.
- Split commit button: Commit, Amend, Commit & Push, Commit & Sync
- Auto-growing commit message field with a Generate control
- Refresh and reveal-in-folder actions live inside the Git frame

Diffs
One file, one side, one addressable tab
Every comparison is a dsh-resource://git/diff address, so the staged and working-tree diffs of one file open side by side. Asking for an address that already exists reveals its tab and refreshes it on a revision counter.
- Rendering is the official DSH DiffBlock — copying, folding and line wrapping included where the host offers them
- Binary, metadata-only, empty and truncated files are distinguished, not flattened
- The address is the tab identity, so diffs restore with the layout
Two addresses for one file
dsh-resource://git/diff/src%2Fcart.tsx/stagedstaged comparison
dsh-resource://git/diff/src%2Fcart.tsx/worktreeworking-tree comparison
Graph
A lane graph that pages itself
History renders as a canvas-drawn lane graph in one continuous coordinate space, so rails and merge edges never break at row boundaries. A scroll sentinel appends older commits instead of materializing everything.
- Auto, All and First-parent scopes beside refresh
- Kind-colored HEAD, branch, remote and tag chips on each line
- A hover card carries the full subject, hash, author and date
- HEAD → main
Merge pull request #14: status panel UI
cherrchen · 2h ago
- status-panel-ui
fix(client): restore graph node hover emphasis
cherrchen · 5h ago
- origin/main
fix(compat): support DSH 0.1.5-rc.3 and 0.2.1-alpha.1
cherrchen · 1d ago
- v0.2.5
feat(client): staged diff opens beside the worktree one
cherrchen · 1d ago
Composer
Branch and change count, before you type
A branch selector and a changed-files indicator sit to the left of the input and open the Changes tab. Creating a branch shares one modal, and after git init with no commits the menu explains that the first commit must exist.
- The selector follows the session’s effective directory when the host projects one
- A linked checkout shows a worktree label; “Use in this session” enters it through the host directory service
- Each session keeps its own repository state — two sessions never share a snapshot
Describe what you want to build…
Commit messages
Suggested, never committed
When the host exposes an LLM runtime, Generate sends the staged diff — capped by commitMessage.maxDiffBytes — to the session model or a provider/model pair pinned in plugin configuration. The streamed draft lands in the editable input.
- Generation never stages, commits or pushes anything
- The system prompt defaults to a Conventional Commits instruction and is editable
- With no resolvable model the control reports unavailable instead of guessing
plugins: - entry: @dsh-electron/dsh-plugin-git config: commitMessage: mode: custom provider: anthropic model: claude-haiku-4-5Design boundaries
Git runs as Git. Nothing is reinvented.
The plugin shells out to the Git on the machine and keeps every risky edge explicit — including the ones it refuses to build.
- 01
Never a shell
ctx.subprocess starts Git with an executable plus separate argv values. Every caller-supplied path, branch and message stays one argv — no interpolation, no quoting surprises.
- 02
Destructive means two clicks
Discard restores one staged, unstaged or untracked change through explicit index, worktree and clean steps — and always behind a second confirmation that names the path.
- 03
Credentials stay with Git
Push and sync invoke git push and git pull --rebase as argv. A missing origin or rejected auth surfaces Git’s own error; the plugin has no credential UI to misplace trust in.
- 04
Desktop is optional
A child ctx.inject(['desktop']) fiber adds reveal-in-folder and open-path where the provider exists. Repository, status, diff, stage, commit and branch operations work without it.
- 05
Bounded output
One command’s stream is capped at 8 MiB by default; past the cap the collector keeps the tail. It is validated configuration, not a hidden constant.
- 06
Nothing reaches the model
The plugin registers no model tools, prompt sections or request context. Commit-message generation is a separate host LLM request that leaves session tokens untouched.
Getting started
Two commands on a web profile.
The plugin installs through the DSH plugin manager from four sources — and in Rivetdeck it is already preinstalled, so there is nothing to do.
- 1
Install the package
Run this with a supported DSH runtime. Replace the profile for Electron desktop.
Recommended. Pre-built artifact; no package code runs at install time.
install · npm $ dsh plugin --profile web add @dsh-electron/dsh-plugin-git$ dsh --profile webPre-built offline package; the same tgz is attached to the GitHub Release.
install · tarball $ pnpm pack @dsh-electron/dsh-plugin-git$ dsh plugin --profile web add ./dsh-electron-dsh-plugin-git-0.2.5.tgzFetches sources and builds via prepare. allowBuilds must name the git+ key pnpm prints — the bare package name does not match it.
install · github $ dsh plugin --profile web add github:cherrchen/dsh-plugin-git#v0.2.5Links a local checkout for development. pnpm build produces lib/, which the install reads.
install · local $ git clone https://github.com/cherrchen/dsh-plugin-git.git$ cd dsh-plugin-git$ pnpm install$ pnpm build$ dsh plugin --profile web add "$PWD" - 2
Approve the GitHub build step
Only a
github:install builds on your machine — the package’s ownprepare. pnpm 10+ refuses withERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWEDuntil the key it prints is allowed in that profile’spnpm-workspace.yaml; pin a tag so a later push cannot change what runs.pnpm-workspace.yaml allowBuilds: '@dsh-electron/dsh-plugin-git@git+https://github.com/cherrchen/dsh-plugin-git#v0.2.5': true - 3
Open a session in a repository
The branch chip and the changed-files indicator appear in the composer once the session’s directory is a repository.
Every supported release ships the right sidebar this plugin registers into — no extra host plugin is needed.
Notes
- Rivetdeck preinstalls Git; the bundled version can lag the npm release. Install into the profile to run a newer one.
- Commands above use the web profile. For Electron desktop, replace
--profile webwith--profile desktop. - Running DSH from a source checkout? Use
pnpm dshinstead ofdsh.
Compatibility
An exact list, not a range.
The client registers into sidebar and settings slots whose shapes change between pre-stable releases, so support is the exact list CI has run. The rows marked development-only are verified on main but not in the published v0.2.5 package.
| DSH release | Status | Added in | Notes |
|---|---|---|---|
| 0.1.5-rc.2 | Verified | v0.2.0 | Baseline: the earliest release shipping the right sidebar this plugin registers into. |
| 0.1.5-rc.3 | Development only | development branch | Manifest-only re-release; verified on the development branch. |
| 0.1.6-alpha.1 | Verified | v0.2.2 | Plugin configuration sits under Settings → Plugins → Plugin configuration. |
| 0.1.6-alpha.2 | Verified | v0.2.2 | Configuration moves to the bundle’s detail page; session lookup probes the new list shape. |
| 0.1.7-alpha.1 | Verified | v0.2.2 | configForms replaces settingsScope; icons move to weighted names. |
| 0.1.7-alpha.2 | Verified | v0.2.2 | Same shapes as 0.1.7-alpha.1 for this plugin. |
| 0.1.7-rc.1 | Verified | v0.2.2 | Install starts enforcing the exact peerDependencies list. |
| 0.1.7-rc.2 | Verified | v0.2.3 | Same shapes as 0.1.7-rc.1. |
| 0.2.0-rc.1 | Verified | v0.2.4 | DSH 0.2 release candidate. |
| 0.2.0-rc.2 | Verified | v0.2.4 | Development pin; the runtime inside Rivetdeck 0.2.0-beta.2. |
| 0.2.1-alpha.1 | Development only | development branch | Verified on the development branch; not in the published package. |
| 0.2.1-alpha.2 | Verified | v0.2.5 | Effective session working directories and linked-worktree switching. |
| Any other release | Unsupported | — | Unverified. On 0.1.7-rc.1 and later the install-time peer range refuses; on older hosts it may install but is untested. |
Platforms
- macOSVerified
Same portable build on web and desktop; reveal actions use the desktop provider when present
- LinuxVerified
Same portable build; no platform-specific code paths
- WindowsVerified
Same portable build; Git errors from push and sync surface verbatim
Status is declared per release and never inferred from version order. From DSH 0.1.7-rc.1 the plugin manager enforces these exact peer ranges at install time. Per-release adaptation notes live in the compatibility reference (opens in a new tab).
Review the change where it happens.
One command on a supported host — and in Rivetdeck it is already there. Uninstall and the window is exactly upstream again.
