dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
deepseek-harness Web GUI 的局域网访问插件(带口令的全功能版;移动端优化官方界面 UI,适配竖屏及触控手势)。
⚠️ 版本要求(1.6.0 起收紧):仅支持 `@deepseek-ai/dsh` `0.2.1-rc.3`(桌面版 0.2.1-rc.3)。package.json的engines.dsh已锁定到该版本:在其它 DSH 版本上安装/启用会被判为incompatible-version而拒绝(这是有意为之——插件直接改写connection、webServer的内部行为,跨版本不做兼容承诺)。DSH 升级后请等待对应版本的插件发布。
🔧 1.5.0 起换了实现方式(重要,升级必读):0.2.1 起 DSH 不再允许把监听地址绑到通配地址(0.0.0.0),而桌面端又要求 DSH 自己必须听127.0.0.1,所以本插件不再改动 DSH 的任何绑定:它保持官方默认只听本机,由插件自己内置的反向代理在你机器的局域网地址上提供入口(复用同一个端口号)。升级后局域网地址与用法完全不变,但旧版本留在 profile 补丁里的那段覆盖会让 0.2.1 直接起不来——请先看下面的「升级」一节。
🚀 配合 DSH-Launcher 与 dsh-app 使用,体验感更好。
📦 本包是标准 DSH 插件 bundle(声明 dsh.bundle.patch),用官方插件机制安装,没有安装脚本;功能开关在设置页里,安装过程不询问口令。安装后,在设置页打开「局域网访问」开关即可让局域网设备访问(Windows 自动放行防火墙 Domain + Private;Linux 依次尝试 firewalld / ufw / iptables,无可用防火墙工具时视为无需放行):
webserver 覆盖,GUI 保持官方默认(只听 127.0.0.1,gzip 完整保留)http://:,和以前一样;代理会把 Host 原样转发,所以登录凭据与官方一致http://: 都先显示口令页,输入口令后进入;地址栏始终不出现 token(插件在后台完成官方 token→cookie 兑换)127.0.0.1、localhost、[::1]、机器名还是本机局域网地址)直接进入,不显示口令页。判定依据是 TCP 连接来源(回环或本机自己的地址),与页面用的域名无关——所以桌面端不会被自己的口令门挡住(1.4.1 修的就是这个问题)。x-dsh-lan-key 请求头或会话 cookie),否则一律拒绝;特权方法(设置/权限/凭据等)同样只认这道门。主机自己的请求一律放行(任何域名/地址),这是刻意设计:桌面端必须始终可用。DSH 官方对非本机浏览器刻意不提供设置作用域(dsh-client-ui-settings 的 persistence 在页面加载时按 isLoopback 固定,且 dsh-client-locale / dsh-client-ui-chat 的文档都写明这是有意为之)。因此局域网设备上:
能力 · 局域网设备 聊天、切换模型与工作模式、工作区与会话、历史、任务、审批、终端 · ✅ 可用 设置 / 权限预设 / 凭据 / 预设管理页面 · ❌ 只在主机上可用(请在主机上修改) 工作区目录选择 · ✅ 插件自带的目录选择器(含盘符下拉、路径跳转)
http://: 时,插件在官方界面之上注入触控适配(紧凑侧栏、≥44px 触控目标、16px 输入字号防 iOS 聚焦缩放、安全区 padding),横屏/桌面视口自动还原。ask_user_question)卡片完整适配窄屏(选项 42px 触控目标);权限/模型两行布局与底部状态栏对齐。SameSite=Strict 的 Cookie 会被丢弃),口令页最多自动跳转 2 次即停下并给出提示,不会无限闪烁。在 DSH 桌面版侧栏 Plugins 页输入包名 `dsh-lan-tool` 安装。装完后 dsh.profile.bundles 会自动登记该包。
⚠️ 装完(或更新后)请完全退出桌面版再重新打开一次。 插件的 node 半边(口令门、开关、/dsh-lan/* 路由都在这里)只在应用启动时载入一次;同一个应用进程内重装/升级插件,node 半边仍是旧代码(浏览器半边会热更新,于是出现"一半新一半旧")。1.4.2 起客户端会把这种不一致直接写在设置卡片与控制台里(旧版表现为一个没人能解释的口令页)。⚠️ 刚发布的版本可能装不上(pnpm 的"发布年龄"策略):pnpm 默认不装太新的包,插件管理器只会给它实际装到过的版本豁免,于是你在 Plugins 页输入包名时可能被解析回上一个版本(表现:新版本的功能/修复没出现)。此时在 Plugins 页显式写版本(如dsh-lan-tool@1.4.2),或把该版本加进/profiles//pnpm-workspace.yaml的minimumReleaseAgeExclude再装。
前提:该包已发布到 npm。若尚未发布(或你想装本地这份代码),用方式 2。
# 本地开发目录(绝对路径)
dsh plugin --profile desktop add D:\DeepSeek\dsh-LAN
# 或 link: / file: / tarball / git 形式
dsh plugin --profile desktop add link:D:\DeepSeek\dsh-LAN
# 发布之后则可以直接用包名
dsh plugin --profile desktop add dsh-lan-toolCLI 路径需要先退出桌面版再执行(dsh-desktop-host 的提示文案如此;它实际只检查 profile 是否初始化过,但应用运行中改写 node_modules 在 Windows 上容易被占用)。
http://:,输入口令进入。端口由 DSH 自己决定(0.2.1 的桌面启动器传--port 0,由系统分配,所以每次启动都可能不同;dsh web默认3080)。以卡片里显示的地址为准。
📌 想让局域网地址固定下来:在卡片里填一个「局域网端口」(1024–65535)并点「应用端口」,留空则继续跟随 DSH。固定的是插件自己的入口,不是 DSH 的端口——DSH 那边不能安全地钉死(写 webserver 覆盖一旦端口被占会让整个应用起不来,而插件这个入口被占只是暂时没有局域网访问,不影响应用启动)。固定之后,已经打开的页面、书签与二维码在 DSH 重启后依然可用;不固定的话,DSH 每次重启都会换端口,之前开着的局域网页面会一直尝试重连旧端口(界面上表现为一直"重新连接中"、能看列表但对话加载不出来),刷新页面即可恢复。⚠️ 重装或升级后设置页里看不到卡片? 多半是 profile 补丁里留着一条旧的禁用行(停用/卸载时 dsh-plugin-manager 会写它,而重新安装不会自动清掉;profile 补丁层优先级高于 bundle 层,于是它压过了新装的包):```yaml
# %USERPROFILE%.dsh\profiles\\cordis.patch.yml 末尾
- id: dsh-lan-tool
disabled: true
`删掉这两行保存即可——DSH 会热加载,刷新页面卡片就回来了(症状同时包括:设置页没有卡片、http://127.0.0.1:/dsh-lan/status 返回 404、局域网地址无法访问)。dsh-lan-tool (auto)(Domain + Private)。未以管理员身份运行时,第一次开启会出现一次系统的「是否允许访问」弹窗——点允许即可,Windows 会自己建一条放行规则;卡片会自动识别这条系统规则(几秒内把状态改成「防火墙已放行」,显示系统规则的名称),不需要管理员权限、也不需要重启。只有既没建成本插件的规则、系统里也找不到放行规则时,才会显示「防火墙未放行(需管理员权限)」。如果你在「局域网访问」开着的时候把 DSH 升到了 0.2.1,DSH 会起不来,弹出「DeepSeek Harness is unavailable」,日志(%APPDATA%\@deepseek-ai\dsh-desktop\logs\crash-*-host.log)里是类似这样一句:
webserver (required)
Error: host "0.0.0.0" is an unspecified (wildcard) address, which is not supported: …原因:0.2.1 的 webserver 行不再接受通配监听地址(上游为缩小暴露面主动禁掉),而它是必需组件 ⇒ 配置校验失败 ⇒ 整个应用拒绝启动;而旧版本(≤1.4.7)的开关正是往 profile 补丁里写了一段 host: '0.0.0.0' 的覆盖,那段覆盖不会因为升级而消失,于是每次启动都失败。这不是你的配置坏了,也不是 DSH 的 bug;1.5.0 起插件已经彻底不再写这段覆盖。
两条恢复路径,任选一条:
A. 用 DSH 自带按钮(最快):在启动失败对话框上点第三个按钮「禁用第三方插件,备份 profile 补丁并重启」。它会备份补丁、摘掉第三方 bundle,然后正常启动。进去之后把本插件升级到 1.5.0 再重新启用即可(1.5.0 会自动清理遗留的那段覆盖)。
B. 手工删掉那一段:
%USERPROFILE%.dsh\profiles\desktop\cordis.patch.yml;# --- dsh-lan-tool LAN block (managed - do not edit) --- 到 # --- end dsh-lan-tool LAN block --- 的整段(含这两行;不要动文件里其它内容);升级到 1.5.0 之后,插件在激活时也会自动剥除任何遗留的受管块(包括上面那段)。但已经被它卡住的机器里插件根本加载不到,所以那种情况只能先用 A 或 B 救回来——这也是本节存在的原因。
⚠️ 1.5.0 本身有一个缺陷,请直接用 1.5.1 或更新版本:0.2.1 把 API 的放行判定挪到了connection.admit()里的信任漏斗(isTrusted),而 1.5.0 的口令闸仍只替换旧的requestRejection⇒ 局域网设备能打开界面,但每一个 API 调用都会 403(只能看不能用)。1.5.1 已修(fence 同时接管信任漏斗),并补了一条"本地与局域网必须同结果"的端到端断言防回归。
· 1.4.x · 1.5.0 DSH 自己的监听 · 开关打开时改成 0.0.0.0 · 始终 `127.0.0.1`(官方默认,插件不再改动它) 局域网入口 · DSH 自己监听局域网 · 插件内置反向代理监听局域网地址并转发到 DSH 端口 · 同一个 · 同一个(代理复用 DSH 的端口号) 开关的落点 · profile 补丁里的受管覆盖 · 插件内部状态(dsh-lan.json 的 lanEnabled) 关掉开关 · 删覆盖 + 等热重载 · 立即停止对外监听 口令 / 落地页 / 防火墙 · — · 完全不变
包已改名(dsh-LAN → dsh-lan-tool),用安装脚本装过旧版的机器需要按下面处理;插件在首次激活时会自动完成迁移:
profiles//cordis.patch.yml 里 dsh-LAN install block、dsh-LAN toggle block 两段受管块会被删掉(profile 补丁层优先级高于 bundle 补丁层,留着会永远压过新配置——正是"开关显示关、实际仍绑 0.0.0.0"的成因)。迁移后局域网回到关闭状态,请在设置页重新打开。dsh-LAN (auto)、DSH LAN Access (auto) 会被删除(规则名已改成 dsh-lan-tool (auto),旧规则再没有代码能碰到,留着会永久放行端口且 UI 看不见)。%USERPROFILE%.dsh\dsh-lan.json(文件名没变,避免丢口令),无需重设。profiles/node_modules/dsh-LAN 目录可以手工删除(新安装不会用到)。手工兜底(没跑迁移时):把 profiles//cordis.patch.yml 里两个受管块整段删掉,然后在设置卡片里重新开关一次。
在 Plugins 页移除该插件,或:
dsh plugin --profile desktop remove dsh-lan-tool停用/卸载时:局域网的对外监听会立即关闭(它是插件自己的监听器,门禁也在插件里,所以不能等);防火墙规则与 profile 补丁里任何遗留的受管块会在约 8 秒后清理(等这 8 秒是为了区分"热重载"与"真的没了"——热重载会立刻重新挂载插件,从而取消这次清理)。所以正常情况下卸载后局域网会自动回到关闭。
下面两种情况需要手工确认(清理还没跑):
手工清理三步:删 %USERPROFILE%.dsh\dsh-lan.json;确认 profiles//cordis.patch.yml 里没有 dsh-lan-tool LAN block 受管块(有就整段删掉);netsh advfirewall firewall show rule name="dsh-lan-tool (auto)" 应无匹配(有就 netsh advfirewall firewall delete rule name="dsh-lan-tool (auto)")。
单一 DSH 服务进程持有全部状态:会话(jsonl 持久化 + 内存投影)、工作区、目标、子代理。所有浏览器只是同一服务的客户端,通过 /api RPC 读写同一状态,通过事件流(WebSocket 下行)接收相同的服务端事件推送。桌面与移动端连接的是同一份状态,任何一端的操作对其他端实时可见。
早期移动端实现参考过 dsh-web-ui 的 dsh-remote-web-ui(独立轻量远程界面 + 令牌门);移动端自 v48 起直接复用官方桌面界面(插件注入竖屏适配),口令模型不变。
MIT(license: MIT)