wanyexin1998/dsh-workbench

dsh-workbench

Community-maintained source preview for two-Pane DeepSeek Harness Web workflows

Uncategorized

DSH Workbench dual-Pane visual with two independent Session panels and a central divider

A two-Pane workspace for DeepSeek Harness Web: run two Sessions side by side, with application shortcuts, quote annotation, and optional Pane-local side panels.

简体中文 · English

[!IMPORTANT] Version 0.2.0-rc.6 is a source preview, not a one-command npm release. Split Pane requires the pinned Harness fork. Better Sidebar and Panel Compatibility are entirely optional. This project never installs, updates, or modifies a third-party plugin automatically.

[!TIP] One-line install prompt: send the complete sentence below to DeepSeek Harness

Install DSH Workbench. First check the current Harness: if it is compatible with Split Pane, install directly; if not, keep the general-plugin functionality and tell me how to install, in parallel, the self-installed patch path (bootstrap) that does not overwrite the official Harness. If the sandbox cannot write to DSH_HOME, give me only one final terminal command.

Full decision rules and commands live in docs/INSTALL.md. The v0.2.0-rc.6 GitHub Release is published — both the general-plugin and Split Pane bootstrap paths work today. Status still reads 0.2.0-rc.6 source preview (see release-contract.json); that is not an npm release. To audit the source yourself, use "Advanced: build from source" below.

What it solves

DeepSeek Harness normally drives the interface from one current Session. DSH Workbench adds two stable, independent Session Panes to the Web client without copying Conversation or changing the Agent loop.

CapabilityExperience
Two PanesView and operate two Sessions at once without remounting the other Pane on focus changes
Pane-local stateDrafts, scroll position, the turn rail, and optional panels remain independent
Application shortcutsConfigurable Simplified Chinese / English labels following the Harness global locale; New Session, Open Settings, Previous Session, and Jump to Latest are listed under "Default shortcuts" below
Workbench AskOpen a zero-tool chat quickly, or fork a completed-message selection into a side chat to follow up
Quote annotationMark a quoted passage where it lives (tint plus a numbered badge), write a note per quote, and keep only a counted chip on the composer
Pane-local panelsOptional compatibility package gives each Pane independent right and bottom panels
Safe degradationSplit Pane capacity is not enabled when Presentation protocol is incompatible

Product screenshots

Two Session Panes

DSH Workbench light-mode split view with the wyx_code and data-warehouse Sessions open in independent Panes

Each Session owns its title, workspace, mode, composer, and Pane-panel controls. The center split preserves independent SessionProvider lifecycles.

Shortcuts following the global locale

DSH Workbench shortcuts settings listing localized actions for the composer, sidebar, stop Session, and close Pane with their chords

Shortcut labels follow the Harness global language, and every chord can be rebound and persisted.

This screenshot was taken against 0.2.0-rc.2. Settings has since been simplified: the grey and amber secondary line under each action (its action id and browser-reserved warning) was removed. The chords, action names, and rebinding interaction still match the image; only those two lines are gone. The screenshot is due for a re-capture.

Compatibility at a glance

ComponentRequiredSupported baselineNotes
DeepSeek HarnessYesfork rc4/presentation-on-0.1.2, commit c5a387cd…Provides Session Presentation protocol 2, plus ctx.layout.toggleSettings() so the Settings shortcut also closes the panel
DSH WorkbenchYes0.2.0-rc.6Maximum two visible Panes
Better SidebarOptionalfork 0.16.1, commit 1685770…Unavailable today: the fork was built against the previous upstream baseline and fails to load on the one this release pins, taking the whole harness down with it. See docs/KNOWN_ISSUES.md
Panel CompatibilityOptional0.1.0-rc.4Connects only explicit compatible providers

release-contract.json is authoritative for full SHAs, branches, and distribution status. Stock Harness 0.1.2-rc.1 does not expose the required split interface, and stock Better Sidebar 0.16.1 has no multi-instance Pane capability.

Workbench Split Pane and shortcuts work without Better Sidebar. When no compatible provider is installed, Panel Compatibility starts no Pane observer and changes no DOM, layout, or styles.

Quick start

