Commit Graph
3 Commits
Author SHA1 Message Date
Bernd Rodler cab43b8d06 feat(electron): auto-update via electron-updater + GitHub Releases
Phase 1 step 7 of VNCprodbuild. electron/main.ts calls
autoUpdater.checkForUpdatesAndNotify() once the app is ready, only for
packaged builds (app.isPackaged) - dev/test runs have no latest.yml and
would just log a noisy 404 on every launch. electron-builder.config.js gets
a matching `publish` block pointing at this repo's own GitHub Releases
(brvncde-dotcom/vncmail-plus) - the skill's recommendation over standing up
a new distribution channel, since the repo is already private. Flagged as
the "light decision" the skill calls it, not blocking.

Deliberately defensive: no code signing yet (step 9), so update
verification can fail on macOS in particular. Wrapped in try/catch +
autoUpdater's "error" event so a failed check is logged and swallowed, never
fatal - this is background maintenance, not something the user should be
blocked on.

Verified with a --dir packaged build: checkForUpdatesAndNotify() throws
ENOENT for app-update.yml (expected - that file is only emitted by a full
`electron-builder build`, not --dir) and the error handling swallows it
cleanly; the standalone server still boots and serves the app normally.
npm run test:electron still green (4/4) - autoUpdater is a no-op in the
unpacked dev/test path this suite exercises.
2026-08-04 12:57:13 +02:00
Bernd Rodler 4d817ea932 feat(electron): packaging targets - mac/win/linux, unsigned
Phase 1 step 6 of VNCprodbuild. electron-builder.config.js now has real
targets: mac (dmg, zip; x64+arm64), Windows (nsis; x64), Linux (AppImage,
deb; x64). Still no code signing (step 9 - needs an Apple Developer ID and
optionally a Windows cert, both human-owned purchases).

Icon wired from public/icon-512x512.png (the existing PWA manifest icon) -
electron-builder generates .icns/.ico from it automatically. This is a
stand-in, not a dedicated app icon: it's only 512x512 (the macOS icns's
largest slot wants 1024x1024+), and public/branding/Bulwark_Icon_App.svg
looks like the actual intended master for this, but it's a vector file and
this environment has no SVG rasterizer (rsvg-convert/ImageMagick/Inkscape)
to export it at high res. Flagged in the config's comments; someone with
the right tooling (or a designer) should export that SVG at 1024x1024+ and
swap the `icon` path.

Caught and fixed a real bug by actually running a --dir build rather than
just trusting the config: app-builder-lib's extraResources copy
unconditionally drops any directory literally named "node_modules" sitting
at the copy root (node_modules/app-builder-lib/out/util/filter.js), so the
naive `from: ".next/standalone"` silently stripped the standalone server's
own node_modules and the packaged app crashed with "Cannot find module
'next'" on launch. Fixed by copying from one level up (`from: ".next"` with
a `standalone/**/*` filter) so "node_modules" is never the literal copy
root. Verified by launching the packaged --dir mac build directly - it
boots the standalone server and serves the app with no errors, same as the
unpackaged dev flow.
2026-08-04 12:54:43 +02:00
Bernd Rodler 218a584fb3 feat(electron): walking skeleton for the desktop shell
Phase 1 step 1 of VNCprodbuild: electron/main.ts boots the same Next.js
"standalone" server artifact the Dockerfile already produces (next.config.ts's
output: "standalone") as a child process on a random localhost port, then
opens a BrowserWindow at it. electron/preload.ts is a contextBridge stub
(window.vnc.isElectron) for now.

scripts/assemble-standalone.mjs copies public/ and .next/static into
.next/standalone, mirroring what the Dockerfile does by hand, since `next
build` deliberately leaves both out of the standalone output.
scripts/build-electron.mjs bundles main.ts/preload.ts to CommonJS via esbuild
(already a devDependency).

New npm scripts: build:standalone, build:electron, electron:dev.
electron-builder.config.js is intentionally minimal - no signing, no
platform targets yet, just enough to prove the concept end to end.

Also fixes a pre-existing repo-wide lint gap: vnc/plugins/smime is an
independent sub-package (own package.json/esbuild build, browser-only
globals) that was never added to eslint's ignores alongside repos:: and
examples/**, so `npm run lint` - and the husky pre-commit hook - was failing
on every commit regardless of what changed. Excluded it the same way those
are, and added node globals for scripts/**/*.mjs so the new build helpers
above lint cleanly too.

Verified manually: npm run build:standalone && npm run build:electron &&
electron . boots the server and opens a window with no errors.
2026-08-04 12:41:35 +02:00