DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
R

dsh-remote-development

Remote Development

为 DeepSeek Harness 提供轻量级远程开发:通过 SSH 选择远程工作区,让代理使用相同的本地工具在其中工作——文件、Shell 和搜索提供程序由插件路由到远程主机。不增加额外的模型工具,也不使用第三方 UI 插件。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:CJYLZS/dsh-remote-development#172f8d358d7201cdc4792575bce3d40994d3a416
README兼容性版本
dsh-remote-development in the DeepSeek Harness web GUI: a remote workspace session with the document preview sidebarThe remote development settings: saved machines, authentication, and marker color

兼容性与来源证明

Remote Development 以 dsh-remote-development 发布,当前版本为 0.2.1。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/17

版本

0.2.1stable
2026/10/17
0.2.0stable
2026/9/23
0.1.0stable
2026/9/4

相关插件

正在加载相关插件…

最新版
0.2.1
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 7
周下载
0
最近提交
2026/11/4
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Client Ui Git Graph@linxin666/dsh-client-ui-git-graph外部 dsh Web GUI 插件:空会话 Git 分支选择器和 Git 图,包含实际的主机端 Git 操作与防护,作为 dsh 配置文件包Ssh@linxin666/dsh-sshdsh Web GUI 的远程 SSH 操作:主机配置存储(~/.dsh/dsh-ssh.json,可从 ~/.ssh/config 导入)、支持跳板主机的持久化 ssh2 连接池、exec / PTY Web 终端 / SFTP 传输 / 本地端口转发隧道 / 集群执行Opsdsh-ops适用于 Windows x64、Linux x64 和 macOS arm64/x64 的原生文件和 PTC 工具;仅限 Windows 的可选 Bash 负载和主机 PowerShell 集成Update@linxin666/dsh-update用于 dsh Web GUI 的自更新插件:探测 npm 上是否有更新的系列版本,并在原地运行所属配置的 pnpm 更新;可通过设置图标旁侧边栏中的触发器启动,并显示发布说明面板

README

dsh-remote-development

English | 中文

dsh-remote-development in the DeepSeek Harness web GUI: a remote workspace session with the document preview sidebar

The remote development settings: saved machines, authentication, and marker color

Summary

This plugin adds lightweight remote development to DeepSeek Harness: you register an SSH machine, pick a remote directory as the session's workspace, and the agent then works on that remote workspace with the SAME tools it uses locally — file tools, shell, and search. The plugin does not add any model-facing tool and no third-party UI plugin: it replaces the filesystem, subprocess, and bash providers with routing versions that translate local tool calls into remote execution over SSH, and it contributes one settings section plus one workspace directory-flow dialog in the Web GUI.

Highlights

  • Identical toolset. Remote workspaces add no tool calls: the agent works with the exact same tools as a local workspace, and the plugin translates those calls to remote execution underneath.
  • Zero remote dependencies. The remote machine needs no extra server-side component — an SSH connection is all it takes.
  • Web GUI integration. Connection management covers password / private key / SSH agent, jump hosts, host-key TOFU, and connection testing; remote workspaces can be told apart by a custom per-machine color.

Table of Contents

  • Highlights
  • Install
    • Desktop
  • Compatibility
  • Usage
  • Understand the design
  • Configuration
  • Known Limitations and Deferred Work
  • Dev Note
    • Third-party code

Install

Check the host dsh version first:

dsh -V

For dsh ≥ 0.1.7-alpha.1 (the current generation) install the latest plugin straight from the default branch — no #<tag> ref is needed:

dsh plugin add --profile web github:CJYLZS/dsh-remote-development

Only the older generation still needs a pinned ref: dsh 0.1.2-rc.1 – 0.1.5-rc.x is served by v0.1.x, so append #v0.1.0 to that command. See Compatibility for the pairing.

The built lib/ is committed, so a GitHub install needs no build step and never hits pnpm's allowBuilds gate for prepare scripts. The profile's package.json records what you installed.

To remove the plugin, dsh plugin remove --profile web dsh-remote-development.

Desktop

Desktop ships only the current dsh generation: there is no older version to pair with and nothing to pin, so install directly:

dsh plugin add --profile desktop github:CJYLZS/dsh-remote-development

