Repository navigation
Releases
dsh-web-tray 1.0.2
修掉 4 个"从 WSL 安装后实测"发现的问题。全在启动脚本和安装器 CLI 里,托盘助手本体没有改动。
修复
windows/start.sh用curl -f探测存活,于是 DSH 的 401(实例正常,只是还没有 cookie)被读成"没在跑"。它会在端口已被占用的情况下再起一个实例,而且因为日志是在启动之前截断的,连正在运行的那个实例的 token 行也被抹掉 —— 页面最后打开的是登录错误页,而不是应用。现在:任何 HTTP 响应都算存活(curl 不带-f、wget 按响应行判断、/dev/tcp同以前),并且只在确认要启动之后才截断日志,失败的启动再也吃不掉 token。uninstall在安装目录被"从它自己启动的 DSH 实例"占用时以 EACCES 收尾、退出码 1,尽管文件、快捷方式、托盘都已经正确处理好。现在:删不掉的路径降级成一条警告并仍然算成功,会对目录做短暂重试(句柄随托盘退出而释放),并新增--stop-dsh—— 先停 DSH,这才是真正释放目录的做法。- 机器上没有托盘在跑时,
uninstall也会白等满 10 秒握手超时。现在先问一次有没有托盘在跑,再决定要不要写标记文件。 status把托盘运行时才产生的文件当成安装文件,于是刚装好的健康安装会报10 of 12 files present(缺start.log、tray-selftest.json)。现在INSTALLED_FILES= install 写的东西(status查这份),OWNED_FILES= 卸载清单;空目录会被报成"未安装",而不是"装坏了"。
测试
40 项(原来 35)。新增 tests/start-script.spec.ts:对着真实的 401 应答方、一个死端口和一个不存在的 workspace 运行真实启动脚本(应答方跑在独立进程里 —— execFileSync 会阻塞本进程的事件循环,进程内的 server 永远答不上)。安装器测试覆盖了容错的删除和 INSTALLED / OWNED 拆分。
安装:
npm i -g dsh-web-tray@1.0.2
dsh-web-tray install --distro Debian --workspace ~/workdsh-web-tray 1.0.1
修掉 1.0.0 里两个只在"从 registry 安装后"才会暴露的 CLI 缺陷。都是在发布后对新包做冒烟测试时发现的(直接跑 checkout 时看不到)。
修复
npx dsh-web-tray install什么都不做,还返回 0。npm i -g在 Linux 上的bin垫片是个符号链接,于是argv[1]是链接路径、而import.meta.url是真实文件;入口判断直接比较这两者,得出结论"这个模块是被 import 进来的",于是main()从未运行。现在两侧都先realpath再比较。这条影响所有npx调用和 Linux 上的全局安装 —— 也就是 README 里写的安装方式。dsh-web-tray --version打印的是帮助文本。 帮助里明明写着-v, --version,但"没有动词就打印帮助"的短路分支排在版本分支前面。已把顺序调正。
测试
新增回归:tests/installer.spec.ts 现在通过符号链接驱动 CLI,断言帮助输出与版本号,让"被垫片调用时静默退出"不可能再回来。全套 35 项通过,npm run typecheck 干净。
安装:
npm i -g dsh-web-tray@1.0.1
dsh-web-tray install --distro Debian --workspace ~/workdsh-web-tray 1.0.0
1.0 不再是 DSH 插件。宿主半边(HTTP 路由、设置卡片、产物生成)、客户端 bundle 和 TypeScript 构建链全部删除:不再往 DSH profile 里写任何东西,DSH 也永远不会加载这个包。
现在它是一个独立的 Windows 托盘 + 安装器 CLI:
- 一个 Windows 目录(
%USERPROFILE%\.dsh\dsh-web-tray)装下托盘助手、JScript 启动器、WSL 执行的两个 shell 脚本、三个图标和tray.env; - 开始菜单项
DeepSeek Harness (Web); - npm 包提供 CLI:
install | uninstall | status | open | stop。Node 只在安装和执行这些命令时需要,运行时不需要 —— 托盘是一个隐藏的 PowerShell 进程,WSL 侧只跑那两个脚本。
安装
npm i -g dsh-web-tray
dsh-web-tray install --distro Debian --workspace ~/work不安装也可以直接跑:npx dsh-web-tray install。
从 0.3.0(DSH 插件)升级
装好 1.0,然后把插件和它的旧目录一起删掉 —— 1.0 不保留任何兼容:
dsh plugin --profile web remove dsh-web-tray
rm -rf ~/.dsh/dsh-web-tray保留自 0.3.0
只有打开 / 退出两项、复用优先并原地刷新、按桌面端实测配色与尺寸复刻的菜单、随任务栏主题的黑 / 白 favicon 托盘墨色、没有任何看门狗。
移植时修掉的问题
都由对这份代码的评审发现,多数就在为它新写的代码里:
- 只有以
--app/--app-id启动的进程才算应用窗口。早先按标题判断,会把普通标签页窗口误判为应用窗口对它发WM_CLOSE,关掉用户所有标签页。 - 快捷方式戳按 UTF-8 解析时剥掉 BOM:PowerShell 就是这样写的,
JSON.parse之前直接拒绝,于是 uninstall 删掉了错误的路径却报告成功,桌面 → 开始菜单的迁移规则也从未生效。 - 从戳里读到的路径,只有在"是 Desktop 或开始菜单里的
.lnk"时才会被删除;install 会清掉自己以前写过的过期快捷方式。 - 打开流程不会在启动失败时卡死(
wsl.exe缺失或发行版被改名时$shell.Run会抛异常);UI 线程上的异常写进日志,而不是在隐藏进程里弹模态框(那会变成只能靠任务管理器结束的死托盘)。 - 存活探测改成硬上界的 TCP connect:
Invoke-WebRequest在 WSL 转发的端口上可能远超自己的超时时间,从而阻塞 UI 线程。 - 被跳过的窗口计数在所有返回路径上都保留;托盘图标坏了只记一次日志而不是每 5 秒一次;退出项按梯度关窗口:shell 自己的激活 → Ctrl+W → 只对应用窗口发
WM_CLOSE。 - install 在 Windows 上会明确拒绝,而不是抛内部路径错误;
open/stop在缺少安装时给出正常提示而不是裸 ENOENT;非 install 动词拒绝 install-only 选项;写快捷方式失败时 install 以非零退出。
测试
34 项:tests/tray.spec.ts(Windows 互操作,驱动真实助手 -SelfTest 并断言它的 JSON 契约)、tests/installer.spec.ts(路径 / 环境 / 文件规则,无需 Windows)、tests/icons.spec.ts(图标帧与几何)。npm run typecheck 干净。
BREAKING CHANGE:包不再声明 dsh、main、exports、peerDependencies,不能再作为 DSH 插件 bundle 安装;改为暴露一个 bin。
dsh-web-tray 0.3.0
0.2.0 Windows 侧评审的修复,外加两处看得见的变化。
新增 / 变化
- 托盘图标改为页面 favicon 上的鲸鱼(
dsh-web-tray-black.ico/dsh-web-tray-white.ico):去掉圆角底板,按任务栏主题取黑 / 白(每 5 s 读一次注册表),尺寸与桌面应用自带的托盘图标一致;0.2.0 的反色底板会被删除。 - 新增
tray-shortcut.json(快捷方式戳):记下目标、参数、图标以及.lnk自身的大小与摘要。被替换、从备份还原或手工改过的快捷方式会被重建,而不是"只要存在就被信任"。 - 打开方式:优先用 Chromium 的
--app=<url>应用窗口,并且用的是你实际在用的那个浏览器(读默认浏览器的 ProgID 命令行,连同它的--user-data-dir/--profile-directory);已经在显示 DSH 的窗口会被刷新并前置,而不是再开一个标签页。 - 快捷方式目标改为通过注册的脚本引擎解析,不再写死
wscript.exe路径。
修复(来自 0.2.0 评审)
- 烘进生成脚本的每个值都做 bash 单引号处理:路径里的
$()、反引号、换行不再被执行或写坏。 -Uninstall与重新生成走names.ts里的同一份文件清单;卸载会报告删不掉的东西,而不是声称成功。- 助手最外层加
trap:未捕获错误写进tray.log,不再静默失败;Add-Type失败会降级成系统样式的菜单。 wsl.exe -d <发行版>与 WSL 脚本路径分别按 CreateProcess / bash 规则加引号;rm -rf加引号并检查退出码。- 产物改为 temp + rename 原子写,
regenerate()单飞(并发只跑一次)。 ensure()把"遗留文件"和"过期的快捷方式"视为待升级:戳不匹配就重建。- 助手把
PSModulePath归一到$PSHOME\Modules:装了 PowerShell 7 的机器会让 5.1 拿到以 7 的目录开头的模块路径,Get-FileHash解析失败,戳因此从未写出来过。 $HOME/.dsh/dsh-web-tray.env(chmod 600,每行一个KEY=VALUE)成为把密钥转发给 DSH 的正式方式;旧的github-mcp-token仍然生效。pkill兜底也覆盖全局安装的dsh(node /usr/local/bin/dsh web)。- PowerShell 探测遍历所有已挂载盘符,不再写死
C:。
测试
66 项(原来 39)。新增 tests/service.spec.ts:通过注入的宿主桥驱动生命周期本身 —— 幂等、旧版本残留、被替换的快捷方式、并发生成只跑一次 —— 既不需要 Windows 也不需要 WSL。CI 里可用 DSH_WEB_TRAY_REQUIRE_INTEROP=1 把"缺 interop 而跳过"变成失败。
安装:dsh plugin --profile web add dsh-web-tray@0.3.0
dsh-web-tray 0.2.0
Windows 侧重写:托盘缩到 打开 / 退出 两项,不再有开关、守护进程、空闲停服与状态文件。
破坏性变更
- 移除:托盘上的四个开关、守护进程(自动重启)、空闲自动停服、轮询状态卡片、
netstat采样,以及/status里的 DSH 进程信息。 - 移除
tray-config.json与tray-status.json;重新生成产物时会一并删除。 - 桌面快捷方式改用 JScript 启动器(
wscript.exe //E:JScript //B dsh-web-tray.js)。Windows 11 24H2 起 VBScript 是按需功能,旧的.vbs会被删除。
升级方式:装好后重新生成一次产物即可(挂载插件时自动做),或在设置卡片点「重建桌面快捷方式」。
修复
- 桌面快捷方式在 Windows 11 24H2 上失效(执行
.vbs,而 VBScript 已按需提供)→ 改用 JScript。 - 退出托盘会卡死 UI(在 UI 线程上等
wsl.exe)→ 改为隐藏、异步、不等待。 - 托盘菜单被任务栏和 Alt-Tab 列出(进程持有一个隐藏的 PowerShell 控制台,菜单是无属主顶层窗口)→
FreeConsole+WS_EX_TOOLWINDOW。 stop.sh误杀风险 → 先核对 PID 文件背后的命令行,再决定是否结束进程。
新增
- 托盘菜单按桌面应用自己的菜单复刻:量测出的配色与尺寸、按进程 DPI 缩放;由
tests/tray-menu.spec.ts经 Windows interop 断言。 - 反色托盘图标,与桌面应用自带的托盘图标区分。
- 「打开」优先把已经在显示 DSH 的浏览器窗口拿到前台(web app 窗口优先),并显式排除 Electron 桌面应用。
- 托盘助手
-Uninstall:停掉托盘并只清理本插件自己的产物。
其他
- 39 项测试(其中 6 项经 Windows interop 驱动真实托盘菜单与卸载路径),typecheck / build / pack 全绿。
- 安装:
dsh plugin --profile web add dsh-web-tray@0.2.0