Skip to content

feat(desktop): add optional Electron desktop shell for Windows - #224

Open
mochen555 wants to merge 6 commits into
OpenBMB:mainfrom
mochen555:feature/electron-desktop
Open

feat(desktop): add optional Electron desktop shell for Windows#224
mochen555 wants to merge 6 commits into
OpenBMB:mainfrom
mochen555:feature/electron-desktop

Conversation

@mochen555

Copy link
Copy Markdown

Summary

Adds an optional, self-contained Electron desktop shell (desktop/) for
StaffDeck on Windows. It reuses the existing PyInstaller-packed backend
(packaging/out/staffdeck) and loads the already-served web UI into a native
window instead of the system browser.

Additive & opt-in: existing backend/frontend/official pipeline untouched.

Features

  • Auto-launches the backend (dev: backend/.venv, packaged: resources/backend/staffdeck.exe)
  • Backend runs headless — no extra browser tab
  • Native window loads /chat/
  • System tray: close-to-tray (stay resident), tray menu (open / restart / quit),
    click-to-toggle window
  • electron-builder bundles backend + tray icon

Packaging: problems encountered & how they were solved

  • Electron binary / NSIS download in CN network
    Added CN mirrors in desktop/.npmrc and env vars (ELECTRON_MIRROR,
    ELECTRON_BUILDER_BINARIES_MIRROR) to speed up downloads.
  • electron-builder winCodeSign symlink permission error on Windows
    The bundled winCodeSign archive contains macOS .dylib symlinks; extracting
    them fails with "client does not possess the required privilege" unless
    Windows Developer Mode is enabled. Workaround: enable Developer Mode, or
    run as admin. This is a known electron-builder quirk on non-admin Windows.
  • PyInstaller backend must be built BEFORE electron-builder
    electron-builder.yml extraResources.from points at packaging/out/staffdeck,
    so run the official backend build first (build_windows.ps1 / the ultrarag.spec
    command) — otherwise the installer has no backend to bundle.
  • Packaged app opens an extra browser
    desktop_launcher.py auto-opens the browser unless STAFFDECK_HEADLESS=1;
    the shell sets this env var when spawning the backend.

Build & run

# dev
cd desktop && npm install && npm start

# backend (first)
$env:VERSION="0.5.0"; .\packaging\build_windows.ps1   # or run ultrarag.spec
# installer
cd desktop && npm run dist    # => dist/StaffDeck Setup 0.5.0.exe

包一层独立窗口壳,复用现有 Python 后端与已挂载的前端,
替代默认的"启动后跳转系统浏览器"体验。main.js 负责拉起后端、
健康检查(/api/health)、按优先级定位后端地址,并加载 /chat/。
导入国内镜像配置加速 Electron 二进制下载。
开发态下 Electron 壳自动探测 backend/.venv 下的 python 解释器并拉起
desktop_launcher.py,不再依赖 STAFFDECK_URL 或手动先起后端;打包态回退
到 PATH 中的 staffdeck。spawn 参数顺序修正(脚本在前、--host 在后)。

已验证端到端链路:Electron 拉起后端 → 占 5173 → /api/health 命中 →
(spawned=true) 加载 /chat/ 200 OK。
desktop_launcher.py 非 headless 时会在服务就绪后自动 _open_browser_when_ready
打开系统浏览器,导致 Electron 窗口之外又多开一个 tab。由 Electron 窗口负责
UI 展示,故拉起后端时注入 STAFFDECK_HEADLESS=1。

已验证日志输出 headless 启动中,/chat/ 由 Electron 窗口单独加载。
打包态下 Electron 壳从 process.resourcesPath/backend 拉起 PyInstaller 产出
的 staffdeck.exe(自带 Python 运行时),实现装完即用。已验证打包版
frozen=True 独立运行。

配套 electron-builder.yml 通过 extraResources 把 packaging/out/staffdeck
打进安装包。
代码已含上游 v0.5.0(main 比 v0.5.0 还新),壳元数据版本号此前随手填的
0.4.0,与代码版本脱节。改为 0.5.0 使安装包文件名/版本信息与后端一致。
桌面化第一步:关窗最小化到托盘(应用常驻后台,数字员工服务不中断)。
- 关闭按钮隐藏窗口而非退出,并弹系统气球提示后台运行
- 托盘图标 + 右键菜单:打开 / 服务端口 / 重启服务 / 退出
- 单击托盘图标切换窗口显示/隐藏;真正退出仅经托盘"退出"或关机
- electron-builder extraResources 带入托盘图标
@hm1229
hm1229 requested a review from fadeoreo August 25, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant