dsh-session-bridge
Manifest valid★ 6DSH plugin that enables the current agent to directly drive other real DSH sessions from prompts—create, send, wait for replies, read, resume, and cross-workspace search sessions, with support for monitoring scheduling primary tasks and archiving sessions.
dsh-session-bridge — 会话桥 (Session bridge)
Targets DSH 0.1.7-alpha.1. See compatibility changes.
A DSH plugin that lets the current agent drive other real DSH sessions directly from a prompt — create sessions, send messages to any session, wait for and read replies, resume offline sessions, and find sessions across workspaces. On top of that it can monitor and schedule a main task (watch its progress, nudge or correct its direction, and stop it), and archive sessions the same way the DSH sidebar's Archive action does.
中文文档见 README.zh.md.
What it does
- Create real DSH sessions.
session_bridge_createmakes a new main session (top-level UI session) in the current workspace, or in another workspace when you passworkspaceId/cwd. It can send one first prompt and optionally block until the first reply. Provider / model / reasoning effort are inherited from the calling session by default. An async create (nowaitForReply) returns asinceSeqanchor for a later precisewait. - Send messages to any session.
session_bridge_sendappends a turn (mode=queue) or injects steering into the running step (mode=steer), and can optionally wait for the next reply. An async send also returns asinceSeqanchor. - Wait for a reply or a segment.
session_bridge_waitblocks until new assistant output appears aftersinceSeq(default: the latest event seq at call time):waitFor=reply(default) returns as soon as a new text reply is readable;waitFor=segmentreturns as soon as any new completed output step appears (anassistant/message— text, reasoning, or tool-call turn), without waiting for the whole turn, so you can observe output paragraph by paragraph as it is produced. WithrequireTurnEndit additionally waits for the turn to settle. Timeout / abort return the partial result rather than throwing. An already-landed reply is never lost: when no new output arrives within the budget, the latest PRE-EXISTING reply/segment is returned withstale: true(no more(no text)). To retrieve exactly "the reply to what I sent", pass thesinceSeqreturned bysession_bridge_send/session_bridge_create(works regardless of caller latency);sinceSeq: -1counts existing events too, i.e. the anchor for a brand-new session. - Read any session.
session_bridge_readfolds a session's event log into readable rows — live or offline (from persistence) — withsinceSeqpaging, role filtering, and alimit(default 20, max 100). - Read output paragraph by paragraph.
session_bridge_segmentsreturns the session's completed output segments — every finished assistant step (oneassistant/message: its text, reasoning, and requested tool calls) as its own row, paged forward viasinceSeq, returning the next cursor. It works live or offline and does not wait for the whole turn, so you can follow a long agentic run step by step (chain-of-thought included when the model streams it). - Resume offline sessions.
session_bridge_resumebrings a persisted session back online (idempotent); it can also override provider / model. - Find sessions.
session_bridge_findmatches by title, id, workspace, or directory across all workspaces, returning live/running state, title, and working directory. Bridge-registered titles act as aliases. - Monitor and schedule a main task.
session_bridge_statusreads a session's real-time progress (running/idle, open turn, time since the last event for stall detection, pending work, latest reply); only a running session is flagged[STALLED](a quiet idle session is not stuck — same rule as the watchdog).session_bridge_cancelstops a running session.session_bridge_monitor_startruns a background watchdog loop that polls the task, nudges it when it stalls, corrects it when it drifts, terminates it after it stays stuck, and wraps up when it finishes. - Archive sessions.
session_bridge_archiveadds a session to the DSH workspace archive set (hidden from every grouping surface, history and workspace position preserved).session_bridge_archivedlists the archive set, optionally resolving titles.
Monitoring worker
session_bridge_monitor_start installs a timer-driven loop. Every poll it
observes → judges → schedules → logs the target session:
| Observation | Action |
|---|---|
A doneKeywords string appears in the reply and the session is idle | Wrap up and stop the watchdog (log DONE) |
| Idle with no pending work | Wrap up (settled) — no pointless nudging / cancelling |
running and no event for more than stalledMs | Record a stall → steer a nudge (with useLlm, judge offtrack/stuck first) |
Stall repeats ≥ maxStuckCycles | cancel the session |
| Making progress | Reset the stall counter (steady) |
The watchdog only treats running sessions as stalled, so a finished or idle
task is wrapped up rather than nudged forever (the [STALLED] marker in
session_bridge_status follows the same rule and is shown for running sessions
only). Logs go to
~/.dsh/super-injector/dsh-session-bridge-monitor.log (overridable).
Control it with session_bridge_monitor_start / _stop / _list.
Chain-of-thought monitoring & rules
The bridge can watch another session's chain-of-thought (reasoning) in real time — not just its final reply — and act on it:
-
Observe it live.
session_bridge_statusreturns three chain-of-thought fields on a running session:lastReasoning(the most recent finalized reasoning block),liveReasoning(the in-flight reasoning streamed for the current handled turn, fromassistant/chunkreasoning-deltaevents), andreasoningTail(a compact, char-bounded merged preview). Use thereasoningparam (none | last | live | tail) to pick which fields come back;tailis the default and costs the least. -
Read paragraph by paragraph.
session_bridge_segmentsreturns each completed output step (oneassistant/message— text, reasoning, or tool-call turn) as its own segment, paged forward viasinceSeq, without waiting for the whole turn. -
Or read it per message.
session_bridge_readwithincludeReasoningreturns the finalized reasoning of each assistant message. -
Enforce rules.
session_bridge_monitor_startacceptscoRules— an array of { match: contains|not-contains, field: reasoning|text|both, value: string, action: steer|cancel, message?: string } andcotMinHits. Each poll the watchdog matches the rule's condition against the live reasoning/text and, once it stays matched forcotMinHitsconsecutive polls (default 1), fires the action:steerinjects a guiding user message,cancelterminates the session. Example — "stop the session the moment its reasoning no longer contains I'm" becomes:coRules: [{ "match": "not-contains", "field": "reasoning", "value": "I'm", "action": "cancel" }]Caveats: a
not-containsrule onreasoningdeliberately does not fire when the target session produces no reasoning at all (e.g. a non-reasoning model or reasoningEffort off), so you don't cancel sessions that simply don't stream a chain-of-thought. Repeated fires are throttled by a cooldown, and each evaluation/trigger is written to the monitor log.
Requirements
Build
# Install locked DSH release packages, then type-check and build
pnpm install --frozen-lockfile
pnpm build
# type-check src/ against the dsh that is actually installed (no checkout needed)
npm run check:compat
# regression tests for the wait/stall core logic (Node type stripping)
npm test
# via the injector toolchain
dev_build_plugin dsh-session-bridge
Builds use the locked 0.1.7-alpha.1 registry packages; no source checkout is required. check:compat verifies the installed harness types and bundle provenance. CI uses the same lockfile.
Deploy
DSH web loads external plugins from the active profile. This package is a
bundle: its package.json declares dsh.bundle.patch →
cordis.patch.yml, whose insert row mounts the plugin.
That declaration is what lets dsh plugin add install the package and
activate it in one step.
Install from npm
The package is published to npmjs.com.
Releases are cut on a v* git tag by the publish.yml GitHub Actions workflow;
package.json and dsh.plugin.json versions are synced to that tag before
publishing.
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-session-bridge
A prerelease tag (v0.3.2-alpha.1) is published to its own dist-tag (alpha,
beta, rc) instead of latest, so it cannot displace the stable release for
other users. Opt in explicitly:
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-session-bridge@alpha
pnpm installs the published tarball and runs its prepare script (tsdown) to
ensure lib/ is present, then dsh activates the bundle.
Install from GitHub
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:heartmove/dsh-session-bridge
dsh plugin forwards to pnpm inside ~/.dsh/profiles/web/, then reconciles the
bundle into the profile's dsh.profile.bundles layer list. A git install
fetches sources, so pnpm runs the package's prepare script (tsdown) to build
lib/ from src/ after checkout.
pnpm ≥ 10 refuses to run a git dependency's prepare script until it is
allowlisted, so the first add fails with an "Ignored build scripts" hint. Copy
the exact package key pnpm printed into the profile's pnpm-workspace.yaml
(~/.dsh/profiles/web/pnpm-workspace.yaml):
allowBuilds:
dsh-session-bridge: true
then re-run the add. That allowance means "run this package's code on my
machine at install time" — only allow packages whose source you trust, and pin a
commit (github:heartmove/dsh-session-bridge#<sha>) so a later push cannot
silently change what runs.
Restart dsh web, then hard-refresh the page (Ctrl/Cmd+Shift+R).
Install from a local checkout
From the directory that contains this checkout:
npx -p @deepseek-ai/dsh dsh plugin --profile web add ./dsh-session-bridge
pnpm links the checkout and dsh activates the bundle the same way.
Manual link
To manage the profile by hand, link the package and list it as a bundle in
~/.dsh/profiles/web/package.json (the bundle's own cordis.patch.yml supplies
the loader row, so no insert entry is needed):
{
"dependencies": {
"dsh-session-bridge": "link:D:\\path\\to\\dsh-session-bridge"
},
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-session-bridge"]
}
}
}
(On POSIX systems use link:/path/to/dsh-session-bridge.) Then run pnpm install
in the profile directory and restart dsh web.
Inject directly (dev)
For fast iteration while developing the plugin, you can also load it directly through the injector toolchain (no bundle entry required):
dev_inject_plugin D:\code\dsh-session-bridge
Remove it with dev_uninject_plugin dsh-session-bridge (clears the injector
registration and junction; not re-assembled on restart).
Usage
| Tool | What it does |
|---|---|
session_bridge_create | Create a main session (current or another workspace via workspaceId / cwd); optional first prompt + waitForReply; async creates return a sinceSeq anchor. |
session_bridge_send | Send a message (mode=queue/steer); optional wait-for-reply; async sends return a sinceSeq anchor. |
session_bridge_wait | Wait for new output after sinceSeq (default: latest seq at call time; -1 counts existing events): waitFor=reply (text) or waitFor=segment (any completed step, no full-turn wait); optional requireTurnEnd; falls back to the pre-existing reply with stale when nothing new arrives. |
session_bridge_read | Read messages — live or offline; sinceSeq paging, role filter, limit. |
session_bridge_segments | Read completed output segments (each finished assistant step) incrementally by paragraph — live or offline. |
session_bridge_resume | Bring a persisted session back online (idempotent). |
session_bridge_find | Find sessions by title / id / workspace / directory across workspaces. |
session_bridge_status | Read a session's live progress (running, open turn, stall detection, pending work, latest reply) plus live/finalized chain-of-thought (reasoning param); [STALLED] is shown for running sessions only. |
session_bridge_cancel | Stop a running session (abort active turn; clear queued/steering work unless keepInbox). |
session_bridge_monitor_start | Start a background watchdog on a main session (poll, nudge, correct, cancel, wrap up); supports chain-of-thought coRules (e.g. reasoning not-contains "I'm" → cancel). |
session_bridge_monitor_stop | Stop a watchdog (keep the session itself running). |
session_bridge_monitor_list | List active watchdogs and their state. |
session_bridge_archive | Archive a session (hidden from groupings; history and position preserved). |
session_bridge_archived | List the archive set, optionally resolving titles. |
All tools return lossless JSON; wait-style tools never throw on timeout — they
return a timedOut / aborted / stale flag.
Project layout
src/
index.ts host plugin entry (registers the tools; mounts the monitor)
core.ts shared host logic (create/send/wait/read/find, status snapshot, archive attach)
tools.ts tool registrations (bridge + status/cancel + monitor + archive)
monitor.ts the background watchdog loop (statusSnapshot + rules + optional LLM judge)
registry.ts bridge-side title/workspace registry (~/.dsh/session-bridge-registry.json)
scripts/
build.sh compatibility wrapper for npm run build
test-bridge-core.mjs wait/stall regression tests (npm test)
Lifecycle and unloading
DSH ≥ 0.1.6 mounts and unloads plugins at runtime (Settings → Plugins, and
the injector's hot reload). This plugin unloads cleanly: it registers no
loader-level state, its tools are disposed with the plugin fiber, and the
monitor's timer is released through ctx.effect on unload.
One consequence of that ownership model: sessions created by
session_bridge_create are owned by the plugin fiber (the agent is created
under the plugin's context), so unloading or reloading the plugin stops their
live agents. The sessions themselves are persisted and show as offline; bring
one back with session_bridge_resume. Monitor watchdogs also stop on unload.
License
MIT
Compatibility
Versions
| Latest version | Published | Size |
|---|---|---|
| 0.3.1 | — | — |
| 0.2.0 | — | — |
| 0.2.1 | — | — |
| 0.3.0 | — | — |
| 0.3.2-alpha.1 | — | — |
| 0.3.2-alpha.2 | — | — |
| 0.3.2-alpha.3 | — | — |
| 0.3.3-alpha.1 | — | — |
| 0.3.3 | — | — |
| 0.4.0 | — | — |
| 0.5.0 | — | — |
| 0.5.1 | — | — |
| 0.5.2 | — | — |
| 0.7.0 | — | — |
Comments
Loading…
Similar plugins
by drscrewdriver
DSH Web 插件:会话管理台(原名 dsh-session-steward)—— 活跃/归档会话统一管理(浏览、筛选、收藏、批量归档/取消归档/清理),外加四门会话体检;入口自适应顶栏工具行或底栏。不含搜索/索引、不依赖 DRS(搜索在 dsh-search-index)。
★ 1
MIT
TypeScript
Oct 25, 2026
dsh plugin --profile web add dsh-manage-sessionby duanyunlun
DeepSeek Harness(DSH)对话互通插件:同一进程里的对话可以互相发现、直接发消息、盯进度、设护栏——不用先绑定,也不用开子代理。多对话协作 / 跨会话通信 / 监工。Peer messaging, supervision & tool guards between conversations.
★ 3
↓ 151/wk
MIT
JavaScript
Sep 17, 2026
dsh plugin --profile web add dsh-conversation-linkby FuWenLianggit
Session-level multi-thread orchestration for DeepSeek Harness: create ordinary sessions, send queued or interrupt prompts to any session by id, and enumerate sessions. Installs globally, independent o
★ 0
↓ 474/wk
MIT
TypeScript
Aug 15, 2026
dsh plugin --profile web add dsh-session-bridgeby jh1016248
DSH(DeepSeek Harness)插件:会话标题栏一键导出当前会话 —— 「保存 MD」下载纯净 Markdown,「保存 HTML」下载带左侧目录、表格与代码块渲染的网页。自动过滤模型思考过程与工具调用记录,只保留用户与助手的正文,适合归档、分享与撰写报告。安装:dsh plugin --profile web add dsh-save-session
★ 0
↓ 690/wk
MIT
JavaScript
Sep 11, 2026
dsh plugin --profile web add dsh-save-sessionby qingyou002
DSH plugin: hands a long session over to a fresh session in the same workspace on /handoff or at a token threshold, carrying the preset, model, permissions and plan mode across; the brief is written by the session's own model and the switch waits for a step boundary instead of interrupting running work.
★ 0
MIT
TypeScript
Sep 28, 2026
dsh plugin --profile web add dsh-auto-handoffby zhy5
DSH plugin: connect WeChat (official iLink/ClawBot) to DeepSeek Harness — live status settings panel + bundled bridge/keeper kernel
★ 5
↓ 1.1k/wk
MIT
JavaScript
Oct 23, 2026
dsh plugin --profile web add @zmainer/dsh-wx-bridge