DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-session-copy

Session Copy

One copy button in the session header: deep link, whole conversation or just the messages you pick as Markdown, or the working directory. · 会话标题栏一键复制:深度链接、整段对话或勾选的消息 Markdown、工作目录。

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-session-copy@1.8.1
READMECompatibilityVersions

Compatibility and provenance

Session Copy is published as dsh-session-copy and currently resolves to version 1.8.1. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/5/2026

Versions

1.8.1stable
11/5/2026
1.8.0stable
11/1/2026
1.7.0stable
11/1/2026
Show 13 more versionsCollapse versions
1.6.1stable
11/1/2026
1.6.0stable
10/31/2026
1.5.0stable
10/31/2026
1.4.1stable
10/31/2026
1.4.0stable
10/31/2026
1.3.1stable
10/31/2026
1.3.0stable
10/31/2026
1.2.0stable
10/23/2026
1.1.4stable
10/23/2026
1.1.3stable
10/23/2026
1.1.2stable
10/23/2026
1.1.1stable
10/23/2026
1.1.0stable
10/23/2026

Related plugins

Loading related plugins…

Latest
1.8.1
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
143.4 kB
Files
13
Surface
web
License
MIT
Source
npm
GitHub
★ 1
Weekly downloads
1,892
Security scan
✓ v1.8.1 scan passed
Last push
11/5/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in productivity-workflow.

Client Ui Task Board@linxin666/dsh-client-ui-task-boardHost-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / pet / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Archive Manager@michengai/dsh-archive-manager归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。 · Archive, restore, favorite, and permanently delete sessions, and diagnose damaged session logs.Remotedsh-remoteRemote-work assistant for DeepSeek Harness: connect SSH (password/key/agent/keyboard-interactive, multi-hop ProxyJump), list hosts from ~/.ssh/config, pick a remote workspace, operate on it with 21 rw_* tools, conflict-aware mirror sync, an embedded PTY t

README

dsh-session-copy

English | 中文

One button in the session header, four actions behind it

One button in the DSH Web session header. Click it and pick what to copy — deep link, whole conversation as Markdown, only the messages you tick, or working directory. No more row of flat buttons competing with the toolbar.


Why this exists

The session header is a crowded strip of icon buttons, and copying a conversation out of DSH used to mean three of them. This plugin folds the three into one 28-pixel button whose menu carries the same actions, so the header gains nothing but a single icon.

The one that actually takes work is Markdown. A session log is not a chat transcript: it is a stream of tool calls, retries, pruned rows, injected context and — after a while — compaction checkpoints. This plugin reconstructs the conversation from that stream on the Host side and hands back clean Markdown.

What you get

Menu itemWhat you get
Copy deep link@[title](dsh-session:<base64url(session id)>) — the canonical DSH session mention. Paste it into any composer and the Host attaches that session's snapshot, so another conversation can read this one.
Copy MarkdownThe whole conversation as clean Markdown on the clipboard: one section per message, every assistant step kept, tool output and reasoning folded away, compaction points marked, code fences balanced.
Export Markdown fileThe same document saved as a .md file. Use this for anything long — a clipboard write is the part that fails first, and the file has no length cap.
Select messages…Opens a timeline picker; tick the messages you want and copy or export only those — the QQ/WeChat multi-select gesture.
Copy directoryThe session's cwd, read from the Session list projection with the Host snapshot as fallback.

Every action reports back in a small notice — including the character count, so you can tell a 400-character session from a 400,000-character one.

Why there is a file export

A clipboard write is the weakest link in "copy the whole conversation": browsers cap or refuse a single write of a few hundred kilobytes, and a silent truncation looks like the plugin lost your history. Measured on a real 4.3 MB session log:

CharactersComplete?
Clipboard copy (capped)212,330no — trimmed at the cap
File export778,435yes

So the clipboard action keeps its cap and says when it trims, while the export action asks the Host to lift it (8,000,000 characters, still finite so a corrupt log cannot exhaust memory) and hands you the file. The picker has the same pair of buttons: Copy and Export .md.

