dsh-ssh-shell

DSH PLUGIN会话与消息

仓库 framecy/dsh-ssh-shell

会话与消息 未标注验证等级 安全审查:未标注 可信度:未标注 可安装插件

为 DeepSeek Harness 提供密码直连远程主机的 SSH 终端插件:自然语言工具配合浏览器浮动终端面板,基于 ControlMaster 常驻会话,断连可自愈。

一句话选型结论

按资料字段整理

dsh-ssh-shell 是会话与消息类的 DSH 可安装插件,未做沙盒验证,暂无安全审查结论,列出 5 项功能,没有现成安装命令,需要按仓库 README 接入。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类会话与消息 收录类型可安装插件 验证等级未标注验证等级 安全审查未标注
验证等级 UNKNOWN 未标注验证等级
GitHub 星标 1 复刻 0 · 未关闭 issue 未标注
最近更新 2026-10-11 创建于 2026-09-22
README 12.3 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名未发布到 npm可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-ssh-shell:DeepSeek Harness 里用密码直连远程主机的 SSH 终端

  • 自然语言 SSH 工具执行远程命令
  • 浏览器浮动终端面板真实 PTY
  • ControlMaster 常驻会话断连自愈
  • 面板隐藏或刷新不断开连接
  • 凭据仅存当前标签页不落盘

上游标签

controlmasterdshdsh-pluginnode-ptysshssh-clientterminal

验证等级与安全审查

未标注验证等级
自动化流程结论,不是人工审核
验证等级未标注验证等级上游未给出验证结论,安装前请自行确认
安全审查未标注静态分析结论,未标注不代表已通过审查
仓库健康度未标注按仓库活跃度与最近更新时间给出
可信度未标注综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 安全审查还没结论,装之前先看仓库改了什么、要什么权限。
  • 没有现成安装命令,要按仓库 README 手动接入。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在会话与消息场景里给 DSH 补能力的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-ssh-shell当前 未做沙盒验证 未标注 1 未标注 无
dsh-desktop L3 · 安装规范通过 低风险 3.0 万 未标注 无
openpets L4 · 沙盒安装通过 低风险 1,274 未标注 有
deeptide L4 · 沙盒安装通过 低风险 1,104 0.1.1-rc.2 有
jingyun-dsh L3 · 安装规范通过 低风险 1,004 未标注 有
study-mate 未做沙盒验证 未标注 856 未标注 无

仓库档案

会话与消息
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方framecy仓库 dsh-ssh-shell · 默认分支 未标注
分类会话与消息remote
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证Apache-2.0商用或二次分发前请确认条款原文
星标 / 复刻 / issue1 / 0 / 未标注收录时的数值,非实时
创建 / 更新2026-09-22 · 2026-10-11最后推送 未标注
本站收录2026-09-29首次进入本站目录的时间

README 全文

12.3 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-ssh-shell

DSH 插件:用密码直连远程主机的 SSH 终端。一个自然语言工具(connect / exec / close / status)+ 浏览器右侧浮动终端面板,底层是 OpenSSH ControlMaster 常驻会话 + sshpass + node-pty 起的真实 PTY,经 WebSocket 桥到浏览器。

核心目标:不再频繁断连,断了能自己回来。

能力

  • SSH 工具(对话里用):ssh_remote 一次建立连接,之后每次远程命令都先向用户确认;ssh_terminal_send / ssh_terminal_read 直接操作面板里那个活的终端,不逐条确认。
  • 浏览器终端面板:右侧浮动面板,真实 PTY —— 原始终端模式、方向键、全屏程序、Ctrl+C / Ctrl+D / Tab 补全都正常。
  • 一眼看出连接状态:入口竖条自己的描边就是状态指示 —— 灰=未连接、琥珀(呼吸)=连接中/重连中、绿=已连接、红=连接断开,不用打开面板。
  • 断连自愈:
  • ControlMaster + ControlPersist=yes —— master 常驻,不闲置回收;
  • SSH 双保活:ServerAliveInterval=30 + TCPKeepAlive=yes,抗 NAT / 防火墙 / sshd 掐断静默连接;
  • WebSocket 空闲看门狗:25s 一次 ping,60s 无响应即断开这个客户端(不动 pty);
  • pty 意外退出而 master 还活着时原地重建,订阅者自动迁移(最多 3 次);
  • 前端自动重连:最多 3 次,每次间隔 10 秒;可手动「停止重连」,用尽后自动停下并说明原因。凭据存当前标签页。
  • 面板隐藏不断线:折叠面板只切 display:none,socket 和 pty 都活着,展开即续。

