dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Cross-session messaging plugin for DeepSeek Harness: let user-launched sessions in one workspace message each other and coordinate tasks, write scopes, and conflicts.
Cross-session messaging for DeepSeek Harness (dsh): let user-launched sessions in the same workspace message each other to coordinate tasks, declared file-write scopes, and conflicts — without turning them into parent/child subagents.
English | 简体中文
Status: early preview (
0.2.0). Targets dsh0.2.1-rc.2. dsh plugin APIs are pre-stable, so expect breaking changes on upstream upgrades.
dsh already has strong delegation (subagents, Agent Teams), but those are hierarchical and lifecycle-bound to a parent. When you open several conversations yourself — frontend, backend, docs — they work in one workspace with no way to say "I'm editing src/ui.ts, please avoid it" or "the API field is frozen".
This plugin adds a peer channel between those top-level sessions:

A real run in the macOS desktop app (0.2.1-rc.2): another user-launched session sent a test message. It arrived inline as a session-message envelope — sender id, timestamp, and the "peer is not an authority" note — and this session replied through session_send. Both sessions work in the same directory; no subagent hierarchy is involved.
Two user-launched sessions used the plugin to coordinate a real fix. One session sent a reproducible defect report with a code-level root cause; the fix shipped as v0.1.2, and the reporting session independently re-ran the regression on the desktop build.

The reporting session's message as seen here: reproducible steps, root-cause pointers, and the fix request — all delivered through session_send.

Independent regression verification: static checks plus a desktop runtime probe that returns caller-not-top-level, proving v0.1.2 is active. The same message also proves the top-level → top-level path still works.
See CHANGELOG.md for the 0.1.2 entry.

