DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-follow-edits

z

dsh-follow-edits

Manifest valid★ 1

Cline-style follow-along for DeepSeek Harness: open the file the agent just changed in the right Sidebar, jump to the change, and highlight the diff.

UI (client)hasBundlePatch

dsh-follow-edits

English · 中文

test

Watch the agent edit, live. A plugin for DeepSeek Harness (dsh) that opens the file the agent just changed in the right-hand Sidebar preview, jumps to the changed line, and highlights the diff — the Cline / VS Code follow-along experience, inside dsh's own web UI.

Status: v0.3, working. Open + jump + yellow/red highlighting, exact positioning for both edits and deletions. Host/client logic covered by unit tests and verified on a real desktop profile. Every API used here was checked against the packages bundled in dsh desktop 0.2.0-rc.2 — see docs/research.md for the evidence trail.

pnpm install && pnpm test    # host.test.mjs + client.test.mjs (mock ctx, synthetic events)

What dsh already does, and what this adds

CapabilityWhere it comes from
Preview files in the Sidebarbuilt in
Refresh the preview after an editbuilt in (workspace-files changes() stream)
Open a file at a given linebuilt in (ctx.sidebarRight.openResource(address, { params: { line } }))
End-of-turn diff review (red/green)built in (workspace-changes + the deliverables review tab)
Open + jump at the moment the edit happens✅ this plugin
Yellow = changed line, red = removed content, in the preview✅ this plugin (custom documentPreviews renderer)
Files written by terminal / shell commands also open⚠️ this plugin (degraded: opens the file, no jump, no highlight)

In one line: this is not "add a jump button" — it chains a set of primitives dsh already ships behind a live follow trigger, because dsh currently only tells you about edits at the end of a turn.

Two kinds of change, two paths:

  • Edit tools (str_replace_editor / write / edit) → precise follow: open + jump + yellow/red highlighting.
  • Terminal / shell (a command writing a file via pwsh / bash) → degraded follow: open the file only (the preview refreshes itself). Shell writes bypass ctx.fs, so there is no before/after content to diff.

How the line number is obtained:

  • create / write → line 1
  • str_replace_editor insert → insert_line + 1
  • str_replace / edit (both edits and deletions) → the host reads the old file in tools/pre-execute (i.e. before the edit) and locates the start line with indexOf(oldStr) — exact
    • Removed content no longer exists in the file afterwards, so it must be captured before the edit
    • On a cold read/replay that mapping is empty → the client falls back to searching for newStr (still exact for edits; deletions fall back to the top of the file)

Architecture (checked against the official packages)

Path A: edit tools (precise)
agent calls str_replace_editor / write / edit
   ▼ tool/call committed
   ▼ tools/pre-execute   (★ BEFORE the edit) → ctx.fs reads the old file → indexOf(oldStr) → line
   ▼ tool executes
   ▼ tool/result committed
host side: sessionProjections.register({ key: 'followEdits', ... })
   │  folds tool/call + tool/result → last = { path, line, oldStr, newStr, ... }
   │  wire.view pushes that state to the client automatically (keyed, no allow-list)
   ▼
client: openResource(fileAddress, { params: { line } }) → open + jump + yellow/red highlight

Path B: terminal / shell (degraded)
a shell command writes to disk from a child process (bypasses ctx.fs; no tool/call, no fs/observed)
   ▼ host: node:fs.watch(session.header.cwd, { recursive: true })
   ▼ text/code suffix hit → shellBySession.set(sessionId, { path, ts })
   ▼ the next session event recomputes the projection and merges it into last (command = 'shell')
   ▼
client: openResource(fileAddress) → opens the file only, no jump, no highlight
  • Host half (index.js): one sessionProjections.register unit + a tools/pre-execute listener (captures the pre-edit line) + a recursive workspace-root watcher attached on session/created; inject: ['sessionProjections', 'fs'].
  • Client half (client.js): subscribes to the sessions list + faceOf('followEdits'), calls openResource on change, and registers a priority: extension documentPreviews renderer that paints changed lines yellow and removed content red.
  • Key detail: a third-party projection's wire value shows up in the client's faceOf(key) by key — no compile-time allow-list from dsh-api-remotes is needed.

Repository layout

dsh-follow-edits/
├── package.json        # bundle manifest: dsh.bundle.patch + dsh.client
├── cordis.patch.yml    # patch layer: inserts dsh-follow-edits
├── index.js            # host half: projection + tools/pre-execute line capture
├── client.js           # client half: projection subscription → openResource; highlight renderer
├── host.test.mjs       # host unit tests (projection folding / line capture)
├── client.test.mjs     # client unit tests (follow wiring / address building / highlight tree)
├── scripts/verify-install.mjs  # loader-resolution self-check (stale names, missing targets)
├── .github/workflows/ci.yml    # pnpm test on Linux + Windows, Node 20/22
├── docs/research.md    # research notes — where every API was verified
└── LICENSE