安装

前置条件:已经装好 DSH(DeepSeek Harness),并且有一个能跑的 profile(下面以 web 为例)。

方式一:从 GitHub 安装(推荐)

dsh plugin --profile web add github:framecy/dsh-ssh-shell

装完重启该 profile。仓库根目录的 cordis.patch.yml 会被自动应用,不需要手工编辑配置。

方式二:本地开发(软链接)

改代码即生效,适合调试:

git clone https://github.com/framecy/dsh-ssh-shell.git
ln -s "$PWD/dsh-ssh-shell" ~/.dsh/profiles/web/plugins/dsh-ssh-shell

然后在 profile 的 cordis.patch.yml 里手工挂上这一行。这种本地路径方式必须写相对路径,不能写包名(包名只在 dsh plugin add 装好之后才解析得到):

- insert:
- id: ssh-shell
name: './plugins/dsh-ssh-shell/lib/index.js'

重启 DSH

插件只在进程启动时加载,改完必须重启:

# 停掉当前的 dsh 进程(Ctrl+C,或 kill 掉对应 pid),然后重新启动
dsh web

重启后浏览器刷新页面(前端 client.js 是页面加载时取的)。

> 装好后,右侧边缘会出现「终端」竖条(唯一入口,点它即可打开面板,不占会话头部空间)。

> 工具名为什么带 ssh_ 前缀:DSH 自带的终端插件已经占用了
> terminal_open / terminal_send / terminal_read / terminal_signal /
> terminal_close / terminal_list 这六个名字。ctx.tools.register() 遇到重名会抛错,
> 而抛错发生在 apply() 里会让宿主把整个插件判为「未激活」——表现就是
> 面板能连、后端完全正常,但对话里没有 ssh_remote 工具。
> 所以本插件的工具统一加前缀:ssh_remote / ssh_terminal_send / ssh_terminal_read。
> 内置那套终端工具操作的是 DSH 自己的终端,不是本插件的 SSH PTY,别混用。

插件启动时还会把自带的技能装到 $DSH_HOME/skills/ssh-shell/SKILL.md(默认 ~/.dsh/skills/)。
装插件就自动带上技能,不需要手工复制。技能告诉 agent:面板连上的会话和它自己连的会话是同一批,
先查 ssh_remote action=status 再说话。不想让它管技能就在配置里设 installSkill: false。

前置依赖

依赖 说明
ssh OpenSSH 客户端,提供 ControlMaster
sshpass 非交互密码认证。brew install sshpass(需要 keepalive tap)或 brew install esolv/sshpass/sshpass
node-pty 后端起 PTY 用;作为本插件的依赖自动安装,无需手工处理

缺 sshpass 时连接会直接失败并给出明确报错。

配置

cordis.patch.yml 提供这些配置项(由插件自身的 bundle patch 声明,profile 级 cordis.patch.yml 可按 id 覆盖):

配置 默认 说明
controlDir "" → ~/.dsh/ssh-shell ControlMaster socket 存放位置
timeoutMs 30000 单条命令默认超时
controlPersistSeconds "" → yes 留空 = master 常驻直到自己死;填秒数 = 闲置这么久后回收
installSkill true 启动时把自带技能装到 $DSH_HOME/skills/ssh-shell/

远程命令始终逐条向用户确认(走 DSH 的 approval 通道),没有关闭它的开关——这是刻意的:确认是安全边界,不该被一个配置项悄悄关掉。

> 桌面版(DeepSeek Harness.app):桌面版把页面加载在自有协议 dsh-app://app/ 下,
> 该 origin 下 location.host 是 "app"、无法用作 WebSocket 主机名。插件改为读取
> 桌面外壳发布的真实 Host origin(window.__DSH_TRANSPORT__.streamBaseUrl)再拼
> /ssh-terminal——桌面版每次启动用 --port 0 随机端口,写死端口会在下次启动就失效。
> 只有当该 origin 取不到时才回落到旧的固定端口 127.0.0.1:19387;仍可用
> window.__DSH_SSH_SHELL_WS_HOST__ = "127.0.0.1:" 手工覆盖。

