DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Session Backup — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-session-backup

Session Backup

在删除每个会话前进行备份,在网页图形界面中批量选择会话,并一键恢复备份

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-session-backup@0.1.0
README兼容性版本

兼容性与来源证明

Session Backup 以 dsh-session-backup 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/10/18

版本

0.1.0stable
2026/10/18

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
67.9 kB
文件数
7
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
0
最近提交
2026/10/18
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 memory-context 分类下经过校验的插件。

Memory Plugin@openviking/dsh-memory-plugin适用于 DeepSeek Harness 的 OpenViking 记忆与上下文套件Contextdsh-context用于上下文洞察和管理的 DeepSeek Harness 插件,提供上下文仪表板和上下文命令,帮助了解上下文的构成及其演变过程。Ab Memorydsh-ab-memory--- description: "dsh-ab-memory 包:一种跨会话、基于文件的智能体记忆,提供五个工具(remember / recall / forget / load_skill / distill)以及始终启用的轻量注入。" kind: "package-reference" ---Weknora@wxg-prc-cpg/dsh-weknora适用于 DeepSeek Harness (dsh) 的 WeKnora 知识检索工具:通过自有知识库进行语义搜索、文档阅读以及 RAG/代理回答。

README

dsh-session-backup

Backs up every session before the DeepSeek Harness Web GUI deletes it, adds multi-select for batch delete/backup to the session list, and restores a backup in one click — all as a user plugin, without touching any installed harness file.

What you get

featurewhere you see it
automatic backup on deletenowhere — confirming 彻底删除… (Delete session…) silently writes a backup first
multi-select + batch backup/delete多选 (Select) in the sidebar footer, a checkbox on each row, and a 选择/加入选择 row in each session's "…" menu
backup manager with one-click restore备份 (Backups) in the sidebar footer

Batch delete reuses the same automatic backup, so a batch never removes a session that was not copied first. If a backup fails, the delete is refused and the error is shown — the only copy of a session never disappears because a backup could not be written.

Blank placeholder rows (the provisional 新建会话 / New session row) and archived rows carry no checkbox: the harness renders neither a status slot nor its own actions for them, so they cannot be selected. They hold no conversation to preserve, and the next 新建会话 adopts the blank one.

Where backups live

$DSH_HOME/backups/sessions/<sessionId>/<timestamp>-<title>/
├── session.v4.jsonl.zstd        # the session's own directory, copied verbatim
├── …
└── backup.json                  # manifest: sessionId, title, createdAt, sourcePath, size

The directory name is the local timestamp (20261017-184533) followed by the session's current title, sanitized for the filesystem (/ \ : * ? " < > | and control characters become spaces, capped at 48 characters, untitled when nothing usable remains). Two backups inside the same second get -1, -2 … suffixes. session.lock and .DS_Store never enter a backup; the manifest's backup.json never leaves one on restore.

Attachments are content-addressed and survive session deletion, so the session directory alone is a complete, restorable copy.

How the delete hook works

dsh-client-ui-workspace reads ctx.remote.session — a compound Cordis service name — and calls deleteSession on it. That read walks the framework's internal/get waterfall, which is where this plugin wraps the service: the normal resolution runs first (whatever resolved it, including dsh-remote-session-inject-fix's fallback), and this plugin wraps whatever comes back so deleteSession copies the session to the backup store before handing the request to the host.

The listener is registered with prepend so it stays outermost regardless of plugin order — the tests cover both orders.

Semantics of a failed backup:

failureresult
host route answers a real error (disk full, conflict, …)delete refused, failed RemoteResult returned, error dialog shown
session has no directory left to back updelete proceeds (nothing to copy), console note
this profile has no Host face mounted (404/405 without our error code)delete proceeds, console note — the plugin can never become a delete-blocker

HTTP routes

All four are registered on the Host connection below /api, address document-relative by the browser (.slice(1)), and answer JSON:

methodpathbodyanswers
GET/api/session.backup.list—{ backups: [...] } newest first
POST/api/session.backup.create{ sessionId }{ backup } with path, title, dirName, bytes, consistent
POST/api/session.backup.restore{ path }{ restored } with attached, workspaceId / reason; 409 if the session exists again
POST/api/session.backup.remove{ path }{ removed }; prunes an empty session group

sessionId must match a plain id pattern and every client-supplied path is checked to be strictly inside its root, so no request can reach outside the store. The title comes from the sessionQuery service (readTitle), falling back to untitled when it cannot be read. Before copying a live session the host flushes its in-memory log through the sessions service — the same barrier dsh-session-log-export uses — and each file's size is re-verified after the copy, so a log still being appended is re-copied and a copy that never settles is reported in the manifest (consistent: false) instead of silently shipping a torn file.

