v0.2.5 changelog (opens in a new tab)MIT · npm · macOS · Linux · Windows

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
Rivetdeck window with the Workspaces sidebar, a new session composer, and the Git Changes panel listing two modified files and one untracked file on branch feat/checkout-flow.
The Changes tab in Rivetdeck: two modified files and one untracked file on feat/checkout-flow.

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
Rivetdeck window with the Workspaces sidebar, a new session composer, and the Git Changes panel listing two modified files and one untracked file on branch feat/checkout-flow.
Staged, unstaged and untracked sections; the branch sits beside refresh.

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/staged

    staged comparison

  • dsh-resource://git/diff/src%2Fcart.tsx/worktree

    working-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
main
AutoAllFirst-parent
  • Merge pull request #14: status panel UI

    cherrchen · 2h ago

    HEAD → main
  • fix(client): restore graph node hover emphasis

    cherrchen · 5h ago

    status-panel-ui
  • fix(compat): support DSH 0.1.5-rc.3 and 0.2.1-alpha.1

    cherrchen · 1d ago

    origin/main
  • feat(client): staged diff opens beside the worktree one

    cherrchen · 1d ago

    v0.2.5

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…

feat/checkout-flow3 changed

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
pnpm-workspace.yaml · composition config
 plugins:   - entry: @dsh-electron/dsh-plugin-git     config:       commitMessage:         mode: custom         provider: anthropic         model: claude-haiku-4-5

Design 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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. 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 web
  2. 2

    Approve the GitHub build step

    Only a github: install builds on your machine — the package’s own prepare. pnpm 10+ refuses with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED until the key it prints is allowed in that profile’s pnpm-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. 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 web with --profile desktop.
  • Running DSH from a source checkout? Use pnpm dsh instead of dsh.

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 releases supported by plugin version 0.2.5 and the development branch
DSH releaseStatusAdded inNotes
0.1.5-rc.2Verifiedv0.2.0Baseline: the earliest release shipping the right sidebar this plugin registers into.
0.1.5-rc.3Development onlydevelopment branchManifest-only re-release; verified on the development branch.
0.1.6-alpha.1Verifiedv0.2.2Plugin configuration sits under Settings → Plugins → Plugin configuration.
0.1.6-alpha.2Verifiedv0.2.2Configuration moves to the bundle’s detail page; session lookup probes the new list shape.
0.1.7-alpha.1Verifiedv0.2.2configForms replaces settingsScope; icons move to weighted names.
0.1.7-alpha.2Verifiedv0.2.2Same shapes as 0.1.7-alpha.1 for this plugin.
0.1.7-rc.1Verifiedv0.2.2Install starts enforcing the exact peerDependencies list.
0.1.7-rc.2Verifiedv0.2.3Same shapes as 0.1.7-rc.1.
0.2.0-rc.1Verifiedv0.2.4DSH 0.2 release candidate.
0.2.0-rc.2Verifiedv0.2.4Development pin; the runtime inside Rivetdeck 0.2.0-beta.2.
0.2.1-alpha.1Development onlydevelopment branchVerified on the development branch; not in the published package.
0.2.1-alpha.2Verifiedv0.2.5Effective session working directories and linked-worktree switching.
Any other releaseUnsupported—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.