用法

对话里(工具)

> ssh root@1.2.3.4 -p 22,密码 xxx,连上后看一下 /var/log 里最近的报错

第一次连接不确认;之后每条远程命令都会把确切命令写出来让你确认。长时间任务传 run_in_background: true,用 job_output 增量读。

面板(GUI)

点右侧边缘的「终端」竖条(唯一的入口)。填 root@1.2.3.4 -p 22 + 密码,连接。

  • 面板是个浮动窗口:拖标题栏移动位置,拖四条边或四个角调整大小(最小 340×240,不会超出可视区域,也拖不到屏幕外);
  • 尺寸和位置记在当前标签页,刷新后还在;窗口变小时面板会被拉回可视区域内;
  • 拖动结束即把新的行列数同步给远端 PTY,全屏程序(vim / top / htop)跟着变;
  • 竖条自身的描边就是连接状态指示(竖条贴着屏幕右缘,所以只有上/左/下三边有描边,右边留空):
    灰色 = 未连接,琥珀色(发光呼吸)= 连接中/重连中,绿色(淡淡发光)= 已连接,红色(淡淡发光)= 连接断开;
    鼠标悬停在竖条上也能看到文字说明;
  • 最小化面板不会断开 SSH;
  • 断线会自动重连,最多 3 次、每次间隔 10 秒,进度写在面板上;
  • 重连过程中可随时点标题栏的「停止重连」取消;3 次用尽后会自动停下并说明原因,
    不会无限重试,需要时点「重连」再试;
  • 只有「断开」按钮和 master 真的死了才会结束会话。

凭据只存在当前标签页(sessionStorage),关掉标签页即清除,不会写到磁盘。

面板连上的会话,对话里也看得见

这是本插件最容易踩的坑:面板和对话工具过去可能各自持有一份会话表,于是面板里明明连着、
agent 却回「没有会话」。现在两者共用同一份进程级会话表,并且:

  • ssh_remote action=status 会同时列出面板连上的会话,标 source: "gui-panel";
  • 面板会话已经认证过,不会再问密码,直接 ssh_terminal_send / ssh_terminal_read 操作;
  • 对面板会话跑 ssh_remote exec 会直接接管那条会话,不需要重新 connect。

agent 在说「没有会话」之前必须先查 status——这条约定写在插件自带的
skills/ssh-shell/SKILL.md 里,装插件时自动生效。

工具速查

三个工具,别和内置的 terminal_* 混用(那套操作 DSH 自己的终端):

工具 干什么 要确认吗
ssh_remote connect / exec / close / status。自己连会话、跑一次性命令 exec 每条都确认
ssh_terminal_send 往面板里那个活终端敲键盘(data: "ls\r") 不确认
ssh_terminal_read 读那个终端最近的输出(可 clear: true 读增量) 不确认

常用写法:

ssh_remote          { action: "status" }                          # 先看有什么会话
ssh_remote          { action: "connect", target: "root@1.2.3.4 -p 22", password: "..." }
ssh_remote          { action: "exec", target: "root@1.2.3.4", command: "df -h" }
ssh_remote          { action: "exec", command: "tail -f /var/log/nginx/error.log", run_in_background: true }
ssh_terminal_read   {}                                            # 面板终端当前停在哪
ssh_terminal_send   { data: "systemctl status nginx\r" }          # 回车 = \r
ssh_terminal_read   { clear: true }                               # 读增量

