DeepSHPlugins
dsh-ssh-hub 项目预览
GITHUB / COMMUNITY PROJECT

dsh-ssh-hub

客户端与终端JavaScriptMIT

DSH Web GUI 多服务器 SSH 终端面板:浮动终端窗口支持标签页、并排组合、广播、宿主侧持久会话,以及密码/私钥/SSH Agent 认证。

0 StarsJUNQINGV587 更新时间 2026-08-19
访问 GitHub 仓库
dsh-ssh-hub 项目预览

项目介绍

中文

DSH Web GUI 多服务器 SSH 终端面板:浮动终端窗口支持标签页、并排组合、广播、宿主侧持久会话,以及密码/私钥/SSH Agent 认证。

English

Multi-server SSH terminal panel for the DSH Web GUI: floating terminal window with tabs, side-by-side groups, broadcast, host-owned persistent sessions, and password/private-key/SSH-agent auth.

项目信息与收录信号

快照 2026-09-11
作者 / 组织
JUNQINGV587
仓库
JUNQINGV587/dsh-ssh-hub
GitHub Stars
0
Forks
0
开发语言
JavaScript
许可证
MIT
最近推送
2026-08-19
Manifest
数据中检测到声明

公开仓库不自动等于可商用;许可证与当前兼容性以原项目文档为准。Manifest 和数据评分不构成安装安全认证。

数据评分

39/ 100
维护活跃
85
文档与实用信息
100
生态关注度
0
安装便捷信号
100
项目声明信号
100

近 23 天仍在更新;README 含完整安装与使用说明;标准命令一键安装。

评分来自已有数据快照的五维模型,仅作浏览参考,不是实际使用评测或安全检测结论。

安装与使用

所有项目资料与许可均以对应 GitHub 仓库为准。

dsh plugin --profile web add github:JUNQINGV587/dsh-ssh-hub

复制命令不会自动执行。请先阅读仓库文档,确认环境要求与许可证。

项目截图

仓库 README

GitHub 原文

已保存的仓库文档快照;文档抓取时间未记录,可能与上方目录介绍处于不同版本。安装前请核对当前仓库说明。

dsh-ssh-hub

Multi-server SSH terminal panel for the DeepSeek Harness (DSH) Web GUI.

Manage a list of SSH servers and open multiple interactive terminals at once — a lightweight, Wave Terminal-style SSH client built into your DSH conversation. Terminals live in one Terminal Window floating over the GUI: drag it anywhere, resize it, maximize it with a double-click, and arrange sessions as tabs or side-by-side groups — merge two tabs by dragging one onto the other, reorder group members, magnify one to fill the window.