Picking only part of a conversation

A long session usually has one stretch worth sharing: the debugging thread, the decision, the answer. Select messages… opens a timeline of every message with its role, a one-line preview and its size, and copies only what you tick.

The message picker: a timeline rail, turns with sticky headers, per-message times, role chips and a live size meter

  • Timeline. The list is grouped by turn; each group has a sticky header with the turn number, its calendar date and time range, and its size, and a rail down the left marks every turn — click a marker to jump to it, and the active marker follows your scrolling. Every row shows the time its message was sent.
  • Oldest / Newest switches the whole timeline around, rail included, so you can start from the most recent exchange when the part you want is recent. The order never changes which message a tick refers to.
  • Whole turn on a header ticks (or clears) every message in that exchange, which is usually the unit you actually want.
  • Role chips — All / You / Assistant / Compaction — cut the list down to the side you want; only the roles actually present are offered.
  • Filter narrows hundreds of rows to the ones you are after. Both the filter and the chips scope Select all, so "every question I asked about the parser" is one chip plus one word.
  • Shift-click selects a whole range, the way a chat app does, and a range never escapes the current filter.
  • Keyboard: Space toggles the focused row, ↑/↓/Home/End move between rows, Ctrl/⌘+A ticks everything visible, Escape closes.
  • The meter reads 4 of 7 · 1,832 characters — both the count and the size of what you are about to paste.
  • The copied document opens with > Excerpt: 12 of 340 messages selected, so a pasted fragment is never mistaken for a truncated export.
  • The picker includes the complete history: compaction checkpoints appear as their own rows, so an intentional summary can be included or left out on purpose.
  • Selecting is local to the dialog — nothing is copied until you press Copy. Opening it again refreshes the list, so messages added while the picker was closed are not hidden by stale data.

Install

From npm

dsh plugin add dsh-session-copy

Inside the desktop app

The desktop app has its own plugin manager: open Settings → Plugins and install from there, rather than with the CLI (which targets a different profile while the app is running). Then restart DeepSeek Harness — the Loader assembles its plugin list at boot, so a reload of the page is not enough.

From this checkout

node scripts/install.mjs --check    # report profile health, change nothing
node scripts/install.mjs            # install or refresh in the current profile
node scripts/install.mjs --uninstall

From a release tarball

The catalog install path, for hosts that would rather not build from source:

dsh plugin --profile web add \
  https://github.com/2310770803/dsh-session-copy/releases/latest/download/dsh-session-copy.tgz

The asset name is deliberately version-free. A releases/latest/download/ URL resolves latest at request time but takes the filename literally, so a versioned filename would work until the next release and then quietly 404; the release workflow re-uploads dsh-session-copy.tgz on every tag to keep that URL stable.

How the Markdown is built

Three decisions here are the difference between a usable export and a broken one, and each of them replaced a bug:

Every assistant step is kept, not just the last one. A turn is not one reply — an agentic turn is twenty model steps interleaved with tool calls. Keeping only the final assistant/message of each turn discarded 41% of the assistant text on a real session (15,717 of 26,657 characters), and lost all 29 intermediate messages in one turn. All of them are emitted, in order.

Compaction is marked, not swallowed. When DSH compacts a conversation it writes a compact-checkpoint message and a compaction/summary event, and the pre-compaction turns stop being what the model sees. Dropping those as "injected context" makes a long session export with its history silently missing — which reads as "the copy is broken". They are rendered as an explicit Conversation compacted marker instead, so an intentional summary is never mistaken for lost content.

Fences are balanced across the document, not per message. A message that ends inside a fenced code block used to get a synthetic closing fence, which left the next message's fences mismatched; one 21 KB export came out with 34 stray fence markers. Fences are tracked over the assembled document so what you paste renders as written.

A selection is trusted only as indices. The picker sends back the positions it showed; the Host drops anything out of range, repeated or non-integer rather than letting it shift the result onto a different message, and reports how many were discarded. A transcript can then never silently paste someone else's turn.