Install

Through the official Plugin Manager (runs pnpm install and loads both faces):

plugin_manager  action: install_bundle  target: <absolute path to this directory>

Or with the dsh CLI first, to check it on the web build:

dsh web --patch ./cordis.patch.yml

Desktop: merge the insert entry from cordis.patch.yml into ~/.dsh/profiles/desktop/cordis.patch.yml and restart the app.

Uninstall / disable: the Plugin Manager's set_bundle / remove_bundle.


Verification

Unit level (reproducible in this repo): pnpm test

  • host.test.mjs — projection folding (create/insert/write/view/failure/unrelated tools/gating), tools/pre-execute line capture (deletion → line 2, edit → line 3, capture failure → fallback, mapping read-once-then-deleted), and the recursive shell watcher (real node:fs.watch: write → last.command === 'shell', line null, no before/after text, a second write follows the newest file).
  • client.test.mjs — follow wiring (subscribe → open + jump, ts dedupe, 90 s expiry), address building (relative / absolute / outside the workspace), highlight tree (yellow line + red ⊖ row, other files untouched).

Real machine (desktop profile, verified) — after installing into the profile and restarting:

  1. Have the agent change a line → the right Sidebar opens the file automatically, the new content is yellow, the old content shows as red ⊖;
  2. Have the agent delete a line → the removed content appears as red ⊖ where it used to be.

Evidence: screenshot + pixel analysis (the yellow blend lands on (103,96,36) and the red on #e5484d = (229,72,77), both exact) plus eyeball confirmation.

Install-time self-check (reproducible, no dsh needed): node scripts/verify-install.mjs --profile ~/.dsh/profiles/<name>

Walks the same resolution steps the dsh loader does — exports targets exist, the patch entry name and the client module id both match package.json, dependencies resolve, and the profile symlink points back at this directory. It exists because a rename that misses one of those references fails silently: nothing in the UI tells you, it just stops following after the next restart.

Clean-room load check (verified) — a brand-new $DSH_HOME with a brand-new profile whose only non-official entry is this bundle:

export DSH_HOME=/tmp/dsh-home-clean
# profiles/verify-web/package.json → dependencies: { "dsh-follow-edits": "link:<repo>" }
#                                   → dsh.profile.bundles: [dsh-base, dsh-web-app, dsh-follow-edits]
dsh --profile verify-web --dump-config | grep -A2 '== dsh-follow-edits'
# == dsh-follow-edits
- id: dsh-follow-edits
  name: dsh-follow-edits

Exit code 0, 1262-line composed tree, no errors — the bundle layers exactly like an official one.


Known limitations

  • The highlight renderer replaces the built-in code preview. To overlay diff colours it registers a priority: extension renderer, so you lose the built-in Shiki syntax highlighting by default (switch back to "Code" in the preview's renderer dropdown). Folding diff colours onto the built-in highlighter is future work.
  • Exact line numbers depend on a non-session map. The host stores callId → oldStr start line in an in-memory map during tools/pre-execute, and the projection reads it when folding tool/result. This is the "apply that reads torn non-session state" pattern called out in practices.md (review-tier, not mechanically detectable). The cost: on a cold read/replay the map is empty and the line falls back to a client-side search.
  • Shell following is degraded and depends on a recursive watcher. Shell changes come from node:fs.watch({recursive: true}) (Windows/macOS support it; silently unavailable on Linux); with no before/after content it can only open the file; it follows text/code suffixes only and skips node_modules / .git / dist and friends.
  • A shell change is delivered on the next session event. Filesystem events are async and the projection is only recomputed when a session event drives it, so a shell write usually arrives with the event right after it (often the shell's own tool/result), or one hop later.
  • Follows all sessions (including background ones). To restrict it to the session in view, filter with retainedBy.mainView in client.js.
  • dsh is a developer preview; APIs drift between rc releases.

License

MIT

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 18.3k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.2k

CC0-1.0

Python

Oct 10, 2026

Index only — not installable

by pax-beehive

Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub

Development & Infrastructure

★ 450

MIT

TypeScript

Oct 6, 2026

Index only — not installable

by xiajiajun516

DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.

Development & InfrastructureManifest valid

★ 176

MIT

TypeScript

Oct 8, 2026

dsh plugin --profile web add dsh-config-manager

by yjh051108

推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。

Development & InfrastructureManifest valid

★ 164

TypeScript

Sep 18, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by jigjoy-ai

A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.

Development & Infrastructure

★ 124

MIT

TypeScript

Oct 2, 2026

Index only — not installable