# dsh-web-lan-access [English](README.md) | **简体中文** [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web UI 的局域网/远程访问支持插件。 ## 问题 Web UI 在启动关键路径上调用 `crypto.randomUUID()`(RPC id 生成、消息 id、草稿附件)。该 Web API **只在安全上下文存在**(HTTPS,或 `http://localhost` / `http://127.0.0.1`)。当界面通过纯 HTTP 从非回环地址(局域网 IP、Tailscale IP、主机名)提供服务时,`crypto.randomUUID` 是 `undefined`,所有 RPC 抛错,**会话和模型完全无法显示**。 当前 DSH 客户端还会根据浏览器主机名选择宿主设置:即使浏览器认证成功,非回环页面仍只分配内存设置。因此,在其他功能正常的 trusted-host 部署中,模型和插件设置页仍不可用。 ## 原理 宿主端插件使用 webserver 官方扩展点(`webServer.tapIndex`),在每次返回的 index.html 的 `
` 之后、启动清单和 shell 入口之前注入一段 bootstrap。它会: - 提供普通 HTTP transport 并携带 DSH 的 `ownsHost` 部署信号,让受信任远程页面可以使用通过认证的宿主设置; - 用 `crypto.getRandomValues`(非安全上下文仍**可用**)补充 RFC 4122 v4 `crypto.randomUUID`。 如果其他 shell 已提供 transport,bootstrap 不会替换它;安全上下文下 UUID polyfill 为空操作。 - 不修改产品源码,完全可逆 - 使用 DSH 现有的 index-tap 和客户端 transport 扩展点 - 跨平台(Linux / macOS / Windows / Android) ## 安装 ### 方式一:bundle 安装(推荐) 从 npm 安装: ```sh dsh plugin --profile web add dsh-web-lan-access ``` (不走 npm / 本地开发时,可用仓库地址: ```sh dsh plugin --profile web add github:AcidGr/dsh-web-lan-access ``` ) 重启 `dsh web`,浏览器硬刷新。 ### 方式二:手动安装(无 pnpm / 离线) ```sh PROFILE="$DSH_HOME/profiles/web" # 按实际修改 DSH_HOME 和 profile 名 mkdir -p "$PROFILE/plugins" "$PROFILE/node_modules/@dsh-profile" cp -r dsh-web-lan-access "$PROFILE/plugins/lan-access" ln -sfn ../../plugins/lan-access "$PROFILE/node_modules/@dsh-profile/lan-access" # 在 $PROFILE/cordis.patch.yml 追加: # - insert: # - id: lan-access # name: '@dsh-profile/lan-access' ``` ## 使用 插件是**自包含**的:它的 bundle patch 直接把 webserver 的绑定 host 设为 `0.0.0.0`(新版 harness 出于安全**硬性拒绝**命令行 `--host 0.0.0.0`,但 webserver 配置仍接受该值——所以**无需改源码、无需 `--host` 参数**;`--port` 参数照常可用)。它同时会自动扩大 `/api` 信任围栏。 1. **安装插件后正常启动即可**(不带 `--host`): ```sh dsh --profile web --port 3080 ``` bundle patch 会从本机**当前所有非内部 IPv4**(局域网 `192.168.x`、**Tailscale `100.x`**、VPN 接口)重新推导 `/api` 信任围栏,并合并 `resolveLanTrust` 已有的结果。只要远程接口在 `dsh web` 启动时已就绪(Tailscale 通常开机自启、先于它),**局域网 / Tailscale IP 访问零额外配置**:打开 `http://<服务器IP>:3080` 或 `http://