<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packaging/win/service.ps1, branch 0.17</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.17</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.17'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-27T20:20:53Z</updated>
<entry>
<title>fix: Windows installer and desktop app start and stop the node one way</title>
<updated>2026-09-27T20:20:53Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-27T20:20:53Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=8c7e39b6dca758badec6867ab6610fd5e8d93d1e'/>
<id>urn:sha1:8c7e39b6dca758badec6867ab6610fd5e8d93d1e</id>
<content type='text'>
A 0.16 upgrade in service mode left the previous node running: setup's
unelevated taskkill cannot reach session 0, and it ran in customInstall, which
electron-builder inserts after the files are copied. The locked exe was not
replaced, and the new app talked to the old node ("started but could not link",
"No operator paired").

Installer (build/installer.nsh, build/stop-node.ps1):
- customCheckAppRunning, which runs before uninstallOldVersion and extraction,
  stops the node with an embedded stop-node.ps1: control API, then schtasks
  /end, then Stop-Process, and refuses to half-upgrade if one survives.
- An upgrade keeps the mode it finds (task, launcher, previous install),
  restores the sign-in launcher the old uninstaller deletes, and restarts the
  node the way that mode runs it. A silent upgrade of an "at sign-in" install
  used to end with no autostart and no node.
- The uninstaller removes the task and firewall rules only on a real
  uninstall, not on an update.

Desktop app (src/main.js):
- Start, Stop, Restart and node:start go through the CLI's lifecycle verbs
  instead of a second implementation; a child spawned by Electron also held
  Electron's sockets after the app quit.
- "Only while MeshBay is open" is a real mode: the app starts a provisioned
  node at launch and stops the one it started when it quits.
- Switching modes stops the node first -- deleting a task does not end its
  instance, and a new service found the port taken -- keeps the firewall
  rules every mode needs, and starts the node again. A declined or unanswered
  UAC prompt restores the node instead of leaving it stopped, and says that
  nothing changed.
- waiting_for_hub counts as a node that is up; linking waits for a node that
  answers, with a longer deadline, and reports a version mismatch.

Packaging (packaging/win):
- The service task gets no 72-hour limit, runs on battery and ignores a second
  start; service.ps1 status reports a stale registration so setup re-registers
  it; remove ends the running instance before deleting the task.
- build-node-runtime.ps1 starts the frozen daemon in a throwaway profile
  (smoke-node-runtime.ps1) instead of only asking for --help.

The mode that was "Off (start manually)" is labelled "Only while MeshBay is
open" in all ten catalogues.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(win): finish the desktop setup flow — node-key link + service task</title>
<updated>2026-09-05T17:48:10Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-05T17:48:10Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=fff1974edf19cf1186e0f49da5f8a4d237bcb13e'/>
<id>urn:sha1:fff1974edf19cf1186e0f49da5f8a4d237bcb13e</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(node): register the service-mode task with Register-ScheduledTask -LogonType S4U</title>
<updated>2026-09-05T12:48:08Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-05T12:48:08Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=c11dd22b593358ef7932deec53c8200f5f14ed8b'/>
<id>urn:sha1:c11dd22b593358ef7932deec53c8200f5f14ed8b</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: opt-in Windows service mode (boot-time, one elevation) + v1.0.0</title>
<updated>2026-09-04T15:29:24Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-04T15:29:24Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=b78288640d8c13cc0fb3f4ee7c82f3efac33940f'/>
<id>urn:sha1:b78288640d8c13cc0fb3f4ee7c82f3efac33940f</id>
<content type='text'>
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 &lt;user&gt; /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 -&gt; 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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