Reading is also bounded and version-tolerant:

  • The complete history is read, not the model's current view. sessionQuery.readSession (the whole raw log) is the source; readSurface — what the model currently sees — is only the fallback. This matters because a compaction replaces everything before it: the surface has no pre-compaction turns at all. On one real session the surface held 247 messages across turns 14–22, while the log held 398 across turns 1–22 plus the four compaction markers.
  • The response is capped at 220,000 characters for a clipboard copy and trimmed on a section boundary, because one real session produced a 778 KB document — past what a single clipboard write reliably accepts. A file export lifts the cap instead (see Why there is a file export).
  • Clipboard writes try the Host writer, then the textarea + execCommand path (the one that survives long text and a blurred window), then the async Clipboard API, twice. DSH's own bundled writer returns false as soon as navigator.clipboard.writeText throws and never falls back, so delegating to it alone was a trap.

Inside DSH: the plugin market

The repository publishes a single-plugin plugin market index — the format DSH's Plugins → Discover tab and the plugin_market agent tool read:

  1. Turn on the market's Discover surface once, in Settings → Plugins: @deepseek-ai/dsh-experimental-plugin-market-bundle ships with DSH, switched off.
  2. Plugins → Discover → Index sources → add https://cdn.jsdelivr.net/gh/2310770803/dsh-session-copy@main/index.json
  3. Search for "session copy" and install.

The index pins an exact commit rather than a branch, so what Discover installs is reproducible. node scripts/build-index.mjs regenerates index.json from package.json and locale/; node scripts/check-index.mjs validates the result with the host's own parser. The index must name the commit before the one that carries it, which is why the pinned SHA is not the file's own commit.

node scripts/search-index.mjs answers the other question — whether a word typed into Discover actually surfaces the plugin. It runs the host's own search class over the index, so a pass there means Discover's list narrows to this plugin rather than merely that the JSON is well-formed:

node scripts/search-index.mjs --market <dir> --validator <dir>

Both <dir>s are @deepseek-ai/dsh-plugin-market and @deepseek-ai/dsh-plugin-market-index as shipped inside an installed DSH app — extract them from resources/app.asar under dsh/node_modules/@deepseek-ai/.

The plugin is also listed in the awesome-dsh-plugin catalog, whose entry is one YAML file in that repository, data/plugins/2310770803__dsh-session-copy.yml.

Supply chain

Releases are built by GitHub Actions and published with npm's trusted publishing: the workflow authenticates with a short-lived OIDC token, and no long-lived npm token exists in this repository. Every release carries a SLSA provenance statement, so the tarball on npm can be traced back to the commit and workflow that built it. Publishing is idempotent — re-running a release for an already-published version is a no-op, not an error.

Compatibility

HostDSH 0.2.1-rc.2 and newer (@deepseek-ai/dsh-* peers are pinned to the prerelease branches)
SurfaceDSH Web and the desktop app's Web view
Permissionsnone — the Host route is read-only and same-origin fenced

Everything is feature-detected against the shared client module table. If a future DSH release drops the Menu primitive, the menu still renders in a self-contained popover; if it renames a service, the affected piece degrades rather than raising inside the boot activation audit.

Display metadata

The Settings → Plugins card reads this package's metadata without evaluating lib/client.js:

  • locale/en.json and locale/zh.json — meta.title / meta.description;
  • package.json name / description as the fallback;
  • package.json icon (./icon.svg) for the card artwork.

Layout

PathRole
src/plugin.jsHost half: registers the read-only snapshot route on webServer.
src/lib/route.jsThe /api/session-copy.snapshot handler, its trust fence and body limits.
src/lib/markdown.jsSession events → Markdown rendering.
lib/client.jsBrowser half, shipped prebuilt in the loader's closure-factory format.
cordis.patch.ymlInserts the session-copy row into the Web profile.
locale/, icon.svgPlugin-list title, description and artwork.

License

MIT