[!NOTE] The v0.2.0-rc.6 GitHub Release is published, with both TGZs, both Split Pane bootstrap scripts, SHA256SUMS, and release-manifest.json attached — both paths below work today, copy-paste ready. Release artifacts are SHA256-verified, not GPG-signed (release-contract.json's sourceVerification.signedReleaseAvailable is still false). release-contract.json itself still reports 0.2.0-rc.6 / source-preview — that reflects the distribution model (source plus local TGZ, no npm), not an unavailable install path. To audit the source yourself line by line, the collapsed "Advanced: build from source (audit path)" section below (i.e. docs/INSTALL.md § Advanced: source build) remains available.

Pick your path first. The two paths are independent; choose by what you already have:

  • DeepSeek Harness is already installed (dsh --version prints a version) and you do not need Split Pane yet → take (a) General plugin.
  • No Harness yet, or Split Pane is the reason you are here → take (b) Split pane bootstrap. It ships and builds its own pinned Harness fork, so it needs no pre-existing dsh; the trade-off is that it runs in an isolated, brand-new environment.

(a) General plugin (stock Harness, default)

Prerequisite: the dsh command must already be on your PATH — this path is for people already running DeepSeek Harness. Run dsh --version first; only continue if it prints a version. Otherwise the install command stops at its last step with CommandNotFoundException / command not found, and you want (b) below instead. Installing Harness itself is upstream's business; this repository does not provide it.

Download the immutable Workbench TGZ from the GitHub Release, verify its SHA256, install with dsh plugin --profile web add file:<path> (on Windows, keep the install path space-free or you'll hit an ENOENT — see the link below for details). Split Pane stays inactive on stock Harness — the official interface is not merged yet (see discussion #4718); everything else is unaffected. Afterwards, confirm @wanyexin1998/dsh-workbench appears in dsh --profile web --dump-config. Full command blocks, the prerequisite check, and what to expect after installing live in docs/INSTALL.md § Quick Install.

(b) Split pane (bootstrap, one command)

No pre-existing dsh required. Copy and run the single command for your platform below to get Split Pane (coexists with the official Harness, zero changes to the official install; requires Node.js ^22.19/>=24, pnpm@11, git, and PowerShell 7+ on Windows):

Windows (PowerShell 7+ / pwsh):

& { $ErrorActionPreference = 'Stop'; $rel = 'https://github.com/wanyexin1998/dsh-workbench/releases/download/v0.2.0-rc.6'; Invoke-WebRequest "$rel/dsh-workbench-bootstrap.ps1" -OutFile dsh-workbench-bootstrap.ps1; Invoke-WebRequest "$rel/SHA256SUMS" -OutFile SHA256SUMS; $expectedLine = (Select-String -Path SHA256SUMS -Pattern 'dsh-workbench-bootstrap\.ps1$').Line; if (-not $expectedLine) { throw 'SHA256SUMS 中未找到 dsh-workbench-bootstrap.ps1 的记录,已中止' }; $expected = ($expectedLine -split '\s+')[0].ToLower(); if ($expected -notmatch '^[0-9a-f]{64}$') { throw "SHA256SUMS 中的哈希格式不合法:$expected" }; $actual = (Get-FileHash dsh-workbench-bootstrap.ps1 -Algorithm SHA256).Hash.ToLower(); if ($actual -ne $expected) { throw "SHA256 校验失败:期望 $expected,实际 $actual" }; pwsh -NoProfile -ExecutionPolicy Bypass -File .\dsh-workbench-bootstrap.ps1 }

(This command is byte-identical to the normative §1 command, so its own failure messages are currently Chinese; an English variant is tracked as follow-up work for the release task. The command is not altered here.)

macOS (Terminal):

rel='https://github.com/wanyexin1998/dsh-workbench/releases/download/v0.2.0-rc.6'; if curl -fsSLO "$rel/dsh-workbench-bootstrap.sh" && curl -fsSLO "$rel/SHA256SUMS"; then expected=$(grep 'dsh-workbench-bootstrap\.sh$' SHA256SUMS | awk '{print $1}'); actual=$(shasum -a 256 dsh-workbench-bootstrap.sh | awk '{print $1}'); if [ -n "$expected" ] && printf '%s' "$expected" | grep -qE '^[0-9a-f]{64}$' && [ "$actual" = "$expected" ]; then chmod +x dsh-workbench-bootstrap.sh && ./dsh-workbench-bootstrap.sh; else echo 'SHA256 校验失败,已中止,不会执行未校验脚本' >&2; false; fi; else echo '下载失败,已中止,不会执行未校验脚本' >&2; false; fi

(This command is byte-identical to the normative §1 command, so its own failure messages are currently Chinese; an English variant is tracked as follow-up work for the release task. The command is not altered here.)

When it finishes, launch it through the generated launcher: Windows %USERPROFILE%\dsh-workbench\dsh-workbench.cmd, macOS $HOME/dsh-workbench/dsh-workbench. The launcher pins DSH_HOME to <target>/home, so the first launch is a brand-new empty environment: no past Sessions, no Workspaces, and the model and provider need configuring again. Nothing failed — that isolation is precisely why your official install is untouched, and its own data is still there under its own ~/.dsh.

Full details on what the script does, how to uninstall, and when the hashes take effect live in docs/INSTALL.md § Split pane (bootstrap).

Advanced: build from source (audit path)

The complete version lives in docs/INSTALL.md § Advanced: source build. This path remains valid for anyone who wants to audit every line of code themselves; it is simply no longer the default now that immutable Release artifacts exist.

[!TIP] One-line install prompt (source-audit path): send the complete sentence below to DeepSeek Harness

Install DSH Workbench from https://github.com/wanyexin1998/dsh-workbench: first ask me for a full 40-character Workbench commit obtained from an independent trusted channel and stop if I do not provide one; require a nonexistent target directory, use git clone --no-checkout and checkout --detach that commit, stop after every failed Git command, and verify detached HEAD, a completely clean worktree, and case-insensitive exact equality between git rev-parse --verify HEAD and the supplied commit; only after every check succeeds may you read executable repository instructions and run pnpm install --frozen-lockfile and pnpm release:check, then install the generated Workbench TGZ into the web profile; install Panel Compatibility only when a compatible Better Sidebar fork is already present, never install or replace a third-party plugin automatically, never publish to npm, and finally report the actual commits, TGZ SHA256 values, and verification results for Split Pane and shortcuts.

Requirements

  • Node.js ^22.19 or >=24
  • pnpm 11
  • The pinned Harness fork built from source

Build and verify Workbench

Obtain and approve a full 40-character Workbench commit through an independent trusted channel. Do not treat a branch, short SHA, ordinary tag, or mutable repository prose as the trust anchor.

$WorkbenchCommit = Read-Host 'Enter the full 40-character Workbench commit approved through a trusted channel'
if ($WorkbenchCommit -notmatch '^[0-9a-fA-F]{40}$') { throw 'Workbench commit must be a full 40-character hexadecimal value' }
$WorkbenchCommit = $WorkbenchCommit.ToLowerInvariant()
if (Test-Path -LiteralPath 'dsh-workbench') { throw 'Target directory dsh-workbench already exists; retry from an empty directory' }
git clone --no-checkout https://github.com/wanyexin1998/dsh-workbench.git
if ($LASTEXITCODE -ne 0) { throw 'Failed to clone Workbench' }
cd dsh-workbench
git checkout --detach $WorkbenchCommit
if ($LASTEXITCODE -ne 0) { throw 'Failed to check out the Workbench commit' }
$ResolvedCommit = (git rev-parse --verify HEAD).Trim().ToLowerInvariant()
if ($LASTEXITCODE -ne 0) { throw 'Failed to resolve Workbench HEAD' }
if ($ResolvedCommit -ne $WorkbenchCommit) { throw "Workbench commit mismatch: expected $WorkbenchCommit, got $ResolvedCommit" }
$HeadRef = git symbolic-ref -q HEAD
if ($LASTEXITCODE -eq 0) { throw "Workbench must use detached HEAD, currently $HeadRef" }
if ($LASTEXITCODE -ne 1) { throw 'Failed to verify detached HEAD' }
$WorktreeState = git status --porcelain=v1 --untracked-files=all
if ($LASTEXITCODE -ne 0) { throw 'Failed to verify the Workbench worktree' }
if ($WorktreeState) { throw 'Workbench worktree is not clean' }
# WORKBENCH-SOURCE-VERIFIED-BEFORE-REPOSITORY-CODE
pnpm install --frozen-lockfile
pnpm release:check

Successful verification writes these files under dist/:

  • wanyexin1998-dsh-workbench-0.2.0-rc.6.tgz
  • wanyexin1998-dsh-workbench-panel-compat-0.1.0-rc.4.tgz
  • dsh-workbench-bootstrap.ps1
  • dsh-workbench-bootstrap.sh
  • release-manifest.json
  • SHA256SUMS

release:check is 9 steps, in order: privacy and secret scanning, release-contract validation, the secret scanner's own unit tests, the install-contract tests, the bootstrap-script tests, typechecks, package unit tests, a dependency audit, and finally the bundle step's clean rebuild, generated-runtime scanning, TGZ packing, and SHA256 verification. It does not publish to npm. Measured pass counts for each suite are recorded in RELEASE_NOTES.md.

See docs/INSTALL.md for the complete Harness build, installation order, and optional panel setup.

Interaction model

  • Ordinary Session click: replace the focused Pane.
  • Ctrl / Command + Session click: open beside the focused Pane.
  • Third Session: replace the focused Pane instead of adding a third Pane.
  • Focus change: reroute interaction only; never open, close, or remount a panel.
  • Shared workspace: show a non-blocking warning; Workbench does not provide file-write isolation.
  • Refresh: restore one Pane; multi-Pane membership is currently process-local.

Default shortcuts

Primary = ⌘ on macOS, Ctrl on Windows/Linux. Every action can be rebound, cleared, or disabled from Settings; the table below lists shipped defaults, cross-checked against packages/dsh-workbench/src/native-ux/client/shortcuts.tsx.

ActionDefault chordNotes
Focus composerPrimary+/
Toggle sidebarPrimary+BConflicts with the browser bookmark shortcut; Settings surfaces a warning
Stop current SessionPrimary+Shift+X
Close focused PanePrimary+\Requires Presentation protocol 2 (Split Pane bootstrap path only)
Workbench AskPrimary+Shift+CConflicts with the browser DevTools "Inspect element" shortcut; Settings surfaces a warning; the default chord is unchanged
New SessionPrimary+NA normal browser tab reserves this for "New window"; Settings surfaces a warning. Works as bound in a desktop shell environment
Open / Toggle SettingsPrimary+,Three capability tiers: the pinned Harness fork (c5a387cd) exposes ctx.layout.toggleSettings(), so the same chord also dismisses the panel; a host on the older pin, which ships only openSettings(), keeps the open-only verb and the "Open Settings" label; stock Harness has neither, and the action is not registered at all. The earlier default Primary+Space was intercepted by most Chinese IMEs as their language-toggle hotkey and by Spotlight on macOS (confirmed unresponsive in testing), so it is no longer the default
Switch to previous SessionAlt+QDerived from event.code across platforms, so macOS Option-key character composition does not break it
Jump to latest messagePrimary+Shift+L

Optional Pane-local panels

⛔ This section is unavailable today. The pinned Better Sidebar fork was built against the previous upstream baseline; on the one this release pins it throws while the plugin tree loads and the whole harness fails to boot — this is not a degraded sidebar. If an app stopped starting after following this, remove dsh-better-sidebar from the profile and restart. See docs/KNOWN_ISSUES.md. The steps are kept as written so they resume the moment a fork commit rebuilt against the current baseline is pinned in the release contract.

To give each Pane its own right or bottom panel, install:

  1. The pinned Better Sidebar fork.
  2. The local @wanyexin1998/dsh-workbench-panel-compat TGZ.

The adapter consumes only a versioned Pane capability and public data-session-pane* host markers. It does not patch Better Sidebar private stores or infer unknown DOM.

Workbench Ask

Ctrl+Shift+C (Command+Shift+C on macOS) opens a new or the most recent same-day blank Session using the 聊天模式 / Chat mode preset. Workbench Edition opens and focuses it beside the source Pane; at two-Pane capacity, Workbench asks first and replaces only the non-source Pane. On stock Harness the action remains available, switches in place, and shows the degradation notice once. Sessions prefer a Workspace whose title is chat, then the source Session's Workspace. With no resolvable Workspace, the action stops safely and never creates a directory or Workspace.

Selecting text in a completed message exposes three actions:

  • Add to conversation marks the passage where it lives and immediately opens a note card beside it; the composer gains only a counted chip rather than a second copy of the text. Ordinary draft text is preserved, multiple selections aggregate, and nothing sends automatically. It works on stock Harness — see "Quote annotation" below.
  • More details forks from the completed Turn, opens the child in the second Pane, and sends exactly one localized explanation request with a reference-only boundary. It requires Presentation protocol 2.
  • Ask in side chat forks the same way but inserts only a boundary-bearing selection reference into an otherwise empty child draft. No model call occurs until the user writes and explicitly submits a question. It requires Presentation protocol 2.

A side child inherits the parent cwd, model, preset, Workspace, tools, and approval flow. It is not zero-tool Chat mode; tool side effects remain real. Closing its Pane changes presentation only—the durable Session remains in the sidebar. If fork succeeds but opening or input preparation fails, Workbench reports the retained child id and never deletes it silently.

Quote annotation

The full gesture behind "Add to conversation" is: select → click Add → start typing.

  • The quoted passage is marked in place — a tinted band with an underline, and a 16px numbered badge in the margin beside it. The text is no longer copied into a dock above the composer, so adding more quotes never pushes the conversation off screen.
  • A note card opens beside that passage at the same moment, with the caret already in it. Clicking away, pressing Esc, or pressing Save all persist what you wrote.
  • After a save nothing stays parked beside the paragraph. A resting overlay lands directly under the passage's last line, which is normally the next paragraph. There are three ways back to a saved note that cost no space: the quote list behind the composer chip (each row carries the note), resting the pointer on the numbered badge to float the note briefly, or clicking that badge to reopen the card.
  • What the model receives is plain text: a prose heading (Quoting from above:), the quoted text with a │ gutter on every line, and your note on its own ↳ line. No XML tags, no session ids, node keys or character offsets, and no HTML escaping — a quote of Tom & Jerry arrives as Tom & Jerry.

Marking in place does not mutate the Harness DOM. The tint and underline are painted through the browser's CSS Custom Highlight API: Workbench hands the browser a Range and inserts no node and no attribute into the host Conversation. The badge, card, and note layers all portal onto document.body from zero-sized positioned containers, so none of them covers the page or intercepts the host's pointer events.

The cost is that this API has no fallback path: in a browser without it the tint is simply not painted. The numbered badges, the quote list, and the serialized format all still work — what is lost is seeing which passage a quote refers to. See docs/KNOWN_ISSUES.md.

Boundaries between the three modes

Minimal mode (built-in)Chat mode (seeded by Workbench)Side chat (forked child)
Session sourceNew SessionNew or same-day reusable blank chat SessionFork of the selected completed parent Turn
ContextReduced agent scaffoldingClean Session with no parent contextCompleted parent history plus a boundary marking the current task
Tools2: persistent shell + str_replace_editor0Inherited from the parent preset
Can touch your systemYes—still edits files and runs commandsNo—there are no tools by constructionDepends on the parent preset and approval flow; side effects are real
Best forLightweight coding tasksQ&A, design discussions, quick questionsQuestions, explanations, or follow-up work grounded in the current conversation

Installing and removing the Chat mode preset

After installation, the Host entry seeds 聊天模式 / Chat mode into $DSH_HOME/.agent-presets/chat/ (create-only, never overwritten, and never re-created after deletion). The preset has zero tools: no file access, command execution, or project context. Model and provider remain selectable per Session. A measured first turn used 181 input tokens.

That resolves to ~/.dsh/.agent-presets/chat/ only when DSH_HOME is unset. On the Split Pane bootstrap path it is somewhere else: the generated launcher pins DSH_HOME to the home directory under <target>, so the preset lands in .agent-presets/chat/ inside that one (default target: Windows %USERPROFILE%\dsh-workbench, macOS $HOME/dsh-workbench).