DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

Plugin Mesh — DeepSeek Harness 插件(DSH Plugin)
← Plugins
P

dsh-plugin-mesh

Plugin Mesh

DSH 局域网 Mesh:自动发现同网段的其他 DSH 实例,提供对端操作页面,并支持跨机双向派发任务。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:peng456/dsh-plugin-mesh#b3fa9ad3198e2178ad91146d6901ccd3dced8f3f
README兼容性版本

兼容性与来源证明

Plugin Mesh 以 dsh-plugin-mesh 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

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

版本

0.2.0stable
2026/9/17

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

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

Headless@deepseek-ai/dsh-headlessdsh one-shot bundle:基于 dsh-base 的直接核心 Agent/Session 运行器,不包含 Host、HTTP 或浏览器层Experimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profile用于 Agent Teams Remote 和 UI 插件的实验性 Web 配置层Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序Subagent Claude Code@deepseek-ai/dsh-subagent-claude-code基于官方 Agent SDK 的一次性 Claude Code 子代理提供方

README

dsh-plugin-mesh

DSH 的局域网 Mesh 插件:启动后自动发现同一网段的其他 DSH 实例,在侧栏提供一个 操作页面显示各机器的在线状态,并支持把任务派给对端的 agent 执行。

用起来就是你要的那个效果:在 A 机器上开发,把「部署到 B」这件事丢给 agent, 你只下大命令。

零配置:固定端口 + 自动扫描 + ping,装上就能发现彼此,不需要配对码。 首次打开 Mesh 页面会让你给这台机器起个名字(默认填主机名),别的机器就靠这个名字找你。

┌──────── A 机器 (DSH) ────────┐          ┌──────── B 机器 (DSH) ────────┐
│  mesh 插件  :45917            │          │  mesh 插件  :45917            │
│   ├ UDP 组播心跳  ◀───────────┼──────────┼──▶  被动发现                  │
│   ├ 主动扫本网段  ────────────┼──────────┼──▶  兜底发现                  │
│   ├ ping 保活     ────────────┼──────────┼──▶  在线状态                  │
│   └ 侧栏 Mesh 页面            │          │                              │
│                               │───任务──▶│  唤醒本机 agent 执行          │
│                               │◀──回派───┤                              │
└───────────────────────────────┘          └──────────────────────────────┘

发现机制:两条互补的路

只靠组播是不够的 —— 很多路由器/AP 会隔离客户端组播,Windows 防火墙默认也拦入站组播。 所以这里同时用两条路,任一条通就能发现:

路径做法优点缺点
组播心跳每 5s 向 239.255.42.99:45892 广播,同时监听零配置、即时、不产生额外连接可能被路由器/防火墙挡掉
主动扫描并发 GET 本网段每台机器的 :45917/mesh/v1/health只要 TCP 通就能成,最可靠扫一次约 1~2 秒;254 个地址

再加一条ping 保活:每 10s GET 已知对端的 /mesh/v1/health,刷新在线状态。 这条让"发现"一旦建立就不再依赖组播 —— 即使组播完全不通,扫描见过一次之后也能一直维持。

扫描时机:启动时(带退避重试,因为常抢在对方启动之前)+ 每 60s 一次 + UI 上手动触发。

默认端口 45917。固定端口是"扫一下就能连上"的前提。同机跑多个实例时端口会被占用, 此时自动退回随机端口(组播仍能找到,但主动扫描扫不到它)。

组播的作用范围:比"局域网"更窄

239.255.42.99:45892 是我在私有组播段里挑的(239.0.0.0/8 是 RFC 2365 定义的 管理范围,相当于组播里的"私有地址"),TTL 设为 1,所以:

  • ✅ 同一网段(同一个二层广播域)内有效
  • ❌ 路由器不转发 —— 跨子网/VLAN 到不了,那种情况要配 scanRanges
  • ❌ AP isolation 会连它一起挡(那是把客户端之间的所有流量都隔离,不只是组播)
  • ⚠️ 部分交换机的 IGMP snooping 在没有 querier 时会丢掉组播
  • ⚠️ Windows 防火墙默认拦入站组播,要放行 UDP 45892

正因为组播有这么多坑,才加了扫描那条路:只要 TCP 通,扫描就能发现。


身份与命名

每台机器有两个标识,分工不同:

标识是什么稳定性用途
instanceId启动时随机生成的 8 字节 hex每次启动都变内部用:去重、识别"这条是我自己发的"
machineName人可读的名字,如 客厅的Mac持久保存你和 agent 用它指代这台机器

名字解析优先级:插件配置 machineName > 用户首次启动时填的 > 系统主机名。

首次启动时(还没命名过、落在主机名上)Mesh 页面会主动问你一次:输入框预填主机名, 点「就这个」直接用,或改成你想要的名字。名字存在 $DSH_HOME/mesh/state.json (和配对码同一个文件,权限 0600),改完立刻重新广播,对端不用重启就能看到。

重名怎么办

名字是人手填的,可能撞。页面会检测并告警,派发时也不会随便挑一台:

  • 从 A 看:--peer winbox 只要在 A 的上游对端里唯一就能用(自己不算)
  • 从第三台机器看:如果它发现有两台都叫 winbox,mesh_run 会拒绝并列出候选, 让你改用 <ip>:<port> 精确定位

地址也接受实例 id 或 ip:port,所以撞名时总有办法精确指定。


实测验证状态

以下都在真实 DSH host 上跑出来(临时 DSH_HOME,未动你正在用的应用):

项目结果
配置装配进 profile✅ --dump-config 含本项目两行
插件加载、apply 执行✅ 挂载 5 个 UI 接口、注册 4 个工具
两个真实 DSH 互相发现(仅扫描,组播全关)✅ 双向,24 秒内(含启动竞态重试)
两个真实 DSH 互相发现(组播开)✅ 双向,1 秒内
零配对派发任务✅ ok: true,全程没有任何配对操作
对端 agent 被唤醒✅ 建了 mesh-* 会话,17 个事件,含任务提示词 + 线程 + 回派指令,turn/start → assistant/attempt
离线判定✅ 杀掉对端后约 20 秒标记离线(ttl 20s)
固定端口被占用 → 回退✅ 配置 45919、实际 63570
requirePairing: true 时✅ 错误 token → 403;正确 token → 200
首次启动询问名字✅ 未命名时 needsName=true,输入框预填主机名
改名立刻传播✅ 改完 2 秒内对端就看到新名字(立即重新广播)
名字持久化✅ 存 state.json,重启后仍是 客厅的Mac / source=saved
名字校验✅ 空、含 /、超 32 字符均被拒
配置优先✅ 配置里写了 machineName 时改名返回 409,不静默覆盖
重名检测✅ 两端 duplicateNames 均正确列出
客户端 bundle 被提供✅ 出现在 __DSH_BOOT__,路由 200,内容与源码逐字节一致
UI 页面渲染✅ 机器列表 / 任务记录两个 tab
不花你的 token✅ 测试环境无模型密钥,agent 止步于 no API key

没验证的(如实说明):

  • 没在你正在运行的 DSH Desktop 里验证 —— 需要重启应用,会掐断本次会话。 用 dev-boot.mjs 复现了真实主进程的模块解析行为来代替。
  • Windows 侧没跑(手上没那台机器)。代码跨平台,但 Windows 防火墙要放行 TCP 45917 和 UDP 45892。
  • 扫多端口(scanPorts)是我为了在同机测试才加的,真实两机场景用不到。

安装

两台机器都装。装完必须重启 DSH Desktop 才会加载。

方式 A:一键脚本(推荐)

git clone https://github.com/peng456/dsh-plugin-mesh.git
cd dsh-plugin-mesh
./install.sh

脚本做两件事,且可重复执行(已装就跳过):

  1. 把插件复制到 ~/.dsh/profiles/desktop/node_modules/dsh-plugin-mesh/
  2. 把它加进该 profile package.json 的 dsh.profile.bundles (改前自动备份为 package.json.bak)

常用选项:

./install.sh --dry-run              # 只打印会做什么,不落盘
./install.sh --profile web          # 装到别的 profile
./install.sh --home /path/to/.dsh   # 指定 DSH_HOME
./install.sh --uninstall            # 卸载(删目录 + 从 bundles 移除)

方式 B:手动装

# macOS
cp -R dsh-plugin-mesh ~/.dsh/profiles/desktop/node_modules/dsh-plugin-mesh

# Windows (PowerShell)
Copy-Item -Recurse dsh-plugin-mesh "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-plugin-mesh"