readTitle answers with either a bare string or the title provider's snapshot record ({ title, source, eventSeq, … }), depending on which query service the profile has; both are unwrapped, so backups are named after the title the Sidebar shows rather than a generic untitled.

Restore also puts the session back in the Sidebar

Copying the directory back is only half of a restore. Deleting a session does two things — it removes the directory and drops the id from its Workspace record — and the Sidebar lists Workspace membership, not the raw directory tree, so a restore that only copies files leaves an invisible session behind (verified: it stays hidden even after a full dsh web restart).

So restore finishes by re-attaching the id through the harness's own API, workspace.attachSession(sessionId). That call re-reads the restored session's header from persistence and refuses unless its cwd resolves to that Workspace's path, so the restore cannot attach a session to the wrong project. The response reports the outcome:

restored.attachedmeaning
truere-attached; workspaceId names the Workspace, and the session is listed again (reload the page if the list was already open)
falsefiles are restored but the session stays unlisted; reason says why — no Workspace matches the log's cwd, the header is unreadable, or this profile has no workspaceRegistry

A failed attachment never fails the request: the bytes are already back, and the copy would only be refused as a conflict on a retry.

Two faces: index.js and client.js

The Harness loads this package twice, from two different module systems:

facefileconsumed by
host (Node)index.jsdsh importing exports["."]
browserclient.jsthe web host, via exports["./client"]

The web host concatenates every dsh.client.platform: "web" package's client file into a classic script batch served from /plugins/..., so client.js must register itself with window.__ModuleLoader__.load({ id, factory }). Handing it raw ESM makes the whole batch fail with SyntaxError: Unexpected token 'export' and the boot screen reports import failed (see console for the import error).

client.js is generated from src/client.mjs — never edit it directly:

node scripts/build-client.mjs   # regenerate client.js after editing src/client.mjs
node --test "tests/**/*.test.mjs"

The build rewrites each ESM import into a require() of the same specifier (react and @deepseek-ai/dsh-client-ui-primitives are seed words), strips export while recording the exported names, and fails loudly on Node built-ins, export default, or any form it cannot carry. The test suite fails if client.js is stale.

Install

From npm:

dsh plugin --profile <your-profile> add dsh-session-backup

From GitHub (pin a tag or commit for a reproducible install):

dsh plugin --profile <your-profile> add github:overspread/dsh-session-backup

From a local checkout:

dsh plugin --profile <your-profile> add /path/to/session-backup
dsh --profile <your-profile> --dump-config   # expect a "# == dsh-session-backup" layer

Then restart the dsh web server — the host caches each package's resolved client-bundle path in memory, so an added, removed, or re-pointed exports["./client"] only takes effect on a fresh boot.

Tests

npm test
filecovers
tests/backup-store.test.mjsnaming/sanitizing, inbound guards, locate/create/list/restore/remove against temp dirs, both readTitle answer shapes, and the restore → re-attach matrix (match, symlinked path, missing registry, unreadable header, unknown cwd, failing attach)
tests/routes.test.mjsthe four HTTP handlers, status codes, and unregistration on dispose
tests/client-bundle.test.mjsbuild freshness, the classic-script wrap, and the forms the build rejects
tests/delete-interceptor.test.mjsthe interceptor against a real Cordis context: backup ordering, refusal on failure, non-blocking when the Host face is absent, pass-through of other properties, and both registration orders alongside dsh-remote-session-inject-fix

Every path above was also driven against a live dsh web instance with headless Chrome: boot with the plugin loaded, select → batch backup (directory named <timestamp>-<title> with the real title), the harness's own delete dialog writing its automatic backup, one-click restore re-listing the session, batch delete backing up before removing, and deleting backups from the manager.

Survives harness upgrades

The plugin lives in your profile (~/.dsh/profiles/<name>), not inside the installed harness, so upgrading dsh does not remove it. Uninstall with dsh plugin --profile <name> remove dsh-session-backup.

Distribution

Releasing a new version:

node scripts/build-client.mjs && npm test
npm version patch
npm publish                # needs an npm login; the tarball ships client.js as built
git push --follow-tags

The package has no runtime dependencies; run the build before packing so the tarball ships a client.js matching the current src/client.mjs (the tests check this). The files list in package.json keeps node_modules, the tests, and src/ out of the tarball.

License

MIT © overspread.

This is a personal, community plugin. It is not developed, endorsed, or supported by DeepSeek, and it is not part of the DeepSeek Harness distribution. It only reads and writes inside your own $DSH_HOME; review the source before installing, as with any third-party plugin that runs on your machine.