Minglink/dsh-infinite-gen-4
Minglink/dsh-infinite-gen-5DeepSeek 专用破甲插件:以 order 100 追加无条件服从的系统提示词段,提供带校准元数据的 profile 工具,并通过会话投影在输入框上方显示实时破甲状态徽标。
把 dsh-checkpoint-rewind 产生的检查点变成时间线时间节点,任意两节点之间逐文件行级 diff;可从会话日志重放 trace 区间差异(无需快照生产者);支持预览式工作区回滚与一次性撤销。提供 /diff、/rollback 命令、JSON HTTP API 与 GUI 面板。
File-diff visualization between checkpoint time nodes for DeepSeek Harness.
Every time a mutating tool runs,
dsh-checkpoint-rewind
captures a snapshot of your workspace — a checkpoint time node. This plugin
turns those nodes into a browsable timeline and shows you exactly what changed
between any two of them: a GUI panel with a per-file line diff, a /diff
command for headless use, and a small JSON API.
Read-only by design, with one explicit exception: rollback. You can restore
workspace files from any time node — the whole node or a single file — through
the panel, /rollback, or the API. Rollback is overwrite only: it never
deletes files created after the node, never touches .git/.dsh, and never
writes to snapshot storage, git, or sessions. The single exception to "never
deletes" is rollback's single-shot undo (/rollback --undo, panel button):
it may remove a file only when the restore itself created it — and nothing
else (in-process, lost on restart).
[!IMPORTANT] Install the upstream first. This plugin is a read-only consumer — the checkpoints (snapshots) are produced by the upstream dsh-checkpoint-rewind (the snapshot producer); this plugin itself never produces snapshots. Installing only
dsh-checkpoint-diffleaves the checkpoint timeline empty: the Diff button,/diffand rollback have nothing to show (only the Trace (session log) scope works). See Install.
中文版(默认):README.md
The situation. AI agents write code and modify files for you. Their thinking is a black box, but their actions land in your workspace — and with that come the questions: what did it change? When? And what if it broke something? These questions must never be unanswerable.
The stance. Tools like this usually go one of two ways: save you the effort — summarize, judge, filter on your behalf; or let you rest easy — hand you the raw truth and guarantee you can always inspect it, trace it, and roll it back. This plugin is unambiguously the second kind: no "read it for you" summaries or filtering — it hands you the full power to see clearly and step back.
One line: you may not look, but it must never be un-inspectable. People may choose not to look and not to investigate; what they must never lack is the means to do both. That is why this plugin exists.
Real captures from a live harness session. Panel overview — scope switch,
from/to node selects (intent labels, (HEAD) prefix), tree file list
(A/M/D), per-line diff (red/green + ↑/↓ change-block jumping), and the
Restore workspace card:
Trace (session log) scope — session-log replay with the three-lane drag-select timeline (Input / Model / Tools spans, turn boundaries; a drag range maps to the nearest tool-call boundaries in from/to):
This session scope — the current session's checkpoint timeline.Select the version to roll back and click Preview Restore to preview the changes:
This project scope — cross-session merge with the fork-lineage branch dropdown:
Re-capture and update the README after any significant UI change — capture rules in docs/screenshots/README.md.
/diff lists this session's timeline — rewind leaves a snapshot time node
before every mutating tool run (format is the real output, data is
illustrative):
diff: 3 checkpoint(s) for this session
#a1b2c3d4 20m ago turn 2 step 1 copy 3 file(s) 18 KiB edit lib/engine.mjs
#b2c3d4e5 10m ago turn 3 step 1 copy 2 file(s) 12 KiB edit README.md
#c3d4e5f6 5m ago turn 3 step 2 copy 4 file(s) 25 KiB bash pnpm test
usage: /diff <from> <to> (id prefix or "latest" for either side)
/diff <from> <to> between any two nodes — file summary + line diff (the GUI
panel shows the same red/green diff side by side):
diff: #b2c3d4e5 (14:02 · edit README.md) → #c3d4e5f6 (14:07 · bash pnpm test)
4 file(s) changed: +1 added, 2 modified, 1 deleted
M lib/engine.mjs
- function lcs(a, b) {
+ function lcs(a, b, opts) {
M README.md
- Read-only by design, one exception: rollback
+ Read-only by design, one explicit exception: rollback
A test/engine.test.mjs
D lib/legacy.mjs
/diff / HTTP
API), plus preview-first rollback (overwrite-only, never deletes, undoable)./diff · /rollback
· /checkpoint-diff/api.#short-id, time,
turn/step, provider, trigger tool; /rewind guard checkpoints are marked)./rewind fork lineage: branch dropdown (root + side branches, session
titles), per-session tags, and fork / root-missing markers. Falls back to a
flat merge when the optional dsh-session-query service is absent.tool/call
events of its (turn, step) are looked up to produce labels like
edit README.md or bash pnpm test (in the GUI, /diff output and the
JSON API), falling back to the raw trigger tool when the log is unavailable.
Cold sessions are resolved read-only through sessionQuery.readSession.A (added) /
M (modified) / D (deleted) badges.copy
snapshots) renders ctx/del/add lines with aligned line numbers./diff --trace: every tool/call boundary in
the session log (session.jsonl.zstd) becomes a time node
(trace:<seq>), and selecting any two nodes diffs that interval by
replaying write/edit/str_replace_editor arguments (full file
contents are in the tool parameters). No snapshot producer is needed — past
sessions work out of the box, and rewind absence, quota eviction or git gc
no longer silence the "what changed" question. Shell-command edits are
invisible to the trace; any replay divergence is reported in notes
(never silent). Data comes from sessionQuery.readSession first, with a
direct zstd read (Node ≥ 23.5) as the last-resort fallback.git (unreferenced stash/commit-tree objects,
read via git diff-tree/git show) and copy (snapshot directories +
manifests), dispatched per record; mixed-provider pairs are rejected loudly..git/.dsh never touched); the git
provider only uses read-only git primitives and refuses to run unless the
session cwd is the repository root.↩ Undo this restore
action (panel button, /rollback --undo, POST /api/rollback-undo)
reverts it: overwritten files get their pre-restore content back, and files
the restore created are removed (the one "never deletes" exception).
In-process only (lost on restart), no redo; files changed since the restore
are skipped untouched.(HEAD) (uppercase,
prefixed to the id: (HEAD) #bbbbbbbb 20:26 · edit b.txt) in the
from/to/restore-target selects, in the summary range line and in the
restore-preview tag. HEAD always means the current snapshot — the
global newest node — so it never moves when you pick other versions or
filter branches; refreshing the timeline moves it to a newer snapshot.🔍 file).git gc (or lost on re-clone) are marked ⚠ degraded in the
selects and excluded from the default selection; the timeline shows a
"N checkpoint(s) degraded" banner, and any diff/rollback error names the
exact dead node (checkpoint #9312717a (to side) is missing from this repository (bad object …)). No data is ever deleted; pick newer nodes or
run rewind's /rewind clear to reset the timeline. Pruned checkpoints,
missing records and missing files keep their existing clear errors.Through the lens of "an AI agent just modified my workspace", against the common options (facts per each project's official docs):
| Tool | Snapshot granularity | Diff between any two nodes | Restore / rollback | Session awareness |
|---|---|---|---|---|
| dsh-checkpoint-diff (this plugin) | before every mutating tool run | ✅ yes, per file and per line (GUI / /diff / API; intent labels, tree view, change-block jumping) | preview-first → apply; never deletes; single-shot undo; whole node or single file | session + cross-session project scope (fork lineage, branches) |
| dsh-checkpoint-rewind (upstream producer) | before every mutating tool run (0.5.0+: + per-turn / scheduled / manual) | ✅ settings-page pairwise compare (0.5.0+: file change-set + config line diff; no per-file workspace line diff) | /rewind preview → restore → fork (guard checkpoint; 0.5.0+: seed-replay session rewind) | single session |
| dsh-turn-rewind | per user message (coarser) | ❌ no (changeLedger service, no visual diff) | conversation + workspace rewind; web restore dialog | single session |
| dsh-snapshot | before each write/edit/delete (target file content) | ❌ no line-level diff | roll back a whole "conversation" (re-rollbackable) | single session (project-level quota) |
Claude Code native checkpointing + /rewind | per conversation turn (automatic) | no node-to-node diff view in the docs (see official docs) | /rewind restores files (git-tracked) | inside Claude Code sessions |
git baseline (git diff/restore, GitLens etc.) | per manual commit | ✅ any two commits, line-level (mature ecosystem) | git restore/checkout; no preview planning, no undo guard | none (bare repo) |
| IDE local history (JetBrains Local History / VS Code Timeline) | per edit/save (per file) | single-file revision level | restore any single-file revision | none |
| OS-level snapshots (Time Machine / Windows File History) | hourly/daily | ❌ no line-level diff | whole file/directory restore | none |
Note: the DSH ecosystem also has timeline-style plugins such as
dsh-message-timeline, dsh-session-timeline, dsh-chat-timeline and
dsh-undo-savepoint (DSH-config domain); this table focuses on the
diff-visualization + rollback dimension.
Ecological position (verified 2026-08-17): upstream rewind 0.5.0 now ships
its own settings-page timeline with pairwise compare (file change-set + config
diff; source-verified: no per-file workspace line diff). This plugin
does not compete with the producer over "having a diff"; it stays a read-only
consumer + analysis layer — intent labels, cross-session fork lineage, non-git
workspaces (copy), preview-first rollback with single-shot undo, /diff and
the HTTP API — and aims to degrade gracefully even when rewind is absent or
snapshots are gone. Ecosystem assessment, compatibility facts (rewind 0.5.0
domain v2) and the differentiation roadmap:
docs/competitive-analysis.md.
[!IMPORTANT] Upstream first. dsh-checkpoint-rewind is the snapshot producer — it creates the checkpoints (snapshots) this plugin reads; this plugin is a read-only consumer and never produces snapshots itself. Installing only
dsh-checkpoint-diffleaves the timeline empty: the Diff button,/diffand rollback have nothing to show (only the Trace (session log) scope works, see Features). If you skipped the upstream, add it and restart the harness.
dsh plugin --profile web add dsh-checkpoint-rewind # ⚠️ upstream snapshot producer — install first
dsh plugin --profile web add dsh-checkpoint-diff # this plugin (consumer)
Both are bundle plugins: dsh plugin add appends them to the profile's
dsh.profile.bundles, and each package's cordis.patch.yml inserts its row.
Restart the harness for host-side changes; the browser bundle is served
with cache-control: no-cache, so a page refresh picks up client fixes.
The bundle layers must mount rewind before diff (the diff plugin reuses rewind's
checkpointsstorage domain; the bundle order indsh.profile.bundlesdecides this — verify it afterremove/addcycles, which re-sort dependencies).
A Diff button appears in the session header action row. It opens a panel:
readTitle);#a1b2c3d4 14:02 · edit README.md), prefixed with the owning
session's short id in project scope;Rollback. A collapsible Restore workspace card sits below the toolbar,
separate from the node-diff area: pick the node you want to restore to
(defaults to the latest node; every file row also carries a ↩ button to
restore just that file), press Preview restore to see the plan
(would-restore / unchanged / skipped files, plus files created after the node
that will be left in place), then Apply restore. The panel refreshes the
timeline afterwards.
While a restore plan is showing, click any would-restore file (shown as an
obvious 🔍 file link) to see the current workspace → target snapshot
diff in the right pane, tagged "Restore preview: …" — the toolbar from/to
selects switch to a read-only "current workspace → target" pair so the
comparison direction is always obvious (click a file in the tree to exit
back to the normal from/to diff). The preview belongs to the restore section:
picking other from/to versions never clears it, and changing the restore
target reloads it against the new target. After an apply, the status area
lists what was restored without offering stale preview rows; an ↩ Undo this
restore button reverts the restore in one shot (overwritten files get their
previous content back; files the restore created are removed; anything
changed since is left alone). The diff pane also remembers your last viewed
node pair: a small Last view line below it jumps back to it (even across
session/project scope).
Fork junctions crossed by the selected range are shown as ⤷ fork markers;
an incomplete lineage renders an "earlier history unavailable" hint.
Click anywhere outside the panel to close it.
/diff list this session's checkpoint timeline
/diff <from> <to> file summary + per-file line diffs between two nodes
/diff --project list the project timeline (all sessions, branch header)
/diff --project <from> <to> diff between two nodes across sessions
/rollback [--project] [--dry-run] <node> [<path>...]
restore workspace files from a time node
/rollback --undo revert the most recent restore (single-shot)
<from> / <to> accept an id prefix or latest, e.g. /diff a1b2c3d4 latest.
In project scope, ambiguous prefixes prefer the current session's records.
/rollback restores every file of the node, or only the given paths; latest
is a valid node. --dry-run prints the plan without writing anything
(would restore N file(s), M unchanged, K skipped + the files that will be
left in place); --project addresses nodes from any session sharing this
workspace. Rollback never deletes files — contents are overwritten in place.
/rollback --undo reverts the most recent restore (in this process): files
return to their pre-restore content, and files the restore created are
removed; files changed since the restore are skipped (all skipped → error).
Served by the harness webServer at the /checkpoint-diff/api prefix
(same-origin JSON). Read endpoints are GET-only and accept an optional
scope=project parameter to address records across sessions; rollback and
rollback-undo are POST endpoints (the only endpoints that write, and they
only write into the session workspace):
| Endpoint | Method | Params / Body | Returns |
|---|---|---|---|
/api/timeline | GET | session, scope? | {ok, records[]} — newest-first timeline views; scope=project adds branches[] and markers[] |
/api/summary | GET | session, from, to, scope? | {ok, from, to, files[{path,status}], totalFiles, truncated} |
/api/file-diff | GET | session, from, to, path, scope? | {ok, ops[{type:'ctx'|'del'|'add', text, a?, b?}], truncated, binary} |
/api/preview-diff | GET | session, target, path, scope? | {ok, path, ops[], truncated, binary, present} — current workspace → target snapshot diff (read-only) |
/api/rollback | POST | JSON {session, target, scope?, paths?, dryRun?} | {ok, dryRun, scope, target, files[{rel,action,reason?,mode?}], restored, unchanged, skipped, leftovers, notes} |
/api/rollback-undo | POST | JSON {session} | {ok, target, time, restored, removed, skipped[]} — reverts the most recent restore |
For /api/rollback: target is an id prefix or latest; paths limits the
restore to those files (omit = whole node); dryRun: true plans without
writing (restored then means would restore). files[].action is
restore | unchanged | skip; leftovers lists files created after the
node that were left in place (never deleted).
For /api/preview-diff: the diff direction is current → snapshot (del =
lines the restore would remove, add = lines it would bring back); present
is both or workspace-missing (file does not exist in the workspace yet).
For /api/rollback-undo: restored = files rewritten to their pre-restore
content, removed = files the restore created that were deleted (the one
"never deletes" exception), skipped = files left alone because they changed
since the restore (all skipped → 409). Undo state lives in process memory
only — a harness restart clears it (then 404 nothing to undo).
Errors: {ok:false, error} (400 bad params / mixed providers / bad scope /
unsafe paths, 404 unknown session, file absent from the node, or endpoint,
405 wrong method, 413 oversized body, 500 storage or git failures).
The public contract of this plugin's guarantees — consumption contract + rollback safety contract: docs/contract.md.