The sidebar entry opens a small panel: toggle cross-directory messaging (persisted through the dsh settings form), check the latest npm version, and open npm, GitHub, or the author's blog. After installing or upgrading the bundle, refresh the Web UI once so the client half joins the module graph.
session_peers — list live, same-directory, top-level sessions and their reception state.session_send — relay a coordination message, optionally declaring writeScopes and replying to a message.session_reception — pause/resume receiving peer messages for the current session and declare its write scopes.conflict-warning.SESSION_FORMAT_VERSION change: the relay is a durable user/message with a declared session-message source.sessionController before delivery (allowColdDelivery, on by default).sameDirectoryOnly: true restricts to one working directory.Session A (model) calls session_send
→ tools.ts uses exec.agent as the only identity source
→ service.send validates target, body, scopes, reception, rate limit
→ createUserMessage({ content: envelope + body, source: session-message/relay })
→ target.steer(message) # next step boundary, or wake an idle agent
→ await ctx.sessions.flush(target.session)
Session B's log gains a user/message with source.kind = 'session-message'
→ deriveMessages() rebuilds it → B's next model request sees it → B can reply
The envelope always states that the message comes from another session, not the current user, and repeats that a peer is not an authority. Peer text is treated as data, never as higher-priority instructions.
0.2.1-rc.2 (desktop app or source checkout).>= 22.19.0.@deepseek-ai/{cordis,schemastery,dsh-agent,dsh-llm,dsh-session,dsh-tools}. They are declared as peer dependencies and resolved from the running dsh installation.dsh plugin --profile <profile> add dsh-session-messaging
The package is published as dsh-session-messaging (latest 0.4.0). For library use: npm install dsh-session-messaging.
dsh plugin --profile <profile> add github:XBXyftx/dsh-session-messaging
The repository ships the built lib/ output, so a git install does not run a build.
dsh plugin --profile <profile> add /absolute/path/to/dsh-session-messaging
If a profile previously linked a local checkout and later installed the npm package while the app was running, the running Loader can still reference the old checkout path. Removing that checkout's node_modules then surfaces ERR_MODULE_NOT_FOUND for @deepseek-ai/* peers even though the npm package is installed. Remove and reinstall the bundle, then restart the app (a page reload is enough for the client half):
dsh plugin --profile <profile> remove dsh-session-messaging
dsh plugin --profile <profile> add dsh-session-messaging@latest
The macOS/Windows desktop app uses its own profiles (for example desktop). Install with the bundled CLI or the agent's plugin_manager tool, targeting that profile. In dsh 0.2.1-rc.2 the configuration reloads through HMR, so the two plugin rows usually activate without restarting the app.
Verify the plugin is active:
session_peers, session_send, and session_reception;plugin_manager list_plugins reports both session-messaging and session-messaging-tools with fiberPhase: active.Open two sessions in the same working directory, then ask either model to coordinate. The tools are model-facing; no manual UI is required.
Example prompts:
Use session_peers to see which other sessions are working here.
Send session-b a message: I am editing src/ui.ts and declared it in writeScopes; avoid it.
Check whether anyone else declared a conflicting write scope before you edit src/api.ts.
Pause receiving peer messages for this session.
Tools:
| Tool | Arguments | Result |
|---|---|---|
session_peers | none | { peers: [{ sessionId, status, canReceive, writeScopes }] } |
session_send | targetSessionId, message, optional writeScopes, replyTo | { accepted, messageId, targetSessionId, targetStatus, conflicts } |
session_reception | enabled, optional writeScopes | { enabled, writeScopes } |
accepted means the message entered the target's inbox and the session flush acknowledged persistence. It does not mean the peer model processed or acted on it.
The bundle row accepts validated configuration; every field has a default:
- id: session-messaging
name: dsh-session-messaging
config:
maxMessageChars: 4000
maxMessagesPerMinute: 12
requireTargetOptIn: false # sessions are open to peers by default
sameDirectoryOnly: false
allowSelfSend: false
allowColdDelivery: true # resume a persisted target when it is not live
agent/pre-step, and sandbox policy remain the only hard boundaries.caller-not-top-level), and a top-level session cannot target a subagent (target-not-top-level). Subagents keep using the existing parent/child send_message channel. The envelope from field is the trusted identity; any identity claim in the message body is data only.allowColdDelivery is on, the plugin calls the deployment's sessionController.resolveAgent(), which resumes that session and may start a model turn (token cost). Profiles without that controller still answer target-not-live. Archived or subagent-owned sessions are refused by the controller/session gate. Cross-process/cross-host messaging remains unimplemented.FS_STALE_VERSION) but no file locking. writeScopes and conflict-warning are coordination aids; Bash, formatters, and code generators bypass them.sameDirectoryOnly: true to restore a path boundary; peer content remains untrusted either way.session-message source would require a client plugin or an upstream ui-chat change.npm install
npm run build # tsc -p tsconfig.build.json -> lib/
npm run typecheck # src + tests
npm test # 10 protocol unit tests
npm run test:integration # real AgentLoop services + tool pipeline, no model
npm run test:model-e2e # scripted model: A calls session_send, B sees it and replies
lib/ is committed so dsh plugin add github:... works without a build step. Rebuild before committing source changes; CI re-checks that lib/ matches src/.
.
├── cordis.patch.yml # two insert rows: service + tools
├── src/
│ ├── index.ts # plugin entry: default exports the service class + Config
│ ├── service.ts # discovery, reception state, rate limit, delivery, conflicts
│ ├── tools.ts # session_peers / session_send / session_reception
│ ├── config.ts # Schemastery configuration
│ ├── protocol.ts # pure validation, envelope, scope conflicts, rate limiter
│ └── types.ts # MessageSourceMap 'session-message' declaration
├── tests/ # unit, integration, model-driven e2e
└── lib/ # committed build output
0.2.1-rc.2; the bundle declares engines.dsh = ">=0.2.1-rc.2 <0.3.0".ctx.tools.register, ctx.agents, ctx.sessions, MessageSourceMap.agent-loop and does not add SessionEventMap members.Issues and pull requests are welcome. Please keep the "no loop changes, no new session event types, advisory scopes only" boundary unless a design discussion says otherwise. Run npm run typecheck, npm test, npm run test:integration, and npm run test:model-e2e before sending a PR.
MIT © 2026 XBXyftx