| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two live-reproduced bugs in Windows node start/stop, found sideloading the
0.14.0 build:
- node:start's crash-recovery step killed a service-mode daemon with
taskkill/CTRL_BREAK, both of which fail with "Access is denied" against a
process running under the Scheduled Task's own S4U logon session (a
different session from the Electron app's). The daemon it was meant to
replace just kept running, unreplaced, and schtasks /run on a task Windows
still considered Running was then a silent no-op too. Route through
winServiceTaskEnd() (schtasks /end) first, the way nodeServiceStop/
nodeServiceRestart already correctly do. service-mode.ps1 also now starts
the task right after registering it -- Register-ScheduledTask's own
AtStartup trigger does not run it immediately, so nothing was listening
until the next reboot.
- The Node page's Start button called node.start() with no arguments, so an
unlinked node (a fresh install, or one whose hub-side link was lost) could
never link on Start alone -- only create-group-page.js's own call passed
{hubUrl, username, token}. Reproduced on a fresh non-service install signed
in to the real hub: Start hung for ~105s and failed with "could not link",
pointing at a "Link Node" control that lives on Settings, not the Node
page (that message is fixed too).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A second-machine sideload of the MSIX target surfaced three things the
earlier verification round (which only proved the package installs and
runs) had missed:
1. meshbay-node missing from PATH. installer.nsh's customInstall adds
node-runtime\ to HKCU\Environment at install time -- an unelevated
per-user write, never blocked by MSIX's no-elevation rule, only by the
more basic fact that an AppX/MSIX install runs no custom code at all.
packaging/win/ensure-node-path.ps1 (idempotent, no admin verb) plus
main.js's winEnsureNodeOnPath() do it from the app itself instead, once
per launch, shipped to Full and MSIX (not Light, nothing to add there).
Verified live via the Node inspector protocol: the entry was in
HKCU\Environment\Path after a launch, absent before.
2. A daemon that crashes on startup failed silently. spawnNodeDetached()
used stdio: 'ignore', so a real crash reproduced live (a second instance
colliding with the first on 127.0.0.1:18000) left waitForNode()'s
generic 60s timeout as the only failure ever shown. spawnNodeDetachedWatched()
pipes stdio and watches ~2.5s, rejecting immediately with the daemon's
own stderr on an early exit; a survivor has its streams released and
runs fully detached exactly as before. First version bounded the
captured text by line count and a live test showed that cut the actual
OSError line -- two uvicorn/asyncio tracebacks followed it in the real
capture -- so it is bounded by characters instead.
3. No hint that a startup-mode choice exists. The install-time radio page
was the only place this was ever offered, and nothing replaces it now
that no install-time page can exist at all. SetupWelcome (the existing
first-run banner) grew a conditional hint, shown only while a bundled
node is present and neither autostart nor service mode is configured
yet. Considered and rejected: linking straight to the Node page -- its
route is gated on a linked hub node key, false on the exact fresh-install
screen this hint targets, so the link would have been dead on arrival.
New key setup.node_startup_hint, added to all ten locale catalogues.
test_packaging_win.py gained six tests pinning all three (69 total).
Full plan and verification detail: C:\Users\admin\devel\msix-installer.md
section 13 (out of repo).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Store certification of the NSIS "MSI/EXE" submission failed on three
checks (silent-install verification, Add/Remove Programs entry, bundleware
check) -- traced and reproduced live to one cause: SmartScreen blocks an
unsigned, internet-downloaded installer at the shell layer before
Microsoft's own unattended validation bot ever gets to run it. MSIX
sidesteps this class of failure entirely: submitted through the Store's
native pipeline, there is no browser-download-then-launch step for
SmartScreen to intercept, and Microsoft signs the package itself at
publish time -- free, and specific to this submission type (Trusted
Signing remains a paid service for the MSI/EXE path). Full plan and
findings: C:\Users\admin\devel\msix-installer.md (out of repo).
electron-builder.msix.yml carries the same bundle as Full (node runtime,
ffmpeg, both service scripts) -- an AppX/MSIX install never elevates, by
design, but that changes only *when* the two elevated operations can run,
not whether the daemon ships. No main.js changes were needed: the on-demand
elevation path for service-mode (winElevateServiceMode(), driven from the
Node page) already existed for a different reason and depends only on
service-mode.ps1 being present as an extraResource, true for any packaged
Windows target. identityName/publisher/publisherDisplayName are the real
values from Partner Center's app-identity reservation, not placeholders.
build-win-msix.ps1 points electron-builder at the system Windows 10 SDK
(auto-detected) instead of letting it download its own bundled copy --
that download's 7z extraction creates symlinks this target never uses and
fails without SeCreateSymbolicLinkPrivilege, reproduced on this machine.
build/appx/ carries the four tile images the AppX target requires
regardless of showNameOnTiles, generated once from the existing app icon
(see that directory's README) since the system-SDK redirect has no vendor
samples to fall back to. build/appx-extensions.xml declares
windows.startupTask by hand rather than via electron-builder's
addAutoLaunchExtension, which always targets the Electron shell -- this
points at the bundled node binary instead, matching what "starts at sign
in" already means for Full.
Verified live via a signed sideload install (self-signed test cert,
cleaned up after): the package installs and the app runs correctly. One
finding worth carrying forward -- the declared network capabilities
(internetClientServer, privateNetworkClientServer) do not create any
firewall exemption for this app, most likely because automatic
capability-based exemption is an AppContainer-sandbox property and this
app deliberately runs full-trust, outside any sandbox. Not a regression:
no install-time elevation was possible either way, so the cost is the same
one-time OS firewall prompt firewall.ps1's own header already documents as
its fallback today.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
MeshBay Light ships the Electron client + UI only -- no PyInstaller node
freeze, no ffmpeg, no service install/autostart. Two standalone
electron-builder configs (Full via package.json's build field, Light via
electron-builder.light.yml passed with --config, which reads only that
file -- confirmed against app-builder-lib's own config loader) rather than
one config branching on a flag.
build-win-common.ps1 holds the steps both orchestrators share (Node check,
npm ci, Electron bump, sync-ui) so build-win.ps1 (Full) and the new
build-win-light.ps1 cannot drift apart; build-win.ps1 is refactored to
dot-source it with no behavior change (rebuilt and diffed byte-identical
output).
installer-light.nsh keeps the one thing Light still needs -- an
unconditional firewall rule, since the client listens too -- and none of
the service-mode/autostart machinery installer.nsh carries, which has
nothing to gate without a bundled node.
dist-light/ (Light's own electron-builder output dir) gets its own
.gitignore line since the bare dist/ rule does not match it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two independent breaks in the Windows first-run path:
- node:start's win32 branch never linked the node's Ed25519 key to the hub
account, so the daemon sat at waiting_for_account and the Create Group
wizard span on "Detecting local node…" for ever — the only way through
was pasting the key by hand on the Profile page. The Linux branch has
always done this inline; factor it into linkNodeKeyAndAwaitRunning() and
call it from win32 too. PUT /v1/users/me/node_key overwrites, so this
also recovers an account still carrying a previous machine's node key.
- service.ps1's install branch did `$action = New-ScheduledTaskAction`,
shadowing its own [ValidateSet(...)][string]$Action parameter (PowerShell
variable names are case-insensitive). The CimInstance was coerced to the
string "MSFT_TaskExecAction", Register-ScheduledTask -Action rejected it,
and "background service" mode never created the task — reproduced live.
Rename the locals to $taskAction / $bootTrigger / $taskPrincipal.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
-LogonType S4U
schtasks.exe has no flag naming the logon type directly -- it only infers
S4U vs Interactive from whether /rp is present, and both readings broke
live on a blank-password account: /rp "" fails schtasks' own credential
validation, and omitting /rp registers "Interactive only", which never
launches the process at boot or on demand despite installing cleanly.
Register-ScheduledTask -LogonType S4U names the logon type explicitly, no
inference. Confirmed live: install, manual start, and unattended boot-time
start all now work.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
winget install ffmpeg was considered and rejected as the mechanism: it
needs network access and winget/App Installer present at the exact
moment setup runs, and its failure mode is silent -- video just does
not stream, with nothing pointing back at ffmpeg. Not viable for a
non-technical install.
MeshBay transcodes browser-incompatible video to H.264 (-c:v libx264,
webrtc_server.py) -- a real encode, not remux -- so this needs a genuine
GPL ffmpeg build; no LGPL-only build includes an H.264 encoder, since
libx264 itself is GPL.
packaging/win/fetch-ffmpeg.ps1 (new)
Downloads, checksum-verifies and stages ffmpeg for the build. Source:
BtbN/FFmpeg-Builds' Windows x86_64 gpl-shared preset -- shared DLLs
rather than two independent static binaries, which is what nearly
tripled this: the "full" static build many devs already have via
winget is ~220 MB *per executable*. Pinned to one dated release tag
(immutable once published) and its own sha256, not the "latest" alias
BtbN repoints on every auto-build -- verified by hand first (downloaded,
hash matched, ran a real encode+probe with libx264) before pinning.
ffplay.exe (an SDL2 player, ~17 MB) is dropped; MeshBay never invokes
it. Cached after the first build. Runs its own smoke test (encode +
probe a real clip) so a broken fetch fails at build time, not for the
first user who tries to watch something.
packaging/win/LICENSE-ffmpeg.txt (new)
GPLv3 notice + where the corresponding source is, required because
this redistributes a GPL binary even though it is unmodified and only
ever invoked as a subprocess. Ships alongside ffmpeg.exe in the
installer.
build-node-runtime.ps1 / build-win.ps1
Bundling is now the DEFAULT, replacing the old opt-in -FfmpegDir (which
copied from a local directory and left most builds without ffmpeg at
all). -SkipFfmpeg opts out for a smaller, streaming-less local-iteration
build.
Also fixes a real bug the ffmpeg change exposed rather than caused: the
final `--help` smoke test did `$help -notmatch "meshbay-node"` against
$help captured as a PowerShell ARRAY (one element per line) -- -notmatch
on a collection is a FILTER, not a boolean test, and returns the
non-matching elements; any non-empty array is truthy in if() regardless
of content. Once --help wrapped past one line (it now does, with
autostart/service in the verb list) this threw unconditionally. Fixed
by joining to one string before matching, and pinned by a new test so
a future edit cannot silently reintroduce the collection-vs-scalar trap.
Verified: downloaded and hashed the pinned release by hand (matches),
ran a real libx264 encode + ffprobe against the extracted build,
fetch-ffmpeg.ps1 end to end (161 MB staged), a full build-node-runtime.ps1
run (308 MB node-runtime/) and a full installer build (MeshBay-Setup-
1.0.0.exe, 210.8 MB with ffmpeg bundled). Node suite 850 pass / 25 skip.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The per-user Startup-folder launcher (W3) only ever runs after this user
signs in. A real Windows Service would start earlier, but under
LocalSystem/NetworkService -- accounts with no normal profile, so
%LOCALAPPDATA%\meshbay\ (config, keystore, data) would not exist for it.
Relocating storage to make that work is real surgery, deliberately not
done here.
Instead: a Scheduled Task, created once with admin rights, that runs AS
THIS USER at boot without needing them to sign in first.
`schtasks /create ... /ru <user> /rp ""` with no `/it` registers an S4U
(Service For User) logon -- no password stored anywhere, and unlike
LocalSystem it loads this account's own profile, so config_dir()/
data_dir() need zero changes. The cost: S4U carries no network credential,
which the node never needed -- everything it touches is local disk plus
outbound internet. Creating the task needs admin (a boot trigger touches
system-wide scheduler state, the same reason /sc onlogon needed it);
querying/starting/stopping an existing one does not -- Task Scheduler
grants the owning user that much itself, which is what lets the Node
page's Start/Stop/Restart drive it with no further UAC prompts.
meshbay_node/platform.py
service_install/_remove/_status/_run/_end -- mirrors autostart_* but
for the Scheduled Task; TASK_NAME moved here (was decorative before)
meshbay_node/daemon.py
new `service install|remove|start|stop|status` verb; restart-daemon and
reset now check for the service task too
packaging/win/service.ps1
the installer-side equivalent (extraResource); status/run/end never
self-elevate -- only install/remove do, exactly matching what
Task Scheduler itself requires
packaging/win/service-mode.ps1
ONE elevated helper running service.ps1 + firewall.ps1 together, so
choosing service mode costs exactly one UAC prompt, not two
build/installer.nsh
the install-time choice: "run as a background service?" (one
elevation, both jobs) vs the existing per-user + separate firewall
question. Checked first, unelevated, so re-running setup with
everything already configured asks nothing. Uninstall offers the
matching one-elevation cleanup, default No.
src/main.js
winServiceTaskStatus/Run/End, wired into node:installed,
node:service-status/-stop/-restart and node:start: when the Scheduled
Task exists, drive it; otherwise fall back to the existing per-user
spawn/kill path. This is the hard requirement -- Start/Stop/Restart
from the Node page must work in either mode.
node-page.js / locales
a hint explaining why the per-user autostart toggle is absent when
service mode is active (info.mode from the backend, no new field to
gate on -- it just isn't sent in that case)
package.json: 0.1.0 -> 1.0.0.
Verified: electron-builder compiles the new NSIS choice logic and ships
all three scripts; service.ps1's S4U install fails cleanly (Access
denied) when run unelevated, and its status/run/end never touch "runas".
Cannot verify the elevated success path myself (no admin in this
session) -- that needs a real UAC click. Node suite 843 pass / 25 skip;
test_packaging_win.py pins the one-elevation property, the S4U flags,
and that main.js actually checks the service task in all three handlers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Every run of customInstall showed the "Allow MeshBay through Windows
Firewall?" question and, on Yes, a fresh UAC prompt -- an upgrade or repair
install would ask again even with all four rules already in place.
customInstall now checks first: firewall.ps1 check, unelevated
(Get-NetFirewallRule needs no admin, only New/Remove do), exits 0 if every
rule already exists. Only a nonzero result reaches the MessageBox and the
elevated add. A second run of setup on an already-configured machine now
asks nothing.
Verified unelevated: check exits 1 and logs which rules are missing on a
machine with none of them (the fresh-install case); electron-builder
compiles the nsExec::Exec / Pop $0 / ${If} wiring. Node suite 837 pass /
25 skip.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
firewall.ps1 only handled WebRTC. The cast HTTP relay (src/cast-relay.js,
fixed TCP 19550-19553) and Chromecast/Smart TV mDNS discovery
(src/cast-chromecast.js, bonjour-service, UDP 5353) are a separate surface
on the client and were still hitting Windows' own "Allow access" dialog.
Now four named rules: MeshBay / MeshBay Node stay program-scoped with no
port restriction (there is no fixed WebRTC port to name -- the Windows
equivalent of the broad 1024-65535/udp range the Linux packaging needs,
since netfilter has no program scoping); MeshBay Cast / MeshBay Cast
Discovery add the program AND the fixed port, matching
packaging/firewall/*/meshbay-cast.xml exactly.
test_packaging_win.py cross-checks the port numbers against cast-relay.js's
own constants and the Linux firewalld definition, so the three descriptions
of one port range can't quietly drift apart.
Verified: rebuilt MeshBay-Setup-0.1.0.exe; the deployed firewall.ps1 carries
all four rules. Node suite 836 pass / 25 skip.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Installing used to mean clicking through two separate Windows "Allow
access" prompts later — one for MeshBay.exe, one for meshbay-node.exe —
each confusing on its own and worse before the exe carried a version
resource. Adding a firewall rule needs admin, and the installer is
deliberately per-user with no elevation, so this can only ever be opt-in.
packaging/win/firewall.ps1 (new, shipped as an extraResource at
resources\firewall.ps1): idempotent add/remove of the two inbound UDP
rules ("MeshBay", "MeshBay Node"), grouped, logged to
%TEMP%\meshbay-firewall.log. Locates both executables from its own path,
no arguments needed beyond the action.
build/installer.nsh: customInstall asks "Allow MeshBay through Windows
Firewall now?" and runs firewall.ps1 via NSIS ExecShellWait "runas" — one
UAC prompt — only when not ${Silent}; declining or dismissing UAC falls
back to Windows' own per-process prompts, unchanged. customUnInstall
offers the same in reverse, defaulted to No (a stale rule for a deleted
exe is inert, so this should not nag on the way out) and skipped for a
silent uninstall.
Verified: rebuilt MeshBay-Setup-0.1.0.exe (electron-builder compiles the
new LogicLib.nsh / ExecShellWait NSIS successfully); firewall.ps1 run
unelevated fails cleanly into its log ("Access is denied") rather than
silently doing nothing, confirming the fallback path. Node suite 835
pass / 25 skip.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
meshbay-node.spec now builds a VSVersionInfo (ProductName "MeshBay Node",
version read from the installed package so it tracks pyproject) and passes
it to EXE(version=...). The Windows Firewall prompt, Task Manager and the
file's Properties then show "MeshBay Node" instead of a bare exe name —
the prompt the operator has to answer on first run.
packaging/win/README.md gains a Networking section: the first-run firewall
prompt (allow Private AND Public — a VM adapter is Public), that a flat LAN
needs nothing else, what a routed/multi-subnet LAN additionally needs, the
libvirt-NAT caveat, and a pointer to the packaged Linux firewall profiles.
test_packaging_win.py covers the version resource.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
default.env was empty in every build, for three independent reasons:
1. build-node.sh read QE/node.env, which does not exist. Even pointed at the
real file it would have failed: its `grep MESHBAY_TMDB_DEFAULT_TOKEN=`
cannot match QE/tmdb.txt, which is a free-form note, not KEY=VALUE.
2. Nothing consumed default.env. packaging/README.md and build-node.sh both
claimed `meshbay-node init` copies it to <config>/node.env; grep found the
name in exactly two places, the README and the script that writes it. No
code implemented the copy, and `EnvironmentFile=-` hid the absence.
3. build-win.ps1 had no env handling at all, so Windows was empty for a
different reason than Linux.
Now: the build extracts the v4 read token -- tmdb.py sends `Authorization:
Bearer`, so it is the JWT, not the 32-char v3 key beside it in the same file --
matching KEY=VALUE first and then by shape, from MESHBAY_TMDB_TOKEN,
MESHBAY_TMDB_TOKEN_FILE, QE/node.env, QE/tmdb.txt. It writes default.env 0600
and *fails the build* if no token resolves; MESHBAY_ALLOW_NO_TMDB=1 opts out.
An empty default.env is invisible until a user opens Videos and finds no
metadata, which is how this shipped empty on two platforms at once.
platform.py gains packaged_default_env()/install_node_env()/load_node_env().
init copies the packaged file once, never overwriting an existing node.env,
and the daemon loads node.env itself at startup: systemd does this on Linux
via EnvironmentFile, but Windows autostart is a Startup-folder .vbs with no
equivalent. Already-set variables always win.
Also fixes an UnboundLocalError in main(): `config_dir` was assigned at the
top of the init branch, which made it function-local for all of main(), while
the reset branch calls `config_dir()` as the imported function. init returns
before that line, so `meshbay-node reset` could only ever raise. The local is
now cfg_dir.
Verified end to end on Linux: token baked (239 chars), init writes
<config>/node.env 0600 with it. The PowerShell half is written but unrun --
no pwsh on this machine.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtfG7z6wHWj8RKHCvxQtY1
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The installer had no console entry point, so running the CLI meant cd-ing
into resources\node-runtime\ every time. installer.nsh now adds that dir to
HKCU\Environment\Path on install and removes it on uninstall, via stock
WordFunc.nsh (electron-builder's NSIS bundle has no EnVar plugin). It points
at the real meshbay-node.exe dir — not a shim — so `where meshbay-node`,
findNodeBinary and the W3 autostart launcher all resolve to the same binary.
A WM_SETTINGCHANGE broadcast nudges open shells; new ones just work.
Rebuilt: electron-builder --win nsis compiles the WordFunc includes fine,
MeshBay-Setup-0.1.0.exe (155 MB). test_packaging_win.py covers the add/remove
symmetry.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
|
`npm run dist:win` produces MeshBay-Setup-<version>.exe: the Electron client
and, beside it under resources/node-runtime/, the frozen meshbay-node daemon
(meshbay-common inside it). No hub. Per-user, no elevation — matches the W3
constraint that a logon-triggered scheduled task needs admin.
electron-builder / package.json
build.win nsis, build/icon.ico, extraResources -> node-runtime/
build.nsis oneClick:false perMachine:false allowElevation:false
allowToChangeInstallationDirectory:true
dist:win -> packaging/win/build-win.ps1 (mirrors dist -> build-client.sh)
packaging/win/
meshbay-node.spec + node-entry.py PyInstaller freeze of
meshbay_node.daemon:main. The awkward deps (aiortc, av, aioquic,
pydantic_core, uvicorn, watchdog, guessit, blake3, tzdata) are pulled
in whole with collect_all — that list is expected to grow when a frozen
run raises ModuleNotFoundError.
build-node-runtime.ps1 throwaway venv -> pip install -> PyInstaller ->
packages/meshbay-client/node-runtime/ (gitignored)
build-win.ps1 Node>=22 check, npm ci, Electron bump, sync-ui,
node runtime, electron-builder --win nsis
bump-electron.mjs the Chromium-CVE "build against latest Electron"
policy, out of the PS script (5.1 here-string terminator rules)
README.md
PyInstaller, not the python-embed zip: the frozen meshbay-node.exe is a
genuine relocatable single binary, which is what src/main.js:findNodeBinary
spawns (process.resourcesPath/node-runtime/meshbay-node.exe when packaged) and
what the W3 autostart launcher points at. The embeddable zip needs pip to make
that wrapper and the wrapper bakes in an absolute interpreter path.
build/installer.nsh: on uninstall, taskkill meshbay-node.exe and delete the W3
Startup .vbs (it would point wscript at a deleted binary every sign-in).
%LOCALAPPDATA%\meshbay\ — node.toml, keystore.enc — is never touched.
ffmpeg is not bundled by default (node finds it on PATH); build-win.ps1
-FfmpegDir copies ffmpeg.exe/ffprobe.exe in for a self-contained installer.
Verified on the Windows guest: PyInstaller freeze builds first try
(node-runtime 147 MB), frozen `meshbay-node status` talks to the live daemon's
loopback API; electron-builder --win nsis produces MeshBay-Setup-0.1.0.exe
(155 MB), oneClick/perMachine flags applied, node-runtime bundled at the path
findNodeBinary expects. test_packaging_win.py (14) pins the config invariants
and the NSIS <-> platform.py autostart seam. Node suite 798 pass / 34 skip.
Open: Authenticode signing (13.9 — unsigned => SmartScreen), Windows CI
(18.3), electron-updater. First clean-machine install + DPAPI + autostart
round-trip is a manual check.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|