dsh-weknora
Tencent/WeKnora把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己带引用的 RAG 或 ReAct agent 回答(含可续聊的 session id)。
npm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-checkpoint-rewind (counts toward the deepseek1024.com install ranking).Unified DeepSeek Harness checkpoints — session + workspace + config three-state snapshots with one-shot rollback.
*The Claude Code Checkpoints equivalent, built as a capability-seam plugin: capture before every mutation, restore any of the three states with one approved command.*
Official repository. This is the only official repository of dsh-checkpoint-rewind, maintained by PerryLink. Same-name repositories under other accounts are not affiliated.
English · 简体中文 · Español · Português · हिन्दी
dsh plugin --profile <name> add dsh-checkpoint-rewind📖 Ecosystem knowledge base — measured data, not marketing: plugin development guide · plugin-selection data · maintenance criteria.
main): dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind — pure ESM, no prepare or allowBuilds step.dsh plugin --profile web add dsh-checkpoint-rewind.npm pack in this repo, then dsh plugin --profile web add ./dsh-checkpoint-rewind-.tgz.@deepseek-ai/dsh-storage + @deepseek-ai/dsh-storage-json (config root) + @deepseek-ai/dsh-storage-domain (config backend: json) — see Quick start; the plugin still mounts without them and every command explains the fix.dsh plugin --profile web remove dsh-checkpoint-rewind — snapshot files stay until you delete $DSH_HOME/dsh-checkpoint-rewind; git objects are garbage-collected.这个插件是 DSH 插件家族的一员(95 个,全部 Apache-2.0)。如果你在用,给个 star —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。
*English:* part of a 95 plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.
Unified DeepSeek Harness checkpoints — session + workspace + config three-state snapshots with one-shot rollback.
The Claude Code Checkpoints equivalent, built as a capability-seam plugin: capture before every mutation, restore any of the three states with one approved command.
*Workflow overview: install → open panel → act. The examples below use the real command surface.*
Capabilities out of 2 (restores files? / rewinds the session?) · counted from the README comparison table
Surface · Status Harness · DeepSeek Harness dsh-v0.2.1-alpha.1 (GitHub tag, verified 2026-09-25; npm pin 0.1.7-rc.2, peers >=0.1.6-0 =0.1.7-0 =24.0.0 Platforms · All (host commands + listeners; optional Settings page timeline via the settings capability) Model · Any (no model calls — snapshots and restores are deterministic)
dsh-checkpoint-rewind captures a three-state unified checkpoint — workspace, session cursor, and plugin config — and restores one or all three with a single approved command:
seq + turn boundary), and a config snapshot, tagged by source (manual / auto / guard / mutation).fs/write-intent, fs/edit-intent, tools/pre-execute), on automatic interval (autoCheckpoint, default every step), manually (/checkpoint and the checkpoint tool), and as a guard before every rewind.git stash create / commit-tree produce unreferenced snapshot objects that never touch your worktree, index, or history; restore is worktree-only and path-explicit. Non-git directories (and unborn-HEAD repos) degrade to an incremental copy provider with hardlink reuse./rewind workspace|session|config|all restores the selected states; preview is a read-only impact report, diff compares two checkpoints, clear deletes them (this session; clear --all spans all sessions and workspaces).SessionStore.fork primitive into a new child session (falling back to the seeded sessions.create path when the host has no fork or the checkpoint has no boundary); the original session keeps its full history.Plugins → Checkpoints tab renders the session's checkpoints with pairwise line-level diffs.Plugin · What it sells · Restores files? · Rewinds the session? dsh-checkpoint-rewind (this) · git-object snapshots + three-state rollback + one-shot restore · ✅ full workspace state · ✅ seed-replay child session Anionex/dsh-turn-rewind · persistent Change Ledger of per-mutation deltas · ✅ by replaying inverse deltas · ✅ its own ledger model LingLambda/dsh-undo · pure context rollback to the last completed step · ❌ · ✅ context only Mongfayi/dsh-recall · message recall (remove a turn and everything after) · ❌ (explicitly) · ✅ turn removal
The difference in one sentence: **dsh-checkpoint-rewind captures the *workspace state* with side-effect-free git primitives before each mutation, and makes "back to step N" one approved command — guard checkpoint first, files restored second, config restored third, session replayed fourth, each phase logged.** No delta bookkeeping to drift, no message-level editing (that belongs to a different plugin), no cross-device sync.
dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind# 1. install the bundle into your profile
dsh plugin --profile web add github:PerryLink/dsh-checkpoint-rewind
# or from npm (published releases)
dsh plugin --profile web add dsh-checkpoint-rewind
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A4 'id: checkpoint-rewind'Checkpoints persist through the storageDomain service. The plugin mounts without it and never blocks profile startup — checkpoint/rewind commands then return a structured error naming the exact rows to add. Compose the storage stack once to enable checkpoints:
- insert:
- id: checkpoint-rewind-storage
name: '@deepseek-ai/dsh-storage'
- id: checkpoint-rewind-storage-json
name: '@deepseek-ai/dsh-storage-json'
config:
root: !!js dshHomePath('checkpoint-rewind/storage')
- id: checkpoint-rewind-storage-domain
name: '@deepseek-ai/dsh-storage-domain'
config:
backend: jsonThe package is pure ESM with no build step — index.mjs and lib/ are the shipped artifacts. Workspace mutations now create checkpoints automatically; run /rewind to list them (or /rewind list brief for one-line entries carrying each checkpoint's session number):
rewind: 3 checkpoints (newest last):
#a1b2c3d4 · (git) · turn 2 step 1 · 2026-08-14 12:00:01 (3 min ago) · trigger: bash · 4 files · 1.2 MiB
#b2c3d4e5 · (git) · turn 2 step 3 · 2026-08-14 12:00:41 · trigger: str_replace_editor · 2 files · 310 KiB
#c3d4e5f6 · (copy) · turn 3 step 1 · 2026-08-14 12:01:10 · trigger: write · 1 file · 90 KiB
run "/rewind <id>" to restore files and fork the session from that checkpointAddress a checkpoint by its session number (the bounded short number shown by /rewind list brief), by unique id prefix, by step number, or by latest:
/rewind list brief # one line per checkpoint, numbered, newest first
/rewind 3 # the checkpoint numbered 3 in THIS session (exact hit, never a fuzzy match)
/rewind preview 3 # read-only: show which files would change, touch nothing
/rewind b2c3d4e5 # unique id prefix (the 8-char id in the list) works exactly as before
/rewind step 2
/rewind latest
/rewind workspace 3 --files src/a.ts,src/b.ts # selective restore: only these files (approval-gated)
/rewind clear # confirmed deletion of this session's checkpoints (files untouched)
/rewind clear --all # confirmed deletion across ALL sessions and workspaces (files untouched)1. /rewind 3 resolves that number exactly — digits are never treated as an id prefix, so /rewind 3 can never land on the checkpoint whose UUID happens to start with 3.sessionId). Each session numbers its own checkpoints; a number is unique inside its session, and /rewind resolves against the checkpoints of the current session (and workspace) only.maxSnapshots) and /rewind clear / /rewind clear --all delete records but never free a number: after a clear the next checkpoint continues from the previous high-water mark (so after #1 #2 #3 and a clear, the next one is #4, not #1). The number is stored on the record itself and the counter lives in the domain's global slot, so deleting records cannot reset it./rewind list (the detailed list) is unchanged: it still prints the 8-char id per line and its last line points at /rewind list brief for the numbers.preview resolves through the same addressing and prints the impact without asking for confirmation or writing anything. --files restores only the named files through the same approval-gated transaction (unknown paths fail closed; it is incompatible with workspaceRestore: reset-hard and disabled when selectiveRestore: false).
These are the plugin's real entry points; install once, then call one.
Command
~~~sh /rewind preview cp-9 ~~~
Output
~~~text rewind preview: checkpoint #cp-9 (provider git, turn 2 step 3) restoring it would overwrite 2 file(s): a.txt b.txt 5 file(s) already match the checkpoint (not touched). no files are deleted: 1 file(s) created after the checkpoint would be left in place: new.txt run "/rewind " to confirm and apply (a guard checkpoint is captured first) ~~~
*Observed from test/checkpoints.test.mjs:289-301; lib/checkpoints.mjs:484-500*
Input
~~~text /rewind nope ~~~
Output
~~~text rewind: unknown checkpoint id "nope" (run /rewind to list) ~~~
*Observed from plugins/dsh-checkpoint-rewind/lib/errors.mjs:72; plugins/dsh-checkpoint-rewind/index.mjs:1223; plugins/dsh-checkpoint-rewind/test/index.test.mjs:346-350*
/checkpoint/rewind previewAll tunables are Schemastery Config fields (changeable from cordis.yml). Nothing is hardcoded. Provider options (gitBin, snapshotDir, excludeGlobs, verifyByHash) are read from the live config at use time, so cordis.yml changes apply without a restart.
Key · Default · Meaning enabled · true · Master switch; false removes the commands, listeners, and providers entirely provider · auto · Snapshot provider: auto (git if available, else copy) · git · copy gitBin · git · Git executable path snapshotDir · $DSH_HOME/dsh-checkpoint-rewind (fallback ~/.dsh/dsh-checkpoint-rewind when $DSH_HOME is unset) · Root for copy-provider snapshots maxSnapshots · 50 · Checkpoints kept per session (oldest pruned first) maxSnapshotBytes · 536870912 (512 MiB) · Global incremental-byte soft quota (newest per live session always retained) pruneOnTurnEnd · true · Run quota pruning when a turn ends mutationTools · ['bash','write','edit','str_replace_editor','pwsh','terminal_send'] · Tools treated as mutating at tools/pre-execute excludeGlobs · ['node_modules','.git','.dsh','dist','build'] · Glob patterns skipped by the copy provider confirmVia · auto · Confirmation channel: auto (userQuestions first) · userQuestions · approval listLimit · 10 · Checkpoints shown by bare /rewind preRewindCheckpoint · warn · Guard checkpoint before restore: warn · require · off verifyByHash · false · Copy-provider content-hash comparison and restore verification autoCheckpoint.enabled · true · Automatic interval snapshots on step/start autoCheckpoint.intervalMinutes · 0 · Interval; 0 = every step workspaceRestore · restore · Workspace rollback: restore (safe overwrite) · reset-hard (CC-style, opt-in) diffRenderer · pairwise · Settings-page diff renderer: pairwise (line-level text) · side-by-side (per-file two-column) selectiveRestore · true · Per-file selective restore (/rewind … --files) and the panel's per-file checkbox + size total promptSection · true · Inject a short role-statement prompt section checkpointTool · true · Register the checkpoint model tool
- insert:
- id: checkpoint-rewind
name: dsh-checkpoint-rewind
config:
provider: auto
maxSnapshots: 50
maxSnapshotBytes: 536870912
pruneOnTurnEnd: true
confirmVia: auto
preRewindCheckpoint: warnSurface · Kind · Notes /rewind · command · [workspace\ · session\ · config\ · all] \ · latest> · list [brief] · diff · preview · clear [--all] /checkpoint · command · [note \ · list\ · diff ] — capture a manual checkpoint checkpoint · tool · Capture a manual checkpoint with an optional note fs/write-intent · fs/edit-intent · tools/pre-execute · listeners · Pre-mutation capture (prepend pass-through; never steals the policy slot) session/event · listener · Turn/step tracking, auto interval, boundary backfill, turn-end pruning checkpoints projection · session projection · Timeline strip folded from the session log Settings page timeline · client · Plugins → Checkpoints tab with pairwise (diffRenderer) diffs and per-file selective restore (selectiveRestore)
stash create, commit-tree, restore --worktree, ls-tree, diff-tree, ls-files, status, rev-parse, cat-file -e — enforced by a runtime assertion, and object refs are validated as hex ids before being passed to git (a tampered record cannot inject git options). No `reset --hard` by default, no `clean`, no index/history mutation, ever (see workspaceRestore below).git restore … -- . would delete files git add-ed after the checkpoint). Files created after the checkpoint (untracked or staged) are *reported* and left in place.ask semantics; a missing, throwing, or answering-no answerer fails closed. /rewind preview is the read-only way to inspect the impact first.preRewindCheckpoint: require aborts the rewind when the guard cannot be captured.git reset --hard (branch head moves to the snapshot commit; pre-snapshot history stays recoverable via reflog; untracked files untouched). It is off by default.command/run + command/done (and, once the host knows them, checkpoint/* events) plus the durable checkpoints domain.capture ── fs/write-intent · fs/edit-intent · tools/pre-execute (prepend, pass-through)
── step/start auto interval ── /checkpoint · checkpoint tool ── pre-rewind guard
│
▼ ProviderRegistry.resolve(auto) → git: stash create / commit-tree
│ copy: incremental dir + hardlinks
▼
checkpoints storage domain (SQLite rows / JSON file) + checkpoint/* event (adaptive gate)
/rewind <target> ── confirm (userQuestions / approval, fail-closed) ──▶ guard checkpoint
├─ workspace: provider.restore(ref) (restore | reset-hard)
├─ config: settings write-back (persisted on the profile patch)
└─ session: SessionStore.fork(source, boundary) → new child session (original untouched)Full decision record, event vocabulary, and the provider seam contract: ARCHITECTURE.md.
The plugin declares checkpoint/snapshot, checkpoint/bound, checkpoint/prune, and checkpoint/rewind as log-only SessionEventMap members. Harness rc.2 has no plugin event-registration surface and Session.append does not stamp the ignorable envelope (its third argument is surface intent, not options), so appending unknown types would make the session unreadable on reload. The plugin therefore appends through an adaptive gate: a runtime probe (on a detached, never-persisted session store) detects whether the host's append stamps the ignorable envelope — on rc.2 the gate stays closed; on hosts that support it, checkpoint/* events are appended with ignorable: true automatically. Until then the authoritative audit chain is command/run + command/done (harness-known) plus the durable checkpoints storage domain.
The plugin returns the new session id in the command result (session: ) and the Web shell can navigate there. The session-projection unit `checkpoints` is shipped: whenever ctx.sessionProjections exists, the plugin registers the unit via ctx.inject (folds checkpoint/snapshot|bound|prune|rewind into a whole-value list) — it stays an empty list on rc.2 hosts until a harness build ships the checkpoint/* vocabulary or the ignorable envelope, then fills in with zero plugin changes.
Does this replace git? No — it *uses* git where available. In a git repo you get byte-perfect, deduplicated snapshot objects without touching history; in any other directory the copy provider does the same with plain files. Regular commits remain your long-term history.
Why not `git reset --hard` by default? Because destroying state is not the job of a safety net. The plugin only creates unreferenced objects and performs worktree-only, path-explicit restores by default, so a bad rewind can never lose history, the index, or files created after the checkpoint. reset-hard is available behind workspaceRestore: 'reset-hard' for users who explicitly want CC parity.
How long is a checkpoint restorable? No ref is held on git-provider snapshots. They're unreferenced stash create/commit-tree objects by design, and discard deletes only the record, leaving the object itself for git gc. Two independent things bound how long a checkpoint actually stays restorable: the plugin's own quota pruning (maxSnapshots, default 50 kept per session; maxSnapshotBytes, a default 512 MiB global soft quota enforced via pruneAll() on capture and swept on turn ends), and the host repo's git gc. With git's defaults, unreferenced objects survive until an auto-gc runs, and even then only objects older than gc.pruneExpire (2 weeks by default) get pruned. A manual git gc --prune=now, an aggressive repack, filter-repo, or a fresh clone can drop them immediately. Pruned objects are now detected up front: the git provider probes the snapshot object before restore (git cat-file -e) and fails loudly when it is missing instead of silently restoring nothing, and a doctor pass walks every checkpoint recor