然后在 ~/.dsh/profiles/desktop/package.json 的 bundles 里加上 "dsh-plugin-mesh":

{
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-plugin-mesh"],
      "patchReload": "live"
    }
  }
}

⚠️ 必须是真实目录,不能是软链。 DSH 的 profile 包解析器会拒绝 realpath 落在 <profile>/node_modules 之外的包(module-resolution-*.js 里那条判断, 目的是防止陈旧的外部状态覆盖已封装安装)。把插件软链到你的工作目录会在启动时 报 ERR_MODULE_NOT_FOUND。install.sh 已经处理好了这一点。

方式 C:官方命令(用 DSH Desktop 自带的终端)

托盘/菜单 → 终端:

dsh plugin add /path/to/dsh-plugin-mesh

注意 dsh plugin --profile desktop 在普通终端里会被拒绝 (bin.js:29:profile "desktop" is managed exclusively by the Electron application), 必须用应用自带的那个终端。

Windows 防火墙

New-NetFirewallRule -DisplayName "DSH Mesh" -Direction Inbound -Protocol TCP -LocalPort 45917 -Action Allow
New-NetFirewallRule -DisplayName "DSH Mesh (multicast)" -Direction Inbound -Protocol UDP -LocalPort 45892 -Action Allow

只放行 TCP 也行 —— 那时靠主动扫描发现,不依赖组播。

使用

侧栏会出现一个 Mesh 图标(三个节点连成的网状),点开是主页面:

  • 本机信息:机器名、地址、端口、当前发现方式与配对要求
  • 发现的机器:每台一行,在线绿点/离线灰点,显示地址、系统、用户、最后心跳; 每行「探测」和「派发任务」
  • 扫描本网段 / 重新广播 按钮
  • 派发任务:选目标机器 → 填任务 → 派发
  • 任务记录:收到 / 派出的任务
  • 配对码(折叠,默认不需要)

agent 多出四个工具:

工具作用
mesh_peers列出发现的机器
mesh_scan主动扫本网段,找还没发现的机器
mesh_run把任务派给某台机器的 agent(异步)
mesh_tasks查看收到/派出的任务记录

所以你可以直接说:

「看看局域网里有哪些机器,然后让 B 把 web 服务重新部署一下,跑完告诉我。」


工作原理

唤醒:自包含实现,不依赖额外插件

agent 没有事件循环,只在有回合时才思考。所以收到对端任务后,必须建一个会话并让它跑起来。

DSH 提供了官方插件 @deepseek-ai/dsh-webhook 做这件事,但本插件没有用它,理由:

  1. 它不在任何默认 bundle 里,靠补丁替用户插一行,会让"装一个插件"变成配置里两行,困惑
  2. 更实际的问题:万一它已经被启用(比如你以后装了 GitHub webhook 插件), cordis 的 provide 遇到重名会直接抛错(service "webhookRuntime" has been registered at <...>), 而且那是在它的构造函数里,本插件的安全网拦不住

所以这里按官方 createWebhookSession 的做法自己走一遍,用到的都是 DSH 基础服务 (桌面 profile 本来就全都有):

ctx.permissionPresets.resolve / set      校验并设置权限 preset
ctx.agentPresets.resolve / mount         解析并挂载 agent preset
ctx.workspaceRegistry.create             建/取工作区
ctx.agents.create                        建 Agent
ctx.sessionTitle.rename                  给会话起名
ctx.agentDefaultModel.currentSelection   取默认 provider/model
agent.followup(createUserMessage(...))   ← 这一步才是"唤醒"

服务齐备时才启用(用 ctx.inject([...]) 探测);缺任何一个就降级为"只收件不唤醒", 并在日志里说明缺了什么。插件是自包含的,profile 里只多一行。

为什么发现要两条路

我先只做了组播,后来加扫描,是因为组播在真实家庭网络里失败率比想象中高: AP isolation、Windows 防火墙默认策略、跨 VLAN,任何一个都能让它静默失效。 而"TCP 直连固定端口"只要网络通就能成。


配置项

默认已经可用。要改就在 profile 的 cordis.patch.yml 里按 id 覆盖 (注意:patch 是整体替换 config,所以要把想保留的项一起写上):

