dsh-auto-open-web
DeepSeek Harness automatically opens browser plugins and includes a built-in WebView2 program to achieve a lightweight desktop experience.
Install
dsh plugin --profile web add dsh-auto-open-web
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-auto-open-web
English: [README.en.md](README.en.md)
dsh web profile 启动后自动打开独立应用窗口(或网页标签页)的常驻插件,并在
设置界面提供配置表单(手动维护浏览器位置等)。最新版的配置入口是
「插件管理」页里本插件那一行的配置页(dsh ≥ 0.1.6,含 0.2.x);
最新 rc 线(0.1.5-rc.x)为 设置 → 插件配置卡片。
0.2.1-rc.3 适配(0.1.30):清单新增engines.dsh(>=0.1.5-rc.1 <0.3.0,
0.2.1-alpha.3 起优先于 peer 判定、旧版读 peer);bundle 配置层同步到 0.2.1 的
web-runtime键集(补上publicUrl);宿主侧把 dsh ≥0.1.7 的 Volatile 引用
解包后再归一化(此前 .volatile() 字段读到的都是包装对象,所有设置项实际
一直按默认值生效);GUI 地址改用webApp.getAdvertisedUrl()(--public-url、
TLS、非回环绑定都正确)。
行为
启动时(HTTP 服务绑定完成、取得实际监听端口后),按 windowKind 选择窗口类型:
1. WebView2 宿主(windowKind: webview2,默认,仅 Windows):启动随包分发的
DshAppWindow.exe(WinForms + WebView2,独立进程,无标签栏/地址栏),
直接加载 GUI 根地址(无 iframe、无包装页、无注入脚本)。
任务栏/窗口图标 = DSH 图标(窗口由宿主进程所有,直接设置 Form.Icon,
不受浏览器任务栏身份限制)。随 DSH 退出(宿主监视父进程 PID)。
记忆窗口大小/位置/最大化状态(%LOCALAPPDATA%\DeepSeekHarness\window-state.json,
关闭时保存、启动时恢复;显示器布局变化时回退居中)。
2. 浏览器应用窗口(windowKind: browser):--app 专用 Edge/Chrome 实例
(--user-data-dir=~/.dsh/<browser>-app-profile,独立进程树与存储,
不与正常浏览器页面共用进程/Cookie/缓存;--no-first-run 跳过首启欢迎页)。
随 DSH 退出(含强杀):浏览器实例加入 Job Object
(JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,koffi 驱动
JOBOBJECT_EXTENDED_LIMIT_INFORMATION 结构,实测 144 字节);DSH 无论
正常退出还是被强杀(taskkill /F、崩溃、关机等),Windows 内核随作业最后
一个句柄关闭自动结束作业内全部进程——专用实例整个进程树随之消亡,无需
依赖任何退出事件。另有两层兜底:DSH 正常退出时 process 'exit' 结束该
专用实例的整个进程树(仅匹配我们自己的 user-data-dir,不影响正常浏览器);
DSH 被强杀后的残留实例由下次启动前预清理。
3. 默认浏览器打开(最后兜底):所选类型不可用时(宿主缺失/浏览器找不到/
非 Windows 等)→ 降级为官方同款的默认浏览器交接——把 URL 交给操作系统
默认浏览器(普通标签页),保证用户至少能打开 GUI。实现与 DSH 核心
(web-app bundle)启动时打开网页的方式一致:优先用 DSH 部署自带的
open 包(win32 = PowerShell Start,darwin = open,linux = xdg-open),
open 包不可用时退回平台原生拉起(win32 = cmd /c start,darwin = open,
linux = xdg-open)。
appWindow: false 时与官方相同:默认浏览器打开(普通标签页,官方
open 方式)。
4. --no-open / SSH 会话(与官方相同的不打开):dsh web --no-open
(webStartup 服务的 openBrowser === false)或 SSH 会话(SSH_CONNECTION/
SSH_TTY,dsh ≥0.1.7 经 launcher 的 launchEnvironment 快照只认继承进程层,
与官方 launchedThroughSsh 同源——项目/用户 .env 里的同名变量不算 SSH)时
不打开任何窗口/页面——插件读取与官方同一来源做同样的抑制。
监听地址/端口取自 webServer 服务的真实值(--port 自定义、--port 0 均正确)。
打开窗口/浏览器时用的 URL 是公告地址:dsh ≥0.2.1 优先
webApp.getAdvertisedUrl()(尊重 --public-url、TLS、非回环绑定),其次
webServer.getOrigin(),旧版退回 http://127.0.0.1:<port>;连接服务再附加
本进程的启动令牌。无需等待:插件把 webServer 声明为硬依赖(inject),
Cordis 会等 webServer 插件 Service.init() 完成(HTTP socket 已绑定、端口已写入)
后才激活本插件,apply 时端口直接可用。
两种模式都随 DSH 退出而关闭:webview2 宿主监视父进程;browser 专用实例由
Job Object(强杀也生效)+ 退出清理结束进程树。
与 DSH 核心浏览器交接的关系:DSH 核心(web-app bundle)默认会在启动后
用系统默认浏览器打开 GUI(openBrowser: true,普通标签页/窗口,非独立窗口)。
安装本插件后,插件的 bundle 补丁会把web-runtime.openBrowser置为false,
打开行为完全由本插件接管:appWindow: true 时打开独立应用窗口,不弹出
普通浏览器页面;appWindow: false 时插件执行**与官方核心相同的默认浏览器
交接**(open 包 → 平台原生拉起),行为与未安装插件时一致;`dsh web
--no-open`(或 SSH 会话)时与官方一致不打开任何窗口/页面。卸载插件后
恢复官方默认行为。
WebView2 宿主要求(仅 webview2 模式)
- Windows 10 1803+ / Windows 11 / Windows Server 2016+
(Win7/8.1 已于 2023-01 终止支持,见微软公告)
- WebView2 Runtime(常青版,通常随 Edge 预装;本机已验证 151.x)
- 无 .NET 10 运行时要求:宿主自 0.1.15 起目标 .NET Framework 4.7.2,
由 Windows 10 1803+ / Windows 11 操作系统自带(Win11 为 4.8.x),
无需安装任何 .NET Core/10/自包含运行时。构建机需 .NET SDK 与 .NET
Framework 4.x 定位包(随 VS/SDK 安装;无定位包时给 csproj 加
Microsoft.NETFramework.ReferenceAssemblies NuGet 包)。
- DPI 感知(自 0.1.20):宿主声明 PerMonitorV2(
host/app.manifest
清单 + App.config 的 WinForms DpiAwareness 段)。.NET Framework 的
WinForms 默认是 DPI 不感知进程,在 125%/150% 等缩放显示器上 Windows 会把
窗口按 96 DPI 渲染后整体位图放大(DPI 虚拟化)→ 文字与网页内容发糊;
声明感知后按显示器真实 DPI 原生渲染,字迹清晰。
配置
两种途径,等价:
1. 设置表单(推荐)——两条受支持的版本线,插件同时注册、哪条存在就哪条生效:
- 最新版(dsh ≥ 0.1.6,含 0.1.7-alpha.1 与 0.2.x):**「插件管理」页 →
dsh-auto-open-web(bundle 详情页)**,表单直接显示在该页说明与组件行之间
(插槽 plugins.bundle.config,key = bundle 包名)—— 与 dsh-harness-tags
同款席位。0.2.1 该槽的 owner props 仍是 { view: 'summary' | 'page', form? },
bundle 页只传 { view: 'page' },数据由插件自绑:命名空间 = 本条目 id,
经客户端服务 configForms 取 ConfigForm(快照 + set/unset/订阅;镜像首次
加载中会订阅 describe(),命名空间到达后自动补渲染)。此形态只有「保存」,
离开页面即丢弃暂存。
- 最新 rc 线(0.1.5-rc.x):设置 → 插件配置 → 「自动打开网页」折叠卡片
(插槽 settings.plugin.item,按设置命名空间 keyed)。数据走宿主
settings.register + 客户端 settingsScope。
两条线的客户端服务互不存在(新版的 configForms ↔ rc 线的
settingsScope),因此插件把这两个服务都改为惰性读取、inject 只声明
两线共有的服务(slots/locale/connection/remote)——否则硬注入会让插件
在另一条线上永远 pending、设置界面完全不出现。
dsh ≥0.1.7 的 .volatile() 字段在宿主侧是 Volatile 引用(config.<f>.get()):
插件统一解包后再归一化;schemastery 没有 .volatile() 的旧线自动退回普通 schema。
更早的版本(0.1.0-rc.、0.1.1-rc.、0.1.2-*/0.1.3-alpha/0.1.5-alpha/0.1.6-alpha.1)
不再保证。
两种入口都可编辑 appWindow(独立应用窗口)、windowKind(WebView2 宿主 /
浏览器应用窗口)、browserPath(浏览器可执行文件,支持「浏览」原生对话框
选择;位于窗口类型下方,仅选择「浏览器应用窗口」时使能)、
exitOnWindowClose(窗口关闭时退出 DSH,默认关闭)。
保存后设置值优先于行配置(新版落在该行的用户层覆盖上,rc 线落在
auto-open-web 设置命名空间);宿主仅保留「浏览」「测试」辅助路由
(官方通道无法覆盖的能力)。
2. 行配置(cordis.patch.yml):作为启动种子,设置表单保存前生效。
字段 · 默认 · 说明
appWindow · true · 启动时自动打开独立应用窗口;false 时与官方相同——用系统默认浏览器打开 GUI(普通标签页,官方 open 方式)
windowKind · webview2 · webview2 = WebView2 宿主(独立进程、任务栏 DSH 图标、随 DSH 退出);browser = 浏览器 --app 专用实例。所选类型不可用时仅记录日志、不打开
exitOnWindowClose · false · (实验性)关闭自动打开的窗口时随之退出 DSH(默认关闭;仅 appWindow 开启时生效)。窗口进程正常退出(用户关闭窗口)时触发 process.exit(0);启动失败/崩溃/被强杀(非 0 退出码)不触发,避免误退出。设置卡片保存后当前会话即时生效(退出监听始终注册、行为由实时标志决定),无需重启 DSH
browserPath · '' · 手动指定的浏览器可执行文件路径(单条,如 C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe;仅浏览器模式使用),优先于内置候选 Edge → Chrome;路径不存在会跳过并告警。设置卡片上的「浏览」按钮弹出原生文件对话框:与官方工作区目录选择器同一机
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::15,最后更新 2026-10-25