dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Fork a writable side conversation from any completed DSH turn, in the right sidebar.
One writable side conversation per session, in the right Sidebar — the main conversation keeps running untouched.
Two ways to open the same panel:
/side typed in the composer./side is a client-side action command: it consumes the trigger token, opens
the panel, and submits nothing. No model message is produced, so the main
task keeps running while you talk in the side line — which is the whole point.
The first open creates the side session once, at the main session's latest completed turn; every later open reuses that same side session, so opening it again never piles up forks.
The side session is an ordinary DSH Session, so the panel is fully writable and the main conversation is unaffected.
While the main session is still working through its first turn there is no completed prefix to fork from — exactly the moment a side conversation is most wanted — so that one case creates a fresh session in the same directory instead. Neither entry is contributed for a blank session.
Directly under every completed turn sits a pencil icon. Clicking it opens an editor prefilled with that turn's user message; confirming:
The original session is never modified — nothing is rewritten in place, because a session log is append-only.
Placement note — why the icon is not directly under the user bubble.
The shipped user bubble builds its own action row internally and exposes no extension point, and its content projection is not importable by a plugin. Replacing that renderer would mean hand-writing a copy that loses reference chips, attachments and styling.
The documented alternative — register a new Chat row kind through
ctx.uiConversation.events.register plus a conversation.chat.node renderer,
anchored at userMessageSeq + 0.05 — does not render. The registration
succeeds (the key becomes an active occupant), but
conversation-nodes/chat-snapshot-builder.ts ends its legacyContribution
switch with default: return EMPTY_CONTRIBUTION, so a kind the builder does not
know contributes nothing to the rendered node stream. v0.5.0 shipped that
attempt and showed no row; v0.5.1 reverts to the turn-tail entry, which is the
only placement that actually renders today.
v0.5.0. Cold boot verified in a fresh browser page, not inferred from registration.
The web boot audit (assertEntriesActive) refuses to mount the whole GUI
when any client entry fails to activate, so a broken plugin here costs the user
their whole editor, not just the plugin. Every release is checked against that
audit by loading the composed profile in a fresh page with an empty module
table and reading the console:
v0.5.0 title: DeepSeek Harness nodes: 387 console errors: 0
That run also proves every injected service resolved (slots, sessions,
resources, sidebarRightTabs, sidebarRight, commandUi, uiWorkspace,
uiConversation) and that every registration call succeeded: a missing service
would leave the entry pending and a throwing registration would fail it, and the
boot audit refuses to mount on either.
v0.1.1 and earlier are known-bad. The package was renamed without renaming
the __ModuleLoader__ factory id, so the client entry failed to import and the
GUI refused to boot (web boot: 1 entry did not activate).
Known gap: the open → panel → scroll path has not been exercised end to end by a
human. Earlier releases mounted the panel but its conversation could not be
scrolled; v0.1.1 added the display:flex / width:100% / height:100% / min-height:0 tab box the shipped sidebar chat uses, and that fix is still
awaiting hands-on confirmation.
| dsh-sidebar-qa | dsh-nested-followups | dsh-side-branch (Side Ask) | dsh-open-branch | |
|---|---|---|---|---|
| Panel per session | one | branches in its own Tree View | one, rebuilt every turn | one, created once |
| Side conversation | writable | read-only tools | read-only by design | writable |
| Where it lives | right Sidebar | its own Tree View | right Sidebar | right Sidebar |
| Shadows shipped UI | no | no | no | no |
| Writes custom session events | — | — | — | no |
Design commitments, each chosen against a failure mode observed in a competitor:
sidebranch.conversation) instead of replacing
sidebar.chat.conversation, and it disables no built-in component.localStorage, and creation is serialized, so a
second open reveals the same tab instead of forking again.remote.session.fork, so the child carries real lineage and the Harness owns
the cut, the synthetic closers, and the title.index.js): contributes nothing. No route, no service, no state.client.js):
sidebranch resource protocol whose address is one per host
session (dsh-resource://sidebranch/for/<hostSessionId>), which is what
makes the panel a singleton and makes a repeat open reveal the same tab;sidebranch right-Sidebar tab type and its body;sidebranch.conversation child slot with the shared
conversation.content factory, so the embedded conversation is the real one;conversation.input.right entry — the composer-toolbar button;/side client command through ctx.commandUi with the
action kind, which is what makes it submit no model message;ctx.sessions.create({ cwd }) when the fork reports
session/fork-unavailable, and rethrows every other failure;ctx.uiConversation.events.register plus its conversation.chat.node
renderer keyed dsh-open-branch-edit, which is what places the pencil row
under each user message;userMessageSeq - 1, sends the edited text through
reference.binding.session.prompt(..., 'queue') inside
ctx.sessions.using(...), then opens the branch with
ctx.uiWorkspace.openSession.This plugin is distributed through GitHub only; it is not published to npm.
dsh plugin --profile <profile> add github:Arbeiter-bit/dsh-open-branch
Pin a revision when you want a reproducible install:
dsh plugin --profile <profile> add github:Arbeiter-bit/dsh-open-branch#v0.2.0
The GUI Plugins → Add plugin dialog accepts the same spec. Restart or refresh the page afterwards so the browser half loads.
Uninstall:
dsh plugin --profile <profile> remove dsh-open-branch
localStorage; the next open detects the missing session and forks a new one.navigator.language (zh/en); the Client
locale service is not wired yet.rewrite origin kind
the Client already reserves but nothing produces).MIT