转义:\r 回车、\x03 Ctrl+C、\x1b[A 上箭头、\t Tab 补全。

设计取舍

pty 归属于 target(user@host:port),不归属任何单个 WebSocket。理由:

  • 面板折叠、页面刷新、切 tab、网络抖动都不该杀掉远端 shell;
  • 只有显式 type:"close" 或 master 死亡才真正结束;
  • master 活着时浏览器永远不需要重新输密码。

会话表挂在 globalThis(Symbol.for("dsh-ssh-shell.shared"))上,而不是模块常量。
因为 DSH 可能在同一进程里加载本插件两次(宿主自己一份 + 插件管理器为验证更新加载已安装副本),
模块常量会让两份各自持有一个空 Map——这正是「面板连上了但会话无法识别」的根因。

测试

npm install       # 首次:装 ws / node-pty(npm 会因 peer 报 ERESOLVE,加 --legacy-peer-deps)
npm test          # 跑三套测试,不需要 @deepseek-ai/dsh-tools

> 插件不依赖宿主注入才能加载。@deepseek-ai/dsh-tools 只导出
> defineTool = (definition) => definition —— 一个纯恒等函数。lib/index.js 自带同名实现,
> 所以插件在只装了 ws + node-pty 的环境里也能 import 并 apply(),
> 跑测试不需要宿主的模块拦截层在场。
> package.json 里仍保留 peerDependencies 声明,仅用于表达版本兼容意图
> (宿主会读它并为同名裸模块建 interception 路由,但本插件已不再走这条路)。
> scripts/link-host-deps.mjs 与 pretest 是早期遗留物,测试已不需要它们。

不需要真实 sshd、不需要网络。测试用假的 ssh / sshpass / node-pty 替换进程边界,
让插件的真实逻辑(目标解析、脚本拼装、工作目录探测、pty 生命周期、WebSocket 扇出、
几何钳位)照常运行。

文件 覆盖 断言数
tests/core_test.mjs target 解析、shell 引号转义、cwd 探针封帧与提取、ANSI 清洗、ControlPersist 取值、socket 路径长度约束、跨实例共享状态、技能安装 68
tests/terminal_test.mjs 路由注册、未连接时的输入容错、连接失败回报、pty 扇出与重挂载、订阅者隔离、面板会话对 status / ssh_terminal_read / ssh_terminal_send 可见、工具重名不拖垮插件 53
tests/client_test.mjs 前端可加载性(CJS shim 回归)、单槽位注册、store 订阅契约、连接状态镜像与描边状态色、WebSocket 地址解析、有界重连策略、几何钳位与持久化 114

SSH 保活选项已用 ssh -G 验证被 OpenSSH 接受。

依赖是怎么声明的

包 声明位置 原因
node-pty、ws dependencies 本插件自己要用的库,安装时随插件一起装
@deepseek-ai/dsh-tools peerDependencies 由 DSH 宿主提供,插件不重复打包一份

装好插件后运行时不需要手动 npm install——依赖由安装器处理,@deepseek-ai/dsh-tools 则由 DSH 自己的安装树提供。npm install 只在你想跑测试时才需要。

版本

见 CHANGELOG.md。当前 0.7.4。

License

Apache-2.0 © 2026 framecy

常见问题

7 问
答案由本站依据条目字段整理,不引用上游原文
dsh-ssh-shell 怎么安装?

本站没有抓到该条目的安装命令,请到仓库主页确认安装方式;这类条目多数是生态应用或尚未发布安装包的项目。

dsh-ssh-shell 的验证等级是什么意思?

未标注验证等级。上游未给出验证结论,安装前请自行确认

dsh-ssh-shell 安全吗?

未标注。

dsh-ssh-shell 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-ssh-shell 用的是什么许可证?

上游标注为 Apache-2.0。商用或二次分发前请到仓库确认许可证原文。

dsh-ssh-shell 有哪些功能?

自然语言 SSH 工具执行远程命令、浏览器浮动终端面板真实 PTY、ControlMaster 常驻会话断连自愈、面板隐藏或刷新不断开连接、凭据仅存当前标签页不落盘。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

会话与消息
按星标排序,可作替代方案

dsh-desktop

dsh-desktop

为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。

L3 · 安装规范通过 3.0 万 星

openpets

openpets

L4 · 沙盒安装通过 1,274 星

deeptide

deeptide

L4 · 沙盒安装通过 1,104 星

jingyun-dsh

jingyun-dsh

井云 DSH 客户端插件,为 DeepSeek Harness 注入会员登录、订阅支付、算力管控与应用市场,让智能体和技能快速变成可交易商品

L3 · 安装规范通过 1,004 星

study-mate

study-mate

StudyMate 是 DSH 的「学习模式」预设与技能包,为数学、计算机科目定制学习路线、讲解课件与练习评估,跨科目共享记忆。

未标注验证等级 856 星

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。