DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-session-requirement

s

dsh-session-requirement

Manifest valid

Per-conversation requirement / constraint box for DeepSeek Harness - title-row field, @-skill picker, injected into every message of that conversation.

UI (client)hasBundlePatch

dsh-session-requirement

Per-conversation session requirement / constraint box for DeepSeek Harness. It lives in the conversation title row and lets you write one standing requirement for this conversation, plus pick skills with @, and have all of it attached to every message you send.

The box is off until you switch it on. The switch lives in Settings → General → 本对话的整体要求; flip it and the box appears in the title row immediately — no reload, no restart. Flip it back and the box is gone, and nothing is attached to your messages either.

Collapsed, it is one line at the right end of the title row:

… 标准模式                              ┌────────────────────────────────────────┐
                                        │ 输入本对话的限制、约束或整体要求(可选)(●)│
                                        └────────────────────────────────────────┘

Focused, it lifts out of the row as a floating card — the header never grows:

                                        ┌──────────────────────────────────────┐
                                        │ @office-docx ×  @office-xlsx ×       │
                                        │ 只输出中文,表格必须带单位              │
                                        │ …                                    │
                                        │  ┌────────────────────────────────┐  │
                                        │  │ @office-docx   Word documents  │  │
                                        │  │ @office-xlsx   Excel workbooks │  │
                                        │  └────────────────────────────────┘  │
                                        └──────────────────────────────────────┘

Behaviour

| Rule | Detail | | --- | --- || GUI switch | one toggle in Settings → General, stored globally in the state file; off on a fresh install | | Show/hide | off renders nothing at all — no empty gap and no slot in the title row; on mounts the field in every conversation at once | | Placement | conversation.session.header.utilities, order: 0 — the right-aligned utility area of the Session title row (the 创建/标准模式 line), left of the corner controls | | Size | a fixed 380px × 28px slot, so the title row never reflows. On focus the field lifts out of flow as a 470px floating card (position: absolute) over the tab row, because the header must not grow | | Blank conversations | the shipped header hides its whole title-row chrome while a conversation is still blank, so the same field also registers in conversation.input.dock (order: -100) and shows there until the title row appears. A module-level seat registry keeps exactly one copy on screen; the dock copy is the full-width, in-flow variant | | Collapsed | one line; expands to four lines on focus; collapses on blur without losing text | | Scope | text, chips, and the per-conversation switch are stored per conversation; a new conversation starts empty and off | | Effective | requirementText.trim().length > 0 \|\| skillIds.length > 0 | | Switch | grey while there is no content and clicking it focuses the input; turns on by itself on the first effective content; turning it off keeps text and skills but stops attaching them; clearing everything greys it again | | Attach | only when the GUI switch is on, the per-conversation switch is on, and the content is effective | | @ picker | opens on @ at line start or after whitespace; filters by name, description and whenToUse; ↑/↓ move, Enter picks, Esc closes, click picks; empty result and load failure show an inline message instead of breaking the input | | Chips | a picked skill becomes a non-editable @name × chip; × removes it; Backspace in an empty input removes the last one; duplicates are ignored; the cap is maxSkills (default 10) | | Skills source | the live harness skill registry through ctx.remote.skills.list — nothing is hardcoded. Subagent sessions have no catalog and say so instead of showing a fake list | | Skills execution | none. This plugin only selects, stores and forwards skills; the model receives the skill body as context and decides what to do |

How attachment works

conversation.send() on the client is a pure pass-through — there is no outgoing-prompt transform to hook. The durable, model-visible seam is the host's agent/pre-step; when the claimed message batch contains a real user message (a fresh send, not a tool-loop follow-up) this row appends one extra user/message:

<session_requirement>
The user set a standing requirement for this whole conversation. Apply it to every reply until the user changes it.
<requirement>…</requirement>
<selected_skills>office-docx, office-xlsx</selected_skills>
</session_requirement>

<skill_content name="office-docx">…</skill_content>

It is committed through the harness's own surfaceOp: "append" path with source.kind = "session-requirement", so it lands in the transcript like the built-in /skill invocation injection — it never impersonates a user gesture.

HTTP surface

RoutePurpose
GET /api/session-requirement?sessionId=…read one conversation's state (also reports visible)
GET /api/session-requirement?mode=settingsread the GUI switch alone, with no conversation
POST /api/session-requirementwrite one conversation's state: { sessionId, requirementText, requirementEnabled, skillIds }
POST /api/session-requirement { visible }flip the GUI switch alone

State lives in <DSH_HOME>/session-requirement.json, written atomically (.tmp + rename):

{
  "version": 1,
  "settings": { "visible": false },
  "sessions": {
    "session-…": { "conversationId": "session-…", "requirementText": "", "requirementEnabled": false, "skillIds": [], "updatedAt": 0 }
  }
}

Requests are rejected with 400 rather than silently corrected when sessionId is malformed, the text exceeds maxTextLength, or skillIds is not a deduplicated list of at most maxSkills skill names.

