Files
HomeAgent/cmd
JianFeeeee 58ad6831f5 fix(gui): 静默启动开关此前是死设置,永远不生效
## 现象
设置页有「静默启动」开关,文案写着「启动时不显示主窗口,驻留托盘
后台运行」,勾选后启动 GUI 照样弹窗。

实测(本机,gui-prefs.json 里 silentStart=true):窗口标题 HomeAgent
照常出现。

## 根因
silentStart 从未被消费:
  · main.js 的 loadGuiPrefs() 把它读进对象
  · 渲染层设置页读写它
  · **但主进程没有任何地方读它做判断** —— whenReady 无条件 createWindow()
是个纯粹的界面开关,接线缺失。

## 改动
1) createWindow(show = true):支持「创建但不显示」。
   BrowserWindow 初始 show:false,非静默时经 ready-to-show 显示
   (避免先显示再隐藏的闪烁)。

   ★ 为什么静默时**仍然创建窗口**、而不是不创建:
     不创建 ⇒ 渲染进程不启动 ⇒ app.js 整个不执行 ⇒ SSE 通道、
     设备桥轮询、聊天全部失效,GUI 退化成纯托盘图标;且
     showMainWindow() 只做 show()、不会创建窗口,app.on("activate")
     又只在 macOS 触发 —— Windows 上托盘点「显示主界面」将毫无反应,
     进程变成唤不起来的僵尸。已按此结论实现(评审时确认为「创建后隐藏」)。

2) whenReady 读 silentStart 并据此 createWindow(!silent)。
   与 applyAutoLaunch 里的 openAsHidden 是两条不同路径:那个告诉 OS
   「开机自启时如何启动」,这里决定本进程要不要显示,对手动启动同样生效。

3) showMainWindow() 增加兜底:窗口不存在时重建;隐藏时先 show 再 focus。
   消除上述「唤不起来」的隐患。

4) loadGuiPrefs() 补去 UTF-8 BOM。
   ★ 这是排查中发现的**第二个真实缺陷**:Windows 工具
   (PowerShell Set-Content -Encoding UTF8、记事本)改过 gui-prefs.json
   会写入 BOM,而 JSON.parse 遇 BOM 直接抛错 → 走 catch → 返回**默认
   prefs** ⇒ silentStart/exitToTray/deviceBridge 全部被静默重置,
   表现为「开关保存了但不起作用」。loadConnections 早就有去 BOM 处理、
   这里没有,两个读取点不一致。
   (本次实测正是被自己的判据脚本用 Set-Content 改 prefs 后踩到的。)

## 判据
新增 cmd/gui/silent-start.test.mjs(进 npm test),14 条断言:
  · whenReady 确实读 silentStart 并决定 show
  · 静默路径仍创建窗口(不许退化成不建窗)
  · showMainWindow 能在窗口缺失时重建
  · loadGuiPrefs 去 BOM,且 loadConnections 的既有处理不回退
已做变异测试:还原成无条件 createWindow()、抽掉 BOM 处理,均判红。

## 实测(本机 Electron,真实 prefs)
  silentStart=true  → processes=8 visibleWindows=0,日志出现
                      [startup] silentStart=on: window created hidden
  silentStart=false → processes=4 visibleWindows=1(标题 HomeAgent)

判据:cmd/gui npm test 全绿(46 条)。
2026-10-02 09:47:11 +08:00
..