dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH Web 插件:把 DSH Web GUI 发布到 tailnet,并把 tailnet 设备与可达性暴露为 ctx.tailscale 服务
DeepSeek Harness(DSH)Web 插件:把 DSH Web GUI 发布到你的 tailnet,并把 tailnet 设备与可达性作为 `ctx.tailscale` 服务提供给其他插件。
https://..ts.net/,手机/平板在任何网络下打开一个网址就能用ctx.tailscale.devices() / probe() 把 tailnet 节点和 TCP 可达性交给其他插件(dsh-phone 等),插件本身不认 adb/hdc/sshtailscale serve(tailnet 内),永不启用 Funnel要求 DSH >= 0.2.0-rc.2 = 22.5;本机已安装 Tailscale(没有的话插件可以引导安装)。
# CLI
dsh plugin --profile web add @ponydev/dsh-tailscale
# 或在 Web「插件」页搜索安装装完重启宿主(launchctl kickstart -k gui/$(id -u)/local.deepseek-harness.web)并刷新页面,然后打开 设置 → Tailscale。
dsh plugin --profile web add link:/path/to/dsh-tailscaleHost 侧改完重启 dsh web(或 touch profile 的 cordis.patch.yml 触发重组合);lib/client.js 改完保存后浏览器通常免刷新(dsh-client-hmr)。
启动时(autoPublish: true):
tailscale status --json,确认 BackendState === "Running",拿到 Self.DNSNametailscale serve status --json,按四态处理目标路由:absent → 创建 tailscale serve --bg --https= [--set-path=] http://127.0.0.1:exact → 认领(上次崩溃/重启留下的路由),不重建stale → 重建;conflict → 只报错,不覆盖别人的路由 推进 connection.trustedHosts(serve 保留 Host 头,不推进会导致远程 /api` 403)$DSH_HOME/tailscale.json(0600,只含 URL/端口/归属,不存 token)运行期每 60 秒做一次轻量自愈:入口路由丢了(HMR 重载竞态、外部 serve reset、Tailscale 重启)就自动重建。正常退出时只撤自己那条 serve 路由(末位 off),绝不 serve reset、绝不 tailscale down。
插件统一管理本机这一套 Tailscale,不创建独立节点、不产生第二套 state/登录/hostname:
状态 · 设置页行为 未安装 · 「安装 Tailscale」:macOS 优先 brew install --cask tailscale-app,没有 brew 则下载官方 pkg 并通过系统授权弹窗安装(插件不接触密码);安装中显示日志,2 秒轮询状态 已安装未运行 · 「启动 Tailscale」 未登录 · 本地二维码(AuthURL,60 秒后自动隐藏,不上传)或 auth key(环境变量 TAILSCALE_AUTH_KEY 或临时粘贴;只在 Host 内存/0600 临时文件中,不落盘不进日志) 运行中 · 「开启入口」、复制手机登录链接 已发布 · 手机入口、关闭入口
节点 hostname 可在设置页修改(默认不动);修改会二次确认并提示影响整机(SSH、serve 域名、其他服务)。
设置页「远程访问」→「生成登录链接」会调用 DSH 的 connection.authenticatedUrl(),得到带本次进程 launch token 的链接。手机打开一次 → DSH 换成持久 cookie(签名密钥存在 credentials,默认 30 天)→ 之后直接打开 https://..ts.net/ 即可,跨 DSH 重启不用重新登录。
链接含令牌,属敏感信息:UI 展示 60 秒后自动隐藏,插件不落盘、不打日志。
会话右上角工具区有一个 Tailscale 图标(和手机图标同排):
Tailscale · 在线 · · 入口已开启 · 17/30 设备在线ctx.tailscale 把 tailnet 事实暴露给 DSH 内部:设备清单(在线/离线、OS、IP、tags、直连/DERP)、probe(host, port) 单次 TCP 可达性、发布状态与订阅。只提供网络事实,不实现任何设备协议。
cordis.patch.yml)- insert:
- id: tailscale
name: "@ponydev/dsh-tailscale"
config:
autoPublish: true # 启动自动发布入口
httpsPort: 443 # serve 的 HTTPS 端口
publishPath: / # 单实例用 /;多实例可用 /dsh2
unpublishOnExit: true # 退出撤回自己建的路由
adoptExisting: true # 认领上次崩溃残留(target 精确匹配才认)
trustHost: true # 自动维护 connection.trustedHosts
cliPath: auto # auto | 显式 CLI 路径
deviceTtlMs: 10000 # status --json 缓存
probeTimeoutMs: 800 # probe() 默认超时
allow: [] # 设备过滤正则(按 hostName/dnsName/tags)
allowAutoInstall: true # 允许插件代跑安装命令(仍有系统授权/二次确认)
installMethod: auto # auto | brew | pkg | manual
authKeyEnv: TAILSCALE_AUTH_KEYctx.tailscale可选依赖:不要写进 inject(服务不存在时插件会整个不启动),在请求处理时用 ctx.get('tailscale') 惰性取:
const tailscale = ctx.get('tailscale')
if (tailscale) {
const peers = await tailscale.devices({ online: true })
const hit = await tailscale.probe(peers[0].dnsName, 5555) // 单次 TCP connect
const info = await tailscale.publication()
const off = tailscale.subscribe(() => { /* 入口/设备变化 */ })
}常用方法:
方法 · 说明 status({ fresh }) · Tailscale 后端状态 + 本机节点 devices({ fresh, online, allow }) · tailnet 设备列表(TailnetDevice[]) device(ref) · 按 hostName / dnsName / IP 前缀查单个设备 publication({ fresh }) · 远程入口状态(enabled / url / owned / adopted / routeState) health({ deep }) · 诊断报告(checks[] 带 level / hint / command) probe(host, port, { timeoutMs }) · tailnet 内单次 TCP 可达性(不握手、不发协议数据) subscribe(fn) · 入口变化订阅(publish / unpublish / change) config · 只读配置快照
devices() 数据结构(节选):{ id, hostName, dnsName, ips, os, online, tags, lastSeen, direct, relay, isSelf }。
约定:devices() 只给 tailnet 事实,不认协议;probe() 只接受 tailnet 网段地址或当前设备清单里的主机(避免变成任意端口扫描器)。安装/登录/hostname 等管理方法也挂在服务上,但消费方通常不需要。
Host 侧 RPC(给浏览器,全部 POST /tailscale/ 且先过 connection.admit()):snapshot、status、health、login-url、publish、unpublish、devices、setup、install、start、auth-url、login、hostname、update-check。客户端必须用相对路径调用,以兼容 /dsh2/ 之类挂载前缀。
设置页「远程访问」标题右侧显示当前版本(vX.Y.Z),旁边「检查更新」按钮会:
POST /tailscale/update-check 读取 npm registry 的 @ponydev/dsh-tailscale/latestpackage.json 版本,显示「当前 / 最新」与升级命令dsh plugin --profile web add @ponydev/dsh-tailscale@检查是只读的:不登录、不上报标识、不自动升级、不改 profile;结果缓存 10 分钟,可手动重试。
/tailscale/* 全部经 connection.admit():未认证 401,跨站 Origin 403;login-url 只对已认证请求现取现给down、永不 logoutserve(tailnet 内),健康检查会检测 AllowFunnel 并告警execFile + 参数数组 + 超时,不经过 shell;conflict 路由只报错不覆盖0600;probe() 只探 tailnet 地址看 设置 → Tailscale → 诊断(每项带下一步提示和可复制命令)。常见状态:
状态 · 含义 · 处理 未安装 · 找不到 tailscale CLI · macOS 装 standalone 版;或配置 cliPath 未运行 / 未登录 · BackendState 不是 Running · 用设置页「启动 Tailscale」或扫码/auth key 登录 HTTPS 未启用 · tailnet 没开 HTTPS/MagicDNS · 在 Tailscale 管理台开启 路由冲突 · 该域名/path 已指向别的服务 · 设置页显示现有路由,先手动处理(插件不覆盖) 信任未生效 · 远程页面能开、发消息 403 · 重新开启入口;或在 profile patch 里加 trustedHosts 入口偶发丢失 · HMR / 外部 serve reset / Tailscale 重启 · 60 秒内自愈重建;也可在设置页关闭再开启
命令行自查(不打印 token):
/Applications/Tailscale.app/Contents/MacOS/Tailscale status --json | head -5
/Applications/Tailscale.app/Contents/MacOS/Tailscale serve status
curl -sI https://<节点>.<tailnet>.ts.net/ # 401 = 入口可达(正常)npm run check # 语法检查(node --check)
npm run smoke # 冒烟:假 CLI + 单元/服务层/RPC 测试,全部离线
npm run check-i18n # zh/en 字典键一致 + 代码用键存在
npm run release-notes # 从 CHANGELOG 抽取当前版本发布说明
npm pack --dry-run # 发布内容检查