- id: mesh
  config:
    machineName: ''            # 对端列表里的名字,留空用主机名
    port: 45917                # 固定端口
    useMulticast: true         # 组播被动发现
    scanOnStart: true          # 启动扫描(带退避重试)
    scanIntervalMs: 60000      # 周期扫描;0 = 关闭
    scanRanges: []             # 额外网段,如 ["192.168.1.0/24"];空则扫本机 /24
    scanPorts: []              # 除本机端口外额外要扫的端口
    scanConcurrency: 64
    scanTimeoutMs: 800
    pingIntervalMs: 10000      # ping 保活;0 = 关闭
    announceIntervalMs: 5000
    peerTtlMs: 20000           # 多久没消息算离线
    requirePairing: false      # 见下
    agentPreset: standard
    permissionPreset: workspace-write
    workspaceRoot: ''

安全

默认不需要配对 —— 同一内网里任何发现到本机的 DSH 都能派发任务。 对本机 agent 而言,这些任务会被当成一条用户消息(默认权限 workspace-write: 能读写工作区、能执行命令)。

这在自己家的可信内网里是合理取舍,也正是你要的"零配置"。但如果你在 不完全可信的网络里(合租、公司、宿舍、有访客设备、IoT 设备多),请打开:

- id: mesh
  config:
    requirePairing: true

然后在两台机器的 Mesh 页面里互相对一下配对码(首次启动自动生成,页面上可直接复制)。 打开后所有控制接口都要过配对码,用 timingSafeEqual 比较。

其他:

  • 发现是公开的:同一网段任何人都能看见机器名、地址、系统、用户名。这是有意的取舍。
  • 明文 HTTP:局域网内可接受;跨不可信网络请套 SSH 隧道或 TLS 反代。

已知限制

  1. 每次派发新建一个会话,不续接原对话。
  2. 去重只在进程生命周期内(内存),重启后同 id 会重复入箱。
  3. 没有离线排队:对端离线时 mesh_run 直接失败,不暂存重投。 (要这个能力可以用工作区里的 lanmsg.py。)
  4. 同机多实例:第二个实例端口被占会退回随机端口,主动扫描扫不到它(组播仍能发现)。 真要同机多实例,给它们配不同 port 和对方的 scanPorts。
  5. sidebar.panellist 槽位官方插件没人用过(翻遍 58 个客户端 bundle,只有官方侧栏 自己声明它)。我按源码契约接的,实测注册和渲染都正常,但不如 sidebar.footer.action 那样有第三方先例。

开发与测试

# 搭隔离环境(把插件真实复制进 profile,不碰你的 desktop profile)
MACHINE=macbox PORT=45917 MULTICAST=false SCAN_PORTS="[45918]" \
  ./dev-setup.sh meshtest /tmp/mesh-dsh

# 启动(dev-boot.mjs 复现真实主进程的模块解析行为)
DSH_HOME=/tmp/mesh-dsh ELECTRON_RUN_AS_NODE=1 \
  "/Applications/DSH Desktop 2.app/Contents/MacOS/DSH Desktop" \
  dev-boot.mjs --profile meshtest --port 8877

dev-setup.sh 支持的环境变量:MACHINE PORT MULTICAST SCAN_ON_START SCAN_PORTS PING_INTERVAL_MS REQUIRE_PAIRING。

为什么需要 dev-boot.mjs:desktop-cli.js:78 只在 app.asar 内才安装 profile 包解析器,而这个安装是未打包的 Resources/app。真实 Electron 主进程 (main.js:4478)是无条件安装的,所以真实应用没这个问题,只有 CLI 路径有。

发现模块可以脱离 DSH 单独测:

node lib/_selftest-discovery.mjs alpha 45900 9000   # 两个进程同时跑可验证互相发现

文件结构

dsh-plugin-mesh/
├── package.json           # dsh.bundle.patch + dsh.client 声明
├── cordis.patch.yml       # 只插入本插件(含默认配置)
├── lib/
│   ├── index.js           # 主机侧:发现编排 + 对端 HTTP + agent 工具 + UI 接口 + 入站唤醒
│   ├── discovery.js       # UDP 组播被动发现 + 对端注册表 + 过期清理
│   ├── scan.js            # 主动扫描(固定端口 + CIDR 展开)
│   └── _selftest-discovery.mjs
├── client/
│   └── client.js          # 浏览器侧:手写 bundle,无需打包工具
├── dev-setup.sh           # 隔离测试环境搭建
├── dev-boot.mjs           # 带模块解析器的测试启动器
└── README.md