Command

/requirement prints the current conversation's state; /requirement clear clears and disables it.

Requirements

  • DeepSeek Harness 0.2.x (desktop or web), Cordis v4.
  • No npm dependencies. The host half imports only Node built-ins; the browser half is a hand-written CJS bundle that takes react from the harness loader.

Install

git clone https://github.com/sunlei1214/dsh-session-requirement.git

Point your profile at the checkout:

// <DSH_HOME>/profiles/<profile>/package.json
"dependencies": { "dsh-session-requirement": "link:C:/path/to/dsh-session-requirement" },
"dsh": { "profile": { "bundles": [ …, "dsh-session-requirement" ] } }

Then reinstall the profile and restart DeepSeek Harness — the browser half ships as a static client bundle, so a page refresh alone is not enough.

Use link:, not file:. pnpm copies a file: directory dependency and caches it, so later edits never reach the profile. link: creates a junction (Windows) or symlink, so the profile always reads the current source.

Uninstall

Remove the dependency and the bundle entry, reinstall, restart. The host row drops its route, its agent/pre-step listener, and flushes pending state on dispose; the browser half removes its <style data-plugin="dsh-session-requirement"> node, its document listeners, its debounce timers, its caches, and aborts in-flight requests. Deleting <DSH_HOME>/session-requirement.json is optional.

Configuration

OptionDefaultMeaning
maxSkills10maximum chips per conversation
maxTextLength8000maximum requirement length

Tests

node test/host-check.mjs
node test/client-check.mjs

(npm test runs both; if the PowerShell execution policy blocks npm.ps1, run the two files directly.)

Two offline harnesses run against the real source files, with no harness install required:

  • test/host-check.mjs — a fake context, web server and skill registry. Covers both routes, the GUI switch (default off, flip, persist, and that a hidden row never attaches), every validation refusal, the atomic JSON sidecar, the pre-step injection (fresh send vs. tool-loop follow-up, disabled, empty, text-only, unknown and non-user-invocable skills, aborted signal), the /requirement command, and route removal on dispose.
  • test/client-check.mjs — a minimal React hook runtime plus a fake DOM, driving the actual components: the GUI switch gating the row (absent while off, appearing live when flipped), collapsed/expanded rows, the grey toggle focusing instead of enabling, auto-enable on first content, manual off/on, chips, the @ picker (filtering, arrows, Enter, Esc, click, empty state, load failure), dedupe, the cap, Backspace, per-conversation isolation, a late read not clobbering typed text, and a teardown that must leave no style node, listener, or pending write.

test/verify-live.mjs checks a running app after installing and restarting:

node test/verify-live.mjs           # read-only
node test/verify-live.mjs --write   # round-trip a write, then restore

It reports the state route, the GUI switch route, the boot manifest entry, and the validation refusals. A 401 means the host half did not load — restart the app.

License

MIT © 2026 sunlei1214

Not affiliated with DeepSeek. "DeepSeek Harness" and "DSH" refer to the host application this plugin extends.

Comments

Loading…

Similar plugins

dsh-session-prompt

by a404670637-ch

Per-conversation pinned prompt for DeepSeek Harness (DSH) Web: sent as a system-prompt section, never folded by context compression.

Terminal & ClientsManifest valid

★ 0

MIT

JavaScript

Oct 23, 2026

dsh plugin --profile web add dsh-session-prompt

by drscrewdriver

给 DeepSeek Harness 侧边栏加一个会话内容检索——标题/内容一键切换,还能按用户/回复/工具筛选

Terminal & ClientsSessions & MessagesManifest valid

★ 7

↓ 19/wk

MIT

TypeScript

Oct 27, 2026

dsh plugin --profile web add dsh-session-search-toggle

by duanyunlun

Per-provider request headers in the DeepSeek Harness Models settings page, with per-conversation ${sessionId} expansion.

Development & InfrastructureTerminal & ClientsManifest valid

★ 0

MIT

JavaScript

Sep 11, 2026

dsh plugin --profile web add dsh-provider-headers

by drscrewdriver

给 DeepSeek Harness 侧边栏加一个会话内容检索——标题/内容一键切换,还能按用户/回复/工具筛选

Sessions & MessagesManifest valid

★ 3

↓ 294/wk

MIT

TypeScript

Sep 13, 2026

dsh plugin --profile web add dsh-session-search-toggle

by leoan698-tom

Session-to-session messaging with linked replies, native context references, and conversation trees in DeepSeek Harness.

Sessions & MessagesManifest valid

★ 4

MIT

TypeScript

Nov 9, 2026

dsh plugin --profile web add dsh-plugin-sessivra

by XBXyftx

Cross-session messaging plugin for DeepSeek Harness: let user-launched sessions in one workspace message each other and coordinate tasks, write scopes, and conflicts.

Manifest valid

★ 0

MIT

TypeScript

Oct 18, 2026

dsh plugin --profile web add dsh-session-messaging