Use the dsh bundled with Desktop. It lives under the installation directory at resources\runtime\cli\bin (dsh.cmd on Windows, bin/dsh on macOS), so on Windows the command above becomes:

<installation directory>\resources\runtime\cli\bin\dsh.cmd plugin add --profile desktop github:CJYLZS/dsh-remote-development

An npm-installed dsh cannot manage the desktop profile. Launch Desktop once so it initializes its profile, fully quit the application, run the command, then reopen Desktop to use the plugin.

For development, link a local checkout instead:

cd dsh-remote-development
pnpm install          # self-contained workspace; store lives in .pnpm-store/
pnpm run build        # emits lib/index.js (host) and lib/client.js (browser)
dsh plugin add --profile web link:/absolute/path/to/dsh-remote-development

A link: install points the profile at the checkout directory, so later pnpm run build runs apply on the next harness restart without re-adding.

Restart the harness after installing.

Compatibility

dsh changed the shell seam in 0.1.7-alpha.1 with two breaking changes and no compatibility layer: execution converged on resolve() + execute() (run()/start() were deleted), and the local executors' Config became live accessors (Volatile, plus a new pwshPath). Plugin and host therefore pair by generation:

  • v0.2.x → dsh ≥ 0.1.7-alpha.1, declared as peerDependencies: >=0.1.7-alpha.1 (open-ended).
  • v0.1.x → dsh 0.1.2-rc.1 – 0.1.5-rc.x (the run()/start() seam).

The range is open-ended because the current code was verified unchanged on dsh 0.2.1-rc.1: installation, the Web settings section, remote directory browsing, and a remote session's bash, file, and search tools all work. dsh 0.2.1's plugin manager enforces peer ranges at install time, so a plugin that still declares the old <0.2.0 bound is refused as incompatible; this release widens the range instead of requiring a per-version risk exemption.

Older mismatched pairs still fail rather than being caught: a v0.1.x plugin on a 0.1.7+ host throws TypeError: Cannot read properties of undefined (reading 'get') while constructing the local executor (reading config.pwshPath), and a 0.1.7+ plugin on a v0.1.x host fails validation at the same constructor (pwsh-local: timeoutMs must be a positive finite number) with commands throwing ctx.shell.run is not a function.