Features

  • 🪟 Terminal Window — a floating window over the whole GUI (opened with Ctrl+Shift+</kbd> or the SSH 终端 sidebar button): drag by the title bar (kept on screen), resize from the corner, double-click to maximize. <kbd>Esc</kbd> walks out of magnify/maximize one level; closing the window is the explicit ✕. Opening uses a subtle animation (disabled under prefers-reduced-motion`); when the window loses focus only the frame dims — terminal output always stays readable
  • 🗂️ Tabs are sessions — one tab is one session, full-window. Switch tabs in the tab bar (Alt+1-9, F2 renames, Alt+t new); each tab shows a status dot (connecting / live / closed) and an amber pulse when it produced output while you weren't looking
  • 🧱 Groups (workspaces) — put several sessions side-by-side: drag a tab onto another tab to merge them, drag a tab onto a group's tab to append a member, or use the 新建组合 (New group) picker to select sessions. Drag the dividers to resize; drag members to reorder (before/after/swap) or onto the tab strip to make one its own tab again; a group's ✕ dissolves it back into member tabs. Connect a new server with 加入当前 (Join current) to append it to the active group
  • 📡 Broadcast — in a group, hit 广播 (Broadcast), click the members to target, type a command once and press Enter — it goes to every selected member's shell (receivers flash briefly)
  • 🔍 Block magnify — click a block (or Alt+m) to magnify it to fill the window; Esc or Alt+m restores
  • 📋 Sessions panel — the 会话 (Sessions) button opens a global viewport: every session (placed or in the background) with its status dot, reclaim countdown, and place / new-tab / terminate (two-click confirm) actions
  • ♻️ Host-owned sessions — closing the window, removing a view, refreshing the page, or switching conversations never kills your shells; they reattach with recent output replayed, a network blip reconnects automatically, and idle sessions are reclaimed after the configurable window (default 30 minutes) — the countdown is visible in the window's status strip
  • 🎹 Wave-style configurable shortcuts — Alt-based Wave preset (Alt+t new tab, Alt+w close the focused block / remove the focused member, Alt+Shift+w close tab / dissolve a group, Alt+1-9 switch tabs or focus a group member, Alt+m magnify); every action is configurable in 设置 → 插件 → 插件配置 → DSH-SSH-HUB (validated, DSH-conflict warning, applied immediately)
  • 🔑 Four auth methods per server: password, private key (with passphrase), SSH agent, or no-auth (local host keys)
  • 🚀 Connection testing before saving a server (latency + auth check); failures surface in-window with a classified reason and retry / edit actions instead of a raw alert
  • 🎨 Theme-aware terminals: the terminal follows the DSH GUI light/dark theme (falling back to the OS prefers-color-scheme when the theme service is absent), with a toolbar cycle button to pin 跟随界面 / 深色 / 浅色 (auto / dark / light) per browser. Open terminals hot-swap in place. Both palettes are held to WCAG contrast floors (foreground/background ≥ 7:1, ANSI colors ≥ 4.5:1) enforced in npm test
  • ⚙️ Settings card (DSH ≥ 0.1.0-rc.7): set default ready timeout, keepalive interval, host-key verification, terminal theme, and the session reclaim window in 设置 → 插件 → 插件配置; servers that leave a field blank inherit the default (server field > Server Default > built-in constant)
  • 🔒 Secrets handled safely: passwords and private keys are stored at rest only in the DSH home data dir (0600), are never returned by the API, and can be kept unchanged on edit
  • 🧪 Full backend integration test suite against a real SSH daemon

Requirements

  • DeepSeek Harness (DSH) Web GUI (tested on dsh ≥ 0.1.0-rc.7). The Server Defaults settings card requires 0.1.0-rc.7+; on older builds the panel works exactly as before, just without the settings card. The panel is bind-address agnostic: it works identically whether DSH listens on the default loopback 127.0.0.1:3080 or on 0.0.0.0 for LAN / reverse-proxy access — all requests are derived from the page origin, so no configuration is needed either way. See the security note below before exposing DSH on a non-loopback address.
  • Node.js ≥ 20 (the DSH runtime provides this)
  • The machines you connect to must accept SSH logins from the machine DSH runs on

Installation

From the GitHub repository (recommended):

dsh plugin --profile web add github:JUNQINGV587/dsh-ssh-hub
Git-hosted installs build the package on the spot, and pnpm blocks build
scripts by default. If the add fails with an "Ignored build scripts" error,
add the build key pnpm printed under allowBuilds in the profile's
pnpm-workspace.yaml, then re-run the add.

or from npm, once published:

dsh plugin --profile web add dsh-ssh-hub

or install from a local checkout:

dsh plugin --profile web add /path/to/dsh-ssh-hub

Restart DSH afterwards, refresh the browser, and the terminal panel is available.

Usage

  1. Click SSH 终端 at the sidebar foot, or press Ctrl+Shift+` — the Terminal Window opens (centred, remembered position/size). Double-click its title bar to maximize; Esc exits magnify/maximize one level (closing the window is the explicit ✕). Drag the title bar to move (it stays on screen), the corner handle to resize.
  2. Click 管理服务器 (Manage servers) → 添加服务器 (Add server) and fill in:
FieldDescription
名称 (Name)Display name, e.g. prod-db-1
端口 (Port)SSH port, default 22
认证方式 (Auth)password / privateKey / SSH Agent / none
远程初始目录 (Cwd)Optional initial working directory on the remote
Keepalive 间隔Optional, in seconds, 0 disables; blank = inherit the Server Default (default 30 s)

Use 测试连接 (Test) to verify before saving.

  1. Open a session: click the 新会话 (New session) button in the window's tab bar and pick a server (a session opens as its own tab; 加入当前 appends it to the active group). Or use the 会话 (Sessions) panel, or 管理服务器 (Manage servers) → click/double-click a row. The empty state guides you by what you have: no servers → 添加第一台服务器; servers but no sessions → 新会话; sessions in the background → 打开会话面板.
  2. Watch several at once: click the 新建组合 (New group) button, tick the sessions, and they open side-by-side. Or drag a tab onto another tab to merge them into a group, and onto a group's tab to append a member. Connect more servers with 加入当前 (Join current) to append them to the active group; drag the dividers to resize; magnify a member (hover it, or Alt+m) to fill the window. Drag members within a group to reorder them (before/after/swap); drag one out onto the tab strip to make it its own tab again. A group's ✕ dissolves it back into its member tabs.
  3. Sessions you're not watching: closing a tab removes the view only — the session keeps running on the host (a toast reminds you) and appears in the 会话 (Sessions) panel. From there you can place it back (放入当前 into the active item, or 新标签 as its own tab) or terminate it (终止, two clicks to confirm). A detached session shows its reclaim countdown in the panel.
  4. Type, select-to-copy, right-click-to-paste. Theme: the toolbar 跟随界面 / 深色 / 浅色 button cycles the terminal theme; remembered per browser, applied to every open terminal instantly.
  5. Your shells survive: closing the window, removing a view, refreshing the page, or switching conversations detaches the UI but the sessions keep running on the host, reattaching with recent output replayed. A brief network blip reconnects automatically. Closing a session for good: 终止 it in the 会话 (Sessions) panel (or delete the server). Sessions with no viewers are reclaimed after 30 minutes by default — the window is configurable in the settings card (会话回收时长), and the countdown shows in the window's status strip. If DSH restarts (sessions and layout live in memory), the window comes back empty — the status strip offers 恢复上次布局 (Restore last layout) to reopen the same sessions.
  6. Shortcuts are configurable: 设置 → 插件 → 插件配置 → DSH-SSH-HUB → 快捷键 (toggle window, maximize, new tab, close block, close tab, magnify). Values are validated, DSH conflicts warn (not blocked), and changes apply immediately.
  7. On DSH ≥ 0.1.0-rc.7, the same card also sets the Server Defaults blank server fields inherit — including a default terminal theme used when a browser's override is 跟随界面. The card's 管理服务器… link jumps straight to the window's server drawer.
  8. Moving to a new machine? Use 导出配置 (Export) / 导入配置 (Import) in the manage-servers dialog. The exported JSON contains no secrets — re-enter passwords/keys after importing. Import always adds entries as new servers and never overwrites existing ones.

Security notes

  • Credentials are stored in plaintext in $DSH_HOME/plugin-data/ssh-hub/servers.json (default ~/.dsh/…), written with mode 0600. File permissions are the only line of defense — do not commit, sync, or back up this file anywhere plaintext credentials would be unacceptable. Machine-key encryption was considered and rejected: a process running as your user could read the key anyway (see docs/adr/0001-credential-security-posture.md).
  • Switching a server's auth method deletes the credentials of the previous method from disk (e.g. switching to SSH Agent wipes the stored password).
  • The REST API never returns passwords or private keys — only hasPassword / hasPrivateKey flags. The export file follows the same rule.
  • WebSocket terminals are same-origin gated: cross-origin pages cannot connect to a session.
  • Connection attempts honor your server's host-key policy via strictHostKey (default off, or the Server Default you set); turn it on for stricter verification.
  • This is a trusted-host plugin: it runs arbitrary shell commands on the servers you configure, on behalf of whoever can reach the DSH web UI. Deploy DSH with proper access control.
  • Binding DSH to 0.0.0.0 (or any non-loopback address) exposes this panel to your network. The DSH webserver has no authentication by design, and the same-origin gate deliberately allows requests without an Origin header (non-browser clients) — so anyone who can reach the port (e.g. via a LAN IP) can list your configured servers (host/port/username) and open SSH terminals. If you need remote access, put DSH behind an authenticating reverse proxy or restrict the port at the firewall; do not rely on the same-origin gate as an access control.

Development

npm install
npm run build      # bundles lib/index.js (host) + lib/client.js (client) + lib/client.css
npm test           # integration tests against a local test sshd (see tests/)

# after bumping + committing a version, keep package.json / tag / release in sync:
npm version minor --no-git-tag-version && git commit -am "chore: bump version"
scripts/release.sh # tags HEAD, pushes, and creates the GitHub release

How it works

  • Host half (src/host/) is a cordis plugin (inject: ['webServer']) exposing a REST API under /ssh-hub plus per-session WebSocket upgrade routes. SSH is driven by ssh2. Terminal Sessions are host-owned: they survive any client detaching, keep a bounded scrollback ring (replayed on reattach), and are reclaimed after an idle window without viewers (default 30 min, configurable — src/host/registry.ts, src/host/scrollback.ts). The global item collection (tabs and flat groups) is served at /ssh-hub/workspace and broadcast over /workspace/events; dead-session items are dropped everywhere by the host.
  • Client half (src/client/) is a prebuilt React bundle: the Terminal Window renders in the shell.overlay slot (frame-wide, root scope), and a sidebar entry in sidebar.footer.action opens it. The flat groups (src/shared/group.mjs) and keybinding parsing (src/shared/keybind.mjs) are pure DOM-free modules. Terminals use @xterm/xterm.
  • Session data flows: xterm → ws → ssh2 stream → remote shell, and back. Windowed and maximized states attach to the same sessions (multi-client broadcast).

Integration tests

tests/integration.mjs spins up a mock of the DSH server (HTTP + WS), applies the plugin, and drives a real SSH session against a test sshd (default 127.0.0.1:2222, key auth). Override with SSH_TEST_HOST, SSH_TEST_PORT, SSH_TEST_KEY. See scripts/setup-test-sshd.sh for the CI-ready test daemon setup.

npm test runs scripts/check-contrast.mjs and scripts/check-splittree.mjs first (Terminal Theme contrast floors — see docs/adr/0002-adaptive-terminal-theme.md — and the pure split-tree rules), then the integration suite.

License

MIT © JUNQINGV587

使用前核对

安装步骤、兼容版本与授权范围以原项目当前文档为准。Stars 和评分是快照中的导航信号。

安装与排错 · 项目问题反馈

同类项目