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.

Sessionrelay — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
S

@crx1146/dsh-sessionrelay

Sessionrelay

SessionRelay project memory → DSH automatic briefing and memory tool (local-first · offline self-contained · two-stage secure binding)

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

npx -y @deepseek-ai/dsh plugin --profile web add github:rui08984-dot/dsh-sessionrelay#fc612884cff11e20f9ac21d35dde4cf2dfe63941
READMECompatibilityVersions

Compatibility and provenance

Sessionrelay is published as @crx1146/dsh-sessionrelay and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
10/13/2026

Versions

0.1.0stable
10/13/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/14/2026
View source ↗
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 memory-context.

Hindsight Coding Agents@vectorize-io/hindsight-coding-agentsReflect-only Hindsight long-term memory for coding agents (harness-pluggable: opencode, …), with automatic background ingestion (no setup CLI).Ab Memorydsh-ab-memory--- description: "The dsh-ab-memory package: a cross-session, file-backed agent memory with five tools (remember / recall / forget / load_skill / distill) and an always-on light injection." kind: "package-reference" ---Memsearch Dsh@zilliz/memsearch-dshMemSearch plugin for DeepSeek Harness: shared markdown memory across agents, with capture, pre-step context injection, memory-recall skill, and a skill-candidate review panel.Archive Manager@michengai/dsh-archive-manager归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。 · Archive, restore, favorite, and permanently delete sessions, and diagnose damaged session logs.

README

SessionRelay × DeepSeek Harness (DSH) integration

A native DSH plugin that brings SessionRelay project memory into DSH's system prompt — the equivalent of the SessionStart hook that CLI-shaped clients (ZCode, Claude Code) get for free.

中文 · SessionRelay upstream

Why this exists

SessionRelay is an MCP server, so it can be queried by any MCP client. But an MCP server cannot inject anything into a conversation: the initialize response carries no instructions, no resources, and no prompts (verified against srelay serve directly). Anything that appears in the model's context without the model asking for it must be placed there by the client.

CLI-shaped clients get this almost for free: their process working directory is the project root, so a SessionStart hook can resolve the project and shell out to srelay decisions / srelay unresolved. DSH is a desktop GUI:

signalDSH desktop result
process.cwd()the installation directory, not the project
ctx.cmdlineArgsempty array (no argv for a GUI launch)
AssembleContext{ scope?, signal? } only — no cwd, no project

All three are dead ends, so this plugin resolves the project a different way (see below) and registers a systemPrompt.section() provider — DSH's official injection point — that renders the brief before each model step.

What it does

  1. Brief injection. A systemPrompt section, evaluated on every assembly (i.e. before each model step), showing the project's recent decisions and unresolved questions. Bounded to 1200 chars, with an mtime-keyed cache so a repeat evaluation costs ~1 ms instead of ~310 ms.
  2. Project resolution. A four-step fallback chain that needs no configuration in the common case.
  3. Six native tools. srelay_search / srelay_show / srelay_record for querying, plus srelay_bind_project / srelay_confirm_bind_project / srelay_cancel_bind_project for the two-stage binding.

Project resolution

① env SRELAY_PROJECT_ROOT   → if it points at a directory containing .sessionrelay
② DSH session inference     → most recent session group under ~/.dsh/sessions
③ registry single survivor  → exactly one project registered and alive
④ dangling                  → do not guess; list candidates for the user

Step ② is the interesting one. DSH groups its own session storage by working directory slug:

~/.dsh/sessions/
  --E-music~0020player--      ← E:\music player
  --D-agent1super--           ← D:\agent1super

That slug is DSH's own record of which directory a session belongs to, so it is the most reliable "which project am I in" signal available to a plugin. The encoding (mirrored from src/adapters/dsh/format.ts) is:

inputslug
:(dropped)
\ /-
space~0020
non-ASCII~ + 4 uppercase hex

Because - is ambiguous (a real directory may contain a hyphen), decoding is not a pure string operation. The plugin walks the segments depth-first and prunes on real filesystem existence — only prefixes that actually exist are explored. This recovers paths like D:\agent1super\tmp\docx-build correctly.

