DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Proxy Client — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

@jaxzhou/dsh-proxy-client

Proxy Client

DeepSeek Harness plugin: connects this terminal's local dsh web to a dsh-proxy-server and lets the same account's other ends reach it through that server (reverse access). Signs in with the textwork.cn account (phone + SMS code, or username + password), a

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add @jaxzhou/dsh-proxy-client@0.4.1
READMECompatibilityVersions

Compatibility and provenance

Proxy Client is published as @jaxzhou/dsh-proxy-client and currently resolves to version 0.4.1. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
10/16/2026

Versions

0.4.1stable
9/19/2026
0.4.0stable
9/19/2026

Related plugins

Loading related plugins…

Latest
0.4.1
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
100.6 kB
Files
17
Surface
web
License
MIT
Source
npm
GitHub
★ 0
Weekly downloads
10
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in integrations-communication.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseAb Publishdsh-ab-publishBrowser-automation publishing tool that logs into and posts to arbitrary websites, in one publishable plugin packageAb Wechat Scrapedsh-ab-wechat-scrape--- description: "The out-of-tree wechat_scrape tool: retrieves WeChat official-account articles, filters promotional blocks, and saves each as a Markdown file, for maintainers of this machine's dsh profiles." kind: "package-reference" ---Remote Web Ui@linxin666/dsh-remote-web-uiScan-to-pair remote access for the dsh web GUI that shares one official interface: a QR beside the settings button pairs phones and PCs into the same Web GUI (a portrait-touch adaptation layer for phones, full desktop on PCs) through one-time tokens and r

README

@jaxzhou/dsh-proxy-client

dsh-proxy 的 DSH 客户端插件包(npm 包名 @jaxzhou/dsh-proxy-client,本地目录 packages/dsh-proxy-client):把本机终端里的 dsh web 通过 dsh-proxy-server 反向暴露给同账号的其它端,并提供 GUI 配置页面。

  • 宿主半(lib/index.js,cordis 插件):本地配置/令牌存储、出站 WebSocket 持久连接与自动重连、把服务器开出的虚拟流桥接到 ctx.webServer.port 上的本机 dsh web、注册面板 API。零运行时依赖(用 Node 内置 WebSocket)。
  • 浏览器半(lib/client.js,window.__ModuleLoader__ bundle):侧边栏底部入口 + 键控 main 面板,提供服务器地址、与 textwork.cn 相同的账号登录(手机号+短信验证码 / 账号密码)、连接开关、设备列表与「切换到此端」。

账号与 textwork.cn 一致:手机号 + 短信验证码(含京东云人机验证),或账号密码。登录由代理服务器 内部转调 textwork.cn 后端完成;本机只保存服务器签发的长效 token(默认 30 天),密码不落盘。

安装

# 在跑 dsh web 的机器上(包内声明了 dsh.bundle,安装后自动加入 profile bundles 并激活)
dsh plugin --profile web add @jaxzhou/dsh-proxy-client    # 从 npm
dsh plugin --profile web add <仓库路径>/packages/dsh-proxy-client   # 或从本地目录(开发时)
dsh --profile web          # 重启后生效

启动日志出现下面两行即装载成功:

[dsh-proxy-client] panel API ready; local dsh web on 127.0.0.1:3080
[dsh-proxy-client] not connected yet - configure the server address and log in from the DSH sidebar panel

若把包作为普通依赖安装(不带 bundle 声明),需在 profile 的 cordis.patch.yml 手工加入:

- insert:
    - id: jaxzhou-proxy-client
      name: '@jaxzhou/dsh-proxy-client'

⚠️ 不要同时使用两种方式:本包自带的 bundle 层会插入同一行;重复的 loader entry id 会让 dsh web 启动失败(duplicate loader entry id: jaxzhou-proxy-client)。如果你以前手工加过这一行,升级/安装本包后 请把手工行删掉(profile 的 cordis.patch.yml 恢复为 [])再重启。

故障隔离(远端不可用时不影响 DSH)

本插件是可选增强:代理服务器宕机、网络不可达、服务器地址写错、甚至本地配置文件不可写, 都不应影响 DSH 本体和其它插件。为此:

风险处理
启动时阻塞apply() 不做任何网络 I/O;首次连接用 setTimeout(0) 推迟到启动路径之外,DSH 启动不等待本插件
连接挂死连接阶段有 20s 上限(connectTimeoutMs,含 TCP/TLS/WS 升级);握手另有 10s 上限;超时即放弃并按指数退避重试(1s → 30s)
关闭卡住stop() 最多等 3s(stopTimeoutMs),并用 generation 计数让被放弃的旧循环彻底失效,不会出现双循环
未处理 rejection 杀掉进程连接循环、重连、事件回调、节流定时器全部自带捕获;后台任务绝不以 rejection 收尾(unhandled rejection 在现代 Node 上是致命错误,会连带杀掉 DSH)
同步抛错破坏插件树apply() 整体不抛:面板路由注册失败只损失面板、隧道照常;配置存储不可用则整个插件安静退出
配置文件不可写读/写/解析失败一律降级为内存配置(store.lastError 记录原因,日志提示一次),插件继续可用
GUI 渲染异常插件注入的两个 slot 都包在错误边界里:本插件面板崩溃只会显示一块「已隔离」小卡片,不会白屏 DSH 或影响其它插件 slot
面板请求挂住浏览器半的每次调用有 30s 上限;宿主半的面板 API 对上游请求有 20s 上限,服务器不可达时快速返回类型化错误(含上游状态码)
日志刷屏连接失败只在状态变化时记录,退避到 30s 后每分钟最多两条
进程无法退出插件创建的所有定时器都 unref(),不会阻止 DSH 正常关闭

对应的自动化断言见 npm run e2e 的「resilience: remote server unavailable」一节(93 项断言内)。

配置页面

入口在 侧边栏底部、设置(Settings)行正上方:一个「远程访问」行(折叠成窄栏时是圆形图标), 行尾带一个连接状态小圆点(绿=已连接 / 黄=连接中 / 红=认证失败 / 灰=未连接)。点击即可打开配置面板:

区块内容
状态已连接 / 连接中 / 认证失败 / 未配置,以及当前连接的细节
本机 DSH Web代理将要暴露的本机地址(自动取自 DSH 实际监听端口)与设备名/ID
服务器服务器地址、设备名、自动连接、反向访问(是否共享本机 DSH 启动令牌)、连接 / 断开、保存并应用;外加一行只读的「登录账号」状态(已登录显示显示名 + 切换账号 / 退出登录)
同账号在线端设备名、ID、连接时间、「本机」标记与「在服务器中打开 →」(新标签页打开服务器同源的设备视图 https://<server>/d/<设备ID>/,由服务器经本插件的隧道代理到对方本机的 dsh web)

生产服务器地址:https://dsh.textwork.cn。

连接与登录流程

面板本身只有「地址 + 连接」,凭据只在弹窗里输入:

填服务器地址 ──► 点「连接」
                   │
                   ├─ 本机已有可用 token ──► 直接连接(不打扰)
                   │
                   └─ 没有 token / token 已失效 ──► 弹出账号输入框
                                                     ├─ 手机号验证码登录(可注册)
                                                     └─ 账号密码登录
                                                     ↓
                                提交给代理服务器换取登录令牌(密码不落盘)
                                                     ↓
                                              自动连接并上线

要点:

  • 客户端不保存密码:弹窗里的凭据只提交给代理服务器,服务器校验后返回一个长效 token, 本机只保存这个 token($DSH_HOME/dsh-proxy-client.json,0600)。
  • 弹窗内容随服务器能力变化:/api/auth/config 报告该服务器是否支持短信登录 / 账号密码 / 注册 (textwork.cn 三种都支持;--auth local 的独立部署只显示账号密码)。
  • 切换服务器会失效旧 token:/config 发现地址变化时会清掉上一个服务器签发的 token, 下次「连接」重新弹窗——避免拿 A 服务器的 token 去连 B 服务器。
  • 登录态失效(服务器重启、token 过期、被吊销)时面板显示「认证失败」,点「连接」会重新弹窗。
  • 已登录时也可以点「切换账号」主动换一个账号,或点「退出登录」清除本机 token。

本地配置

$DSH_HOME/dsh-proxy-client.json(默认 ~/.dsh/dsh-proxy-client.json,权限 0600):

{
  "serverUrl": "https://dsh.textwork.cn",
  "account": "13810385787",
  "displayName": "138****5787",
  "token": "<代理服务器下发的 bearer token>",
  "deviceId": "<本机稳定设备 ID,首次自动生成>",
  "deviceName": "desk-pc",
  "autoConnect": true,
  "shareLoginToken": true
}

密码与短信验证码从不写入该文件。

面板 API(DSH 同源,供面板使用)

方法与路径说明
GET /dsh-proxy-client/api/status连接状态、脱敏配置、本机 dsh web 地址、同账号设备(带 self 标记)
GET /dsh-proxy-client/api/auth-config?serverUrl=目标服务器支持的登录方式(authMode/phoneLogin/passwordLogin/register)
GET /dsh-proxy-client/api/captcha-session?serverUrl=人机验证风险预判(转发给代理服务器 → textwork 上游)
POST /dsh-proxy-client/api/send-code{serverUrl?, phone, captchaSid, captchaToken} → 发送短信验证码
POST /dsh-proxy-client/api/login | /register{serverUrl?, phone, smsCode, displayName?} 或 {serverUrl?, username, password} → 登录并保存 token、连接
POST /dsh-proxy-client/api/config{serverUrl?, deviceName?, autoConnect?, shareLoginToken?} → 保存并重连;地址变化时清除上一个服务器签发的 token,返回体里的 config.hasToken 决定面板是直接连接还是弹窗
POST /dsh-proxy-client/api/logout注销并断开
POST /dsh-proxy-client/api/connect | /disconnect手动连接控制
POST /dsh-proxy-client/api/attach{deviceId} → 服务器返回同源代理地址(/d/<设备ID>/?ticket&token),浏览器无需能访问目标机器

该路由与 DSH GUI 同源、默认只在回环可达;令牌始终留在宿主半,浏览器半拿不到。 上游状态码会一并回传({ok:false,error,status}),因此验证码服务不可用时前端能与服务器一样「放行」。

反向访问的登录链路

目标端 DSH 的首页需要它自己的进程启动令牌。宿主半通过 DSH Connection 服务的 ctx.connection.authenticatedUrl() 读到该令牌(受「反向访问」开关控制),随 hello 上报给服务器;服务器在 attach URL 上拼接:

https://dsh.textwork.cn/d/<deviceId>/?__dshproxy_ticket=<ticket>&token=<目标端启动令牌>

浏览器停在代理服务器的源上,服务器经隧道转发;目标 DSH 完成 token→cookie 交换,标签页里获得完整可用的 GUI。

开发与测试

# 无需 DSH 的宿主模拟器(跑本包真实的连接管理器)
node scripts/fake-client.ts --server http://127.0.0.1:4000 --username demo --password demo1234 \
     --name desk-pc --target 127.0.0.1:3080 --state .tmp/client-desk.json

npm run smoke:client     # 用 react-dom/server 真渲染浏览器半(28 项:面板无内联凭据表单、弹窗两种登录方式、错误边界)
npm run e2e              # 进程内 97 项断言(含 textwork 认证中转、面板 API 契约与故障隔离)
npm run probe:deployed   # 对已部署服务器做真实 TLS 端到端探测(两阶段:服务端隧道 + 面板 API 登录流程)
npm run check            # typecheck + smoke:client + e2e
npm run demo             # 五进程本地演示

代码地图

文件作用
lib/index.jscordis 插件:注册面板路由、读取 DSH 启动令牌、启动/停止连接;apply() 不抛错、不做内联网络 I/O
lib/connection.jsWebSocket 会话循环、重连退避、流桥接、背压;连接/握手/停止均有超时上界,回调全部隔离
lib/settings.js配置存储(原子写、0600、deviceId 生成);I/O 失败降级为内存配置并记录 lastError
lib/api.js面板 API、textwork 登录链路中转、服务器 REST 调用(20s 上游超时,响应写入自带保护;切换服务器时清 token)
lib/protocol.js线协议帧(与 proxy-server 的 protocol.ts 逐字节一致,e2e 校验)
lib/client.js浏览器半 bundle:侧边栏图标 + 「地址 + 连接」主面板 + 账号弹窗(两种登录方式)+ 人机验证浮层;两个 slot 均包错误边界,调用有 30s 上限
cordis.patch.ymlbundle 层:插入插件行(id: jaxzhou-proxy-client)