Skip to content
dsh.fish
Bundle

dsh-diff-approval

DeepSeek Harness plugin: pending-edit review with whole-file diff and Keep/Revert

Source
9087
stars
5 stars
License
MIT
Updated
Updated 1 hour ago

Readme

# dsh-diff-approval

English | [中文](README.zh.md)

[![npm version](https://img.shields.io/npm/v/dsh-diff-approval)](https://www.npmjs.com/package/dsh-diff-approval)
[![CI](https://img.shields.io/github/actions/workflow/status/9087/dsh-diff-approval/ci.yml)](https://github.com/9087/dsh-diff-approval/actions)

A DeepSeek Harness (DSH) plugin for pending-change review: it automatically tracks every successful `edit`, `write`, and editor (`str_replace_editor`) mutation, folds them into a single pending list in the sidebar where each file's diff can be reviewed and kept/reverted — and it can also import the workspace's version-control repository's local changes (Git / SVN / Perforce) in one click.

![Pending changes panel](docs/images/pending-panel.png)

The panel also collapses its file list into a floating card and expands to fullscreen:

| Collapsed file list | Fullscreen |
| --- | --- |
| ![Collapsed file list](docs/images/file-list-collapsed.png) | ![Fullscreen](docs/images/fullscreen.png) |

For Markdown files, the source-line diff can also be shown as a rendered before/after preview:

![Markdown preview](docs/images/markdown.png)

## ✨ Features

- **Diff view**: syntax-highlighted whole-file diff with +/− counts, an overview ruler on the scrollbar showing where changes sit, and an in-file search (`Ctrl+F`, step with `F3` / `Shift+F3`) that highlights matched words. Rows are virtualized, so huge files stay smooth.
- **Block navigation & decisions**: jump between change blocks with `Ctrl+↑/↓` (or the previous/next buttons) — the focused block flashes, navigation is anchored to the scroll position and wraps at the top/bottom. Hover a block to **Keep** or **Revert** just that block from a small actions frame that also shows its position (e.g. "2/5"); after a single-block decision, focus advances to the next block. The lead rows left above the jumped-to block are configurable in settings.
- **Selection frame**: drag to select a range of lines and a frame appears to **Keep** / **Revert** exactly that range.
- **Per-file and bulk decisions**: the files in the file list can be kept / reverted one at a time, or **Keep all** / **Revert all** from its footer.
- **Resolved files stay listed**: once every change in a file has been kept/reverted, the entry remains in the list and the panel asks whether to remove it or keep it for later.
- **Undo / Redo**: every keep, revert, and import is undoable with `Ctrl+Z` / `Ctrl+Shift+Z` (rebindable in Shortcuts; `Ctrl+Y` remains an alias), active while the panel is open — text inputs keep their own editing.
- **Quick summon & file cycling**: `Ctrl+D` (configurable in settings) toggles the review panel from anywhere and `Esc` closes it; `Ctrl+Tab` / `Ctrl+Shift+Tab` cycle through the pending files.
- **Line references**: select text in the diff — the status bar shows its `(file:line)` / `(file:start-end)` reference; click it (or press `Ctrl+L`) to copy, and with the setting on it auto-pastes into the composer and focuses it. References in the composer and queued messages are **auto-aligned** when the referenced file changes: surviving lines re-map to their new range, and a fully-removed line becomes `(file:LINE_MISSING)`.
- **Highlight language**: auto-detected from the file extension, or overridden from a dropdown.
- **Auto-wrap**: a "Wrap lines" toggle beside the language selector wraps long lines for that language (CJK breaks between characters, Latin words stay whole), remembered per language.
- **Side-by-side split view**: an opt-in two-column diff (left "before" | right "current"), line-aligned with per-side horizontal scrolling and a shared vertical scrollbar. Toggle it from the toolbar or in settings (default: single-column unified view). In split view, changed blocks are aligned by content similarity and changed lines show intra-line word diffs — whole words for Latin text, per-character for CJK.
- **Markdown preview**: for Markdown files, toggle between the source-line diff and a rendered before/after preview (`Preview` / `Source`). The preview content max width is configurable.
- **Customizable appearance**: from the "Diff view" settings group, adjust the diff's code font size (%), line height (px), and the added / removed line colors, with a live preview.
- **External changes**: files already in the pending list are monitored — if one is later modified outside the reviewed edits (another tool, an editor), the panel adopts the new content and flags the divergence.
- **Open / Reveal**: while reviewing a file's diff, open it in its default app or reveal it in the system file manager with one click.
- **Import workspace changes**: when the list is empty, click the button to import the workspace's local changes from **Git / SVN / Perforce** — modified, deleted, and (opt-in) untracked files. The VCS root is found by walking up from the workspace, so a workspace inside a subdirectory works too.
- **Settings**: a "Diff Approval" section in DeepSeek Harness settings, grouped into **Diff view** (code font size, line height, added / removed colors) and **Shortcuts** (rebind the panel's keyboard chords) plus preferences for auto-paste on copy, whether untracked files are included when importing, the diff's tab width (2 / 4 / 8 spaces), the side-by-side split view, the block-jump lead rows, the Markdown preview default and width, and the quick-summon chord.
- **Persistence**: pending state is stored per workspace at `<dshHome>/diff-approval/workspaces/<workspaceId>.json` and survives restarts — unhandled changes are still there when you come back, even in a fresh session.

## 📦 Install

If `dsh` is on your `PATH`:

```sh
dsh plugin --profile web add dsh-diff-approval
```

Or, if you run the harness through npx (e.g. `npx @deepseek-ai/dsh web`):

```sh
npx @deepseek-ai/dsh plugin --profile web add dsh-diff-approval
```

or manually: add the package to your profile's `package.json` dependencies and insert this row into the profile's `cordis.patch.yml`:

```yaml
- insert:
    - id: diff-approval
      name: dsh-diff-approval
      # Optional: relocate durable pending state (defaults to
      # <dshHome>/diff-approval/workspaces).
      # config:
      #   storageDir: ~/dsh-pending
```

Then restart `dsh web`.

## 🚀 Usage

1. Work with the agent as usual — successful `edit` / `write` / editor (`str_replace_editor`) calls are recorded automatically.
2. Click the **Pending changes** action at the sidebar footer, review each file's diff, and **Keep** / **Revert**.
3. When the list is empty, **Import workspace changes** pulls in the workspace's local Git/SVN/Perforce changes.

## 📝 Notes

- Only tracked mutations (`edit`, `write`, and `str_replace_editor` editor calls) are recorded automatically. Deletions made outside these tools (e.g. shell `rm`) are sensed only for tracked files: the entry turns "File is gone" and its Revert restores the file.
- The VCS import runs read-only Git/SVN/Perforce commands through the deployment's shell executor, so the respective CLI must be on `PATH`. Importing untracked files (default off) scans the whole workspace, which can be slow on large trees.
- For a newly-created file, the whole-file revert action reads **Delete** and removes the file.
- Reverting a file writes it back with its current line endings (LF / CRLF) preserved.
- Sessions with no workspace keep their entries memory-only; corrupt persistence files are rejected and can be deleted to reset.
- The sidebar footer entry stacks vertically with other plugins' footer actions and defers to the dedicated `dsh-footer-order` plugin when it is present.

## 🛠 Development

```sh
corepack pnpm install
pnpm run typecheck   # tsc over both faces
pnpm run build       # emits lib/index.js and lib/client.js
pnpm test
```

Install

dsh plugin --profile web add github:9087/dsh-diff-approval

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source