Step ④ deliberately refuses to guess. Injecting the wrong project's brief is worse than injecting nothing: it would show project A's decisions inside a project B conversation, and the model has no way to tell they are unrelated.

Two-stage binding

srelay_bind_project decides which database decisions get written to, so it is not a decision the model may make on its own. If a model in a project B session mis-resolved and bound itself to project A, every decision it then recorded would be written into A's SQLite — irreversibly.

This mirrors SessionRelay's own rule that AI never gets delete tools; the same constraint extends to "which store do writes go to":

  • srelay_bind_project({ projectPath }) — proposes only. Records a pending proposal and returns text explicitly asking the user to confirm.
  • srelay_confirm_bind_project() — applies, and only after the user has said so.
  • srelay_cancel_bind_project() — drops a pending proposal.

Proposals are tracked per scope, so multiple concurrent conversations do not share binding state. A target path is only accepted if it already contains a .sessionrelay database — otherwise binding a fresh directory would report success and then fail silently on every subsequent call.

Self-contained runtime (vendor/)

The plugin ships its own SessionRelay runtime under vendor/ and prefers it over any globally installed copy:

① SRELAY_CLI_PATH env   → development escape hatch (point at a working copy)
② vendor/ (bundled)     → default; works with no npm install and no network
③ global npm location   → fallback only

vendor/ is a build artifact, not tracked in git — it is ~67 MB and carries better-sqlite3 native bindings for every platform, which would bloat the repository (the whole repo is ~13 MB). Generate it with:

node vendor-srelay.mjs                 # fetch from npm
node vendor-srelay.mjs --from <path>   # copy from an existing install (offline)

Install

The plugin is a DSH bundle: a package whose manifest declares dsh.bundle.patch, listed in the profile's dsh.profile.bundles.

// ~/.dsh/profiles/<profile>/package.json
{
  "dependencies": { "dsh-srelay-brief": "file:/path/to/integrations/dsh" },
  "dsh": { "profile": { "bundles": ["…", "dsh-srelay-brief"] } }
}

Then pnpm install in the profile directory. The plugin needs @deepseek-ai/dsh-tools as a peer; DSH resolves it from its own installation.

Development notes

Four things bit us during development and are worth knowing before editing:

  1. apply must be synchronous. Cordis calls apply and expects a fiber; an async apply returns a Promise, and DSH reports failed to import and silently skips the plugin. Resolve optional peers with createRequire(import.meta.url) rather than await import(...).
  2. The section text provider must return a string, not a Promise. renderPrompt calls text.indexOf('{{') directly; a Promise throws text.indexOf is not a function. Use execFileSync, never an async wrapper.
  3. SRELAY_PROJECT_ROOT only affects serve. Every CLI subcommand (search, show, list, decisions) resolves the project from cwd alone. When shelling out, pass cwd: root; setting the env var does nothing.
  4. The two-stage bind needs all three tools. Proposing without a confirm tool means the user can say "yes" and nothing can act on it.
  5. Resolve paths with fileURLToPath, never new URL(...).pathname. .pathname percent-encodes non-ASCII characters, so a plugin installed under a directory like D:\dsh插件 记忆\ resolves to D:/dsh%E6%8F%92%E4%BB%B6%20%20%E8%AE%B0%E5%BF%86/... and every existsSync fails. The vendored runtime is then silently skipped and the plugin falls back to a global install — a 67 MB payload carried for nothing. When you test this, test under a non-ASCII path: an ASCII-only path hides the bug completely (that is exactly how it survived one round of "verified offline" testing). Also build the path in one step; dirname(fileURLToPath(url)) followed by join(..., 'dist') yields vendor/dist/dist/....

Self-test

node selftest.mjs

Covers slug decoding against real DSH directory names, the resolution chain, the section registration contract (deliberately not awaiting the provider), tool registration via a stub collector, and the full two-stage binding flow. It does not require DSH to be running.