Registers a top-level menu item on the DSH settings page, grouping the enable toggles and configurations for the dsh-web-ui plugin family; also provides a loopback-only compatibility bridge for the rc.6 host.
$ dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/dsh-web-ui-settingsRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
在 DSH 设置页注册一个一级菜单项「Web UI 插件」,把 dsh-web-ui 全家桶插件(task-board、remote-web-ui、describe-image 等)的启用开关和配置表单归组在同一处,同时为 DSH 0.1.0-rc.6 宿主提供仅 loopback 的兼容桥,让官方 apiproxy 不放行的第三方设置命名空间也能被全家桶卡片正常读写。
web-ui.plugin.item 由全家桶插件自行注册/api/dsh-web-ui-settings 一对同源 loopback HTTP 接口重新暴露全家桶设置命名空间,绕过 DSH 0.1.0-rc.6 宿主 apiproxy 对第三方命名空间的硬编码拒绝settings.yaml 的 web_settings_namespaces 控制桥接开放范围;未配置时回退到内置全家桶 fallback 列表,配置后取与已注册命名空间的交集,未注册项永远不暴露type: "module")+ React 18(TSX)schemastery ^3.18.0(Host 配置 schema 校验)、@deepseek-ai/dsh-host-webserver(Host 半区 HTTP 路由)、@deepseek-ai/dsh-settings(Host 设置 seam 与 schema 校验/版本号机制)、@deepseek-ai/dsh-client-ui-settings + @deepseek-ai/dsh-client-runtime(浏览器半区设置面与 slot)、react ^18.2.0(peerDependency,UI 渲染)cordis.patch.yml 以 id: ui-web-ui-settings 插入 web profile bundle;Host 半区在 ctx.settings seam 内挂载 loopback-only HTTP 桥接路由(/api/dsh-web-ui-settings/describe、/mutate),浏览器半区先尝试官方 settingsScope,官方显示 unavailable 时回退到桥接控制器(rc.6 兼容路径),rc.7+ 宿主由 apiproxy 直接服务则桥接永不激活src/index.ts(Host 半区入口,桥接路由挂载)、src/client/index.ts(浏览器半区入口,一级菜单项与 locale 注册)、src/bridge.ts(loopback-only HTTP 路由与认证代理门控)、src/client/compat-settings-scope.ts(rc.6 兼容 binder,把官方 settingsScope 与桥接控制器包成一个统一接口)同时装了多个 dsh-web-ui 全家桶插件(task-board、remote-web-ui、describe-image 等),又希望它们集中在 DSH 设置页同一处管理的人;或者运行在 DSH 0.1.0-rc.6 / rc.7 宿主上、没有这个兼容桥时全家桶插件卡片只能显示「namespace 不可用」说明。如果你只装了一个全家桶插件或者已经在 rc.7+ 宿主上让 apiproxy 直接服务设置面,这个分组入口带来的收益就很有限。
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH(@deepseek-ai/dsh-client-runtime / dsh-client-connection / dsh-client-ui-settings / dsh-host-webserver / dsh-settings / cordis) | 0.1.0-rc.6+ | 与 rc.6 / rc.7 兼容,devDependencies 钉到 ^0.1.0-rc.8 |
| Node | ^22.19 或 >=24 | 来自 monorepo packages/AGENTS.md 约定,本包未声明 engines |
| React | >=18.2.0 | peerDependency,浏览器半区构建需要 |
| 平台 | macOS / Windows / Linux | 跨平台,桥接只走标准 HTTP 路由,没有平台相关依赖 |
| 原生模块 | 无 | 仅使用 node:fs / node:os / node:path / node:crypto 等内置模块 |
dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/dsh-web-ui-settings
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
trustedProxyHosts | string[] | 通过已认证反向代理放行的精确 host[:port] 列表;空数组 = 仅 DSH loopback origin 直连,桥接不开放给任何代理 | [] |
proxyTokenEnv | string | 保存反向代理共享 token 的环境变量名;token 本身不会被写入插件配置,未设置或为空时启用 trustedProxyHosts 会抛错 | DSH_WEB_UI_SETTINGS_PROXY_TOKEN |
另外,settings.yaml 里的 web_settings_namespaces(可选)决定桥接开放哪些全家桶命名空间;未配置时使用内置全家桶 fallback 列表,配置后每次桥接调用都会重新读取(不需要重启 DSH);插件自身配置(trustedProxyHosts / proxyTokenEnv)修改后需要重启 DSH 才生效。
Q: 这个插件具体是干什么的?跟 task-board / remote-web-ui / describe-image 是什么关系?
A: 它本身不实现这些功能,而是把它们在 DSH 设置页的启用开关和配置表单集中到一个一级菜单项「Web UI 插件」里,与通用设置 / 模式 / 插件 / Agent 预设同级。皮肤中心、社区插件、桌面宠物各自是独立插件包,也注册各自的一级菜单项并默认展开。
Q: 为什么不装它也能用其它全家桶插件?
A: 其它全家桶插件可以独立运行,只是少了设置页的分组入口。但 DSH 0.1.0-rc.6 宿主的 apiproxy 默认只放行它硬编码的 WEB_SETTINGS_NAMESPACES + 产品命名空间,所有第三方设置命名空间会被一律拒掉——没有这个兼容桥时,全家桶插件卡片就只能渲染一段「namespace 不可用」的说明文本。
Q: 安装后启动报错 "Failed to load plugins ... keyed slot settings.plugin.item requires options.key" 怎么办?
A: 0.1.17 及更早版本把组卡片注册到 keyed 槽 settings.plugin.item 时传的是 id 而不是必填的 key,DSH 0.1.0-rc.6 起在 loader entry 应用阶段会直接拒绝这种注册。修复办法:把 profile package.json 里所有 @linxin666/* 依赖升到 ^0.2.0(至少 ^0.1.18),重新 pnpm install;Windows 下重建陈旧的 node_modules/@linxin666/* junction 链接(先 cmd /c rmdir <链接> 再 cmd /c mklink /J <链接> <目标>),重启 dsh web。参考 issue #513。
Q: 想通过反向代理对外暴露怎么配?
A: 把 DSH Web 绑定到 loopback,在 cordis.patch.yml 里给 trustedProxyHosts 填好精确 authority,把高熵 token 放进 proxyTokenEnv 指向的环境变量里(DSH 和反向代理都要设置),让反向代理完成认证后用服务端注入的 token 替换请求头 X-Dsh-Web-Ui-Settings-Proxy-Token(不要透传客户端送来的);Caddy 示例:header_up X-Dsh-Web-Ui-Settings-Proxy-Token {$DSH_WEB_UI_SETTINGS_PROXY_TOKEN}。带值的 header_up 会覆盖客户端值,不要同时再删除同一字段(Caddy 2.6 会先设置后删除)。trustedProxyHosts 修改后必须重启 DSH 才生效。
Q: web_settings_namespaces 起什么作用?
A: 它写在 settings.yaml 里,用来控制桥接开放哪些全家桶命名空间。未配置时使用内置全家桶 fallback 列表(task-board、remote-web-ui、describe-image、dsh-ssh、pet、skin-background、community-plugins、desktop-launcher 等);配置后取与已注册命名空间的交集,未注册项永远不暴露。每次桥接调用都会重新读取,不需要重启 DSH。
Q: 设置页看不到「Web UI 插件」菜单项怎么办?
A: 仅当依赖的 @deepseek-ai/dsh-client-ui-settings 存在时该菜单项才会出现。检查 DSH 是否兼容(0.1.0-rc.6 起)、是否已安装完成 pnpm install、是否重启 dsh web;如果 profile 是从更早版本迁移过来的,按上面 FAQ「Failed to load plugins」的步骤升级依赖。
Q: 桥接会暴露凭据、本机路径或其它 DSH 特权 API 吗?
A: 不会。桥接只开放已注册全家桶命名空间与 web_settings_namespaces 的交集,schema 走 Host seam 的官方校验与持久化;不开放凭据、本机路径或任何其它 DSH 特权 API。认证代理模式下,token 由反向代理注入上游,浏览器永远拿不到 token。
Q: 如何完全卸载?
A: dsh plugin --profile web remove @linxin666/dsh-client-ui-web-ui-settings,然后重启 dsh web。该包不写入任何持久化设置,不会自动删除 settings.yaml 里的 web_settings_namespaces 条目。
入门 — 装好之后默认仅 loopback、无需任何配置就能在设置页出现菜单项;只有需要走反向代理或限制 web_settings_namespaces 白名单时才需要读 README 的反向代理章节,理解 DSH 监听/认证头注入/header_up 替换顺序这几件事即可。
@deepseek-ai/dsh-client-ui-settings 存在时才会出现;缺少该依赖时不会报错,只是不显示分区trustedProxyHosts 保持为空,否则会出现「启用了 token 但请求不带 token」或「客户端伪造 token 绕过认证」等风险trustedProxyHosts / proxyTokenEnv)修改后必须重启 DSH 才生效;web_settings_namespaces 每次桥接调用重新读取,不需要重启package.json 里的 @linxin666/* 依赖必须升到 ^0.2.0(至少 ^0.1.18),Windows 下还需重建 junction 链接mountOnce 保证只跑一次(共享同一 globalThis symbol),浏览器半区由官方 client 模块系统按包名去重;不会出现重复注册路由或重复设置命名空间caddy run --environ 启动,会在启动时打印 proxyTokenEnv 指向的环境变量;请去掉 --environ 或严格保护其输出,避免 token 泄露到日志