The open-ended range admits later 0.2.x releases; a 0.3 generation still needs a compatibility check before it can be trusted (semver's prerelease rules will not admit a new alpha on their own).

Usage

Three steps and nothing else:

  1. Add a machine. In the Web GUI's dsh-remote-development settings section, enter host, port, and username, choose password / private key / SSH agent authentication (optional jump proxy), and click test.
  2. Pick a remote directory. In the workspace directory flow (the hero "choose directory" dialog or the sidebar workspaces picker), open the Remote tab, browse the machine's directories, and set one as the session workspace.
  3. Work as usual. That is the whole setup. File tools, shell, bash, and search run through the same tool calls as before — only now they execute on the remote machine; the model's working directory is the remote path, so it needs no special instructions and gains no new tools. Anything outside the chosen directory keeps local behavior, so existing sessions are untouched.

Under the hood, setting a remote workspace creates an anchor under $DSH_HOME/remote-workspaces/<host>-<user>-<port>/<basename> — a real local directory whose metadata records the remote coordinates. There is no "current machine" and no default target: the anchor alone decides where its session's tools execute. If that machine is later deleted, operations on the workspace fail with an explicit "machine is no longer configured" error instead of silently running elsewhere — re-add the machine to resume, or delete the workspace directory.


Understand the design

Three routing providers replace the base row of the same service, so every local tool keeps working and only the transport changes:

  • RoutingFileSystem (replaces the sandbox filesystem) — file reads, writes, edits, and listings whose path resolves to a remote root go through SFTP; everything else delegates to the local base via super().
  • RoutingSubprocessRuntime (replaces the local subprocess runtime) — spawns with an anchor cwd execute on the remote host over an SSH exec channel; the packaged ripgrep used by search tools is rewritten to the remote rg binary. Routing keys on the workdir alone, so behavior is identical on every host platform.
  • RoutingBashExecutor / RoutingPwshExecutor (replace the sandbox bash/pwsh executor) — commands with a workdir under an anchor run through bash -c on the remote host, and background processes get a real remote PID via a process-group kill protocol. The host platform picks which executor mounts — only the LOCAL fallback is platform-bound (local bash on POSIX, local pwsh on Windows); the remote host's POSIX shell always decides the remote dialect.
  • Per-agent tool visibility. The patch mounts both shell tool stacks, and a scoped restriction per session hides the dialect the session's workspace must not use: a remote session sees the bash tool (never pwsh), and a local session on a Windows host sees pwsh (never the plugin-added bash). POSIX local sessions keep bash for both worlds, matching the base composition. A remote session also declares its own presentation, native: run_code needs a Node process on the machine that owns the session directory plus a control pipe to it, and an anchor session has neither, so a PTC-mode deployment would otherwise hand the model one tool that can never run.
  • One shared SFTP session per machine. The SFTP protocol multiplexes every request over one subsystem channel, so all file operations share a single session instead of opening (and leaking) a channel per call — servers cap sessions per connection, and exhausted caps answer every open with a channel failure.
  • Remote workspaces are marked in the file tree. The client recolors folder icons for remote workspaces: the host joins every anchor with its machine's marker color (a Machine field, editable in settings), and the client turns that list into attribute selectors over the tree's data-files-* hooks, injected as a stylesheet. One color per machine; leaving it empty falls back to the theme accent. The sidebar's workspace rows expose no data hooks, so their rules reach the row through its aria-labels (:has()), matching the workspace title an anchor workspace adopts from its directory basename. Two machines mounting the same remote directory would adopt the same title — and one row rule would then paint both rows with the last machine's color — so the host settles a unique title for such an anchor (the machine name appended, , falling back to the remote path's hash when two machines share a name) and the client renames the Workspace onto it; a title the operator typed is never overwritten, and a title that stays ambiguous emits no row rule at all, leaving those rows on the theme default instead of a wrong color.

The model never sees the anchor handle. The harness's system prompt reports the session's working directory; for a remote session the plugin overrides that variable per agent with the remote path, so the model-visible cwd is the directory its commands actually run in. As a safety net, anchor-directory spellings (absolute, ~, $HOME, ${HOME}) in command text are rewritten to their remote paths before execution — same-machine anchors only, stdin left verbatim. Local sessions pass through unchanged.

Remote mutation policy mirrors the local sandbox: read-only mode rejects remote writes; workspace-write allows writes only under the remote workspace root and the remote /tmp. Remote writes are serialized per file, publish atomically (temp file + rename), and refuse stale versions and ambiguous edits with the same error codes the local filesystem produces.

Host keys use TOFU (accept-new by default): the first-seen key is recorded, a changed key is rejected with a MITM reason, and verify/off modes are available per machine.


Configuration

Machines are managed in the settings section; the plugin itself takes config defaults through cordis.yml (all optional):

FieldDefaultMeaning
commandTimeoutMs20000Per-command timeout; the channel is closed after SIGTERM grace.
connectTimeoutMs15000SSH connection establishment timeout.
maxOutputChars200000Command output kept head-plus-tail beyond this size.
maxFileBytes52428800Largest file read or written through SFTP.
hostKeyModeaccept-newaccept-new, verify, or off.
remoteRipgreprgRemote binary the packaged ripgrep is rewritten to.
anchorRoot$DSH_HOME/remote-workspacesRoot directory for anchor directories.
auditLogoffAppend-only JSONL audit of remote executions.

Known Limitations and Deferred Work

  • Windows remote hosts are deferred. Remote machines must run a POSIX shell; uname detection rejects Windows targets with a clear error. Adaptation is reserved for a later phase.
  • Windows local hosts route remote shell commands. A Windows host mounts the pwsh-based routing executor: local workdirs keep the sandboxed pwsh executor, and anchor workdirs cross to the remote host's bash. The model sees the bash tool for remote sessions and the pwsh tool for local ones.
  • Persistent terminal sessions are not supported. The terminal tool reports an explicit "not supported by dsh-remote-development" error instead of letting the agent try; use the bash tool for remote commands. Persistent shell tools remain local-only: a persistent tool pointed at a remote workspace refuses with the same error.
  • PTC mode presents remote sessions natively. run_code executes a program on the machine that owns the session directory and talks to it over a control pipe; an anchor session has neither half (the routing subprocess provider serves no control pipe), so a mode: ptc deployment would offer a single tool that always fails. Remote sessions therefore present natively and their file and shell tools stay directly callable. A scope whose presentation an agent preset already declares cannot be overridden — there run_code is denied with an explicit model-facing reason instead. A real remote program executor (remote Node plus a control channel over SSH) is deferred; it would cost the plugin's zero-remote-dependency property.
  • @ file references are not supported in remote sessions. Typing @ in a remote session yields a single explicit "not supported yet" candidate rather than a silent failure; the reference-source interface is reserved for a later phase.
  • No mirror or sync layer. Anchor directories hold metadata only, not file copies; every read and write crosses SSH, bounded by maxFileBytes.
  • Tree marking depends on in-box data-files-* hooks. The recoloring targets the file tree's data attributes, which are not a declared public contract; a dsh rename silently drops the coloring (purely presentational — nothing else breaks). Workspace-row markers additionally match by workspace title: renaming a workspace, or a dsh change to the sidebar's aria-label copy, drops the row marker while the file-tree marker keeps working.
  • Path aliasing depends on display structure. The remote-path rewrite targets the tree root header's span shape and the hover card's portal shape, both undeclared; a dsh change to either silently leaves the local anchor path visible (purely presentational — navigation, addressing, and the copy action are untouched and still use the real local directory).

Dev Note

The plugin directory is a self-contained pnpm workspace (packages: [- .], storeDir: .pnpm-store) so pnpm cannot reach the harness repository's workspace. dsh framework packages are declared as peerDependencies (>=0.1.7-alpha.1, supplied by the host profile) and pinned exactly in devDependencies for local types and builds; no relative link: dependencies exist inside the dependency graph, so the directory builds standalone in any location.

Commands: pnpm run build (tsdown, both halves), pnpm run typecheck, pnpm run test (node:test via tsx; no SSH server needed — the pool accepts an injected client factory and the SFTP surface is faked).

ssh2 is a devDependency because it is build input, not a runtime dependency: pnpm run build bundles it into lib/index.js. Commit the rebuilt lib/ with any source change, or the GitHub install serves stale code.

Third-party code

lib/index.js contains bundled copies of ssh2 (MIT), asn1 (MIT), safer-buffer (MIT), tweetnacl (Unlicense), and bcrypt-pbkdf (BSD-3-Clause). Their license texts are reproduced in THIRD-PARTY-NOTICES.md.

Bundling moves security updates onto this repository: an ssh2 advisory no longer reaches users through their own pnpm update. Patching it means pnpm update ssh2 && pnpm run build, then committing the result here.

myapp (build-box)
  • Remote workspaces display their remote path. The shell shows a workspace's directory — the tree's root header and the workspace list's hover card — as the session's working directory, which for a remote workspace is the plugin's local anchor directory. The client keeps an alias table (anchor directory → remote path, from the same /status join the marker color uses) and rewrites those display texts to the remote path through a mutation observer, touching only existing text nodes so React's reconciler keeps every element it owns. The underlying data-files-* coordinates stay local: the tree still navigates by them.
  • Search needs a remote ripgrep. The rg binary must exist on the remote machine (configurable via remoteRipgrep); otherwise search tools fail on remote paths.
  • SSH runs on pure JS, not native crypto. The bundled ssh2 never loads its optional native accelerators, so throughput on large SFTP transfers is lower than a natively-built ssh2 would give.
  • Not published to npm. Install from GitHub or a local checkout — see Install.
  • The built-in directory-picker flow is shadowed, not replaced. Both directory-flow registrations coexist at distinct priorities (this plugin uses -1, lowest renders); unloading this plugin hands the slot back to the built-in picker.
  • The 本机 (local) tab follows the host's composed picker capability. The host resolves its directory-picker backend once at boot: a WSL without zenity/kdialog, an SSH launch, a non-loopback bind, or a display-less Linux all compose the browse backend (only the list/createDirectory primitives — no OS chooser). The local tab branches on that resolution — native opens the OS chooser, browse drives the host's in-app web browser instead; before this, the tab hard-coded pick, which fails with directory-picker/unavailable on such boots.
  • Deleting a machine strands its workspaces on purpose. Anchors survive machine deletion, and every tool surface refuses them with the same "no longer configured" error (fs, bash, subprocess, and the prompt's cwd variable falls back to the local handle) rather than executing on another machine or locally.